intel_extreme:DP links on sky- upto/incl coffeelake are now done (refclk detection added)
This commit is contained in:
parent
6c88202d33
commit
9ef22aa9d7
@ -612,9 +612,21 @@ struct intel_free_graphics_memory {
|
||||
#define SKL_DPLL2_CFGCR2 (0xc04c | REGS_NORTH_PIPE_AND_PORT)
|
||||
#define SKL_DPLL3_CFGCR1 (0xc050 | REGS_NORTH_PIPE_AND_PORT)
|
||||
#define SKL_DPLL3_CFGCR2 (0xc054 | REGS_NORTH_PIPE_AND_PORT)
|
||||
// These exist also still in CoffeeLake (confirmed):
|
||||
#define SKL_DPLL_CTRL1 (0xc058 | REGS_NORTH_PIPE_AND_PORT)
|
||||
#define SKL_DPLL_CTRL2 (0xc05c | REGS_NORTH_PIPE_AND_PORT)
|
||||
#define SKL_DPLL_STATUS (0xc060 | REGS_NORTH_PIPE_AND_PORT)
|
||||
#define SKL_DPLL0_DP_LINKRATE_SHIFT 1
|
||||
#define SKL_DPLL1_DP_LINKRATE_SHIFT 7
|
||||
#define SKL_DPLL2_DP_LINKRATE_SHIFT 13
|
||||
#define SKL_DPLL3_DP_LINKRATE_SHIFT 19
|
||||
#define SKL_DPLL_DP_LINKRATE_MASK 7
|
||||
#define SKL_DPLL_CTRL1_2700 0
|
||||
#define SKL_DPLL_CTRL1_1350 1
|
||||
#define SKL_DPLL_CTRL1_810 2
|
||||
#define SKL_DPLL_CTRL1_1620 3
|
||||
#define SKL_DPLL_CTRL1_1080 4
|
||||
#define SKL_DPLL_CTRL1_2160 5
|
||||
|
||||
// Icelake PLLs
|
||||
#define ICL_DSSM 0x51004
|
||||
|
@ -463,71 +463,71 @@ Pipe::ConfigureClocks(const pll_divisors& divisors, uint32 pixelClock,
|
||||
|
||||
void
|
||||
Pipe::ConfigureClocksSKL(const skl_wrpll_params& wrpll_params, uint32 pixelClock,
|
||||
port_index pllForPort)
|
||||
port_index pllForPort, uint32* pllSel)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
//find our PLL as set by the BIOS
|
||||
uint32 portSel = read32(SKL_DPLL_CTRL2);
|
||||
uint32 pllSel = 0;
|
||||
*pllSel = 0xff;
|
||||
switch (pllForPort) {
|
||||
case INTEL_PORT_A:
|
||||
pllSel = (portSel & 0x0006) >> 1;
|
||||
*pllSel = (portSel & 0x0006) >> 1;
|
||||
break;
|
||||
case INTEL_PORT_B:
|
||||
pllSel = (portSel & 0x0030) >> 4;
|
||||
*pllSel = (portSel & 0x0030) >> 4;
|
||||
break;
|
||||
case INTEL_PORT_C:
|
||||
pllSel = (portSel & 0x0180) >> 7;
|
||||
*pllSel = (portSel & 0x0180) >> 7;
|
||||
break;
|
||||
case INTEL_PORT_D:
|
||||
pllSel = (portSel & 0x0c00) >> 10;
|
||||
*pllSel = (portSel & 0x0c00) >> 10;
|
||||
break;
|
||||
case INTEL_PORT_E:
|
||||
pllSel = (portSel & 0x6000) >> 13;
|
||||
*pllSel = (portSel & 0x6000) >> 13;
|
||||
break;
|
||||
default:
|
||||
TRACE("No port selected!");
|
||||
return;
|
||||
}
|
||||
TRACE("PLL selected is %" B_PRIx32 "\n", pllSel);
|
||||
TRACE("PLL selected is %" B_PRIx32 "\n", *pllSel);
|
||||
|
||||
TRACE("Skylake DPLL_CFGCR1 0x%" B_PRIx32 "\n",
|
||||
read32(SKL_DPLL1_CFGCR1 + (pllSel - 1) * 8));
|
||||
read32(SKL_DPLL1_CFGCR1 + (*pllSel - 1) * 8));
|
||||
TRACE("Skylake DPLL_CFGCR2 0x%" B_PRIx32 "\n",
|
||||
read32(SKL_DPLL1_CFGCR2 + (pllSel - 1) * 8));
|
||||
read32(SKL_DPLL1_CFGCR2 + (*pllSel - 1) * 8));
|
||||
|
||||
// only program PLL's that are in non-DP mode (otherwise the linkspeed sets refresh)
|
||||
portSel = read32(SKL_DPLL_CTRL1);
|
||||
if ((portSel & (1 << (pllSel * 6 + 5))) && pllSel) { // DPLL0 might only know DP mode
|
||||
if ((portSel & (1 << (*pllSel * 6 + 5))) && *pllSel) { // DPLL0 might only know DP mode
|
||||
// enable pgm on our PLL in case that's currently disabled
|
||||
write32(SKL_DPLL_CTRL1, portSel | (1 << (pllSel * 6)));
|
||||
write32(SKL_DPLL_CTRL1, portSel | (1 << (*pllSel * 6)));
|
||||
|
||||
write32(SKL_DPLL1_CFGCR1 + (pllSel - 1) * 8,
|
||||
write32(SKL_DPLL1_CFGCR1 + (*pllSel - 1) * 8,
|
||||
1 << 31 |
|
||||
wrpll_params.dco_fraction << 9 |
|
||||
wrpll_params.dco_integer);
|
||||
write32(SKL_DPLL1_CFGCR2 + (pllSel - 1) * 8,
|
||||
write32(SKL_DPLL1_CFGCR2 + (*pllSel - 1) * 8,
|
||||
wrpll_params.qdiv_ratio << 8 |
|
||||
wrpll_params.qdiv_mode << 7 |
|
||||
wrpll_params.kdiv << 5 |
|
||||
wrpll_params.pdiv << 2 |
|
||||
wrpll_params.central_freq);
|
||||
read32(SKL_DPLL1_CFGCR1 + (pllSel - 1) * 8);
|
||||
read32(SKL_DPLL1_CFGCR2 + (pllSel - 1) * 8);
|
||||
read32(SKL_DPLL1_CFGCR1 + (*pllSel - 1) * 8);
|
||||
read32(SKL_DPLL1_CFGCR2 + (*pllSel - 1) * 8);
|
||||
|
||||
//assuming DPLL0 and 1 are already enabled by the BIOS if in use (LCPLL1,2 regs)
|
||||
|
||||
spin(5);
|
||||
if (read32(SKL_DPLL_STATUS) & (1 << (pllSel * 8))) {
|
||||
if (read32(SKL_DPLL_STATUS) & (1 << (*pllSel * 8))) {
|
||||
TRACE("Programmed PLL; PLL is locked\n");
|
||||
} else {
|
||||
TRACE("Programmed PLL; PLL did not lock\n");
|
||||
}
|
||||
TRACE("Skylake DPLL_CFGCR1 now: 0x%" B_PRIx32 "\n",
|
||||
read32(SKL_DPLL1_CFGCR1 + (pllSel - 1) * 8));
|
||||
read32(SKL_DPLL1_CFGCR1 + (*pllSel - 1) * 8));
|
||||
TRACE("Skylake DPLL_CFGCR2 now: 0x%" B_PRIx32 "\n",
|
||||
read32(SKL_DPLL1_CFGCR2 + (pllSel - 1) * 8));
|
||||
read32(SKL_DPLL1_CFGCR2 + (*pllSel - 1) * 8));
|
||||
} else {
|
||||
TRACE("PLL programming not needed, skipping.\n");
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ public:
|
||||
void ConfigureClocksSKL(
|
||||
const skl_wrpll_params& wrpll_params,
|
||||
uint32 pixelClock,
|
||||
port_index pllForPort);
|
||||
port_index pllForPort,
|
||||
uint32* pllSel);
|
||||
|
||||
// access to the various parts of the pipe
|
||||
::FDILink* FDI()
|
||||
|
@ -1449,13 +1449,43 @@ DigitalDisplayInterface::IsConnected()
|
||||
}
|
||||
|
||||
status_t
|
||||
DigitalDisplayInterface::_SetPortLinkGen8(const display_timing& timing)
|
||||
DigitalDisplayInterface::_SetPortLinkGen8(const display_timing& timing, uint32 pllSel)
|
||||
{
|
||||
// Khz / 10. ( each output octet encoded as 10 bits.
|
||||
//uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; //=270000 khz
|
||||
//fixme: always so?
|
||||
//fixme: always so on pre gen 9?
|
||||
uint32 linkBandwidth = 270000; //khz
|
||||
|
||||
if (gInfo->shared_info->device_type.Generation() >= 9) {
|
||||
if (pllSel != 0xff) {
|
||||
linkBandwidth = (read32(SKL_DPLL_CTRL1) >> (1 + 6 * pllSel)) & SKL_DPLL_DP_LINKRATE_MASK;
|
||||
switch (linkBandwidth) {
|
||||
case SKL_DPLL_CTRL1_2700:
|
||||
linkBandwidth = 2700000 / 5;
|
||||
break;
|
||||
case SKL_DPLL_CTRL1_1350:
|
||||
linkBandwidth = 1350000 / 5;
|
||||
break;
|
||||
case SKL_DPLL_CTRL1_810:
|
||||
linkBandwidth = 810000 / 5;
|
||||
break;
|
||||
case SKL_DPLL_CTRL1_1620:
|
||||
linkBandwidth = 1620000 / 5;
|
||||
break;
|
||||
case SKL_DPLL_CTRL1_1080:
|
||||
linkBandwidth = 1080000 / 5;
|
||||
break;
|
||||
case SKL_DPLL_CTRL1_2160:
|
||||
linkBandwidth = 2160000 / 5;
|
||||
break;
|
||||
default:
|
||||
ERROR("%s: DDI No known DP-link reference clock selected, assuming default\n", __func__);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ERROR("%s: DDI No known PLL selected, assuming default DP-link reference\n", __func__);
|
||||
}
|
||||
}
|
||||
TRACE("%s: DDI DP-link reference clock is %gMhz\n", __func__, linkBandwidth / 1000.0f);
|
||||
|
||||
uint32 fPipeOffset = 0;
|
||||
switch (fPipe->Index()) {
|
||||
case INTEL_PIPE_B:
|
||||
@ -1609,6 +1639,7 @@ DigitalDisplayInterface::SetDisplayMode(display_mode* target, uint32 colorMode)
|
||||
// Program general pipe config
|
||||
fPipe->Configure(target);
|
||||
|
||||
uint32 pllSel = 0xff; // no PLL selected
|
||||
if (gInfo->shared_info->device_type.Generation() <= 8) {
|
||||
unsigned int r2_out, n2_out, p_out;
|
||||
hsw_ddi_calculate_wrpll(
|
||||
@ -1622,12 +1653,13 @@ DigitalDisplayInterface::SetDisplayMode(display_mode* target, uint32 colorMode)
|
||||
&wrpll_params);
|
||||
fPipe->ConfigureClocksSKL(wrpll_params,
|
||||
hardwareTarget.pixel_clock,
|
||||
PortIndex());
|
||||
PortIndex(),
|
||||
&pllSel);
|
||||
}
|
||||
|
||||
// Program target display mode
|
||||
fPipe->ConfigureTimings(target, !needsScaling);
|
||||
_SetPortLinkGen8(hardwareTarget);
|
||||
_SetPortLinkGen8(hardwareTarget, pllSel);
|
||||
|
||||
// Set fCurrentMode to our set display mode
|
||||
memcpy(&fCurrentMode, target, sizeof(display_mode));
|
||||
|
@ -218,7 +218,8 @@ virtual addr_t _PortRegister();
|
||||
private:
|
||||
uint8 fMaxLanes;
|
||||
|
||||
status_t _SetPortLinkGen8(const display_timing& timing);
|
||||
status_t _SetPortLinkGen8(const display_timing& timing,
|
||||
uint32 pllSel);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user