From b01aed831036cdc78ec1ffe0cbd33a12cdc19d37 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Tue, 24 Nov 2015 12:11:31 -0600 Subject: [PATCH] intel_extreme: Don't store pipes within ports * Store pipes within accelerant, and tell ports about them. * Rebrand DisplayPipe class to Pipe --- src/add-ons/accelerants/intel_extreme/Jamfile | 2 +- .../{DisplayPipe.cpp => Pipes.cpp} | 21 ++++---- .../intel_extreme/{DisplayPipe.h => Pipes.h} | 9 ++-- .../accelerants/intel_extreme/Ports.cpp | 49 ++++++++++--------- src/add-ons/accelerants/intel_extreme/Ports.h | 13 +++-- .../accelerants/intel_extreme/accelerant.cpp | 41 +++++++++++----- .../accelerants/intel_extreme/accelerant.h | 4 ++ 7 files changed, 84 insertions(+), 55 deletions(-) rename src/add-ons/accelerants/intel_extreme/{DisplayPipe.cpp => Pipes.cpp} (94%) rename src/add-ons/accelerants/intel_extreme/{DisplayPipe.h => Pipes.h} (92%) diff --git a/src/add-ons/accelerants/intel_extreme/Jamfile b/src/add-ons/accelerants/intel_extreme/Jamfile index a9adbce91d..a4f42b0372 100644 --- a/src/add-ons/accelerants/intel_extreme/Jamfile +++ b/src/add-ons/accelerants/intel_extreme/Jamfile @@ -18,9 +18,9 @@ Addon intel_extreme.accelerant : # overlay_3d_i965.cpp pll.cpp # classes - DisplayPipe.cpp FlexibleDisplayInterface.cpp # PanelFitter.cpp Ports.cpp + Pipes.cpp : be $(TARGET_LIBSTDC++) libaccelerantscommon.a ; diff --git a/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp b/src/add-ons/accelerants/intel_extreme/Pipes.cpp similarity index 94% rename from src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp rename to src/add-ons/accelerants/intel_extreme/Pipes.cpp index 074417bb07..17425ac449 100644 --- a/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp +++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp @@ -6,7 +6,7 @@ * Michael Lotz, mmlr@mlotz.ch * Alexander von Gluck IV, kallisti5@unixzen.com */ -#include "DisplayPipe.h" +#include "Pipes.h" #include "accelerant.h" #include "intel_extreme.h" @@ -33,6 +33,7 @@ extern "C" void _sPrintf(const char* format, ...); // PIPE: 6 // PLANE: 7 + void program_pipe_color_modes(uint32 colorMode) { @@ -46,10 +47,10 @@ program_pipe_color_modes(uint32 colorMode) } -// #pragma mark - DisplayPipe +// #pragma mark - Pipe -DisplayPipe::DisplayPipe(pipe_index pipeIndex) +Pipe::Pipe(pipe_index pipeIndex) : fFDILink(NULL), // fPanelFitter(NULL), @@ -68,19 +69,19 @@ DisplayPipe::DisplayPipe(pipe_index pipeIndex) fFDILink = new(std::nothrow) FDILink(pipeIndex); } - TRACE("DisplayPipe %s. Pipe Base: 0x%" B_PRIxADDR + TRACE("Pipe %s. Pipe Base: 0x%" B_PRIxADDR " Plane Base: 0x% " B_PRIxADDR "\n", (pipeIndex == INTEL_PIPE_A) ? "A" : "B", fPipeBase, fPlaneBase); } -DisplayPipe::~DisplayPipe() +Pipe::~Pipe() { } bool -DisplayPipe::IsEnabled() +Pipe::IsEnabled() { CALLED(); return (read32(fPlaneBase + INTEL_PIPE_CONTROL) & INTEL_PIPE_ENABLED) != 0; @@ -88,7 +89,7 @@ DisplayPipe::IsEnabled() void -DisplayPipe::Enable(display_mode* target, addr_t portAddress) +Pipe::Enable(display_mode* target, addr_t portAddress) { CALLED(); @@ -152,14 +153,14 @@ DisplayPipe::Enable(display_mode* target, addr_t portAddress) void -DisplayPipe::Disable() +Pipe::Disable() { _Enable(false); } void -DisplayPipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock, +Pipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock, uint32 extraFlags) { CALLED(); @@ -250,7 +251,7 @@ DisplayPipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock, void -DisplayPipe::_Enable(bool enable) +Pipe::_Enable(bool enable) { CALLED(); diff --git a/src/add-ons/accelerants/intel_extreme/DisplayPipe.h b/src/add-ons/accelerants/intel_extreme/Pipes.h similarity index 92% rename from src/add-ons/accelerants/intel_extreme/DisplayPipe.h rename to src/add-ons/accelerants/intel_extreme/Pipes.h index 123553a394..08831daf2d 100644 --- a/src/add-ons/accelerants/intel_extreme/DisplayPipe.h +++ b/src/add-ons/accelerants/intel_extreme/Pipes.h @@ -18,15 +18,18 @@ #include "FlexibleDisplayInterface.h" +#define MAX_PIPES 2 + + void program_pipe_color_modes(uint32 colorMode); //class FDILink; //class PanelFitter; -class DisplayPipe { +class Pipe { public: - DisplayPipe(pipe_index pipeIndex); - ~DisplayPipe(); + Pipe(pipe_index pipeIndex); + ~Pipe(); pipe_index Index() { return fPipeIndex; } diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index 289a97f574..e6700f2486 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -67,7 +67,7 @@ wait_for_clear(addr_t address, uint32 mask, uint32 timeout) Port::Port(port_index index, const char* baseName) : - fDisplayPipe(NULL), + fPipe(NULL), fPortIndex(index), fPortName(NULL), fEDIDState(B_NO_INIT) @@ -103,10 +103,15 @@ Port::HasEDID() status_t -Port::AssignPipe(pipe_index pipeIndex) +Port::SetPipe(Pipe* pipe) { CALLED(); + if (pipe == NULL) { + ERROR("%s: Invalid pipe provided!\n", __func__); + return B_ERROR; + } + uint32 portRegister = _PortRegister(); if (portRegister == 0) { ERROR("%s: Invalid PortRegister ((0x%" B_PRIx32 ") for %s\n", __func__, @@ -115,29 +120,29 @@ Port::AssignPipe(pipe_index pipeIndex) } // TODO: UnAssignPipe? This likely needs reworked a little - if (fDisplayPipe != NULL) { - ERROR("%s: Can't reassign DisplayPipe (yet)\n", __func__); + if (fPipe != NULL) { + ERROR("%s: Can't reassign display pipe (yet)\n", __func__); return B_ERROR; } TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe %s\n", __func__, - PortName(), portRegister, (pipeIndex == INTEL_PIPE_A) ? "A" : "B"); + PortName(), portRegister, (pipe->Index() == INTEL_PIPE_A) ? "A" : "B"); uint32 portState = read32(portRegister); - if (pipeIndex == INTEL_PIPE_A) + if (pipe->Index() == INTEL_PIPE_A) write32(portRegister, portState & ~DISPLAY_MONITOR_PIPE_B); else write32(portRegister, portState | DISPLAY_MONITOR_PIPE_B); - fDisplayPipe = new(std::nothrow) DisplayPipe(pipeIndex); + fPipe = pipe; - if (fDisplayPipe == NULL) + if (fPipe == NULL) return B_NO_MEMORY; // Disable display pipe until modesetting enables it - if (fDisplayPipe->IsEnabled()) - fDisplayPipe->Disable(); + if (fPipe->IsEnabled()) + fPipe->Disable(); read32(portRegister); @@ -283,13 +288,13 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode) TRACE("%s: %s %dx%d\n", __func__, PortName(), target->virtual_width, target->virtual_height); - if (fDisplayPipe == NULL) { + if (fPipe == NULL) { ERROR("%s: Setting display mode without assigned pipe!\n", __func__); return B_ERROR; } // Train FDI if it exists - FDILink* link = fDisplayPipe->FDI(); + FDILink* link = fPipe->FDI(); if (link != NULL) link->Train(target); @@ -301,11 +306,11 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode) extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; // Program pipe PLL's - fDisplayPipe->ConfigureTimings(divisors, target->timing.pixel_clock, + fPipe->ConfigureTimings(divisors, target->timing.pixel_clock, extraPLLFlags); // Program target display mode - fDisplayPipe->Enable(target, _PortRegister()); + fPipe->Enable(target, _PortRegister()); // Set fCurrentMode to our set display mode memcpy(&fCurrentMode, target, sizeof(display_mode)); @@ -384,7 +389,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) TRACE("%s: %s-%d %dx%d\n", __func__, PortName(), PortIndex(), target->virtual_width, target->virtual_height); - if (fDisplayPipe == NULL) { + if (fPipe == NULL) { ERROR("%s: Setting display mode without assigned pipe!\n", __func__); return B_ERROR; } @@ -408,7 +413,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) // Disable PanelFitter for now addr_t panelFitterControl = PCH_PANEL_FITTER_BASE_REGISTER + PCH_PANEL_FITTER_CONTROL; - if (fDisplayPipe->Index() == INTEL_PIPE_B) + if (fPipe->Index() == INTEL_PIPE_B) panelFitterControl += PCH_PANEL_FITTER_PIPE_OFFSET; write32(panelFitterControl, (read32(panelFitterControl) & ~PANEL_FITTER_ENABLED)); read32(panelFitterControl); @@ -543,7 +548,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) - fDisplayPipe->ConfigureTimings(divisors, target->timing.pixel_clock, + fPipe->ConfigureTimings(divisors, target->timing.pixel_clock, extraPLLFlags); // Power on Panel @@ -554,7 +559,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) ERROR("%s: %s didn't power on within 1000ms!\n", __func__, PortName()); // Program target display mode - fDisplayPipe->Enable(target, _PortRegister()); + fPipe->Enable(target, _PortRegister()); #if 0 @@ -704,13 +709,13 @@ DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode) TRACE("%s: %s %dx%d\n", __func__, PortName(), target->virtual_width, target->virtual_height); - if (fDisplayPipe == NULL) { + if (fPipe == NULL) { ERROR("%s: Setting display mode without assigned pipe!\n", __func__); return B_ERROR; } // Train FDI if it exists - FDILink* link = fDisplayPipe->FDI(); + FDILink* link = fPipe->FDI(); if (link != NULL) link->Train(target); @@ -722,11 +727,11 @@ DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode) extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; // Program pipe PLL's - fDisplayPipe->ConfigureTimings(divisors, target->timing.pixel_clock, + fPipe->ConfigureTimings(divisors, target->timing.pixel_clock, extraPLLFlags); // Program target display mode - fDisplayPipe->Enable(target, _PortRegister()); + fPipe->Enable(target, _PortRegister()); // 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 db33b6b43d..b63615561c 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.h +++ b/src/add-ons/accelerants/intel_extreme/Ports.h @@ -14,7 +14,7 @@ #include "intel_extreme.h" -#include "DisplayPipe.h" +#include "Pipes.h" #include "pll.h" @@ -56,7 +56,10 @@ virtual uint32 Type() const = 0; virtual bool IsConnected() = 0; - status_t AssignPipe(pipe_index pipeIndex); + status_t SetPipe(Pipe* pipe); + ::Pipe* GetPipe() + { return fPipe; }; + bool HasEDID(); virtual status_t GetEDID(edid1_info* edid, @@ -70,9 +73,6 @@ virtual status_t SetDisplayMode(display_mode* mode, virtual pipe_index PipePreference() { return INTEL_PIPE_ANY; }; - ::DisplayPipe* Pipe() - { return fDisplayPipe; }; - protected: void _SetName(const char* name); @@ -82,8 +82,7 @@ static status_t _SetI2CSignals(void* cookie, int clock, int data); display_mode fCurrentMode; - DisplayPipe* fDisplayPipe; - + Pipe* fPipe; private: virtual addr_t _DDCRegister() = 0; diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index a67a50049f..6fa8c32fcc 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -158,6 +158,26 @@ init_common(int device, bool isClone) } } + gInfo->pipe_count = 0; + + // Allocate all of our pipes + for (int i = 0; i < MAX_PIPES; i++) { + switch (i) { + case 0: + gInfo->pipes[i] = new(std::nothrow) Pipe(INTEL_PIPE_A); + break; + case 1: + gInfo->pipes[i] = new(std::nothrow) Pipe(INTEL_PIPE_B); + break; + default: + ERROR("%s: Unknown pipe %d\n", __func__, i); + } + if (gInfo->pipes[i] == NULL) + ERROR("%s: Error allocating pipe %d\n", __func__, i); + else + gInfo->pipe_count++; + } + return B_OK; } @@ -321,37 +341,34 @@ probe_ports() static status_t assign_pipes() { - uint32 assigned = 0; - // TODO: At some point we should "group" ports to pipes with the same mode. // You can drive multiple ports from a single pipe as long as the mode is // the same. For the moment we could get displays with the wrong pipes // assigned when the count is > 1; + uint32 current = 0; for (uint32 i = 0; i < gInfo->port_count; i++) { if (gInfo->ports[i] == NULL) continue; - if (gInfo->ports[i]->PipePreference() != INTEL_PIPE_ANY) { + pipe_index preference = gInfo->ports[i]->PipePreference(); + if (preference != INTEL_PIPE_ANY) { // Some ports *really* need to be assigned a pipe due to // implementation bugs. - gInfo->ports[i]->AssignPipe(gInfo->ports[i]->PipePreference()); + int index = (preference == INTEL_PIPE_B) ? 1 : 0; + gInfo->ports[i]->SetPipe(gInfo->pipes[index]); continue; } if (gInfo->ports[i]->IsConnected()) { - pipe_index currentPipe = INTEL_PIPE_A; - if (assigned == 1) - currentPipe = INTEL_PIPE_B; - else if (assigned > 2) { + if (current >= gInfo->pipe_count) { ERROR("%s: No pipes left to assign to port %s!\n", __func__, gInfo->ports[i]->PortName()); continue; } - - gInfo->ports[i]->AssignPipe(currentPipe); - - assigned++; + + gInfo->ports[i]->SetPipe(gInfo->pipes[current]); + current++; } } diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.h b/src/add-ons/accelerants/intel_extreme/accelerant.h index 0f3f6d8904..2f34eb4f12 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.h +++ b/src/add-ons/accelerants/intel_extreme/accelerant.h @@ -15,6 +15,7 @@ #include #include "Ports.h" +#include "Pipes.h" struct overlay { @@ -53,6 +54,9 @@ struct accelerant_info { uint32 port_count; Port* ports[MAX_PORTS]; + uint32 pipe_count; + Pipe* pipes[MAX_PIPES]; + edid1_info edid_info; bool has_edid;