diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp b/src/add-ons/accelerants/intel_extreme/Pipes.cpp index 18fea97423..4801e583d4 100644 --- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp +++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp @@ -87,13 +87,14 @@ bool Pipe::IsEnabled() { CALLED(); - return (read32(INTEL_DISPLAY_A_PIPE_CONTROL + fPlaneOffset) + + return (read32(INTEL_DISPLAY_A_PIPE_CONTROL + fPipeOffset) & INTEL_PIPE_ENABLED) != 0; } void -Pipe::_EnableTranscoder(display_mode* target) +Pipe::_ConfigureTranscoder(display_mode* target) { // update timing (fPipeOffset bumps the DISPLAY_A to B when needed) write32(INTEL_TRANSCODER_A_HTOTAL + fPipeOffset, @@ -127,7 +128,7 @@ Pipe::_EnableTranscoder(display_mode* target) void -Pipe::Enable(display_mode* target) +Pipe::ConfigureTimings(display_mode* target) { CALLED(); @@ -173,22 +174,12 @@ Pipe::Enable(display_mode* target) //write32(INTEL_DISPLAY_A_RED + fPipeOffset, 0x00FF0000); if (fHasTranscoder) - _EnableTranscoder(target); - - // Enable display pipe - _Enable(true); + _ConfigureTranscoder(target); } void -Pipe::Disable() -{ - _Enable(false); -} - - -void -Pipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock, +Pipe::ConfigureClocks(const pll_divisors& divisors, uint32 pixelClock, uint32 extraFlags) { CALLED(); @@ -286,13 +277,25 @@ Pipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock, void -Pipe::_Enable(bool enable) +Pipe::Enable(bool enable) { CALLED(); - addr_t targetRegister = INTEL_DISPLAY_A_PIPE_CONTROL + fPlaneOffset; + addr_t pipeReg = INTEL_DISPLAY_A_PIPE_CONTROL + fPipeOffset; + addr_t planeReg = INTEL_DISPLAY_A_CONTROL + fPlaneOffset; - write32(targetRegister, (read32(targetRegister) & ~INTEL_PIPE_ENABLED) - | (enable ? INTEL_PIPE_ENABLED : 0)); - read32(targetRegister); + // Planes always have to operate on an enabled pipe + + if (enable) { + write32(pipeReg, read32(pipeReg) | INTEL_PIPE_ENABLED); + wait_for_vblank(); + write32(planeReg, read32(planeReg) | DISPLAY_CONTROL_ENABLED); + } else { + write32(planeReg, read32(planeReg) & ~DISPLAY_CONTROL_ENABLED); + wait_for_vblank(); + write32(pipeReg, read32(pipeReg) & ~INTEL_PIPE_ENABLED); + } + + read32(INTEL_DISPLAY_A_BASE); + // flush the eventually cached PCI bus writes } diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.h b/src/add-ons/accelerants/intel_extreme/Pipes.h index 3bab501a90..5137f01dbf 100644 --- a/src/add-ons/accelerants/intel_extreme/Pipes.h +++ b/src/add-ons/accelerants/intel_extreme/Pipes.h @@ -35,10 +35,11 @@ public: { return fPipeIndex; } bool IsEnabled(); - void Enable(display_mode* mode); + void Enable(bool enable); void Disable(); - void ConfigureTimings( + void ConfigureTimings(display_mode* mode); + void ConfigureClocks( const pll_divisors& divisors, uint32 pixelClock, uint32 extraFlags); @@ -50,8 +51,7 @@ public: // { return fPanelFitter; } private: - void _Enable(bool enable); - void _EnableTranscoder(display_mode* mode); + void _ConfigureTranscoder(display_mode* mode); bool fHasTranscoder; diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index e0d1bc72ef..9c3fd3a0ff 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -142,7 +142,7 @@ Port::SetPipe(Pipe* pipe) // Disable display pipe until modesetting enables it if (fPipe->IsEnabled()) - fPipe->Disable(); + fPipe->Enable(false); read32(portRegister); @@ -150,6 +150,15 @@ Port::SetPipe(Pipe* pipe) } +status_t +Port::Power(bool enabled) +{ + fPipe->Enable(enabled); + + return B_OK; +} + + status_t Port::GetEDID(edid1_info* edid, bool forceRead) { @@ -305,6 +314,9 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode) if (gInfo->shared_info->device_type.Generation() >= 3) extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; + // Program pipe PLL's + fPipe->ConfigureClocks(divisors, target->timing.pixel_clock, extraPLLFlags); + write32(_PortRegister(), (read32(_PortRegister()) & ~(DISPLAY_MONITOR_POLARITY_MASK | DISPLAY_MONITOR_VGA_POLARITY)) | ((target->timing.flags & B_POSITIVE_HSYNC) != 0 @@ -312,12 +324,8 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode) | ((target->timing.flags & B_POSITIVE_VSYNC) != 0 ? DISPLAY_MONITOR_POSITIVE_VSYNC : 0)); - // Program pipe PLL's - fPipe->ConfigureTimings(divisors, target->timing.pixel_clock, - extraPLLFlags); - // Program target display mode - fPipe->Enable(target); + fPipe->ConfigureTimings(target); // Set fCurrentMode to our set display mode memcpy(&fCurrentMode, target, sizeof(display_mode)); @@ -560,8 +568,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) extraPLLFlags |= DISPLAY_PLL_MODE_LVDS; // Program pipe PLL's (pixel_clock is *always* the hardware pixel clock) - fPipe->ConfigureTimings(divisors, target->timing.pixel_clock, - extraPLLFlags); + fPipe->ConfigureClocks(divisors, target->timing.pixel_clock, extraPLLFlags); // Power on Panel write32(panelControl, read32(panelControl) | PANEL_CONTROL_POWER_TARGET_ON); @@ -571,7 +578,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) ERROR("%s: %s didn't power on within 1000ms!\n", __func__, PortName()); // Program target display mode - fPipe->Enable(target); + fPipe->ConfigureTimings(target); #if 0 @@ -739,11 +746,10 @@ DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode) extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; // Program pipe PLL's - fPipe->ConfigureTimings(divisors, target->timing.pixel_clock, - extraPLLFlags); + fPipe->ConfigureClocks(divisors, target->timing.pixel_clock, extraPLLFlags); // Program target display mode - fPipe->Enable(target); + fPipe->ConfigureTimings(target); // Set fCurrentMode to our set display mode memcpy(&fCurrentMode, target, sizeof(display_mode)); diff --git a/src/add-ons/accelerants/intel_extreme/Ports.h b/src/add-ons/accelerants/intel_extreme/Ports.h index b63615561c..996ad61956 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.h +++ b/src/add-ons/accelerants/intel_extreme/Ports.h @@ -60,6 +60,7 @@ virtual bool IsConnected() = 0; ::Pipe* GetPipe() { return fPipe; }; + status_t Power(bool enabled); bool HasEDID(); virtual status_t GetEDID(edid1_info* edid, diff --git a/src/add-ons/accelerants/intel_extreme/dpms.cpp b/src/add-ons/accelerants/intel_extreme/dpms.cpp index 513588c323..babdca6f84 100644 --- a/src/add-ons/accelerants/intel_extreme/dpms.cpp +++ b/src/add-ons/accelerants/intel_extreme/dpms.cpp @@ -23,75 +23,23 @@ #define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__) -void -enable_display_plane(bool enable) -{ - uint32 planeAControl = read32(INTEL_DISPLAY_A_CONTROL); - uint32 planeBControl = read32(INTEL_DISPLAY_B_CONTROL); - - if (enable) { - // when enabling the display, the register values are updated - // automatically - if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { - write32(INTEL_DISPLAY_A_CONTROL, - planeAControl | DISPLAY_CONTROL_ENABLED); - } - - if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { - write32(INTEL_DISPLAY_B_CONTROL, - planeBControl | DISPLAY_CONTROL_ENABLED); - } - - read32(INTEL_DISPLAY_A_BASE); - // flush the eventually cached PCI bus writes - } else { - // when disabling it, we have to trigger the update using a write to - // the display base address - if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { - write32(INTEL_DISPLAY_A_CONTROL, - planeAControl & ~DISPLAY_CONTROL_ENABLED); - } - - if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { - write32(INTEL_DISPLAY_B_CONTROL, - planeBControl & ~DISPLAY_CONTROL_ENABLED); - } - - set_frame_buffer_base(); - } -} - - static void -enable_display_pipe(bool enable) +enable_all_pipes(bool enable) { - uint32 pipeAControl = read32(INTEL_DISPLAY_A_PIPE_CONTROL); - uint32 pipeBControl = read32(INTEL_DISPLAY_B_PIPE_CONTROL); + // Go over each port and enable pipe/plane + for (uint32 i = 0; i < gInfo->port_count; i++) { + if (gInfo->ports[i] == NULL) + continue; + if (!gInfo->ports[i]->IsConnected()) + continue; - if (enable) { - if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { - write32(INTEL_DISPLAY_A_PIPE_CONTROL, - pipeAControl | INTEL_PIPE_ENABLED); - } - - if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { - write32(INTEL_DISPLAY_B_PIPE_CONTROL, - pipeBControl | INTEL_PIPE_ENABLED); - } - } else { - if (gInfo->head_mode & HEAD_MODE_A_ANALOG) { - write32(INTEL_DISPLAY_A_PIPE_CONTROL, - pipeAControl & ~INTEL_PIPE_ENABLED); - } - - if (gInfo->head_mode & HEAD_MODE_B_DIGITAL) { - write32(INTEL_DISPLAY_B_PIPE_CONTROL, - pipeBControl & ~INTEL_PIPE_ENABLED); - } + gInfo->ports[i]->Power(enable); } read32(INTEL_DISPLAY_A_BASE); - // flush the eventually cached PCI bus writes + // flush the possibly cached PCI bus writes + + set_frame_buffer_base(); } @@ -162,8 +110,7 @@ set_display_power_mode(uint32 mode) spin(150); } - enable_display_pipe(true); - enable_display_plane(true); + enable_all_pipes(true); } wait_for_vblank(); @@ -197,11 +144,8 @@ set_display_power_mode(uint32 mode) // TODO: monitorMode? } - if (mode != B_DPMS_ON) { - enable_display_plane(false); - wait_for_vblank(); - enable_display_pipe(false); - } + if (mode != B_DPMS_ON) + enable_all_pipes(false); if (mode == B_DPMS_OFF) { write32(INTEL_DISPLAY_A_PLL, read32(INTEL_DISPLAY_A_PLL)