intel_extreme: Add pipe selection for ports
This commit is contained in:
@@ -424,7 +424,7 @@ struct intel_free_graphics_memory {
|
|||||||
#define PCH_INTERRUPT_VBLANK_PIPEA_SNB (1 << 7)
|
#define PCH_INTERRUPT_VBLANK_PIPEA_SNB (1 << 7)
|
||||||
#define PCH_INTERRUPT_VBLANK_PIPEB_SNB (1 << 15)
|
#define PCH_INTERRUPT_VBLANK_PIPEB_SNB (1 << 15)
|
||||||
|
|
||||||
// display ports
|
// graphics port control
|
||||||
#define DISPLAY_MONITOR_PORT_ENABLED (1UL << 31)
|
#define DISPLAY_MONITOR_PORT_ENABLED (1UL << 31)
|
||||||
#define DISPLAY_MONITOR_PIPE_B (1UL << 30)
|
#define DISPLAY_MONITOR_PIPE_B (1UL << 30)
|
||||||
#define DISPLAY_MONITOR_VGA_POLARITY (1UL << 15)
|
#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_POLARITY_MASK (3UL << 3)
|
||||||
#define DISPLAY_MONITOR_POSITIVE_HSYNC (1UL << 3)
|
#define DISPLAY_MONITOR_POSITIVE_HSYNC (1UL << 3)
|
||||||
#define DISPLAY_MONITOR_POSITIVE_VSYNC (2UL << 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_SLOW 14 // PLL Divisors
|
||||||
#define LVDS_POST2_RATE_FAST 7
|
#define LVDS_POST2_RATE_FAST 7
|
||||||
#define LVDS_CLKB_POWER_MASK (3 << 4)
|
#define LVDS_CLKB_POWER_MASK (3 << 4)
|
||||||
#define LVDS_CLKB_POWER_UP (3 << 4)
|
#define LVDS_CLKB_POWER_UP (3 << 4)
|
||||||
#define LVDS_PORT_EN (1 << 31)
|
#define LVDS_PORT_EN (1 << 31)
|
||||||
#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
|
#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
|
||||||
#define LVDS_PIPEB_SELECT (1 << 30)
|
|
||||||
#define LVDS_B0B3PAIRS_POWER_UP (3 << 2)
|
#define LVDS_B0B3PAIRS_POWER_UP (3 << 2)
|
||||||
#define LVDS_PLL_MODE_LVDS (2 << 26)
|
#define LVDS_PLL_MODE_LVDS (2 << 26)
|
||||||
#define LVDS_18BIT_DITHER (1 << 25)
|
#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_C (0x4200 | REGS_NORTH_PIPE_AND_PORT)
|
||||||
#define INTEL_DISPLAY_PORT_D (0x4300 | 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
|
// planes
|
||||||
#define INTEL_PIPE_BASE_REGISTER (0x0000 | REGS_NORTH_PLANE_CONTROL)
|
#define INTEL_PIPE_BASE_REGISTER (0x0000 | REGS_NORTH_PLANE_CONTROL)
|
||||||
#define INTEL_PIPE_ENABLED (1UL << 31)
|
#define INTEL_PIPE_ENABLED (1UL << 31)
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ Port::Port(port_index index, const char* baseName)
|
|||||||
:
|
:
|
||||||
fPortIndex(index),
|
fPortIndex(index),
|
||||||
fPortName(NULL),
|
fPortName(NULL),
|
||||||
|
fPipeIndex(INTEL_PIPE_ANY),
|
||||||
fEDIDState(B_NO_INIT)
|
fEDIDState(B_NO_INIT)
|
||||||
{
|
{
|
||||||
char portID[2];
|
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
|
status_t
|
||||||
Port::GetEDID(edid1_info* edid, bool forceRead)
|
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
|
status_t
|
||||||
AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode)
|
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
|
status_t
|
||||||
LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode)
|
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
|
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;
|
lvds |= LVDS_18BIT_DITHER;
|
||||||
// TODO: do not do this if the connected panel is 24-bit
|
// 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
|
// #pragma mark - HDMI
|
||||||
|
|
||||||
|
|
||||||
@@ -678,7 +729,7 @@ HDMIPort::IsConnected()
|
|||||||
if (!gInfo->shared_info->device_type.SupportsHDMI())
|
if (!gInfo->shared_info->device_type.SupportsHDMI())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 portRegister = _PortRegister();
|
addr_t portRegister = _PortRegister();
|
||||||
TRACE("%s - %d: PortRegister: %" B_PRIx32 "\n", PortName(), PortIndex(),
|
TRACE("%s - %d: PortRegister: %" B_PRIx32 "\n", PortName(), PortIndex(),
|
||||||
portRegister);
|
portRegister);
|
||||||
|
|
||||||
@@ -688,14 +739,14 @@ HDMIPort::IsConnected()
|
|||||||
if (!gInfo->shared_info->device_type.HasPlatformControlHub()
|
if (!gInfo->shared_info->device_type.HasPlatformControlHub()
|
||||||
&& PortIndex() == INTEL_PORT_C) {
|
&& PortIndex() == INTEL_PORT_C) {
|
||||||
// there's no detection bit on this port
|
// 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 false;
|
||||||
|
|
||||||
return HasEDID();
|
return HasEDID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32
|
addr_t
|
||||||
HDMIPort::_PortRegister()
|
HDMIPort::_PortRegister()
|
||||||
{
|
{
|
||||||
// on PCH there's an additional port sandwiched in
|
// on PCH there's an additional port sandwiched in
|
||||||
@@ -736,18 +787,18 @@ DisplayPort::DisplayPort(port_index index, const char* baseName)
|
|||||||
bool
|
bool
|
||||||
DisplayPort::IsConnected()
|
DisplayPort::IsConnected()
|
||||||
{
|
{
|
||||||
uint32 portRegister = _PortRegister();
|
addr_t portRegister = _PortRegister();
|
||||||
if (portRegister == 0)
|
if (portRegister == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((read32(portRegister) & PORT_DETECTED) == 0)
|
if ((read32(portRegister) & DISPLAY_MONITOR_PORT_DETECTED) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return HasEDID();
|
return HasEDID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32
|
addr_t
|
||||||
DisplayPort::_PortRegister()
|
DisplayPort::_PortRegister()
|
||||||
{
|
{
|
||||||
switch (PortIndex()) {
|
switch (PortIndex()) {
|
||||||
|
|||||||
@@ -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 {
|
class Port {
|
||||||
public:
|
public:
|
||||||
Port(port_index index,
|
Port(port_index index,
|
||||||
@@ -52,8 +60,13 @@ virtual uint32 Type() const = 0;
|
|||||||
port_index PortIndex() const
|
port_index PortIndex() const
|
||||||
{ return fPortIndex; }
|
{ return fPortIndex; }
|
||||||
|
|
||||||
|
pipe_index PipeIndex() const
|
||||||
|
{ return fPipeIndex; }
|
||||||
|
|
||||||
virtual bool IsConnected() = 0;
|
virtual bool IsConnected() = 0;
|
||||||
|
|
||||||
|
void PipeSelect(pipe_index pipeIndex);
|
||||||
|
|
||||||
bool HasEDID();
|
bool HasEDID();
|
||||||
virtual status_t GetEDID(edid1_info* edid,
|
virtual status_t GetEDID(edid1_info* edid,
|
||||||
bool forceRead = false);
|
bool forceRead = false);
|
||||||
@@ -75,10 +88,13 @@ static status_t _SetI2CSignals(void* cookie, int clock,
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
virtual addr_t _DDCRegister() = 0;
|
virtual addr_t _DDCRegister() = 0;
|
||||||
|
virtual addr_t _PortRegister() = 0;
|
||||||
|
|
||||||
port_index fPortIndex;
|
port_index fPortIndex;
|
||||||
char* fPortName;
|
char* fPortName;
|
||||||
|
|
||||||
|
pipe_index fPipeIndex;
|
||||||
|
|
||||||
status_t fEDIDState;
|
status_t fEDIDState;
|
||||||
edid1_info fEDIDInfo;
|
edid1_info fEDIDInfo;
|
||||||
};
|
};
|
||||||
@@ -98,6 +114,7 @@ virtual status_t SetDisplayMode(display_mode* mode,
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual addr_t _DDCRegister();
|
virtual addr_t _DDCRegister();
|
||||||
|
virtual addr_t _PortRegister();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -115,6 +132,7 @@ virtual status_t SetDisplayMode(display_mode* mode,
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual addr_t _DDCRegister();
|
virtual addr_t _DDCRegister();
|
||||||
|
virtual addr_t _PortRegister();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -132,6 +150,7 @@ virtual bool IsConnected();
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual addr_t _DDCRegister();
|
virtual addr_t _DDCRegister();
|
||||||
|
virtual addr_t _PortRegister();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -145,7 +164,7 @@ virtual uint32 Type() const
|
|||||||
virtual bool IsConnected();
|
virtual bool IsConnected();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32 _PortRegister();
|
virtual addr_t _PortRegister();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -160,7 +179,7 @@ virtual uint32 Type() const
|
|||||||
virtual bool IsConnected();
|
virtual bool IsConnected();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32 _PortRegister();
|
virtual uint32 _PortRegister();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -189,16 +189,16 @@ dump_ports()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("%s: Connected ports: (port_count: %d)\n", __func__,
|
TRACE("%s: Connected ports: (port_count: %" B_PRIu32 ")\n", __func__,
|
||||||
gInfo->port_count);
|
gInfo->port_count);
|
||||||
|
|
||||||
for (uint32 i = 0; i < gInfo->port_count; i++) {
|
for (uint32 i = 0; i < gInfo->port_count; i++) {
|
||||||
Port* port = gInfo->ports[i];
|
Port* port = gInfo->ports[i];
|
||||||
if (!port) {
|
if (!port) {
|
||||||
TRACE("port %d: INVALID ALLOC!\n", i);
|
TRACE("port %" B_PRIu32 ":: INVALID ALLOC!\n", i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TRACE("port %d: %s %s\n", i, port->PortName(),
|
TRACE("port %" B_PRIu32 ": %s %s\n", i, port->PortName(),
|
||||||
port->IsConnected() ? "connected" : "disconnected");
|
port->IsConnected() ? "connected" : "disconnected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -615,6 +615,9 @@ if (first) {
|
|||||||
if (!gInfo->ports[i]->IsConnected())
|
if (!gInfo->ports[i]->IsConnected())
|
||||||
continue;
|
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);
|
status_t status = gInfo->ports[i]->SetDisplayMode(&target, colorMode);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
ERROR("%s: Unable to set display mode!\n", __func__);
|
ERROR("%s: Unable to set display mode!\n", __func__);
|
||||||
|
|||||||
Reference in New Issue
Block a user