intel_extreme: Extend DDI port probing to A-E

* The Linux code made this a bit hard to figure out via
  complex define functions, however there can be up to
  5 DDI ports (A-E)
This commit is contained in:
Alexander von Gluck IV 2016-05-08 15:39:22 -05:00
parent 88445a43e8
commit 8fe5054828
5 changed files with 55 additions and 4 deletions

View File

@ -537,6 +537,8 @@ struct intel_free_graphics_memory {
#define INTEL_TRANSCODER_A_IMAGE_SIZE (0x001c | REGS_SOUTH_TRANSCODER_PORT)
#define INTEL_TRANSCODER_B_IMAGE_SIZE (0x101c | REGS_SOUTH_TRANSCODER_PORT)
// TODO: Is there consolidation that could happen here with digital ports?
#define INTEL_ANALOG_PORT (0x1100 | REGS_SOUTH_TRANSCODER_PORT)
#define INTEL_DIGITAL_PORT_A (0x1120 | REGS_SOUTH_TRANSCODER_PORT)
#define INTEL_DIGITAL_PORT_B (0x1140 | REGS_SOUTH_TRANSCODER_PORT)
@ -557,6 +559,9 @@ struct intel_free_graphics_memory {
// DDI Buffer Control (This replaces DP on Haswell+)
#define DDI_BUF_CTL_A (0x4000 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_B (0x4100 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_C (0x4200 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_D (0x4300 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_E (0x4400 | REGS_NORTH_PIPE_AND_PORT)
#define DDI_BUF_CTL_ENABLE (1 << 31)
#define DDI_BUF_TRANS_SELECT(n) ((n) << 24)
#define DDI_BUF_EMP_MASK (0xf << 24)

View File

@ -64,7 +64,13 @@ Pipe::Pipe(pipe_index pipeIndex)
fPlaneOffset = INTEL_PLANE_OFFSET;
}
// IvyBridge: Analog + Digital Ports behind FDI (on northbridge)
// Haswell: Only VGA behind FDI (on northbridge)
// SkyLake: FDI gone. No more northbridge video.
if (gInfo->shared_info->device_type.HasPlatformControlHub()) {
TRACE("%s: Pipe %s routed through FDI\n", __func__,
(pipeIndex == INTEL_PIPE_A) ? "A" : "B");
fHasTranscoder = true;
// Program FDILink if PCH

View File

@ -966,11 +966,19 @@ DigitalDisplayInterface::DigitalDisplayInterface(port_index index,
addr_t
DigitalDisplayInterface::_PortRegister()
{
// TODO: Linux does a DDI_BUF_CTL(INTEL_PORT_A) which is cleaner
// (but we have to ensure the offsets + region base is correct)
switch (PortIndex()) {
case INTEL_PORT_A:
return DDI_BUF_CTL_A;
case INTEL_PORT_B:
return DDI_BUF_CTL_B;
case INTEL_PORT_C:
return DDI_BUF_CTL_C;
case INTEL_PORT_D:
return DDI_BUF_CTL_D;
case INTEL_PORT_E:
return DDI_BUF_CTL_E;
default:
return 0;
}
@ -1020,6 +1028,36 @@ DigitalDisplayInterface::IsConnected()
return false;
}
// Probe a little port info.
if ((read32(DDI_BUF_CTL_A) & DDI_A_4_LANES) != 0) {
switch (PortIndex()) {
case INTEL_PORT_A:
fMaxLanes = 4;
break;
case INTEL_PORT_E:
fMaxLanes = 0;
break;
default:
fMaxLanes = 4;
break;
}
} else {
switch (PortIndex()) {
case INTEL_PORT_A:
fMaxLanes = 2;
break;
case INTEL_PORT_E:
fMaxLanes = 2;
break;
default:
fMaxLanes = 4;
break;
}
}
TRACE("%s: %s Maximum Lanes: %" B_PRId8 "\n", __func__,
PortName(), fMaxLanes);
HasEDID();
return true;

View File

@ -37,7 +37,8 @@ enum port_index {
INTEL_PORT_A,
INTEL_PORT_B,
INTEL_PORT_C,
INTEL_PORT_D
INTEL_PORT_D,
INTEL_PORT_E
};
@ -219,6 +220,8 @@ virtual status_t SetDisplayMode(display_mode* mode,
protected:
virtual addr_t _DDCRegister();
virtual addr_t _PortRegister();
private:
uint8 fMaxLanes;
};

View File

@ -308,7 +308,7 @@ probe_ports()
// Digital Display Interface
if (gInfo->shared_info->device_type.HasDDI()) {
for (int i = INTEL_PORT_A; i <= INTEL_PORT_B; i++) {
for (int i = INTEL_PORT_A; i <= INTEL_PORT_E; i++) {
Port* ddiPort
= new(std::nothrow) DigitalDisplayInterface((port_index)i);
@ -419,7 +419,7 @@ assign_pipes()
gInfo->ports[i]->PortName());
continue;
}
gInfo->ports[i]->SetPipe(gInfo->pipes[current]);
current++;
}
@ -593,4 +593,3 @@ intel_accelerant_retrace_semaphore()
CALLED();
return gInfo->shared_info->vblank_sem;
}