intel_extreme: Sandy/IvyBridge fix 4 lanes DP detect, fully pgm eDP link
This commit is contained in:
@@ -861,7 +861,11 @@ struct intel_free_graphics_memory {
|
|||||||
#define INTEL_DISP_PORT_WIDTH_MASK (7 << INTEL_DISP_PORT_WIDTH_SHIFT)
|
#define INTEL_DISP_PORT_WIDTH_MASK (7 << INTEL_DISP_PORT_WIDTH_SHIFT)
|
||||||
#define INTEL_DISP_PORT_WIDTH_1 0
|
#define INTEL_DISP_PORT_WIDTH_1 0
|
||||||
#define INTEL_DISP_PORT_WIDTH_2 1
|
#define INTEL_DISP_PORT_WIDTH_2 1
|
||||||
#define INTEL_DISP_PORT_WIDTH_4 2
|
#define INTEL_DISP_PORT_WIDTH_4 3
|
||||||
|
#define INTEL_DISP_EDP_PLL_FREQ_SHIFT 16
|
||||||
|
#define INTEL_DISP_EDP_PLL_FREQ_MASK (3 << INTEL_DISP_EDP_PLL_FREQ_SHIFT)
|
||||||
|
#define INTEL_DISP_EDP_PLL_FREQ_270 0
|
||||||
|
#define INTEL_DISP_EDP_PLL_FREQ_162 1
|
||||||
|
|
||||||
#define INTEL_TRANSCODER_A_DP_CTL (0x0300 | REGS_SOUTH_TRANSCODER_PORT)
|
#define INTEL_TRANSCODER_A_DP_CTL (0x0300 | REGS_SOUTH_TRANSCODER_PORT)
|
||||||
#define INTEL_TRANSCODER_B_DP_CTL (0x1300 | REGS_SOUTH_TRANSCODER_PORT)
|
#define INTEL_TRANSCODER_B_DP_CTL (0x1300 | REGS_SOUTH_TRANSCODER_PORT)
|
||||||
|
|||||||
@@ -281,7 +281,6 @@ FDILink::PreTrain(display_timing* target, uint32* linkBandwidth, uint32* lanes,
|
|||||||
TRACE("%s: FDI Link Colordepth: %" B_PRIu32 "\n", __func__, *bitsPerPixel);
|
TRACE("%s: FDI Link Colordepth: %" B_PRIu32 "\n", __func__, *bitsPerPixel);
|
||||||
|
|
||||||
// Khz / 10. ( each output octet encoded as 10 bits.
|
// Khz / 10. ( each output octet encoded as 10 bits.
|
||||||
// note: if used for eDP (PORT_A) might be we should check reg. DP_CTL (0x64000), bit 16-17 (Ivy).
|
|
||||||
*linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10;
|
*linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10;
|
||||||
//Reserving 5% bandwidth for possible spread spectrum clock use
|
//Reserving 5% bandwidth for possible spread spectrum clock use
|
||||||
uint32 bps = target->pixel_clock * *bitsPerPixel * 21 / 20;
|
uint32 bps = target->pixel_clock * *bitsPerPixel * 21 / 20;
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ Pipe::ConfigureScalePos(display_mode* target)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Pipe::ConfigureTimings(display_mode* target, bool hardware)
|
Pipe::ConfigureTimings(display_mode* target, bool hardware, port_index portIndex)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
@@ -373,6 +373,13 @@ Pipe::ConfigureTimings(display_mode* target, bool hardware)
|
|||||||
|
|
||||||
ConfigureScalePos(target);
|
ConfigureScalePos(target);
|
||||||
|
|
||||||
|
// transcoder is not applicable if eDP is targeted on Sandy- and IvyBridge
|
||||||
|
if ((gInfo->shared_info->device_type.InGroup(INTEL_GROUP_SNB) ||
|
||||||
|
gInfo->shared_info->device_type.InGroup(INTEL_GROUP_IVB)) &&
|
||||||
|
(portIndex == INTEL_PORT_A)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (fHasTranscoder && hardware) {
|
if (fHasTranscoder && hardware) {
|
||||||
_ConfigureTranscoder(target);
|
_ConfigureTranscoder(target);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ public:
|
|||||||
uint32 bitsPerPixel);
|
uint32 bitsPerPixel);
|
||||||
void ConfigureScalePos(display_mode* mode);
|
void ConfigureScalePos(display_mode* mode);
|
||||||
void ConfigureTimings(display_mode* mode,
|
void ConfigureTimings(display_mode* mode,
|
||||||
bool hardware = true);
|
bool hardware = true,
|
||||||
|
port_index portIndex = INTEL_PORT_ANY);
|
||||||
void ConfigureClocks(
|
void ConfigureClocks(
|
||||||
const pll_divisors& divisors,
|
const pll_divisors& divisors,
|
||||||
uint32 pixelClock,
|
uint32 pixelClock,
|
||||||
|
|||||||
@@ -1152,7 +1152,6 @@ status_t
|
|||||||
DisplayPort::_SetPortLinkGen4(const display_timing& timing)
|
DisplayPort::_SetPortLinkGen4(const display_timing& timing)
|
||||||
{
|
{
|
||||||
// Khz / 10. ( each output octet encoded as 10 bits.
|
// Khz / 10. ( each output octet encoded as 10 bits.
|
||||||
//uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; //=270000 khz
|
|
||||||
//fixme: always so?
|
//fixme: always so?
|
||||||
uint32 linkBandwidth = 270000; //khz
|
uint32 linkBandwidth = 270000; //khz
|
||||||
uint32 fPipeOffset = 0;
|
uint32 fPipeOffset = 0;
|
||||||
@@ -1216,8 +1215,7 @@ status_t
|
|||||||
DisplayPort::_SetPortLinkGen6(const display_timing& timing)
|
DisplayPort::_SetPortLinkGen6(const display_timing& timing)
|
||||||
{
|
{
|
||||||
// Khz / 10. ( each output octet encoded as 10 bits.
|
// Khz / 10. ( each output octet encoded as 10 bits.
|
||||||
//uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; //=270000 khz
|
//note: (fixme) eDP is fixed option 162 or 270Mc, other DPs go via DPLL programming to one of the same vals.
|
||||||
//fixme: eDP is fixed option 162 or 270Mc, other DPs go via DPLL programming to one of the same vals.
|
|
||||||
uint32 linkBandwidth = 270000; //khz
|
uint32 linkBandwidth = 270000; //khz
|
||||||
TRACE("%s: DP link reference clock is %gMhz\n", __func__, linkBandwidth / 1000.0f);
|
TRACE("%s: DP link reference clock is %gMhz\n", __func__, linkBandwidth / 1000.0f);
|
||||||
|
|
||||||
@@ -1259,8 +1257,7 @@ DisplayPort::_SetPortLinkGen6(const display_timing& timing)
|
|||||||
}
|
}
|
||||||
TRACE("%s: DP link colordepth: %" B_PRIu32 "\n", __func__, bitsPerPixel);
|
TRACE("%s: DP link colordepth: %" B_PRIu32 "\n", __func__, bitsPerPixel);
|
||||||
|
|
||||||
uint32 lanes =
|
uint32 lanes = ((read32(_PortRegister()) & INTEL_DISP_PORT_WIDTH_MASK) >> INTEL_DISP_PORT_WIDTH_SHIFT) + 1;
|
||||||
1 << ((read32(_PortRegister()) & INTEL_DISP_PORT_WIDTH_MASK) >> INTEL_DISP_PORT_WIDTH_SHIFT);
|
|
||||||
if (lanes > 4) {
|
if (lanes > 4) {
|
||||||
ERROR("%s: DP illegal number of lanes set.\n", __func__);
|
ERROR("%s: DP illegal number of lanes set.\n", __func__);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -1386,16 +1383,60 @@ DisplayPort::SetDisplayMode(display_mode* target, uint32 colorMode)
|
|||||||
PanelFitter* fitter = fPipe->PFT();
|
PanelFitter* fitter = fPipe->PFT();
|
||||||
if (fitter != NULL)
|
if (fitter != NULL)
|
||||||
fitter->Enable(hardwareTarget);
|
fitter->Enable(hardwareTarget);
|
||||||
// we should skip FDI if PORT_A, but need pipe M/N programming (is eDP link), so call always for now
|
|
||||||
FDILink* link = fPipe->FDI();
|
|
||||||
if (link != NULL) {
|
|
||||||
uint32 lanes = 0;
|
uint32 lanes = 0;
|
||||||
uint32 linkBandwidth = 0;
|
uint32 linkBandwidth = 0;
|
||||||
uint32 bitsPerPixel = 0;
|
uint32 bitsPerPixel = 0;
|
||||||
|
if (PortIndex() != INTEL_PORT_A) {
|
||||||
|
FDILink* link = fPipe->FDI();
|
||||||
|
if (link != NULL) {
|
||||||
link->PreTrain(&hardwareTarget, &linkBandwidth, &lanes, &bitsPerPixel);
|
link->PreTrain(&hardwareTarget, &linkBandwidth, &lanes, &bitsPerPixel);
|
||||||
fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel);
|
fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel);
|
||||||
link->Train(&hardwareTarget, lanes);
|
link->Train(&hardwareTarget, lanes);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 'local' eDP port is in use
|
||||||
|
linkBandwidth =
|
||||||
|
(read32(INTEL_DISPLAY_PORT_A) & INTEL_DISP_EDP_PLL_FREQ_MASK) >> INTEL_DISP_EDP_PLL_FREQ_SHIFT;
|
||||||
|
switch (linkBandwidth) {
|
||||||
|
case INTEL_DISP_EDP_PLL_FREQ_270:
|
||||||
|
linkBandwidth = 270000; //khz
|
||||||
|
break;
|
||||||
|
case INTEL_DISP_EDP_PLL_FREQ_162:
|
||||||
|
linkBandwidth = 162000; //khz
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TRACE("%s: eDP illegal reference clock ID set, assuming 270Mhz.\n", __func__);
|
||||||
|
linkBandwidth = 270000; //khz
|
||||||
|
}
|
||||||
|
|
||||||
|
bitsPerPixel =
|
||||||
|
(read32(INTEL_DISPLAY_A_PIPE_CONTROL) & INTEL_PIPE_BPC_MASK) >> INTEL_PIPE_COLOR_SHIFT;
|
||||||
|
switch (bitsPerPixel) {
|
||||||
|
case INTEL_PIPE_8BPC:
|
||||||
|
bitsPerPixel = 24;
|
||||||
|
break;
|
||||||
|
case INTEL_PIPE_10BPC:
|
||||||
|
bitsPerPixel = 30;
|
||||||
|
break;
|
||||||
|
case INTEL_PIPE_6BPC:
|
||||||
|
bitsPerPixel = 18;
|
||||||
|
break;
|
||||||
|
case INTEL_PIPE_12BPC:
|
||||||
|
bitsPerPixel = 36;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bitsPerPixel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lanes = 2; //fixme: doc is incorrect on SandyBridge (DP_CTL b19..21 is NOT port_width)
|
||||||
|
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_IVB)) {
|
||||||
|
lanes =
|
||||||
|
((read32(_PortRegister()) & INTEL_DISP_PORT_WIDTH_MASK) >> INTEL_DISP_PORT_WIDTH_SHIFT) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel);
|
||||||
|
}
|
||||||
|
|
||||||
// Program general pipe config
|
// Program general pipe config
|
||||||
fPipe->Configure(target);
|
fPipe->Configure(target);
|
||||||
@@ -1403,7 +1444,7 @@ DisplayPort::SetDisplayMode(display_mode* target, uint32 colorMode)
|
|||||||
// Pll programming is not needed for (e)DP..
|
// Pll programming is not needed for (e)DP..
|
||||||
|
|
||||||
// Program target display mode
|
// Program target display mode
|
||||||
fPipe->ConfigureTimings(target, !needsScaling);
|
fPipe->ConfigureTimings(target, !needsScaling, PortIndex());
|
||||||
} else {
|
} else {
|
||||||
TRACE("%s: Setting display mode via fallback: using scaling!\n", __func__);
|
TRACE("%s: Setting display mode via fallback: using scaling!\n", __func__);
|
||||||
// Keep monitor at native mode and scale image to that
|
// Keep monitor at native mode and scale image to that
|
||||||
|
|||||||
Reference in New Issue
Block a user