diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 2a71571a27..a8b5babe6d 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -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_1 0 #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_B_DP_CTL (0x1300 | REGS_SOUTH_TRANSCODER_PORT) diff --git a/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp b/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp index 619380bbd5..90cc71f989 100644 --- a/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp +++ b/src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp @@ -281,7 +281,6 @@ FDILink::PreTrain(display_timing* target, uint32* linkBandwidth, uint32* lanes, TRACE("%s: FDI Link Colordepth: %" B_PRIu32 "\n", __func__, *bitsPerPixel); // 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; //Reserving 5% bandwidth for possible spread spectrum clock use uint32 bps = target->pixel_clock * *bitsPerPixel * 21 / 20; diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.cpp b/src/add-ons/accelerants/intel_extreme/Pipes.cpp index 4a97991b46..ea8413d072 100644 --- a/src/add-ons/accelerants/intel_extreme/Pipes.cpp +++ b/src/add-ons/accelerants/intel_extreme/Pipes.cpp @@ -331,7 +331,7 @@ Pipe::ConfigureScalePos(display_mode* target) void -Pipe::ConfigureTimings(display_mode* target, bool hardware) +Pipe::ConfigureTimings(display_mode* target, bool hardware, port_index portIndex) { CALLED(); @@ -373,6 +373,13 @@ Pipe::ConfigureTimings(display_mode* target, bool hardware) 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) { _ConfigureTranscoder(target); } diff --git a/src/add-ons/accelerants/intel_extreme/Pipes.h b/src/add-ons/accelerants/intel_extreme/Pipes.h index c9ed4be238..1c361b99cf 100644 --- a/src/add-ons/accelerants/intel_extreme/Pipes.h +++ b/src/add-ons/accelerants/intel_extreme/Pipes.h @@ -47,7 +47,8 @@ public: uint32 bitsPerPixel); void ConfigureScalePos(display_mode* mode); void ConfigureTimings(display_mode* mode, - bool hardware = true); + bool hardware = true, + port_index portIndex = INTEL_PORT_ANY); void ConfigureClocks( const pll_divisors& divisors, uint32 pixelClock, diff --git a/src/add-ons/accelerants/intel_extreme/Ports.cpp b/src/add-ons/accelerants/intel_extreme/Ports.cpp index be703f7059..683a118bbf 100644 --- a/src/add-ons/accelerants/intel_extreme/Ports.cpp +++ b/src/add-ons/accelerants/intel_extreme/Ports.cpp @@ -1152,7 +1152,6 @@ status_t DisplayPort::_SetPortLinkGen4(const display_timing& timing) { // Khz / 10. ( each output octet encoded as 10 bits. - //uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; //=270000 khz //fixme: always so? uint32 linkBandwidth = 270000; //khz uint32 fPipeOffset = 0; @@ -1216,8 +1215,7 @@ status_t DisplayPort::_SetPortLinkGen6(const display_timing& timing) { // Khz / 10. ( each output octet encoded as 10 bits. - //uint32 linkBandwidth = gInfo->shared_info->fdi_link_frequency * 1000 / 10; //=270000 khz - //fixme: eDP is fixed option 162 or 270Mc, other DPs go via DPLL programming to one of the same vals. + //note: (fixme) eDP is fixed option 162 or 270Mc, other DPs go via DPLL programming to one of the same vals. uint32 linkBandwidth = 270000; //khz 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); - uint32 lanes = - 1 << ((read32(_PortRegister()) & INTEL_DISP_PORT_WIDTH_MASK) >> INTEL_DISP_PORT_WIDTH_SHIFT); + uint32 lanes = ((read32(_PortRegister()) & INTEL_DISP_PORT_WIDTH_MASK) >> INTEL_DISP_PORT_WIDTH_SHIFT) + 1; if (lanes > 4) { ERROR("%s: DP illegal number of lanes set.\n", __func__); return B_ERROR; @@ -1386,15 +1383,59 @@ DisplayPort::SetDisplayMode(display_mode* target, uint32 colorMode) PanelFitter* fitter = fPipe->PFT(); if (fitter != NULL) 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 linkBandwidth = 0; - uint32 bitsPerPixel = 0; - link->PreTrain(&hardwareTarget, &linkBandwidth, &lanes, &bitsPerPixel); + + uint32 lanes = 0; + uint32 linkBandwidth = 0; + uint32 bitsPerPixel = 0; + if (PortIndex() != INTEL_PORT_A) { + FDILink* link = fPipe->FDI(); + if (link != NULL) { + link->PreTrain(&hardwareTarget, &linkBandwidth, &lanes, &bitsPerPixel); + fPipe->SetFDILink(hardwareTarget, linkBandwidth, lanes, bitsPerPixel); + 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); - link->Train(&hardwareTarget, lanes); } // Program general pipe config @@ -1403,7 +1444,7 @@ DisplayPort::SetDisplayMode(display_mode* target, uint32 colorMode) // Pll programming is not needed for (e)DP.. // Program target display mode - fPipe->ConfigureTimings(target, !needsScaling); + fPipe->ConfigureTimings(target, !needsScaling, PortIndex()); } else { TRACE("%s: Setting display mode via fallback: using scaling!\n", __func__); // Keep monitor at native mode and scale image to that