intel_extreme: First work at programming FDI
This commit is contained in:
parent
32807945aa
commit
00e0982f68
|
@ -263,6 +263,12 @@ struct intel_shared_info {
|
|||
bool has_vesa_edid_info;
|
||||
};
|
||||
|
||||
enum pipe_index {
|
||||
INTEL_PIPE_ANY,
|
||||
INTEL_PIPE_A,
|
||||
INTEL_PIPE_B
|
||||
};
|
||||
|
||||
//----------------- ioctl() interface ----------------
|
||||
|
||||
// magic code for ioctls
|
||||
|
@ -710,12 +716,17 @@ struct intel_free_graphics_memory {
|
|||
// FDI receiver A is hooked up to transcoder A, FDI receiver B is hooked up to
|
||||
// transcoder B, so we have the same mapping as with the display pipes.
|
||||
#define PCH_FDI_RX_BASE_REGISTER 0xf0000
|
||||
#define PCH_FDI_TX_BASE_REGISTER 0x60000
|
||||
#define PCH_FDI_RX_PIPE_OFFSET 0x01000
|
||||
#define PCH_FDI_TX_PIPE_OFFSET 0x01000
|
||||
|
||||
#define PCH_FDI_RX_CONTROL 0x0c
|
||||
#define PCH_FDI_RX_CONTROL 0x00c
|
||||
#define PCH_FDI_TX_CONTROL 0x100
|
||||
#define FDI_RX_CLOCK_MASK (1 << 4)
|
||||
#define FDI_RX_CLOCK_RAW (0 << 4)
|
||||
#define FDI_RX_CLOCK_PCD (1 << 4)
|
||||
#define FDI_TX_PLL_ENABLED (1 << 14)
|
||||
#define FDI_RX_PLL_ENABLED (1 << 13)
|
||||
|
||||
#define PCH_FDI_RX_TRANS_UNIT_SIZE_1 0x30
|
||||
#define PCH_FDI_RX_TRANS_UNIT_SIZE_2 0x38
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
* Michael Lotz, mmlr@mlotz.ch
|
||||
* Alexander von Gluck IV, kallisti5@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#include "DisplayPipe.h"
|
||||
|
||||
#include "accelerant.h"
|
||||
|
@ -17,6 +15,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
|
||||
#define TRACE_PIPE
|
||||
#ifdef TRACE_PIPE
|
||||
|
@ -29,6 +29,7 @@ extern "C" void _sPrintf(const char* format, ...);
|
|||
#define ERROR(x...) _sPrintf("intel_extreme: " x)
|
||||
#define CALLED(x...) TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
|
||||
|
||||
|
||||
// PIPE: 6
|
||||
// PLANE: 7
|
||||
|
||||
|
@ -50,7 +51,7 @@ program_pipe_color_modes(uint32 colorMode)
|
|||
|
||||
DisplayPipe::DisplayPipe(pipe_index pipeIndex)
|
||||
:
|
||||
// fFDILink(NULL),
|
||||
fFDILink(NULL),
|
||||
// fPanelFitter(NULL),
|
||||
fPipeIndex(pipeIndex),
|
||||
fPipeBase(REGS_NORTH_PIPE_AND_PORT),
|
||||
|
@ -61,6 +62,12 @@ DisplayPipe::DisplayPipe(pipe_index pipeIndex)
|
|||
fPlaneBase += INTEL_PLANE_OFFSET;
|
||||
}
|
||||
|
||||
// Program FDILink if PCH
|
||||
if (gInfo->shared_info->device_type.HasPlatformControlHub()) {
|
||||
if (fFDILink == NULL)
|
||||
fFDILink = new(std::nothrow) FDILink(pipeIndex);
|
||||
}
|
||||
|
||||
TRACE("DisplayPipe %s. Pipe Base: 0x%" B_PRIxADDR
|
||||
" Plane Base: 0x% " B_PRIxADDR "\n", (pipeIndex == INTEL_PIPE_A)
|
||||
? "A" : "B", fPipeBase, fPlaneBase);
|
||||
|
|
|
@ -13,14 +13,9 @@
|
|||
#include <edid.h>
|
||||
|
||||
#include "intel_extreme.h"
|
||||
|
||||
#include "pll.h"
|
||||
|
||||
|
||||
enum pipe_index {
|
||||
INTEL_PIPE_ANY,
|
||||
INTEL_PIPE_A,
|
||||
INTEL_PIPE_B
|
||||
};
|
||||
#include "FlexibleDisplayInterface.h"
|
||||
|
||||
|
||||
void program_pipe_color_modes(uint32 colorMode);
|
||||
|
@ -47,15 +42,15 @@ public:
|
|||
uint32 extraFlags);
|
||||
|
||||
// access to the various parts of the pipe
|
||||
// ::FDILink* FDILink()
|
||||
// { return fFDILink; }
|
||||
::FDILink* FDI()
|
||||
{ return fFDILink; }
|
||||
// ::PanelFitter* PanelFitter()
|
||||
// { return fPanelFitter; }
|
||||
|
||||
private:
|
||||
void _Enable(bool enable);
|
||||
|
||||
// FDILink* fFDILink;
|
||||
FDILink* fFDILink;
|
||||
// PanelFitter* fPanelFitter;
|
||||
|
||||
pipe_index fPipeIndex;
|
||||
|
|
|
@ -9,11 +9,12 @@
|
|||
|
||||
#include "FlexibleDisplayInterface.h"
|
||||
|
||||
#include "accelerant.h"
|
||||
#include "intel_extreme.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include "accelerant.h"
|
||||
#include "intel_extreme.h"
|
||||
|
||||
|
||||
#define TRACE_FDI
|
||||
|
@ -28,9 +29,16 @@ extern "C" void _sPrintf(const char* format, ...);
|
|||
// #pragma mark - FDITransmitter
|
||||
|
||||
|
||||
FDITransmitter::FDITransmitter(int32 pipeIndex)
|
||||
FDITransmitter::FDITransmitter(pipe_index pipeIndex)
|
||||
:
|
||||
fBaseRegister(PCH_FDI_TX_BASE_REGISTER + pipeIndex * PCH_FDI_TX_PIPE_OFFSET)
|
||||
fRegisterBase(PCH_FDI_TX_BASE_REGISTER)
|
||||
{
|
||||
if (pipeIndex == INTEL_PIPE_B)
|
||||
fRegisterBase += PCH_FDI_TX_PIPE_OFFSET * 1;
|
||||
}
|
||||
|
||||
|
||||
FDITransmitter::~FDITransmitter()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -38,7 +46,7 @@ FDITransmitter::FDITransmitter(int32 pipeIndex)
|
|||
bool
|
||||
FDITransmitter::IsPLLEnabled()
|
||||
{
|
||||
return (read32(fBaseRegister + PCH_FDI_TX_CONTROL) & PCH_FDI_TX_PLL_ENABLED)
|
||||
return (read32(fRegisterBase + PCH_FDI_TX_CONTROL) & FDI_TX_PLL_ENABLED)
|
||||
!= 0;
|
||||
}
|
||||
|
||||
|
@ -46,14 +54,14 @@ FDITransmitter::IsPLLEnabled()
|
|||
void
|
||||
FDITransmitter::EnablePLL()
|
||||
{
|
||||
uint32 targetRegister = fBaseRegister + PCH_FDI_TX_CONTROL;
|
||||
uint32 targetRegister = fRegisterBase + PCH_FDI_TX_CONTROL;
|
||||
uint32 value = read32(targetRegister);
|
||||
if ((value & PCH_FDI_TX_PLL_ENABLED) != 0) {
|
||||
if ((value & FDI_TX_PLL_ENABLED) != 0) {
|
||||
// already enabled, possibly IronLake where it always is
|
||||
return;
|
||||
}
|
||||
|
||||
write32(targetRegister, value | PCH_FDI_TX_PLL_ENABLED);
|
||||
write32(targetRegister, value | FDI_TX_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
spin(100); // warmup 10us + dmi delay 20us, be generous
|
||||
}
|
||||
|
@ -62,13 +70,13 @@ FDITransmitter::EnablePLL()
|
|||
void
|
||||
FDITransmitter::DisablePLL()
|
||||
{
|
||||
if (gInfo->shared_info->device_type.IsGroup(INTEL_GROUP_ILK)) {
|
||||
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_ILK)) {
|
||||
// on IronLake the FDI PLL is alaways enabled, so no point in trying...
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 targetRegister = fBaseRegister + PCH_FDI_TX_CONTROL;
|
||||
write32(targetRegister, read32(targetRegister) & ~PCH_FDI_TX_PLL_ENABLED);
|
||||
uint32 targetRegister = fRegisterBase + PCH_FDI_TX_CONTROL;
|
||||
write32(targetRegister, read32(targetRegister) & ~FDI_TX_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
spin(100);
|
||||
}
|
||||
|
@ -77,9 +85,16 @@ FDITransmitter::DisablePLL()
|
|||
// #pragma mark - FDIReceiver
|
||||
|
||||
|
||||
FDIReceiver::FDIReceiver(int32 pipeIndex)
|
||||
FDIReceiver::FDIReceiver(pipe_index pipeIndex)
|
||||
:
|
||||
fBaseRegister(PCH_FDI_RX_BASE_REGISTER + pipeIndex * PCH_FDI_RX_PIPE_OFFSET)
|
||||
fRegisterBase(PCH_FDI_RX_BASE_REGISTER)
|
||||
{
|
||||
if (pipeIndex == INTEL_PIPE_B)
|
||||
fRegisterBase += PCH_FDI_RX_PIPE_OFFSET * 1;
|
||||
}
|
||||
|
||||
|
||||
FDIReceiver::~FDIReceiver()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -87,7 +102,7 @@ FDIReceiver::FDIReceiver(int32 pipeIndex)
|
|||
bool
|
||||
FDIReceiver::IsPLLEnabled()
|
||||
{
|
||||
return (read32(fBaseRegister + PCH_FDI_RX_CONTROL) & PCH_FDI_RX_PLL_ENABLED)
|
||||
return (read32(fRegisterBase + PCH_FDI_RX_CONTROL) & FDI_RX_PLL_ENABLED)
|
||||
!= 0;
|
||||
}
|
||||
|
||||
|
@ -95,12 +110,12 @@ FDIReceiver::IsPLLEnabled()
|
|||
void
|
||||
FDIReceiver::EnablePLL()
|
||||
{
|
||||
uint32 targetRegister = fBaseRegister + PCH_FDI_RX_CONTROL;
|
||||
uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL;
|
||||
uint32 value = read32(targetRegister);
|
||||
if ((value & PCH_FDI_RX_PLL_ENABLED) != 0)
|
||||
if ((value & FDI_RX_PLL_ENABLED) != 0)
|
||||
return;
|
||||
|
||||
write32(targetRegister, value | PCH_FDI_RX_PLL_ENABLED);
|
||||
write32(targetRegister, value | FDI_RX_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
spin(200); // warmup 10us + dmi delay 20us, be generous
|
||||
}
|
||||
|
@ -109,19 +124,19 @@ FDIReceiver::EnablePLL()
|
|||
void
|
||||
FDIReceiver::DisablePLL()
|
||||
{
|
||||
uint32 targetRegister = fBaseRegister + PCH_FDI_RX_CONTROL;
|
||||
write32(targetRegister, read32(targetRegister) & ~PCH_FDI_RX_PLL_ENABLED);
|
||||
uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL;
|
||||
write32(targetRegister, read32(targetRegister) & ~FDI_RX_PLL_ENABLED);
|
||||
read32(targetRegister);
|
||||
spin(100);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FDIReceiver::SwtichClock(bool toPCDClock)
|
||||
FDIReceiver::SwitchClock(bool toPCDClock)
|
||||
{
|
||||
uint32 targetRegister = fBaseRegister + PCH_FDI_RX_CONTROL;
|
||||
write32(targetRegister, (read32(targetRegister) & ~PCH_FDI_RX_CLOCK_MASK)
|
||||
| (toPCDClock ? PCH_FDI_RX_CLOCK_PCD : PCH_FDI_RX_CLOCK_RAW));
|
||||
uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL;
|
||||
write32(targetRegister, (read32(targetRegister) & ~FDI_RX_CLOCK_MASK)
|
||||
| (toPCDClock ? FDI_RX_CLOCK_PCD : FDI_RX_CLOCK_RAW));
|
||||
read32(targetRegister);
|
||||
spin(200);
|
||||
}
|
||||
|
@ -130,9 +145,14 @@ FDIReceiver::SwtichClock(bool toPCDClock)
|
|||
// #pragma mark - FDILink
|
||||
|
||||
|
||||
FDILink::FDILink(int32 pipeIndex)
|
||||
FDILink::FDILink(pipe_index pipeIndex)
|
||||
:
|
||||
fTransmitter(pipeIndex),
|
||||
fReceiver(pipeIndex)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FDILink::~FDILink()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -9,10 +9,13 @@
|
|||
#define INTEL_FDI_H
|
||||
|
||||
|
||||
#include "intel_extreme.h"
|
||||
|
||||
|
||||
class FDITransmitter {
|
||||
public:
|
||||
FDITransmitter(int32 pipeIndex);
|
||||
virtual ~FDITransmitter();
|
||||
FDITransmitter(pipe_index pipeIndex);
|
||||
~FDITransmitter();
|
||||
|
||||
bool IsPLLEnabled();
|
||||
void EnablePLL();
|
||||
|
@ -25,7 +28,8 @@ private:
|
|||
|
||||
class FDIReceiver {
|
||||
public:
|
||||
FDIReceiver(int32 pipeIndex);
|
||||
FDIReceiver(pipe_index pipeIndex);
|
||||
~FDIReceiver();
|
||||
|
||||
bool IsPLLEnabled();
|
||||
void EnablePLL();
|
||||
|
@ -40,14 +44,18 @@ protected:
|
|||
|
||||
class FDILink {
|
||||
public:
|
||||
FDILink(int32 pipeIndex);
|
||||
FDILink(pipe_index pipeIndex);
|
||||
~FDILink();
|
||||
|
||||
FDITransmitter& Transmitter();
|
||||
FDIReceiver& Receiver();
|
||||
FDITransmitter& Transmitter()
|
||||
{ return fTransmitter; };
|
||||
FDIReceiver& Receiver()
|
||||
{ return fReceiver; };
|
||||
|
||||
private:
|
||||
FDITransmitter fTransmitter;
|
||||
FDIReceiver fReceiver;
|
||||
};
|
||||
|
||||
|
||||
#endif // INTEL_FDI_H
|
||||
|
|
|
@ -19,7 +19,7 @@ Addon intel_extreme.accelerant :
|
|||
pll.cpp
|
||||
# classes
|
||||
DisplayPipe.cpp
|
||||
# FlexibleDisplayInterface.cpp
|
||||
FlexibleDisplayInterface.cpp
|
||||
# PanelFitter.cpp
|
||||
Ports.cpp
|
||||
: be $(TARGET_LIBSTDC++) libaccelerantscommon.a
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "accelerant.h"
|
||||
#include "accelerant_protos.h"
|
||||
#include "FlexibleDisplayInterface.h"
|
||||
#include "intel_extreme.h"
|
||||
|
||||
#include <new>
|
||||
|
@ -85,6 +86,12 @@ Port::AssignPipe(pipe_index pipeIndex)
|
|||
return B_ERROR;
|
||||
}
|
||||
|
||||
// TODO: UnAssignPipe? This likely needs reworked a little
|
||||
if (fDisplayPipe != NULL) {
|
||||
ERROR("%s: Can't reassign DisplayPipe (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");
|
||||
|
||||
|
@ -253,6 +260,14 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode)
|
|||
return B_ERROR;
|
||||
}
|
||||
|
||||
// Train FDI if it exists
|
||||
FDILink* link = fDisplayPipe->FDI();
|
||||
if (link != NULL) {
|
||||
link->Receiver().EnablePLL();
|
||||
link->Receiver().SwitchClock(true);
|
||||
link->Transmitter().EnablePLL();
|
||||
}
|
||||
|
||||
pll_divisors divisors;
|
||||
compute_pll_divisors(target, &divisors, false);
|
||||
|
||||
|
@ -660,6 +675,14 @@ DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode)
|
|||
return B_ERROR;
|
||||
}
|
||||
|
||||
// Train FDI if it exists
|
||||
FDILink* link = fDisplayPipe->FDI();
|
||||
if (link != NULL) {
|
||||
link->Receiver().EnablePLL();
|
||||
link->Receiver().SwitchClock(true);
|
||||
link->Transmitter().EnablePLL();
|
||||
}
|
||||
|
||||
pll_divisors divisors;
|
||||
compute_pll_divisors(target, &divisors, false);
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
|
||||
#include <edid.h>
|
||||
|
||||
#include "DisplayPipe.h"
|
||||
#include "intel_extreme.h"
|
||||
|
||||
#include "DisplayPipe.h"
|
||||
#include "pll.h"
|
||||
|
||||
|
||||
|
@ -69,6 +70,9 @@ 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);
|
||||
|
||||
|
|
|
@ -350,6 +350,7 @@ assign_pipes()
|
|||
}
|
||||
|
||||
gInfo->ports[i]->AssignPipe(currentPipe);
|
||||
|
||||
assigned++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,10 +23,6 @@
|
|||
|
||||
#include "accelerant_protos.h"
|
||||
#include "accelerant.h"
|
||||
#if 0
|
||||
#include "DisplayPipe.h"
|
||||
#include "FlexibleDisplayInterface.h"
|
||||
#endif
|
||||
#include "pll.h"
|
||||
#include "Ports.h"
|
||||
#include "utility.h"
|
||||
|
|
Loading…
Reference in New Issue