intel_extreme: Move rest of pipe control into pipe class

This commit is contained in:
Alexander von Gluck IV
2016-01-08 22:43:59 -06:00
parent 72dbe9d2ce
commit b979c66c86
5 changed files with 60 additions and 106 deletions
+23 -20
View File
@@ -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;
+18 -12
View File
@@ -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,
+14 -70
View File
@@ -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)