intel driver: added panelfitter pgmming.

This commit is contained in:
Rudolf Cornelissen 2021-06-14 22:49:31 +00:00
parent 08d7c6e8f3
commit 16ea5aac34
7 changed files with 58 additions and 37 deletions

View File

@ -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;

View File

@ -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

View File

@ -9,11 +9,12 @@
#include "PanelFitter.h"
#include "accelerant.h"
#include "intel_extreme.h"
#include <stdlib.h>
#include <string.h>
#include <Debug.h>
#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);
}

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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);