intel_extreme: Begin using new DisplayPipe class
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user