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:
Alexander von Gluck IV 2011-12-02 16:49:20 -06:00
parent 9bcf0b2e39
commit dad34be3e1
4 changed files with 72 additions and 8 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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 */

View File

@ -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(