intel_extreme: program the DPLL_SEL register on SandyBridge

We need to assign PLLs to pipes and transcoders. The assignments on
previous generations were fixed, but now it's up to us to set it up.

Do the simplest thing for now: assign PLL1 to pipe A and PLL2 to pipe B.
This commit is contained in:
Adrien Destugues
2020-03-08 16:01:43 +01:00
parent 7991d1b79d
commit 168aff90a7
2 changed files with 35 additions and 0 deletions
@@ -723,6 +723,7 @@ struct intel_free_graphics_memory {
#define INTEL_DISPLAY_A_PLL (0x6014 | REGS_SOUTH_SHARED)
#define INTEL_DISPLAY_B_PLL (0x6018 | REGS_SOUTH_SHARED)
#define CHV_DISPLAY_C_PLL (0x6030 | REGS_SOUTH_SHARED)
#define SNB_DPLL_SEL (0x7000 | REGS_SOUTH_SHARED)
// Ironlake PCH reference clk control
#define PCH_DREF_CONTROL (0x6200 | REGS_SOUTH_SHARED)
@@ -345,6 +345,40 @@ Pipe::ConfigureClocks(const pll_divisors& divisors, uint32 pixelClock,
write32(pllControl, pll);
read32(pllControl);
spin(150);
if (gInfo->shared_info->device_type.Generation() >= 6) {
// SandyBridge has 3 transcoders, but only 2 PLLs. So there is a new
// register which routes the PLL output to the transcoder that we need
// to configure
uint32 pllSel = read32(SNB_DPLL_SEL);
TRACE("Old PLL selection: %x\n", pllSel);
uint32 shift = 0;
uint32 pllIndex = 0;
// FIXME we assume that pipe A is used with transcoder A, and pipe B
// with transcoder B, that may not always be the case
if (fPipeIndex == INTEL_PIPE_A) {
shift = 0;
pllIndex = 0;
TRACE("Route PLL A to transcoder A\n");
} else if (fPipeIndex == INTEL_PIPE_B) {
shift = 4;
pllIndex = 1;
TRACE("Route PLL B to transcoder B\n");
} else {
ERROR("Attempting to configure PLL for unhandled pipe");
return;
}
// Mask out the previous PLL configuration for this transcoder
pllSel &= ~(0xF << shift);
// Set up the new configuration for this transcoder and enable it
pllSel |= (8 | pllIndex) << shift;
TRACE("New PLL selection: %x\n", pllSel);
write32(SNB_DPLL_SEL, pllSel);
}
}