intel_extreme: Enable / Disable FDI TX/RX

This commit is contained in:
Alexander von Gluck IV
2015-11-19 13:26:55 -06:00
parent 00e0982f68
commit aa06863ccd
3 changed files with 83 additions and 14 deletions
@@ -716,25 +716,25 @@ struct intel_free_graphics_memory {
// FDI receiver A is hooked up to transcoder A, FDI receiver B is hooked up to // 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. // transcoder B, so we have the same mapping as with the display pipes.
#define PCH_FDI_RX_BASE_REGISTER 0xf0000 #define PCH_FDI_RX_BASE_REGISTER 0xf0000
#define PCH_FDI_TX_BASE_REGISTER 0x60000
#define PCH_FDI_RX_PIPE_OFFSET 0x01000 #define PCH_FDI_RX_PIPE_OFFSET 0x01000
#define PCH_FDI_TX_PIPE_OFFSET 0x01000
#define PCH_FDI_RX_CONTROL 0x00c #define PCH_FDI_RX_CONTROL 0x00c
#define PCH_FDI_TX_CONTROL 0x100 #define FDI_RX_ENABLE (1 << 31)
#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 FDI_RX_PLL_ENABLED (1 << 13)
#define PCH_FDI_RX_TRANS_UNIT_SIZE_1 0x30 #define PCH_FDI_RX_TRANS_UNIT_SIZE_1 0x30
#define PCH_FDI_RX_TRANS_UNIT_SIZE_2 0x38 #define PCH_FDI_RX_TRANS_UNIT_SIZE_2 0x38
#define FDI_RX_TRANS_UNIT_SIZE(x) ((x - 1) << 25) #define FDI_RX_TRANS_UNIT_SIZE(x) ((x - 1) << 25)
#define FDI_RX_TRANS_UNIT_MASK 0x7e000000 #define FDI_RX_TRANS_UNIT_MASK 0x7e000000
// Transfer unit size 1 is the primary and fixed transfer unit size,
// TU size 2 is the lower power state transfer unit size when using dynamic #define FDI_RX_CLOCK_MASK (1 << 4)
// refresh rates (we don't do that though). #define FDI_RX_CLOCK_RAW (0 << 4)
#define FDI_RX_CLOCK_PCD (1 << 4)
#define PCH_FDI_TX_BASE_REGISTER 0x60000
#define PCH_FDI_TX_PIPE_OFFSET 0x01000
#define PCH_FDI_TX_CONTROL 0x100
#define FDI_TX_ENABLE (1 << 31)
#define FDI_TX_PLL_ENABLED (1 << 14)
// CPU Panel Fitters - These are for IronLake and up and are the CPU internal // CPU Panel Fitters - These are for IronLake and up and are the CPU internal
// panel fitters. // panel fitters.
@@ -11,20 +11,24 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <Debug.h>
#include <KernelExport.h> #include <KernelExport.h>
#include "accelerant.h" #include "accelerant.h"
#include "intel_extreme.h" #include "intel_extreme.h"
#undef TRACE
#define TRACE_FDI #define TRACE_FDI
#ifdef TRACE_FDI #ifdef TRACE_FDI
extern "C" void _sPrintf(const char* format, ...); # define TRACE(x...) _sPrintf("intel_extreme: " x)
# define TRACE(x) _sPrintf x
#else #else
# define TRACE(x) ; # define TRACE(x...)
#endif #endif
#define ERROR(x...) _sPrintf("intel_extreme: " x)
#define CALLED() TRACE("CALLED %s\n", __PRETTY_FUNCTION__)
// #pragma mark - FDITransmitter // #pragma mark - FDITransmitter
@@ -43,9 +47,36 @@ FDITransmitter::~FDITransmitter()
} }
void
FDITransmitter::Enable()
{
CALLED();
uint32 targetRegister = fRegisterBase + PCH_FDI_TX_CONTROL;
uint32 value = read32(targetRegister);
write32(targetRegister, value | FDI_TX_ENABLE);
read32(targetRegister);
spin(150);
}
void
FDITransmitter::Disable()
{
CALLED();
uint32 targetRegister = fRegisterBase + PCH_FDI_TX_CONTROL;
uint32 value = read32(targetRegister);
write32(targetRegister, value & ~FDI_TX_ENABLE);
read32(targetRegister);
spin(150);
}
bool bool
FDITransmitter::IsPLLEnabled() FDITransmitter::IsPLLEnabled()
{ {
CALLED();
return (read32(fRegisterBase + PCH_FDI_TX_CONTROL) & FDI_TX_PLL_ENABLED) return (read32(fRegisterBase + PCH_FDI_TX_CONTROL) & FDI_TX_PLL_ENABLED)
!= 0; != 0;
} }
@@ -54,6 +85,7 @@ FDITransmitter::IsPLLEnabled()
void void
FDITransmitter::EnablePLL() FDITransmitter::EnablePLL()
{ {
CALLED();
uint32 targetRegister = fRegisterBase + PCH_FDI_TX_CONTROL; uint32 targetRegister = fRegisterBase + PCH_FDI_TX_CONTROL;
uint32 value = read32(targetRegister); uint32 value = read32(targetRegister);
if ((value & FDI_TX_PLL_ENABLED) != 0) { if ((value & FDI_TX_PLL_ENABLED) != 0) {
@@ -70,6 +102,7 @@ FDITransmitter::EnablePLL()
void void
FDITransmitter::DisablePLL() FDITransmitter::DisablePLL()
{ {
CALLED();
if (gInfo->shared_info->device_type.InGroup(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... // on IronLake the FDI PLL is alaways enabled, so no point in trying...
return; return;
@@ -99,9 +132,36 @@ FDIReceiver::~FDIReceiver()
} }
void
FDIReceiver::Enable()
{
CALLED();
uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL;
uint32 value = read32(targetRegister);
write32(targetRegister, value | FDI_RX_ENABLE);
read32(targetRegister);
spin(150);
}
void
FDIReceiver::Disable()
{
CALLED();
uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL;
uint32 value = read32(targetRegister);
write32(targetRegister, value & ~FDI_RX_ENABLE);
read32(targetRegister);
spin(150);
}
bool bool
FDIReceiver::IsPLLEnabled() FDIReceiver::IsPLLEnabled()
{ {
CALLED();
return (read32(fRegisterBase + PCH_FDI_RX_CONTROL) & FDI_RX_PLL_ENABLED) return (read32(fRegisterBase + PCH_FDI_RX_CONTROL) & FDI_RX_PLL_ENABLED)
!= 0; != 0;
} }
@@ -110,6 +170,7 @@ FDIReceiver::IsPLLEnabled()
void void
FDIReceiver::EnablePLL() FDIReceiver::EnablePLL()
{ {
CALLED();
uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL; uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL;
uint32 value = read32(targetRegister); uint32 value = read32(targetRegister);
if ((value & FDI_RX_PLL_ENABLED) != 0) if ((value & FDI_RX_PLL_ENABLED) != 0)
@@ -124,6 +185,7 @@ FDIReceiver::EnablePLL()
void void
FDIReceiver::DisablePLL() FDIReceiver::DisablePLL()
{ {
CALLED();
uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL; uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL;
write32(targetRegister, read32(targetRegister) & ~FDI_RX_PLL_ENABLED); write32(targetRegister, read32(targetRegister) & ~FDI_RX_PLL_ENABLED);
read32(targetRegister); read32(targetRegister);
@@ -134,6 +196,7 @@ FDIReceiver::DisablePLL()
void void
FDIReceiver::SwitchClock(bool toPCDClock) FDIReceiver::SwitchClock(bool toPCDClock)
{ {
CALLED();
uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL; uint32 targetRegister = fRegisterBase + PCH_FDI_RX_CONTROL;
write32(targetRegister, (read32(targetRegister) & ~FDI_RX_CLOCK_MASK) write32(targetRegister, (read32(targetRegister) & ~FDI_RX_CLOCK_MASK)
| (toPCDClock ? FDI_RX_CLOCK_PCD : FDI_RX_CLOCK_RAW)); | (toPCDClock ? FDI_RX_CLOCK_PCD : FDI_RX_CLOCK_RAW));
@@ -17,6 +17,9 @@ public:
FDITransmitter(pipe_index pipeIndex); FDITransmitter(pipe_index pipeIndex);
~FDITransmitter(); ~FDITransmitter();
void Enable();
void Disable();
bool IsPLLEnabled(); bool IsPLLEnabled();
void EnablePLL(); void EnablePLL();
void DisablePLL(); void DisablePLL();
@@ -31,6 +34,9 @@ public:
FDIReceiver(pipe_index pipeIndex); FDIReceiver(pipe_index pipeIndex);
~FDIReceiver(); ~FDIReceiver();
void Enable();
void Disable();
bool IsPLLEnabled(); bool IsPLLEnabled();
void EnablePLL(); void EnablePLL();
void DisablePLL(); void DisablePLL();