intel_extreme: Don't store pipes within ports

* Store pipes within accelerant, and tell ports
  about them.
* Rebrand DisplayPipe class to Pipe
This commit is contained in:
Alexander von Gluck IV
2015-11-24 12:11:31 -06:00
parent 864275121f
commit b01aed8310
7 changed files with 84 additions and 55 deletions
@@ -18,9 +18,9 @@ Addon intel_extreme.accelerant :
# overlay_3d_i965.cpp # overlay_3d_i965.cpp
pll.cpp pll.cpp
# classes # classes
DisplayPipe.cpp
FlexibleDisplayInterface.cpp FlexibleDisplayInterface.cpp
# PanelFitter.cpp # PanelFitter.cpp
Ports.cpp Ports.cpp
Pipes.cpp
: be $(TARGET_LIBSTDC++) libaccelerantscommon.a : be $(TARGET_LIBSTDC++) libaccelerantscommon.a
; ;
@@ -6,7 +6,7 @@
* Michael Lotz, mmlr@mlotz.ch * Michael Lotz, mmlr@mlotz.ch
* Alexander von Gluck IV, kallisti5@unixzen.com * Alexander von Gluck IV, kallisti5@unixzen.com
*/ */
#include "DisplayPipe.h" #include "Pipes.h"
#include "accelerant.h" #include "accelerant.h"
#include "intel_extreme.h" #include "intel_extreme.h"
@@ -33,6 +33,7 @@ extern "C" void _sPrintf(const char* format, ...);
// PIPE: 6 // PIPE: 6
// PLANE: 7 // PLANE: 7
void void
program_pipe_color_modes(uint32 colorMode) 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), fFDILink(NULL),
// fPanelFitter(NULL), // fPanelFitter(NULL),
@@ -68,19 +69,19 @@ DisplayPipe::DisplayPipe(pipe_index pipeIndex)
fFDILink = new(std::nothrow) FDILink(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) " Plane Base: 0x% " B_PRIxADDR "\n", (pipeIndex == INTEL_PIPE_A)
? "A" : "B", fPipeBase, fPlaneBase); ? "A" : "B", fPipeBase, fPlaneBase);
} }
DisplayPipe::~DisplayPipe() Pipe::~Pipe()
{ {
} }
bool bool
DisplayPipe::IsEnabled() Pipe::IsEnabled()
{ {
CALLED(); CALLED();
return (read32(fPlaneBase + INTEL_PIPE_CONTROL) & INTEL_PIPE_ENABLED) != 0; return (read32(fPlaneBase + INTEL_PIPE_CONTROL) & INTEL_PIPE_ENABLED) != 0;
@@ -88,7 +89,7 @@ DisplayPipe::IsEnabled()
void void
DisplayPipe::Enable(display_mode* target, addr_t portAddress) Pipe::Enable(display_mode* target, addr_t portAddress)
{ {
CALLED(); CALLED();
@@ -152,14 +153,14 @@ DisplayPipe::Enable(display_mode* target, addr_t portAddress)
void void
DisplayPipe::Disable() Pipe::Disable()
{ {
_Enable(false); _Enable(false);
} }
void void
DisplayPipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock, Pipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock,
uint32 extraFlags) uint32 extraFlags)
{ {
CALLED(); CALLED();
@@ -250,7 +251,7 @@ DisplayPipe::ConfigureTimings(const pll_divisors& divisors, uint32 pixelClock,
void void
DisplayPipe::_Enable(bool enable) Pipe::_Enable(bool enable)
{ {
CALLED(); CALLED();
@@ -18,15 +18,18 @@
#include "FlexibleDisplayInterface.h" #include "FlexibleDisplayInterface.h"
#define MAX_PIPES 2
void program_pipe_color_modes(uint32 colorMode); void program_pipe_color_modes(uint32 colorMode);
//class FDILink; //class FDILink;
//class PanelFitter; //class PanelFitter;
class DisplayPipe { class Pipe {
public: public:
DisplayPipe(pipe_index pipeIndex); Pipe(pipe_index pipeIndex);
~DisplayPipe(); ~Pipe();
pipe_index Index() pipe_index Index()
{ return fPipeIndex; } { return fPipeIndex; }
+27 -22
View File
@@ -67,7 +67,7 @@ wait_for_clear(addr_t address, uint32 mask, uint32 timeout)
Port::Port(port_index index, const char* baseName) Port::Port(port_index index, const char* baseName)
: :
fDisplayPipe(NULL), fPipe(NULL),
fPortIndex(index), fPortIndex(index),
fPortName(NULL), fPortName(NULL),
fEDIDState(B_NO_INIT) fEDIDState(B_NO_INIT)
@@ -103,10 +103,15 @@ Port::HasEDID()
status_t status_t
Port::AssignPipe(pipe_index pipeIndex) Port::SetPipe(Pipe* pipe)
{ {
CALLED(); CALLED();
if (pipe == NULL) {
ERROR("%s: Invalid pipe provided!\n", __func__);
return B_ERROR;
}
uint32 portRegister = _PortRegister(); uint32 portRegister = _PortRegister();
if (portRegister == 0) { if (portRegister == 0) {
ERROR("%s: Invalid PortRegister ((0x%" B_PRIx32 ") for %s\n", __func__, 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 // TODO: UnAssignPipe? This likely needs reworked a little
if (fDisplayPipe != NULL) { if (fPipe != NULL) {
ERROR("%s: Can't reassign DisplayPipe (yet)\n", __func__); ERROR("%s: Can't reassign display pipe (yet)\n", __func__);
return B_ERROR; return B_ERROR;
} }
TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe %s\n", __func__, 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); uint32 portState = read32(portRegister);
if (pipeIndex == INTEL_PIPE_A) if (pipe->Index() == INTEL_PIPE_A)
write32(portRegister, portState & ~DISPLAY_MONITOR_PIPE_B); write32(portRegister, portState & ~DISPLAY_MONITOR_PIPE_B);
else else
write32(portRegister, portState | DISPLAY_MONITOR_PIPE_B); 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; return B_NO_MEMORY;
// Disable display pipe until modesetting enables it // Disable display pipe until modesetting enables it
if (fDisplayPipe->IsEnabled()) if (fPipe->IsEnabled())
fDisplayPipe->Disable(); fPipe->Disable();
read32(portRegister); read32(portRegister);
@@ -283,13 +288,13 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode)
TRACE("%s: %s %dx%d\n", __func__, PortName(), target->virtual_width, TRACE("%s: %s %dx%d\n", __func__, PortName(), target->virtual_width,
target->virtual_height); target->virtual_height);
if (fDisplayPipe == NULL) { if (fPipe == NULL) {
ERROR("%s: Setting display mode without assigned pipe!\n", __func__); ERROR("%s: Setting display mode without assigned pipe!\n", __func__);
return B_ERROR; return B_ERROR;
} }
// Train FDI if it exists // Train FDI if it exists
FDILink* link = fDisplayPipe->FDI(); FDILink* link = fPipe->FDI();
if (link != NULL) if (link != NULL)
link->Train(target); link->Train(target);
@@ -301,11 +306,11 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode)
extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL;
// Program pipe PLL's // Program pipe PLL's
fDisplayPipe->ConfigureTimings(divisors, target->timing.pixel_clock, fPipe->ConfigureTimings(divisors, target->timing.pixel_clock,
extraPLLFlags); extraPLLFlags);
// Program target display mode // Program target display mode
fDisplayPipe->Enable(target, _PortRegister()); fPipe->Enable(target, _PortRegister());
// Set fCurrentMode to our set display mode // Set fCurrentMode to our set display mode
memcpy(&fCurrentMode, target, sizeof(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(), TRACE("%s: %s-%d %dx%d\n", __func__, PortName(), PortIndex(),
target->virtual_width, target->virtual_height); target->virtual_width, target->virtual_height);
if (fDisplayPipe == NULL) { if (fPipe == NULL) {
ERROR("%s: Setting display mode without assigned pipe!\n", __func__); ERROR("%s: Setting display mode without assigned pipe!\n", __func__);
return B_ERROR; return B_ERROR;
} }
@@ -408,7 +413,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode)
// Disable PanelFitter for now // Disable PanelFitter for now
addr_t panelFitterControl = PCH_PANEL_FITTER_BASE_REGISTER addr_t panelFitterControl = PCH_PANEL_FITTER_BASE_REGISTER
+ PCH_PANEL_FITTER_CONTROL; + PCH_PANEL_FITTER_CONTROL;
if (fDisplayPipe->Index() == INTEL_PIPE_B) if (fPipe->Index() == INTEL_PIPE_B)
panelFitterControl += PCH_PANEL_FITTER_PIPE_OFFSET; panelFitterControl += PCH_PANEL_FITTER_PIPE_OFFSET;
write32(panelFitterControl, (read32(panelFitterControl) & ~PANEL_FITTER_ENABLED)); write32(panelFitterControl, (read32(panelFitterControl) & ~PANEL_FITTER_ENABLED));
read32(panelFitterControl); read32(panelFitterControl);
@@ -543,7 +548,7 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode)
extraPLLFlags |= DISPLAY_PLL_MODE_LVDS; extraPLLFlags |= DISPLAY_PLL_MODE_LVDS;
// Program pipe PLL's (pixel_clock is *always* the hardware pixel clock) // 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); extraPLLFlags);
// Power on Panel // 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()); ERROR("%s: %s didn't power on within 1000ms!\n", __func__, PortName());
// Program target display mode // Program target display mode
fDisplayPipe->Enable(target, _PortRegister()); fPipe->Enable(target, _PortRegister());
#if 0 #if 0
@@ -704,13 +709,13 @@ DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode)
TRACE("%s: %s %dx%d\n", __func__, PortName(), target->virtual_width, TRACE("%s: %s %dx%d\n", __func__, PortName(), target->virtual_width,
target->virtual_height); target->virtual_height);
if (fDisplayPipe == NULL) { if (fPipe == NULL) {
ERROR("%s: Setting display mode without assigned pipe!\n", __func__); ERROR("%s: Setting display mode without assigned pipe!\n", __func__);
return B_ERROR; return B_ERROR;
} }
// Train FDI if it exists // Train FDI if it exists
FDILink* link = fDisplayPipe->FDI(); FDILink* link = fPipe->FDI();
if (link != NULL) if (link != NULL)
link->Train(target); link->Train(target);
@@ -722,11 +727,11 @@ DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode)
extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL; extraPLLFlags |= DISPLAY_PLL_MODE_NORMAL;
// Program pipe PLL's // Program pipe PLL's
fDisplayPipe->ConfigureTimings(divisors, target->timing.pixel_clock, fPipe->ConfigureTimings(divisors, target->timing.pixel_clock,
extraPLLFlags); extraPLLFlags);
// Program target display mode // Program target display mode
fDisplayPipe->Enable(target, _PortRegister()); fPipe->Enable(target, _PortRegister());
// Set fCurrentMode to our set display mode // Set fCurrentMode to our set display mode
memcpy(&fCurrentMode, target, sizeof(display_mode)); memcpy(&fCurrentMode, target, sizeof(display_mode));
@@ -14,7 +14,7 @@
#include "intel_extreme.h" #include "intel_extreme.h"
#include "DisplayPipe.h" #include "Pipes.h"
#include "pll.h" #include "pll.h"
@@ -56,7 +56,10 @@ virtual uint32 Type() const = 0;
virtual bool IsConnected() = 0; virtual bool IsConnected() = 0;
status_t AssignPipe(pipe_index pipeIndex); status_t SetPipe(Pipe* pipe);
::Pipe* GetPipe()
{ return fPipe; };
bool HasEDID(); bool HasEDID();
virtual status_t GetEDID(edid1_info* edid, virtual status_t GetEDID(edid1_info* edid,
@@ -70,9 +73,6 @@ virtual status_t SetDisplayMode(display_mode* mode,
virtual pipe_index PipePreference() virtual pipe_index PipePreference()
{ return INTEL_PIPE_ANY; }; { return INTEL_PIPE_ANY; };
::DisplayPipe* Pipe()
{ return fDisplayPipe; };
protected: protected:
void _SetName(const char* name); void _SetName(const char* name);
@@ -82,8 +82,7 @@ static status_t _SetI2CSignals(void* cookie, int clock,
int data); int data);
display_mode fCurrentMode; display_mode fCurrentMode;
DisplayPipe* fDisplayPipe; Pipe* fPipe;
private: private:
virtual addr_t _DDCRegister() = 0; virtual addr_t _DDCRegister() = 0;
@@ -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; return B_OK;
} }
@@ -321,37 +341,34 @@ probe_ports()
static status_t static status_t
assign_pipes() assign_pipes()
{ {
uint32 assigned = 0;
// TODO: At some point we should "group" ports to pipes with the same mode. // 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 // 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 // the same. For the moment we could get displays with the wrong pipes
// assigned when the count is > 1; // assigned when the count is > 1;
uint32 current = 0;
for (uint32 i = 0; i < gInfo->port_count; i++) { for (uint32 i = 0; i < gInfo->port_count; i++) {
if (gInfo->ports[i] == NULL) if (gInfo->ports[i] == NULL)
continue; 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 // Some ports *really* need to be assigned a pipe due to
// implementation bugs. // 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; continue;
} }
if (gInfo->ports[i]->IsConnected()) { if (gInfo->ports[i]->IsConnected()) {
pipe_index currentPipe = INTEL_PIPE_A; if (current >= gInfo->pipe_count) {
if (assigned == 1)
currentPipe = INTEL_PIPE_B;
else if (assigned > 2) {
ERROR("%s: No pipes left to assign to port %s!\n", __func__, ERROR("%s: No pipes left to assign to port %s!\n", __func__,
gInfo->ports[i]->PortName()); gInfo->ports[i]->PortName());
continue; continue;
} }
gInfo->ports[i]->AssignPipe(currentPipe); gInfo->ports[i]->SetPipe(gInfo->pipes[current]);
current++;
assigned++;
} }
} }
@@ -15,6 +15,7 @@
#include <video_overlay.h> #include <video_overlay.h>
#include "Ports.h" #include "Ports.h"
#include "Pipes.h"
struct overlay { struct overlay {
@@ -53,6 +54,9 @@ struct accelerant_info {
uint32 port_count; uint32 port_count;
Port* ports[MAX_PORTS]; Port* ports[MAX_PORTS];
uint32 pipe_count;
Pipe* pipes[MAX_PIPES];
edid1_info edid_info; edid1_info edid_info;
bool has_edid; bool has_edid;