diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h b/src/add-ons/accelerants/radeon_hd/accelerant.h index 9f7998c38e..c138938784 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.h +++ b/src/add-ons/accelerants/radeon_hd/accelerant.h @@ -72,7 +72,7 @@ struct accelerant_info { volatile uint32 dpms_mode; // current driver dpms mode - uint16 maximumPixelClock; + uint32 maximumPixelClock; uint32 displayClockFrequency; uint32 dpExternalClock; @@ -138,7 +138,7 @@ struct encoder_info { bool valid; uint16 objectID; uint32 type; - uint16 capabilities; + uint32 capabilities; uint32 linkEnumeration; // ex. linkb == GRAPH_OBJECT_ENUM_ID2 bool isExternal; bool isDPBridge; diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp b/src/add-ons/accelerants/radeon_hd/display.cpp index d81ab779bc..46e35c54a0 100644 --- a/src/add-ons/accelerants/radeon_hd/display.cpp +++ b/src/add-ons/accelerants/radeon_hd/display.cpp @@ -267,29 +267,26 @@ detect_displays() if (gConnector[id]->type == VIDEO_CONNECTOR_DP) { TRACE("%s: connector(%" B_PRIu32 "): Checking DP.\n", __func__, id); + if (gConnector[id]->encoderExternal.valid == true) { + // If this has a valid external encoder (dp bridge) + // normally TRAVIS (LVDS) or NUTMEG (VGA) + TRACE("%s: external encoder, performing bridge DDC setup\n", + __func__); + encoder_external_setup(id, + EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP); + } edid1_info* edid = &gDisplay[displayIndex]->edidData; gDisplay[displayIndex]->attached = ddc2_dp_read_edid1(id, edid); + // TODO: DDC Router switching for DisplayPort (and others?) + if (gDisplay[displayIndex]->attached) { TRACE("%s: connector(%" B_PRIu32 "): Found DisplayPort EDID!\n", __func__); } } - // TODO: Handle external DP brides - ?? - #if 0 - if (gConnector[id]->encoderExternal.isDPBridge == true) { - // If this is a DisplayPort Bridge, setup ddc on bus - // TRAVIS (LVDS) or NUTMEG (VGA) - TRACE("%s: is bridge, performing bridge DDC setup\n", __func__); - encoder_external_setup(id, 23860, - EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP); - gDisplay[displayIndex]->attached = true; - - // TODO: DDC Router switching for DisplayPort (and others?) - } - #endif if (gConnector[id]->type == VIDEO_CONNECTOR_LVDS) { display_mode preferredMode; diff --git a/src/add-ons/accelerants/radeon_hd/displayport.cpp b/src/add-ons/accelerants/radeon_hd/displayport.cpp index 9e712547d5..60f1783d91 100644 --- a/src/add-ons/accelerants/radeon_hd/displayport.cpp +++ b/src/add-ons/accelerants/radeon_hd/displayport.cpp @@ -970,7 +970,7 @@ dp_is_dp12_capable(uint32 connectorIndex) uint32 capabilities = gConnector[connectorIndex]->encoder.capabilities; if (info.dceMajor >= 5 - && gInfo->dpExternalClock >= 53900 + && gInfo->dpExternalClock >= 539000 && (capabilities & ATOM_ENCODER_CAP_RECORD_HBR2) != 0) { return true; } diff --git a/src/add-ons/accelerants/radeon_hd/gpu.cpp b/src/add-ons/accelerants/radeon_hd/gpu.cpp index 3e006b602b..93f7f49cb4 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.cpp +++ b/src/add-ons/accelerants/radeon_hd/gpu.cpp @@ -68,21 +68,24 @@ radeon_gpu_probe() if (info.dceMajor >= 4) { gInfo->displayClockFrequency = B_LENDIAN_TO_HOST_INT32( firmwareInfo->info_21.ulDefaultDispEngineClkFreq); + gInfo->displayClockFrequency *= 10; if (gInfo->displayClockFrequency == 0) { if (info.dceMajor >= 5) - gInfo->displayClockFrequency = 54000; + gInfo->displayClockFrequency = 540000; else - gInfo->displayClockFrequency = 60000; + gInfo->displayClockFrequency = 600000; } gInfo->dpExternalClock = B_LENDIAN_TO_HOST_INT16( firmwareInfo->info_21.usUniphyDPModeExtClkFreq); + gInfo->dpExternalClock *= 10; } gInfo->maximumPixelClock = B_LENDIAN_TO_HOST_INT16( firmwareInfo->info.usMaxPixelClock); + gInfo->maximumPixelClock *= 10; if (gInfo->maximumPixelClock == 0) - gInfo->maximumPixelClock = 40000; + gInfo->maximumPixelClock = 400000; return B_OK; } diff --git a/src/add-ons/accelerants/radeon_hd/pll.cpp b/src/add-ons/accelerants/radeon_hd/pll.cpp index 2f7fc72302..ec8a1f0c82 100644 --- a/src/add-ons/accelerants/radeon_hd/pll.cpp +++ b/src/add-ons/accelerants/radeon_hd/pll.cpp @@ -34,6 +34,16 @@ extern "C" void _sPrintf(const char* format, ...); #define ERROR(x...) _sPrintf("radeon_hd: " x) +// Pixel Clock Storage +// kHz Value Result +// Haiku: 104000 khz 104 Mhz +// Linux: 104000 khz 104 Mhz +// AtomBIOS: 10400 * 10 khz 104 Mhz +// Ghz +// Haiku: 162000 * 10 khz 1.62 Ghz +// Linux: 162000 * 10 khz 1.62 Ghz +// AtomBIOS: 16200 * 10 Khz 0.162 * 10 Ghz + status_t pll_limit_probe(pll_info* pll) @@ -118,9 +128,9 @@ pll_limit_probe(pll_info* pll) pll->pllInMax = B_LENDIAN_TO_HOST_INT16( firmwareInfo->info.usMaxPixelClockPLL_Input) * 10; - TRACE("%s: referenceFreq: %" B_PRIu16 "; pllOutMin: %" B_PRIu16 "; " - " pllOutMax: %" B_PRIu16 "; pllInMin: %" B_PRIu16 ";" - "pllInMax: %" B_PRIu16 "\n", __func__, pll->referenceFreq, + TRACE("%s: referenceFreq: %" B_PRIu32 "; pllOutMin: %" B_PRIu32 "; " + " pllOutMax: %" B_PRIu32 "; pllInMin: %" B_PRIu32 ";" + "pllInMax: %" B_PRIu32 "\n", __func__, pll->referenceFreq, pll->pllOutMin, pll->pllOutMax, pll->pllInMin, pll->pllInMax); return B_OK; @@ -205,7 +215,7 @@ pll_asic_ss_probe(pll_info* pll, uint32 ssID) continue; } TRACE("%s: ss match found\n", __func__); - if (pll->pixelClock > B_LENDIAN_TO_HOST_INT32( + if (pll->pixelClock * 10 > B_LENDIAN_TO_HOST_INT32( ss_info->info.asSpreadSpectrum[i].ulTargetClockRange)) { TRACE("%s: pixelClock > targetClockRange!\n", __func__); continue; @@ -232,7 +242,7 @@ pll_asic_ss_probe(pll_info* pll, uint32 ssID) continue; } TRACE("%s: ss match found\n", __func__); - if (pll->pixelClock > B_LENDIAN_TO_HOST_INT32( + if (pll->pixelClock * 10 > B_LENDIAN_TO_HOST_INT32( ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange)) { TRACE("%s: pixelClock > targetClockRange!\n", __func__); continue; @@ -260,7 +270,7 @@ pll_asic_ss_probe(pll_info* pll, uint32 ssID) continue; } TRACE("%s: ss match found\n", __func__); - if (pll->pixelClock > B_LENDIAN_TO_HOST_INT32( + if (pll->pixelClock * 10 > B_LENDIAN_TO_HOST_INT32( ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange)) { TRACE("%s: pixelClock > targetClockRange!\n", __func__); continue; @@ -433,11 +443,15 @@ pll_compute(pll_info* pll) + (referenceFrequency * pll->feedbackDivFrac)) / (pll->referenceDiv * pll->postDiv * 10); - TRACE("%s: pixel clock: %" B_PRIu32 " gives:" - " feedbackDivider = %" B_PRIu32 ".%" B_PRIu32 - "; referenceDivider = %" B_PRIu32 "; postDivider = %" B_PRIu32 "\n", - __func__, pll->adjustedClock, pll->feedbackDiv, pll->feedbackDivFrac, - pll->referenceDiv, pll->postDiv); + TRACE("%s: Calculated pixel clock of %" B_PRIu32 " based on:\n", __func__, + calculatedClock); + TRACE("%s: referenceFrequency: %" B_PRIu32 "; " + "referenceDivider: %" B_PRIu32 "\n", __func__, referenceFrequency, + pll->referenceDiv); + TRACE("%s: feedbackDivider: %" B_PRIu32 "; " + "feedbackDividerFrac: %" B_PRIu32 "\n", __func__, pll->feedbackDiv, + pll->feedbackDivFrac); + TRACE("%s: postDivider: %" B_PRIu32 "\n", __func__, pll->postDiv); if (pll->adjustedClock != calculatedClock) { TRACE("%s: pixel clock %" B_PRIu32 " was changed to %" B_PRIu32 "\n", @@ -579,9 +593,10 @@ pll_adjust(pll_info* pll, display_mode* mode, uint8 crtcID) TRACE("%s: encoderMode is DP\n", __func__); args.v3.sInput.ucDispPllConfig |= DISPPLL_CONFIG_COHERENT_MODE; - /* 16200 or 27000 */ + /* 162000 or 270000 */ uint32 dpLinkSpeed = dp_get_link_rate(connectorIndex, mode); + /* 16200 or 27000 */ args.v3.sInput.usPixelClock = B_HOST_TO_LENDIAN_INT16(dpLinkSpeed / 10); } else if ((connectorFlags & ATOM_DEVICE_DFP_SUPPORT) @@ -608,8 +623,7 @@ pll_adjust(pll_info* pll, display_mode* mode, uint8 crtcID) atom_execute_table(gAtomContext, index, (uint32*)&args); // get returned adjusted clock - pll->adjustedClock - = B_LENDIAN_TO_HOST_INT32( + pll->adjustedClock = B_LENDIAN_TO_HOST_INT32( args.v3.sOutput.ulDispPllFreq); pll->adjustedClock *= 10; // convert to kHz for storage @@ -650,7 +664,7 @@ pll_set(display_mode* mode, uint8 crtcID) { uint32 connectorIndex = gDisplay[crtcID]->connectorIndex; pll_info* pll = &gConnector[connectorIndex]->encoder.pll; - uint32 dp_clock = gConnector[connectorIndex]->dpInfo.linkRate / 10; + uint32 dp_clock = gConnector[connectorIndex]->dpInfo.linkRate; bool ssEnabled = false; pll->pixelClock = mode->timing.pixel_clock; @@ -671,7 +685,7 @@ pll_set(display_mode* mode, uint8 crtcID) if (info.dceMajor >= 4) pll_asic_ss_probe(pll, ASIC_INTERNAL_SS_ON_DP); else { - if (dp_clock == 16200) { + if (dp_clock == 162000) { ssEnabled = pll_ppll_ss_probe(pll, ATOM_DP_SS_ID2); if (!ssEnabled) // id2 failed, try id1 @@ -889,13 +903,14 @@ pll_external_set(uint32 clock) // If the default DC PLL clock is specified, // SetPixelClock provides the dividers. args.v5.ucCRTC = ATOM_CRTC_INVALID; - args.v5.usPixelClock = B_HOST_TO_LENDIAN_INT16(clock); + args.v5.usPixelClock = B_HOST_TO_LENDIAN_INT16(clock / 10); args.v5.ucPpll = ATOM_DCPLL; break; case 6: // If the default DC PLL clock is specified, // SetPixelClock provides the dividers. - args.v6.ulDispEngClkFreq = B_HOST_TO_LENDIAN_INT32(clock); + args.v6.ulDispEngClkFreq + = B_HOST_TO_LENDIAN_INT32(clock / 10); if (dceVersion == 601) args.v6.ucPpll = ATOM_EXT_PLL1; else if (dceVersion >= 600)