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_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)
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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__);
|
||||
|
||||
Reference in New Issue
Block a user