intel_extreme: Move rest of pipe control into pipe class
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user