intel_extreme: Begin using new DisplayPipe class

This commit is contained in:
Alexander von Gluck IV
2015-11-08 11:58:49 -06:00
parent 37b903fbc8
commit 6e1ff82f45
7 changed files with 117 additions and 65 deletions
@@ -1,9 +1,10 @@
/*
* Copyright 2011, Haiku, Inc. All Rights Reserved.
* Copyright 2011-2015, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz, [email protected]
* Alexander von Gluck IV, [email protected]
*/
@@ -11,6 +12,7 @@
#include "accelerant.h"
#include "intel_extreme.h"
#include <KernelExport.h>
#include <stdlib.h>
#include <string.h>
@@ -25,14 +27,28 @@ extern "C" void _sPrintf(const char* format, ...);
#endif
void
program_pipe_color_modes(uint32 colorMode)
{
// All pipes get the same color mode
write32(INTEL_DISPLAY_A_CONTROL, (read32(INTEL_DISPLAY_A_CONTROL)
& ~(DISPLAY_CONTROL_COLOR_MASK | DISPLAY_CONTROL_GAMMA))
| colorMode);
write32(INTEL_DISPLAY_B_CONTROL, (read32(INTEL_DISPLAY_B_CONTROL)
& ~(DISPLAY_CONTROL_COLOR_MASK | DISPLAY_CONTROL_GAMMA))
| colorMode);
}
// #pragma mark - DisplayPipe
DisplayPipe::DisplayPipe(int32 pipeIndex)
DisplayPipe::DisplayPipe(pipe_index pipeIndex)
:
fFDILink(NULL),
fPanelFitter(NULL),
fBaseRegister(INTEL_PIPE_BASE_REGISTER + pipeIndex * INTEL_PIPE_PIPE_OFFSET)
// fFDILink(NULL),
// fPanelFitter(NULL),
fBaseRegister(INTEL_PIPE_BASE_REGISTER + pipeIndex * INTEL_PIPE_OFFSET),
fPipeIndex(pipeIndex)
{
}
@@ -40,7 +56,8 @@ DisplayPipe::DisplayPipe(int32 pipeIndex)
bool
DisplayPipe::IsEnabled()
{
return (read32(fBaseRegister + INTEL_PIPE_CONTROL) & PIPE_ENABLED) != 0;
return (read32(fBaseRegister + INTEL_PIPE_CONTROL)
& INTEL_PIPE_ENABLED) != 0;
}
@@ -48,6 +65,8 @@ void
DisplayPipe::Enable(const display_mode& mode)
{
_Enable(true);
write32(INTEL_DISPLAY_B_IMAGE_SIZE, ((uint32)(mode.virtual_width - 1) << 16)
| (uint32)(mode.virtual_height - 1));
}
@@ -117,6 +136,7 @@ DisplayPipe::ConfigureTimings(const pll_divisors& divisors)
read32(INTEL_DISPLAY_A_PLL);
spin(150);
#if 0
// update timing parameters
write32(INTEL_DISPLAY_A_HTOTAL,
((uint32)(target.timing.h_total - 1) << 16)
@@ -149,27 +169,7 @@ DisplayPipe::ConfigureTimings(const pll_divisors& divisors)
? DISPLAY_MONITOR_POSITIVE_HSYNC : 0)
| ((target.timing.flags & B_POSITIVE_VSYNC) != 0
? DISPLAY_MONITOR_POSITIVE_VSYNC : 0));
// TODO: verify the two comments below: the X driver doesn't seem to
// care about both of them!
// These two have to be set for display B, too - this obviously means
// that the second head always must adopt the color space of the first
// head.
write32(INTEL_DISPLAY_A_CONTROL, (read32(INTEL_DISPLAY_A_CONTROL)
& ~(DISPLAY_CONTROL_COLOR_MASK | DISPLAY_CONTROL_GAMMA))
| colorMode);
if ((gInfo->head_mode & HEAD_MODE_B_DIGITAL) != 0) {
write32(INTEL_DISPLAY_B_IMAGE_SIZE,
((uint32)(target.virtual_width - 1) << 16)
| ((uint32)target.virtual_height - 1));
write32(INTEL_DISPLAY_B_CONTROL, (read32(INTEL_DISPLAY_B_CONTROL)
& ~(DISPLAY_CONTROL_COLOR_MASK | DISPLAY_CONTROL_GAMMA))
| colorMode);
}
#endif
}
@@ -177,7 +177,7 @@ void
DisplayPipe::_Enable(bool enable)
{
uint32 targetRegister = fBaseRegister + INTEL_PIPE_CONTROL;
write32(targetRegister, read32(targetRegister) & ~PIPE_ENABLED
| (enable ? PIPE_ENABLED | 0));
write32(targetRegister, (read32(targetRegister) & ~INTEL_PIPE_ENABLED)
| (enable ? INTEL_PIPE_ENABLED : 0));
read32(targetRegister);
}
@@ -1,24 +1,40 @@
/*
* Copyright 2011, Haiku, Inc. All Rights Reserved.
* Copyright 2011-2015, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz, [email protected]
* Alexander von Gluck IV, [email protected]
*/
#ifndef INTEL_PIPE_H
#define INTEL_PIPE_H
class FDILink;
class PanelFitter;
#include <edid.h>
struct pll_divisors;
#include "intel_extreme.h"
#include "pll.h"
enum pipe_index {
INTEL_PIPE_A,
INTEL_PIPE_B
};
void program_pipe_color_modes(uint32 colorMode);
//class FDILink;
//class PanelFitter;
class DisplayPipe {
public:
DisplayPipe(int32 pipeIndex);
DisplayPipe(pipe_index pipeIndex);
virtual ~DisplayPipe();
pipe_index Index()
{ return fPipeIndex; }
bool IsEnabled();
void Enable(const display_mode& mode);
void Disable();
@@ -27,18 +43,20 @@ virtual ~DisplayPipe();
const pll_divisors& divisors);
// access to the various parts of the pipe
::FDILink* FDILink()
{ return fFDILink; }
::PanelFitter* PanelFitter()
{ return fPanelFitter; }
// ::FDILink* FDILink()
// { return fFDILink; }
// ::PanelFitter* PanelFitter()
// { return fPanelFitter; }
private:
void _Enable(bool enable);
FDILink* fFDILink;
PanelFitter* fPanelFitter;
// FDILink* fFDILink;
// PanelFitter* fPanelFitter;
uint32 fRegisterBase;
addr_t fBaseRegister;
pipe_index fPipeIndex;
};
#endif // INTEL_PIPE_H
@@ -18,7 +18,7 @@ Addon intel_extreme.accelerant :
# overlay_3d_i965.cpp
pll.cpp
# classes
# DisplayPipe.cpp
DisplayPipe.cpp
# FlexibleDisplayInterface.cpp
# PanelFitter.cpp
Ports.cpp
@@ -21,6 +21,8 @@
#include "accelerant_protos.h"
#include "intel_extreme.h"
#include <new>
#undef TRACE
#define TRACE_PORTS
@@ -38,7 +40,7 @@ Port::Port(port_index index, const char* baseName)
:
fPortIndex(index),
fPortName(NULL),
fPipeIndex(INTEL_PIPE_ANY),
fDisplayPipe(NULL),
fEDIDState(B_NO_INIT)
{
char portID[2];
@@ -71,8 +73,8 @@ Port::HasEDID()
}
void
Port::PipeSelect(pipe_index pipeIndex)
status_t
Port::AssignPipe(pipe_index pipeIndex)
{
CALLED();
@@ -80,7 +82,7 @@ Port::PipeSelect(pipe_index pipeIndex)
if (portRegister == 0) {
ERROR("%s: Invalid PortRegister ((0x%" B_PRIx32 ") for %s\n", __func__,
portRegister, PortName());
return;
return B_ERROR;
}
TRACE("%s: Assigning %s (0x%" B_PRIx32 ") to pipe %s\n", __func__,
@@ -93,8 +95,14 @@ Port::PipeSelect(pipe_index pipeIndex)
else
write32(portRegister, portState | DISPLAY_MONITOR_PIPE_B);
fPipeIndex = pipeIndex;
fDisplayPipe = new(std::nothrow) DisplayPipe(pipeIndex);
if (fDisplayPipe == NULL)
return B_NO_MEMORY;
read32(portRegister);
return B_OK;
}
@@ -730,7 +738,7 @@ HDMIPort::IsConnected()
return false;
addr_t portRegister = _PortRegister();
TRACE("%s - %d: PortRegister: %" B_PRIx32 "\n", PortName(), PortIndex(),
TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
portRegister);
if (portRegister == 0)
+4 -14
View File
@@ -12,6 +12,7 @@
#include <edid.h>
#include "DisplayPipe.h"
#include "intel_extreme.h"
#include "pll.h"
@@ -39,14 +40,6 @@ enum port_index {
};
// TODO: This likely should go in some pipe header
enum pipe_index {
INTEL_PIPE_ANY,
INTEL_PIPE_A,
INTEL_PIPE_B
};
class Port {
public:
Port(port_index index,
@@ -60,12 +53,9 @@ virtual uint32 Type() const = 0;
port_index PortIndex() const
{ return fPortIndex; }
pipe_index PipeIndex() const
{ return fPipeIndex; }
virtual bool IsConnected() = 0;
void PipeSelect(pipe_index pipeIndex);
status_t AssignPipe(pipe_index pipeIndex);
bool HasEDID();
virtual status_t GetEDID(edid1_info* edid,
@@ -93,7 +83,7 @@ virtual addr_t _PortRegister() = 0;
port_index fPortIndex;
char* fPortName;
pipe_index fPipeIndex;
DisplayPipe* fDisplayPipe;
status_t fEDIDState;
edid1_info fEDIDInfo;
@@ -179,7 +169,7 @@ virtual uint32 Type() const
virtual bool IsConnected();
protected:
virtual uint32 _PortRegister();
virtual addr_t _PortRegister();
};
@@ -318,6 +318,37 @@ 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 (uint32 i = 0; i < gInfo->port_count; i++) {
if (gInfo->ports[i] == NULL)
continue;
if (gInfo->ports[i]->IsConnected()) {
pipe_index currentPipe = INTEL_PIPE_A;
if (assigned == 1)
currentPipe = INTEL_PIPE_B;
else if (assigned > 2) {
ERROR("%s: No pipes left to assign to port %s!\n", __func__,
gInfo->ports[i]->PortName());
continue;
}
gInfo->ports[i]->AssignPipe(currentPipe);
assigned++;
}
}
return B_OK;
}
// #pragma mark - public accelerant functions
@@ -350,6 +381,11 @@ intel_init_accelerant(int device)
if (status != B_OK)
ERROR("Warning: zero active displays were found!\n");
status = assign_pipes();
if (status != B_OK)
ERROR("Warning: error while assigning pipes!\n");
status = create_mode_list();
if (status != B_OK) {
uninit_common();
@@ -615,9 +615,6 @@ if (first) {
if (!gInfo->ports[i]->IsConnected())
continue;
// XXX: For now we force everything on PIPE A
gInfo->ports[i]->PipeSelect(INTEL_PIPE_A);
status_t status = gInfo->ports[i]->SetDisplayMode(&target, colorMode);
if (status != B_OK)
ERROR("%s: Unable to set display mode!\n", __func__);
@@ -717,6 +714,9 @@ if (first) {
// RIP ANALOG
// We set the same color mode across all pipes
program_pipe_color_modes(colorMode);
// TODO: This may not be neccesary (see DPMS OFF at top)
set_display_power_mode(sharedInfo.dpms_mode);