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
pll.cpp
# classes
DisplayPipe.cpp
FlexibleDisplayInterface.cpp
# PanelFitter.cpp
Ports.cpp
Pipes.cpp
: be $(TARGET_LIBSTDC++) libaccelerantscommon.a
;
@@ -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();
@@ -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; }
+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)
:
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));
@@ -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;
@@ -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++;
}
}
@@ -15,6 +15,7 @@
#include <video_overlay.h>
#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;