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:
@@ -320,7 +320,7 @@ detect_connectors_legacy()
|
|||||||
gConnector[connectorIndex]->encoder.type
|
gConnector[connectorIndex]->encoder.type
|
||||||
= encoder_type_lookup(encoderID, (1 << i));
|
= encoder_type_lookup(encoderID, (1 << i));
|
||||||
gConnector[connectorIndex]->encoder.isExternal
|
gConnector[connectorIndex]->encoder.isExternal
|
||||||
= encoder_isexternal(encoderID);
|
= encoder_is_external(encoderID);
|
||||||
|
|
||||||
radeon_gpu_i2c_attach(connectorIndex, ci.sucI2cId.ucAccess);
|
radeon_gpu_i2c_attach(connectorIndex, ci.sucI2cId.ucAccess);
|
||||||
|
|
||||||
@@ -519,7 +519,7 @@ detect_connectors()
|
|||||||
gConnector[connectorIndex]->encoder.type
|
gConnector[connectorIndex]->encoder.type
|
||||||
= encoderType;
|
= encoderType;
|
||||||
gConnector[connectorIndex]->encoder.isExternal
|
gConnector[connectorIndex]->encoder.isExternal
|
||||||
= encoder_isexternal(encoderID);
|
= encoder_is_external(encoderID);
|
||||||
|
|
||||||
pll_limit_probe(
|
pll_limit_probe(
|
||||||
&gConnector[connectorIndex]->encoder.pll);
|
&gConnector[connectorIndex]->encoder.pll);
|
||||||
|
|||||||
@@ -1250,7 +1250,7 @@ encoder_type_lookup(uint32 encoderID, uint32 connectorFlags)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
encoder_isexternal(uint32 encoderID)
|
encoder_is_external(uint32 encoderID)
|
||||||
{
|
{
|
||||||
switch (encoderID) {
|
switch (encoderID) {
|
||||||
case ENCODER_OBJECT_ID_SI170B:
|
case ENCODER_OBJECT_ID_SI170B:
|
||||||
@@ -1267,3 +1267,26 @@ encoder_isexternal(uint32 encoderID)
|
|||||||
|
|
||||||
return false;
|
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);
|
void encoder_dpms_set(uint8 crtcID, uint8 encoderID, int mode);
|
||||||
uint32 encoder_object_lookup(uint32 encoderFlags, uint8 dacID);
|
uint32 encoder_object_lookup(uint32 encoderFlags, uint8 dacID);
|
||||||
uint32 encoder_type_lookup(uint32 encoderID, uint32 connectorFlags);
|
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 */
|
#endif /* RADEON_HD_ENCODER_H */
|
||||||
|
|||||||
@@ -338,6 +338,15 @@ pll_adjust(pll_info *pll, uint8 crtcID)
|
|||||||
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
|
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
|
||||||
uint32 encoderID = gConnector[connectorIndex]->encoder.objectID;
|
uint32 encoderID = gConnector[connectorIndex]->encoder.objectID;
|
||||||
uint32 encoderMode = display_get_encoder_mode(connectorIndex);
|
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) {
|
if (info.dceMajor >= 3) {
|
||||||
union adjust_pixel_clock args;
|
union adjust_pixel_clock args;
|
||||||
@@ -385,13 +394,43 @@ pll_adjust(pll_info *pll, uint8 crtcID)
|
|||||||
args.v3.sInput.ucDispPllConfig
|
args.v3.sInput.ucDispPllConfig
|
||||||
|= DISPPLL_CONFIG_SS_ENABLE;
|
|= DISPPLL_CONFIG_SS_ENABLE;
|
||||||
}
|
}
|
||||||
// TODO: if ATOM_DEVICE_DFP_SUPPORT
|
|
||||||
// TODO: display port DP
|
|
||||||
|
|
||||||
// TODO: is DP?
|
// Handle DP adjustments
|
||||||
args.v3.sInput.ucExtTransmitterID = 0;
|
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);
|
atom_execute_table(gAtomContext, index, (uint32*)&args);
|
||||||
|
|
||||||
// get returned adjusted clock
|
// get returned adjusted clock
|
||||||
pll->pixelClock
|
pll->pixelClock
|
||||||
= B_LENDIAN_TO_HOST_INT32(
|
= B_LENDIAN_TO_HOST_INT32(
|
||||||
|
|||||||
Reference in New Issue
Block a user