diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index f36f7be5e9..4043c4131f 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -424,7 +424,7 @@ struct intel_free_graphics_memory { #define PCH_INTERRUPT_VBLANK_PIPEA_SNB (1 << 7) #define PCH_INTERRUPT_VBLANK_PIPEB_SNB (1 << 15) -// display ports +// graphics port control #define DISPLAY_MONITOR_PORT_ENABLED (1UL << 31) #define DISPLAY_MONITOR_PIPE_B (1UL << 30) #define DISPLAY_MONITOR_VGA_POLARITY (1UL << 15) @@ -436,13 +436,14 @@ struct intel_free_graphics_memory { #define DISPLAY_MONITOR_POLARITY_MASK (3UL << 3) #define DISPLAY_MONITOR_POSITIVE_HSYNC (1UL << 3) #define DISPLAY_MONITOR_POSITIVE_VSYNC (2UL << 3) +#define DISPLAY_MONITOR_PORT_DETECTED (1UL << 2) // TMDS/DisplayPort only + #define LVDS_POST2_RATE_SLOW 14 // PLL Divisors #define LVDS_POST2_RATE_FAST 7 #define LVDS_CLKB_POWER_MASK (3 << 4) #define LVDS_CLKB_POWER_UP (3 << 4) #define LVDS_PORT_EN (1 << 31) #define LVDS_A0A2_CLKA_POWER_UP (3 << 8) -#define LVDS_PIPEB_SELECT (1 << 30) #define LVDS_B0B3PAIRS_POWER_UP (3 << 2) #define LVDS_PLL_MODE_LVDS (2 << 26) #define LVDS_18BIT_DITHER (1 << 25) @@ -511,9 +512,6 @@ struct intel_free_graphics_memory { #define INTEL_DISPLAY_PORT_C (0x4200 | REGS_NORTH_PIPE_AND_PORT) #define INTEL_DISPLAY_PORT_D (0x4300 | REGS_NORTH_PIPE_AND_PORT) -// valid for both DVI/HDMI and DisplayPort -#define PORT_DETECTED (1 << 2) - // planes #define INTEL_PIPE_BASE_REGISTER (0x0000 | REGS_NORTH_PLANE_CONTROL) #define INTEL_PIPE_ENABLED (1UL << 31) diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index 3dee0888c7..dea72a59e0 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -38,6 +38,7 @@ Port::Port(port_index index, const char* baseName) : fPortIndex(index), fPortName(NULL), + fPipeIndex(INTEL_PIPE_ANY), fEDIDState(B_NO_INIT) { char portID[2]; @@ -70,6 +71,33 @@ Port::HasEDID() } +void +Port::PipeSelect(pipe_index pipeIndex) +{ + CALLED(); + + uint32 portRegister = _PortRegister(); + if (portRegister == 0) { + ERROR("%s: Invalid PortRegister ((0x%" B_PRIx32 ") for %s\n", __func__, + portRegister, PortName()); + return; + } + + TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe %s\n", __func__, + PortName(), portRegister, (pipeIndex == INTEL_PIPE_A) ? "A" : "B"); + + uint32 portState = read32(portRegister); + + if (pipeIndex == INTEL_PIPE_A) + write32(portRegister, portState & ~DISPLAY_MONITOR_PIPE_B); + else + write32(portRegister, portState | DISPLAY_MONITOR_PIPE_B); + + fPipeIndex = pipeIndex; + read32(portRegister); +} + + status_t Port::GetEDID(edid1_info* edid, bool forceRead) { @@ -194,6 +222,14 @@ AnalogPort::_DDCRegister() } +addr_t +AnalogPort::_PortRegister() +{ + // always fixed + return INTEL_ANALOG_PORT; +} + + status_t AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode) { @@ -373,6 +409,14 @@ LVDSPort::_DDCRegister() } +addr_t +LVDSPort::_PortRegister() +{ + // always fixed + return INTEL_DIGITAL_LVDS_PORT; +} + + status_t LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) { @@ -465,7 +509,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) } uint32 lvds = read32(INTEL_DIGITAL_LVDS_PORT) | LVDS_PORT_EN - | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; + | LVDS_A0A2_CLKA_POWER_UP; lvds |= LVDS_18BIT_DITHER; // TODO: do not do this if the connected panel is 24-bit @@ -662,6 +706,13 @@ DigitalPort::_DDCRegister() } +addr_t +DigitalPort::_PortRegister() +{ + return 0; +} + + // #pragma mark - HDMI @@ -678,7 +729,7 @@ HDMIPort::IsConnected() if (!gInfo->shared_info->device_type.SupportsHDMI()) return false; - uint32 portRegister = _PortRegister(); + addr_t portRegister = _PortRegister(); TRACE("%s - %d: PortRegister: %" B_PRIx32 "\n", PortName(), PortIndex(), portRegister); @@ -688,14 +739,14 @@ HDMIPort::IsConnected() if (!gInfo->shared_info->device_type.HasPlatformControlHub() && PortIndex() == INTEL_PORT_C) { // there's no detection bit on this port - } else if ((read32(portRegister) & PORT_DETECTED) == 0) + } else if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0) return false; return HasEDID(); } -uint32 +addr_t HDMIPort::_PortRegister() { // on PCH there's an additional port sandwiched in @@ -736,18 +787,18 @@ DisplayPort::DisplayPort(port_index index, const char* baseName) bool DisplayPort::IsConnected() { - uint32 portRegister = _PortRegister(); + addr_t portRegister = _PortRegister(); if (portRegister == 0) return false; - if ((read32(portRegister) & PORT_DETECTED) == 0) + if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0) return false; return HasEDID(); } -uint32 +addr_t DisplayPort::_PortRegister() { switch (PortIndex()) { diff --git a/src/add-ons/accelerants/intel_extreme/Ports.h b/src/add-ons/accelerants/intel_extreme/Ports.h index 13e4fd281a..31bcc6f777 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.h +++ b/src/add-ons/accelerants/intel_extreme/Ports.h @@ -39,6 +39,14 @@ enum port_index { }; +// TODO: This likely should go in some pipe header +enum pipe_index { + INTEL_PIPE_ANY, + INTEL_PIPE_A, + INTEL_PIPE_B +}; + + class Port { public: Port(port_index index, @@ -52,8 +60,13 @@ virtual uint32 Type() const = 0; port_index PortIndex() const { return fPortIndex; } + pipe_index PipeIndex() const + { return fPipeIndex; } + virtual bool IsConnected() = 0; + void PipeSelect(pipe_index pipeIndex); + bool HasEDID(); virtual status_t GetEDID(edid1_info* edid, bool forceRead = false); @@ -75,10 +88,13 @@ static status_t _SetI2CSignals(void* cookie, int clock, private: virtual addr_t _DDCRegister() = 0; +virtual addr_t _PortRegister() = 0; port_index fPortIndex; char* fPortName; + pipe_index fPipeIndex; + status_t fEDIDState; edid1_info fEDIDInfo; }; @@ -98,6 +114,7 @@ virtual status_t SetDisplayMode(display_mode* mode, protected: virtual addr_t _DDCRegister(); +virtual addr_t _PortRegister(); }; @@ -115,6 +132,7 @@ virtual status_t SetDisplayMode(display_mode* mode, protected: virtual addr_t _DDCRegister(); +virtual addr_t _PortRegister(); }; @@ -132,6 +150,7 @@ virtual bool IsConnected(); protected: virtual addr_t _DDCRegister(); +virtual addr_t _PortRegister(); }; @@ -145,7 +164,7 @@ virtual uint32 Type() const virtual bool IsConnected(); protected: - uint32 _PortRegister(); +virtual addr_t _PortRegister(); }; @@ -160,7 +179,7 @@ virtual uint32 Type() const virtual bool IsConnected(); protected: - uint32 _PortRegister(); +virtual uint32 _PortRegister(); }; diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index 155bc6c53f..fde449df3d 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -189,16 +189,16 @@ dump_ports() return; } - TRACE("%s: Connected ports: (port_count: %d)\n", __func__, + TRACE("%s: Connected ports: (port_count: %" B_PRIu32 ")\n", __func__, gInfo->port_count); for (uint32 i = 0; i < gInfo->port_count; i++) { Port* port = gInfo->ports[i]; if (!port) { - TRACE("port %d: INVALID ALLOC!\n", i); + TRACE("port %" B_PRIu32 ":: INVALID ALLOC!\n", i); continue; } - TRACE("port %d: %s %s\n", i, port->PortName(), + TRACE("port %" B_PRIu32 ": %s %s\n", i, port->PortName(), port->IsConnected() ? "connected" : "disconnected"); } } diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index 5c659f9250..aa5cc07f50 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -615,6 +615,9 @@ if (first) { if (!gInfo->ports[i]->IsConnected()) continue; + // XXX: For now we force everything on PIPE A + gInfo->ports[i]->PipeSelect(INTEL_PIPE_A); + status_t status = gInfo->ports[i]->SetDisplayMode(&target, colorMode); if (status != B_OK) ERROR("%s: Unable to set display mode!\n", __func__);