radeon_hd: clean up clock units
* Ensure we store all clock units as khz or n * 10 off from AtomBIOS unit expected * Perform DDC setup of external encoder
This commit is contained in:
parent
5ed8c605ef
commit
224b875b3a
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user