diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 42c0c97efb..fd7e97eecb 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -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 diff --git a/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp b/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp index 568dce06ad..074417bb07 100644 --- a/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp +++ b/src/add-ons/accelerants/intel_extreme/DisplayPipe.cpp @@ -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 #include +#include + #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); diff --git a/src/add-ons/accelerants/intel_extreme/DisplayPipe.h b/src/add-ons/accelerants/intel_extreme/DisplayPipe.h index f0f5edefc6..123553a394 100644 --- a/src/add-ons/accelerants/intel_extreme/DisplayPipe.h +++ b/src/add-ons/accelerants/intel_extreme/DisplayPipe.h @@ -13,14 +13,9 @@ #include #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; diff --git a/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp b/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp index 2e526498ec..c8f6313c62 100644 --- a/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp +++ b/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp @@ -9,11 +9,12 @@ #include "FlexibleDisplayInterface.h" -#include "accelerant.h" -#include "intel_extreme.h" - #include #include +#include + +#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() +{ +} diff --git a/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.h b/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.h index baa6767ec9..d56b00aeea 100644 --- a/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.h +++ b/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.h @@ -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 diff --git a/src/add-ons/accelerants/intel_extreme/Jamfile b/src/add-ons/accelerants/intel_extreme/Jamfile index 59307e59c4..a9adbce91d 100644 --- a/src/add-ons/accelerants/intel_extreme/Jamfile +++ b/src/add-ons/accelerants/intel_extreme/Jamfile @@ -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 diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index 1f9eb75244..69c3bbf5a1 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -19,6 +19,7 @@ #include "accelerant.h" #include "accelerant_protos.h" +#include "FlexibleDisplayInterface.h" #include "intel_extreme.h" #include @@ -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); diff --git a/src/add-ons/accelerants/intel_extreme/Ports.h b/src/add-ons/accelerants/intel_extreme/Ports.h index 7b3c225a1a..db33b6b43d 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.h +++ b/src/add-ons/accelerants/intel_extreme/Ports.h @@ -12,8 +12,9 @@ #include -#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); diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index 04d65f0727..a67a50049f 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -350,6 +350,7 @@ assign_pipes() } gInfo->ports[i]->AssignPipe(currentPipe); + assigned++; } } diff --git a/src/add-ons/accelerants/intel_extreme/mode.cpp b/src/add-ons/accelerants/intel_extreme/mode.cpp index b7ce22b149..8d7ddc6434 100644 --- a/src/add-ons/accelerants/intel_extreme/mode.cpp +++ b/src/add-ons/accelerants/intel_extreme/mode.cpp @@ -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"