Improve pll calculations dealing with DisplayPort devices
* rename encoder_isexternal to encoder_is_external * add encoder_is_dp_bridge call for special DP cases * add initial get_dp_link_clock, hard code a guess for now * take external DP encoders into consideration when making pixel clock adjustments
This commit is contained in:
parent
9bcf0b2e39
commit
dad34be3e1
@ -320,7 +320,7 @@ detect_connectors_legacy()
|
||||
gConnector[connectorIndex]->encoder.type
|
||||
= encoder_type_lookup(encoderID, (1 << i));
|
||||
gConnector[connectorIndex]->encoder.isExternal
|
||||
= encoder_isexternal(encoderID);
|
||||
= encoder_is_external(encoderID);
|
||||
|
||||
radeon_gpu_i2c_attach(connectorIndex, ci.sucI2cId.ucAccess);
|
||||
|
||||
@ -519,7 +519,7 @@ detect_connectors()
|
||||
gConnector[connectorIndex]->encoder.type
|
||||
= encoderType;
|
||||
gConnector[connectorIndex]->encoder.isExternal
|
||||
= encoder_isexternal(encoderID);
|
||||
= encoder_is_external(encoderID);
|
||||
|
||||
pll_limit_probe(
|
||||
&gConnector[connectorIndex]->encoder.pll);
|
||||
|
@ -1250,7 +1250,7 @@ encoder_type_lookup(uint32 encoderID, uint32 connectorFlags)
|
||||
|
||||
|
||||
bool
|
||||
encoder_isexternal(uint32 encoderID)
|
||||
encoder_is_external(uint32 encoderID)
|
||||
{
|
||||
switch (encoderID) {
|
||||
case ENCODER_OBJECT_ID_SI170B:
|
||||
@ -1267,3 +1267,26 @@ encoder_isexternal(uint32 encoderID)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
encoder_is_dp_bridge(uint32 encoderID) {
|
||||
switch (encoderID) {
|
||||
case ENCODER_OBJECT_ID_TRAVIS:
|
||||
case ENCODER_OBJECT_ID_NUTMEG:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
encoder_get_dp_link_clock(uint32 connectorIndex) {
|
||||
uint16 encoderID = gConnector[connectorIndex]->encoder.objectID;
|
||||
|
||||
if (encoderID == ENCODER_OBJECT_ID_NUTMEG)
|
||||
return 270000;
|
||||
|
||||
// TODO: calculate DisplayPort max pixel clock based on bpp and DP channels
|
||||
return 162000;
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ void encoder_dpms_scratch(uint8 crtcID, bool power);
|
||||
void encoder_dpms_set(uint8 crtcID, uint8 encoderID, int mode);
|
||||
uint32 encoder_object_lookup(uint32 encoderFlags, uint8 dacID);
|
||||
uint32 encoder_type_lookup(uint32 encoderID, uint32 connectorFlags);
|
||||
bool encoder_isexternal(uint32 encoderID);
|
||||
bool encoder_is_external(uint32 encoderID);
|
||||
bool encoder_is_dp_bridge(uint32 encoderID);
|
||||
uint32 encoder_get_dp_link_clock(uint32 connectorIndex);
|
||||
|
||||
|
||||
#endif /* RADEON_HD_ENCODER_H */
|
||||
|
@ -338,6 +338,15 @@ pll_adjust(pll_info *pll, uint8 crtcID)
|
||||
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
|
||||
uint32 encoderID = gConnector[connectorIndex]->encoder.objectID;
|
||||
uint32 encoderMode = display_get_encoder_mode(connectorIndex);
|
||||
uint32 encoderFlags = gConnector[connectorIndex]->encoder.flags;
|
||||
bool dpBridge = false;
|
||||
|
||||
if ((encoderFlags & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT))
|
||||
|| encoder_is_dp_bridge(encoderID)) {
|
||||
TRACE("%s: external DP bridge detected!\n", __func__);
|
||||
dpBridge = true;
|
||||
}
|
||||
|
||||
|
||||
if (info.dceMajor >= 3) {
|
||||
union adjust_pixel_clock args;
|
||||
@ -385,13 +394,43 @@ pll_adjust(pll_info *pll, uint8 crtcID)
|
||||
args.v3.sInput.ucDispPllConfig
|
||||
|= DISPPLL_CONFIG_SS_ENABLE;
|
||||
}
|
||||
// TODO: if ATOM_DEVICE_DFP_SUPPORT
|
||||
// TODO: display port DP
|
||||
|
||||
// TODO: is DP?
|
||||
args.v3.sInput.ucExtTransmitterID = 0;
|
||||
// Handle DP adjustments
|
||||
if (encoderMode == ATOM_ENCODER_MODE_DP
|
||||
|| encoderMode == ATOM_ENCODER_MODE_DP_MST) {
|
||||
TRACE("%s: encoderMode is DP\n", __func__);
|
||||
args.v3.sInput.ucDispPllConfig
|
||||
|= DISPPLL_CONFIG_COHERENT_MODE;
|
||||
/* 16200 or 27000 */
|
||||
uint32 dpLinkSpeed
|
||||
= encoder_get_dp_link_clock(connectorIndex);
|
||||
args.v3.sInput.usPixelClock
|
||||
= B_LENDIAN_TO_HOST_INT16(dpLinkSpeed / 10);
|
||||
} else if ((encoderFlags & ATOM_DEVICE_DFP_SUPPORT)
|
||||
!= 0) {
|
||||
TRACE("%s: encoderFlags are DFP but not DP mode.\n",
|
||||
__func__);
|
||||
#if 0
|
||||
if (encoderMode == ATOM_ENCODER_MODE_HDMI) {
|
||||
/* deep color support */
|
||||
args.v3.sInput.usPixelClock =
|
||||
cpu_to_le16((mode->clock * bpc / 8) / 10);
|
||||
}
|
||||
#endif
|
||||
if (pixelClock > 165000) {
|
||||
args.v3.sInput.ucDispPllConfig
|
||||
|= DISPPLL_CONFIG_DUAL_LINK;
|
||||
}
|
||||
if (1) { // dig coherent mode?
|
||||
args.v3.sInput.ucDispPllConfig
|
||||
|= DISPPLL_CONFIG_COHERENT_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
args.v3.sInput.ucExtTransmitterID = dpBridge ? 1 : 0;
|
||||
|
||||
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||
|
||||
// get returned adjusted clock
|
||||
pll->pixelClock
|
||||
= B_LENDIAN_TO_HOST_INT32(
|
||||
|
Loading…
Reference in New Issue
Block a user