diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 6bfb530860..7e503d23b5 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -305,7 +305,8 @@ struct intel_shared_info { enum pipe_index { INTEL_PIPE_ANY, INTEL_PIPE_A, - INTEL_PIPE_B + INTEL_PIPE_B, + INTEL_PIPE_C }; //----------------- ioctl() interface ---------------- @@ -1064,6 +1065,7 @@ struct intel_free_graphics_memory { #define PCH_PANEL_FITTER_WINDOW_POS 0x70 #define PCH_PANEL_FITTER_WINDOW_SIZE 0x74 #define PCH_PANEL_FITTER_CONTROL 0x80 +//not on IvyBridge: #define PCH_PANEL_FITTER_V_SCALE 0x84 #define PCH_PANEL_FITTER_H_SCALE 0x90 @@ -1071,17 +1073,10 @@ struct intel_free_graphics_memory { #define PANEL_FITTER_PIPE_MASK (3 << 29) #define PANEL_FITTER_PIPE_A (0 << 29) #define PANEL_FITTER_PIPE_B (1 << 29) +#define PANEL_FITTER_PIPE_C (2 << 29) #define PANEL_FITTER_SCALING_MODE_MASK (7 << 26) #define PANEL_FITTER_FILTER_MASK (3 << 24) -// panel fitters again, more directly -#define INTEL_PANELFITTER_0_CTRL (0x8080 | REGS_NORTH_PIPE_AND_PORT) -#define INTEL_PANELFITTER_1_CTRL (0x8880 | REGS_NORTH_PIPE_AND_PORT) -#define INTEL_PANELFITTER_2_CTRL (0x9080 | REGS_NORTH_PIPE_AND_PORT) -#define INTEL_PANELFITTER_0_WINDOW_SIZE (0x8074 | REGS_NORTH_PIPE_AND_PORT) -#define INTEL_PANELFITTER_1_WINDOW_SIZE (0x8874 | REGS_NORTH_PIPE_AND_PORT) -#define INTEL_PANELFITTER_2_WINDOW_SIZE (0x9074 | REGS_NORTH_PIPE_AND_PORT) - struct overlay_scale { uint32 _reserved0 : 3; uint32 horizontal_scale_fraction : 12; diff --git a/src/add-ons/accelerants/intel_extreme/Jamfile b/src/add-ons/accelerants/intel_extreme/Jamfile index cb4750872c..14ef36f55e 100644 --- a/src/add-ons/accelerants/intel_extreme/Jamfile +++ b/src/add-ons/accelerants/intel_extreme/Jamfile @@ -18,7 +18,7 @@ Addon intel_extreme.accelerant : pll.cpp # classes FlexibleDisplayInterface.cpp -# PanelFitter.cpp + PanelFitter.cpp Ports.cpp Pipes.cpp : be $(TARGET_LIBSTDC++) libaccelerantscommon.a diff --git a/src/add-ons/accelerants/intel_extreme/PanelFitter.cpp b/src/add-ons/accelerants/intel_extreme/PanelFitter.cpp index 45317e2496..d6959628a7 100644 --- a/src/add-ons/accelerants/intel_extreme/PanelFitter.cpp +++ b/src/add-ons/accelerants/intel_extreme/PanelFitter.cpp @@ -9,11 +9,12 @@ #include "PanelFitter.h" -#include "accelerant.h" -#include "intel_extreme.h" - #include #include +#include + +#include "accelerant.h" +#include "intel_extreme.h" #undef TRACE @@ -31,10 +32,20 @@ // #pragma mark - PanelFitter -PanelFitter::PanelFitter(int32 pipeIndex) +PanelFitter::PanelFitter(pipe_index pipeIndex) : - fBaseRegister(PCH_PANEL_FITTER_BASE_REGISTER - + pipeIndex * PCH_PANEL_FITTER_PIPE_OFFSET) + fRegisterBase(PCH_PANEL_FITTER_BASE_REGISTER) +{ + if (pipeIndex == INTEL_PIPE_B) { + fRegisterBase += PCH_PANEL_FITTER_PIPE_OFFSET; + } + if (pipeIndex == INTEL_PIPE_C) { + fRegisterBase += 2 * PCH_PANEL_FITTER_PIPE_OFFSET; + } +} + + +PanelFitter::~PanelFitter() { } @@ -42,7 +53,7 @@ PanelFitter::PanelFitter(int32 pipeIndex) bool PanelFitter::IsEnabled() { - return (read32(fBaseRegister + PCH_PANEL_FITTER_CONTROL) + return (read32(fRegisterBase + PCH_PANEL_FITTER_CONTROL) & PANEL_FITTER_ENABLED) != 0; } @@ -50,8 +61,15 @@ PanelFitter::IsEnabled() void PanelFitter::Enable(const display_mode& mode) { - // TODO: program the right window size and position based on the mode _Enable(true); + + // TODO: program the window position based on the mode, setup/select filter + // Note: for now assuming fitter was setup by BIOS and pipeA has fitterA, etc. + TRACE("%s: PCH_PANEL_FITTER_CONTROL, 0x%" B_PRIx32 "\n", __func__, read32(fRegisterBase + PCH_PANEL_FITTER_CONTROL)); + TRACE("%s: PCH_PANEL_FITTER_WINDOW_POS, 0x%" B_PRIx32 "\n", __func__, read32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_POS)); + + // Window size _must_ be the last register programmed as it 'arms'/unlocks all the other ones.. + write32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_SIZE, (mode.timing.h_display << 16) | mode.timing.v_display); } @@ -59,14 +77,17 @@ void PanelFitter::Disable() { _Enable(false); + + // Window size _must_ be the last register programmed as it 'arms'/unlocks all the other ones.. + write32(fRegisterBase + PCH_PANEL_FITTER_WINDOW_SIZE, 0); } void PanelFitter::_Enable(bool enable) { - uint32 targetRegister = fBaseRegister + PCH_PANEL_FITTER_CONTROL; - write32(targetRegister, read32(targetRegister) & ~PANEL_FITTER_ENABLED + uint32 targetRegister = fRegisterBase + PCH_PANEL_FITTER_CONTROL; + write32(targetRegister, (read32(targetRegister) & ~PANEL_FITTER_ENABLED) | (enable ? PANEL_FITTER_ENABLED : 0)); read32(targetRegister); } diff --git a/src/add-ons/accelerants/intel_extreme/PanelFitter.h b/src/add-ons/accelerants/intel_extreme/PanelFitter.h index 7648ad7074..8d2ce11009 100644 --- a/src/add-ons/accelerants/intel_extreme/PanelFitter.h +++ b/src/add-ons/accelerants/intel_extreme/PanelFitter.h @@ -9,9 +9,11 @@ #define INTEL_FITTER_H +#include "intel_extreme.h" + class PanelFitter { public: - PanelFitter(int32 pipeIndex); + PanelFitter(pipe_index pipeIndex); virtual ~PanelFitter(); bool IsEnabled(); diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp b/src/add-ons/accelerants/intel_extreme/Pipes.cpp index f136974e66..7e40610c83 100644 --- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp +++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp @@ -54,7 +54,7 @@ Pipe::Pipe(pipe_index pipeIndex) : fHasTranscoder(false), fFDILink(NULL), -// fPanelFitter(NULL), + fPanelFitter(NULL), fPipeIndex(pipeIndex), fPipeOffset(0), fPlaneOffset(0) @@ -75,6 +75,8 @@ Pipe::Pipe(pipe_index pipeIndex) // Program FDILink if PCH fFDILink = new(std::nothrow) FDILink(pipeIndex); + // Program gen5(+) style panelfitter as well + fPanelFitter = new(std::nothrow) PanelFitter(pipeIndex); } TRACE("Pipe %s. Pipe Base: 0x%" B_PRIxADDR diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.h b/src/add-ons/accelerants/intel_extreme/Pipes.h index 596d21e626..8fa336f004 100644 --- a/src/add-ons/accelerants/intel_extreme/Pipes.h +++ b/src/add-ons/accelerants/intel_extreme/Pipes.h @@ -16,6 +16,7 @@ #include "pll.h" #include "FlexibleDisplayInterface.h" +#include "PanelFitter.h" #define MAX_PIPES 2 @@ -49,8 +50,8 @@ public: // access to the various parts of the pipe ::FDILink* FDI() { return fFDILink; } - // ::PanelFitter* PanelFitter() - // { return fPanelFitter; } + ::PanelFitter* PFT() + { return fPanelFitter; } private: void _ConfigureTranscoder(display_mode* mode); @@ -58,7 +59,7 @@ private: bool fHasTranscoder; FDILink* fFDILink; - // PanelFitter* fPanelFitter; + PanelFitter* fPanelFitter; pipe_index fPipeIndex; diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index e9cf899a0d..b1b458d9c4 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -316,12 +316,12 @@ AnalogPort::SetDisplayMode(display_mode* target, uint32 colorMode) } // Setup PanelFitter and Train FDI if it exists + PanelFitter* fitter = fPipe->PFT(); + if (fitter != NULL) + fitter->Enable(*target); FDILink* link = fPipe->FDI(); - if (link != NULL) { - // fixme insert fitter setup here - + if (link != NULL) link->Train(target); - } pll_divisors divisors; compute_pll_divisors(target, &divisors, false); @@ -501,12 +501,12 @@ LVDSPort::SetDisplayMode(display_mode* target, uint32 colorMode) } // Setup PanelFitter and Train FDI if it exists + PanelFitter* fitter = fPipe->PFT(); + if (fitter != NULL) + fitter->Enable(*target); FDILink* link = fPipe->FDI(); - if (link != NULL) { - // fixme insert fitter setup here - + if (link != NULL) link->Train(target); - } // For LVDS panels, we may need to set the timings according to the panel // native video mode, and let the panel fitter do the scaling. But the @@ -736,12 +736,12 @@ DigitalPort::SetDisplayMode(display_mode* target, uint32 colorMode) } // Setup PanelFitter and Train FDI if it exists + PanelFitter* fitter = fPipe->PFT(); + if (fitter != NULL) + fitter->Enable(*target); FDILink* link = fPipe->FDI(); - if (link != NULL) { - // fixme insert fitter setup here - + if (link != NULL) link->Train(target); - } pll_divisors divisors; compute_pll_divisors(target, &divisors, false);