diff --git a/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp b/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp index 779e6b5a91..721a8a6a1e 100644 --- a/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp +++ b/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp @@ -97,6 +97,9 @@ DisplayPipe::Enable(display_mode* target, addr_t portAddress) // Enable display pipe _Enable(true); + // Wait for the clocks to stabilize + spin(150); + // update timing (fPipeBase bumps the DISPLAY_A to B when needed) write32(fPipeBase + REGISTER_REGISTER(INTEL_DISPLAY_A_HTOTAL), ((uint32)(target->timing.h_total - 1) << 16) @@ -118,9 +121,15 @@ DisplayPipe::Enable(display_mode* target, addr_t portAddress) ((uint32)(target->timing.v_sync_end - 1) << 16) | ((uint32)target->timing.v_sync_start - 1)); + write32(fPipeBase + REGISTER_REGISTER(INTEL_DISPLAY_A_POS), 0); + + // TODO: Review these write32(fPipeBase + REGISTER_REGISTER(INTEL_DISPLAY_A_IMAGE_SIZE), ((uint32)(target->virtual_width - 1) << 16) - | ((uint32)target->virtual_height - 1)); + | ((uint32)target->virtual_height - 1)); + write32(fPipeBase + REGISTER_REGISTER(INTEL_DISPLAY_A_PIPE_SIZE), + ((uint32)(target->timing.v_display - 1) << 16) + | ((uint32)target->timing.h_display - 1)); write32(portAddress, (read32(portAddress) & ~(DISPLAY_MONITOR_POLARITY_MASK @@ -140,18 +149,29 @@ DisplayPipe::Disable() void -DisplayPipe::ConfigureTimings(const pll_divisors& divisors, uint32 extraFlags) +DisplayPipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock, + uint32 extraFlags) { CALLED(); addr_t pllDivisorA = INTEL_DISPLAY_A_PLL_DIVISOR_0; addr_t pllDivisorB = INTEL_DISPLAY_A_PLL_DIVISOR_1; addr_t pllControl = INTEL_DISPLAY_A_PLL; + addr_t pllMD = INTEL_DISPLAY_A_PLL_MD; if (fPipeIndex == INTEL_PIPE_B) { pllDivisorA = INTEL_DISPLAY_B_PLL_DIVISOR_0; pllDivisorB = INTEL_DISPLAY_B_PLL_DIVISOR_1; pllControl = INTEL_DISPLAY_B_PLL; + pllMD = INTEL_DISPLAY_B_PLL_MD; + } + + float refFreq = gInfo->shared_info->pll_info.reference_frequency / 1000.0f; + + if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_96x)) { + float adjusted = ((refFreq * divisors.m) / divisors.n) / divisors.post; + uint32 pixelMultiply = uint32(adjusted / (pixelClock / 1000.0f)); + write32(pllMD, (0 << 24) | ((pixelMultiply - 1) << 8)); } if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_IGD)) { @@ -200,6 +220,7 @@ DisplayPipe::ConfigureTimings(const pll_divisors& divisors, uint32 extraFlags) pll |= DISPLAY_PLL_POST1_DIVIDE_2; } + write32(pllControl, pll); read32(pllControl); spin(150); diff --git a/src/add-ons/accelerants/intel_extreme/DisplayPipe.h b/src/add-ons/accelerants/intel_extreme/DisplayPipe.h index f26fb1fae6..f0f5edefc6 100644 --- a/src/add-ons/accelerants/intel_extreme/DisplayPipe.h +++ b/src/add-ons/accelerants/intel_extreme/DisplayPipe.h @@ -41,7 +41,9 @@ public: addr_t portRegister); void Disable(); - void ConfigureTimings(const pll_divisors& divisors, + void ConfigureTimings( + const pll_divisors& divisors, + uint32 pixelClock, uint32 extraFlags); // access to the various parts of the pipe diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index ccb716554e..8cda979e85 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -257,7 +257,8 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode) extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; // Program pipe PLL's - fDisplayPipe->ConfigureTimings(divisors, extraPLLFlags); + fDisplayPipe->ConfigureTimings(divisors, target->timing.pixel_clock, + extraPLLFlags); // Program target display mode fDisplayPipe->Enable(target, _PortRegister()); @@ -463,57 +464,14 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) if (gInfo->shared_info->device_type.Generation() >= 4) extraPLLFlags |= DISPLAY_PLL_MODE_LVDS; - // Program pipe PLL's - fDisplayPipe->ConfigureTimings(divisors, extraPLLFlags); + // Program pipe PLL's (pixel_clock is *always* the hardware pixel clock) + fDisplayPipe->ConfigureTimings(divisors, target->timing.pixel_clock, + extraPLLFlags); // Program target display mode fDisplayPipe->Enable(target, _PortRegister()); #if 0 - if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_IGD)) { - write32(INTEL_DISPLAY_B_PLL_DIVISOR_0, - (((1 << divisors.n) << DISPLAY_PLL_N_DIVISOR_SHIFT) - & DISPLAY_PLL_IGD_N_DIVISOR_MASK) - | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT) - & DISPLAY_PLL_IGD_M2_DIVISOR_MASK)); - } else { - write32(INTEL_DISPLAY_B_PLL_DIVISOR_0, - (((divisors.n - 2) << DISPLAY_PLL_N_DIVISOR_SHIFT) - & DISPLAY_PLL_N_DIVISOR_MASK) - | (((divisors.m1 - 2) << DISPLAY_PLL_M1_DIVISOR_SHIFT) - & DISPLAY_PLL_M1_DIVISOR_MASK) - | (((divisors.m2 - 2) << DISPLAY_PLL_M2_DIVISOR_SHIFT) - & DISPLAY_PLL_M2_DIVISOR_MASK)); - } - - write32(INTEL_DISPLAY_B_PLL, dpll); - read32(INTEL_DISPLAY_B_PLL); - - // Wait for the clocks to stabilize - spin(150); - - float referenceClock = gInfo->shared_info->pll_info.reference_frequency - / 1000.0f; - - if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_96x)) { - float adjusted = ((referenceClock * divisors.m) / divisors.n) - / divisors.post; - uint32 pixelMultiply; - if (needsScaling) { - pixelMultiply = uint32(adjusted - / (hardwareTarget.timing.pixel_clock / 1000.0f)); - } else { - pixelMultiply = uint32(adjusted - / (target->timing.pixel_clock / 1000.0f)); - } - - write32(INTEL_DISPLAY_B_PLL_MD, (0 << 24) - | ((pixelMultiply - 1) << 8)); - } else - write32(INTEL_DISPLAY_B_PLL, dpll); - - read32(INTEL_DISPLAY_B_PLL); - spin(150); // update timing parameters if (needsScaling) { @@ -591,19 +549,6 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) (uint32)(target->timing.v_sync_end - 1) << 16) | ((uint32)target->timing.v_sync_start - 1)); } - - write32(INTEL_DISPLAY_B_POS, 0); - write32(INTEL_DISPLAY_B_PIPE_SIZE, - ((uint32)(target->timing.v_display - 1) << 16) - | ((uint32)target->timing.h_display - 1)); - - write32(INTEL_DISPLAY_B_CONTROL, (read32(INTEL_DISPLAY_B_CONTROL) - & ~(DISPLAY_CONTROL_COLOR_MASK | DISPLAY_CONTROL_GAMMA)) - | colorMode); - - write32(INTEL_DISPLAY_B_PIPE_CONTROL, - read32(INTEL_DISPLAY_B_PIPE_CONTROL) | INTEL_PIPE_ENABLED); - read32(INTEL_DISPLAY_B_PIPE_CONTROL); #endif // XXX: Crashes? @@ -688,7 +633,8 @@ DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode) extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; // Program pipe PLL's - fDisplayPipe->ConfigureTimings(divisors, extraPLLFlags); + fDisplayPipe->ConfigureTimings(divisors, target->timing.pixel_clock, + extraPLLFlags); // Program target display mode fDisplayPipe->Enable(target, _PortRegister());