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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Michael Lotz, [email protected]
|
* Michael Lotz, [email protected]
|
||||||
|
* Alexander von Gluck IV, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@
|
|||||||
|
|
||||||
#include "accelerant.h"
|
#include "accelerant.h"
|
||||||
#include "intel_extreme.h"
|
#include "intel_extreme.h"
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -25,14 +27,28 @@ extern "C" void _sPrintf(const char* format, ...);
|
|||||||
#endif
|
#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
|
// #pragma mark - DisplayPipe
|
||||||
|
|
||||||
|
|
||||||
DisplayPipe::DisplayPipe(int32 pipeIndex)
|
DisplayPipe::DisplayPipe(pipe_index pipeIndex)
|
||||||
:
|
:
|
||||||
fFDILink(NULL),
|
// fFDILink(NULL),
|
||||||
fPanelFitter(NULL),
|
// fPanelFitter(NULL),
|
||||||
fBaseRegister(INTEL_PIPE_BASE_REGISTER + pipeIndex * INTEL_PIPE_PIPE_OFFSET)
|
fBaseRegister(INTEL_PIPE_BASE_REGISTER + pipeIndex * INTEL_PIPE_OFFSET),
|
||||||
|
fPipeIndex(pipeIndex)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +56,8 @@ DisplayPipe::DisplayPipe(int32 pipeIndex)
|
|||||||
bool
|
bool
|
||||||
DisplayPipe::IsEnabled()
|
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)
|
DisplayPipe::Enable(const display_mode& mode)
|
||||||
{
|
{
|
||||||
_Enable(true);
|
_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);
|
read32(INTEL_DISPLAY_A_PLL);
|
||||||
spin(150);
|
spin(150);
|
||||||
|
|
||||||
|
#if 0
|
||||||
// update timing parameters
|
// update timing parameters
|
||||||
write32(INTEL_DISPLAY_A_HTOTAL,
|
write32(INTEL_DISPLAY_A_HTOTAL,
|
||||||
((uint32)(target.timing.h_total - 1) << 16)
|
((uint32)(target.timing.h_total - 1) << 16)
|
||||||
@@ -149,27 +169,7 @@ DisplayPipe::ConfigureTimings(const pll_divisors& divisors)
|
|||||||
? DISPLAY_MONITOR_POSITIVE_HSYNC : 0)
|
? DISPLAY_MONITOR_POSITIVE_HSYNC : 0)
|
||||||
| ((target.timing.flags & B_POSITIVE_VSYNC) != 0
|
| ((target.timing.flags & B_POSITIVE_VSYNC) != 0
|
||||||
? DISPLAY_MONITOR_POSITIVE_VSYNC : 0));
|
? DISPLAY_MONITOR_POSITIVE_VSYNC : 0));
|
||||||
|
#endif
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ void
|
|||||||
DisplayPipe::_Enable(bool enable)
|
DisplayPipe::_Enable(bool enable)
|
||||||
{
|
{
|
||||||
uint32 targetRegister = fBaseRegister + INTEL_PIPE_CONTROL;
|
uint32 targetRegister = fBaseRegister + INTEL_PIPE_CONTROL;
|
||||||
write32(targetRegister, read32(targetRegister) & ~PIPE_ENABLED
|
write32(targetRegister, (read32(targetRegister) & ~INTEL_PIPE_ENABLED)
|
||||||
| (enable ? PIPE_ENABLED | 0));
|
| (enable ? INTEL_PIPE_ENABLED : 0));
|
||||||
read32(targetRegister);
|
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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Michael Lotz, [email protected]
|
* Michael Lotz, [email protected]
|
||||||
|
* Alexander von Gluck IV, [email protected]
|
||||||
*/
|
*/
|
||||||
#ifndef INTEL_PIPE_H
|
#ifndef INTEL_PIPE_H
|
||||||
#define INTEL_PIPE_H
|
#define INTEL_PIPE_H
|
||||||
|
|
||||||
|
|
||||||
class FDILink;
|
#include <edid.h>
|
||||||
class PanelFitter;
|
|
||||||
|
|
||||||
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 {
|
class DisplayPipe {
|
||||||
public:
|
public:
|
||||||
DisplayPipe(int32 pipeIndex);
|
DisplayPipe(pipe_index pipeIndex);
|
||||||
virtual ~DisplayPipe();
|
virtual ~DisplayPipe();
|
||||||
|
|
||||||
|
pipe_index Index()
|
||||||
|
{ return fPipeIndex; }
|
||||||
|
|
||||||
bool IsEnabled();
|
bool IsEnabled();
|
||||||
void Enable(const display_mode& mode);
|
void Enable(const display_mode& mode);
|
||||||
void Disable();
|
void Disable();
|
||||||
@@ -27,18 +43,20 @@ virtual ~DisplayPipe();
|
|||||||
const pll_divisors& divisors);
|
const pll_divisors& divisors);
|
||||||
|
|
||||||
// access to the various parts of the pipe
|
// access to the various parts of the pipe
|
||||||
::FDILink* FDILink()
|
// ::FDILink* FDILink()
|
||||||
{ return fFDILink; }
|
// { return fFDILink; }
|
||||||
::PanelFitter* PanelFitter()
|
// ::PanelFitter* PanelFitter()
|
||||||
{ return fPanelFitter; }
|
// { return fPanelFitter; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _Enable(bool enable);
|
void _Enable(bool enable);
|
||||||
|
|
||||||
FDILink* fFDILink;
|
// FDILink* fFDILink;
|
||||||
PanelFitter* fPanelFitter;
|
// PanelFitter* fPanelFitter;
|
||||||
|
|
||||||
uint32 fRegisterBase;
|
addr_t fBaseRegister;
|
||||||
|
pipe_index fPipeIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // INTEL_PIPE_H
|
#endif // INTEL_PIPE_H
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Addon intel_extreme.accelerant :
|
|||||||
# overlay_3d_i965.cpp
|
# overlay_3d_i965.cpp
|
||||||
pll.cpp
|
pll.cpp
|
||||||
# classes
|
# classes
|
||||||
# DisplayPipe.cpp
|
DisplayPipe.cpp
|
||||||
# FlexibleDisplayInterface.cpp
|
# FlexibleDisplayInterface.cpp
|
||||||
# PanelFitter.cpp
|
# PanelFitter.cpp
|
||||||
Ports.cpp
|
Ports.cpp
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#include "accelerant_protos.h"
|
#include "accelerant_protos.h"
|
||||||
#include "intel_extreme.h"
|
#include "intel_extreme.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
#undef TRACE
|
#undef TRACE
|
||||||
#define TRACE_PORTS
|
#define TRACE_PORTS
|
||||||
@@ -38,7 +40,7 @@ Port::Port(port_index index, const char* baseName)
|
|||||||
:
|
:
|
||||||
fPortIndex(index),
|
fPortIndex(index),
|
||||||
fPortName(NULL),
|
fPortName(NULL),
|
||||||
fPipeIndex(INTEL_PIPE_ANY),
|
fDisplayPipe(NULL),
|
||||||
fEDIDState(B_NO_INIT)
|
fEDIDState(B_NO_INIT)
|
||||||
{
|
{
|
||||||
char portID[2];
|
char portID[2];
|
||||||
@@ -71,8 +73,8 @@ Port::HasEDID()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
status_t
|
||||||
Port::PipeSelect(pipe_index pipeIndex)
|
Port::AssignPipe(pipe_index pipeIndex)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
@@ -80,7 +82,7 @@ Port::PipeSelect(pipe_index pipeIndex)
|
|||||||
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__,
|
||||||
portRegister, PortName());
|
portRegister, PortName());
|
||||||
return;
|
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__,
|
||||||
@@ -93,8 +95,14 @@ Port::PipeSelect(pipe_index pipeIndex)
|
|||||||
else
|
else
|
||||||
write32(portRegister, portState | DISPLAY_MONITOR_PIPE_B);
|
write32(portRegister, portState | DISPLAY_MONITOR_PIPE_B);
|
||||||
|
|
||||||
fPipeIndex = pipeIndex;
|
fDisplayPipe = new(std::nothrow) DisplayPipe(pipeIndex);
|
||||||
|
|
||||||
|
if (fDisplayPipe == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
read32(portRegister);
|
read32(portRegister);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -730,7 +738,7 @@ HDMIPort::IsConnected()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
addr_t portRegister = _PortRegister();
|
addr_t portRegister = _PortRegister();
|
||||||
TRACE("%s - %d: PortRegister: %" B_PRIx32 "\n", PortName(), PortIndex(),
|
TRACE("%s: %s PortRegister: 0x%" B_PRIxADDR "\n", __func__, PortName(),
|
||||||
portRegister);
|
portRegister);
|
||||||
|
|
||||||
if (portRegister == 0)
|
if (portRegister == 0)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <edid.h>
|
#include <edid.h>
|
||||||
|
|
||||||
|
#include "DisplayPipe.h"
|
||||||
#include "intel_extreme.h"
|
#include "intel_extreme.h"
|
||||||
#include "pll.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 {
|
class Port {
|
||||||
public:
|
public:
|
||||||
Port(port_index index,
|
Port(port_index index,
|
||||||
@@ -60,12 +53,9 @@ virtual uint32 Type() const = 0;
|
|||||||
port_index PortIndex() const
|
port_index PortIndex() const
|
||||||
{ return fPortIndex; }
|
{ return fPortIndex; }
|
||||||
|
|
||||||
pipe_index PipeIndex() const
|
|
||||||
{ return fPipeIndex; }
|
|
||||||
|
|
||||||
virtual bool IsConnected() = 0;
|
virtual bool IsConnected() = 0;
|
||||||
|
|
||||||
void PipeSelect(pipe_index pipeIndex);
|
status_t AssignPipe(pipe_index pipeIndex);
|
||||||
|
|
||||||
bool HasEDID();
|
bool HasEDID();
|
||||||
virtual status_t GetEDID(edid1_info* edid,
|
virtual status_t GetEDID(edid1_info* edid,
|
||||||
@@ -93,7 +83,7 @@ virtual addr_t _PortRegister() = 0;
|
|||||||
port_index fPortIndex;
|
port_index fPortIndex;
|
||||||
char* fPortName;
|
char* fPortName;
|
||||||
|
|
||||||
pipe_index fPipeIndex;
|
DisplayPipe* fDisplayPipe;
|
||||||
|
|
||||||
status_t fEDIDState;
|
status_t fEDIDState;
|
||||||
edid1_info fEDIDInfo;
|
edid1_info fEDIDInfo;
|
||||||
@@ -179,7 +169,7 @@ virtual uint32 Type() const
|
|||||||
virtual bool IsConnected();
|
virtual bool IsConnected();
|
||||||
|
|
||||||
protected:
|
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
|
// #pragma mark - public accelerant functions
|
||||||
|
|
||||||
|
|
||||||
@@ -350,6 +381,11 @@ intel_init_accelerant(int device)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
ERROR("Warning: zero active displays were found!\n");
|
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();
|
status = create_mode_list();
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
uninit_common();
|
uninit_common();
|
||||||
|
|||||||
@@ -615,9 +615,6 @@ if (first) {
|
|||||||
if (!gInfo->ports[i]->IsConnected())
|
if (!gInfo->ports[i]->IsConnected())
|
||||||
continue;
|
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);
|
status_t status = gInfo->ports[i]->SetDisplayMode(&target, colorMode);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
ERROR("%s: Unable to set display mode!\n", __func__);
|
ERROR("%s: Unable to set display mode!\n", __func__);
|
||||||
@@ -717,6 +714,9 @@ if (first) {
|
|||||||
|
|
||||||
// RIP ANALOG
|
// 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)
|
// TODO: This may not be neccesary (see DPMS OFF at top)
|
||||||
set_display_power_mode(sharedInfo.dpms_mode);
|
set_display_power_mode(sharedInfo.dpms_mode);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user