diff --git a/src/add-ons/accelerants/radeon_hd/mode.cpp b/src/add-ons/accelerants/radeon_hd/mode.cpp index afa9ed02cc..e3bdc20b11 100644 --- a/src/add-ons/accelerants/radeon_hd/mode.cpp +++ b/src/add-ons/accelerants/radeon_hd/mode.cpp @@ -186,8 +186,14 @@ radeon_set_display_mode(display_mode* mode) // *** CRT controler mode set // TODO: program SS - pll_set(ATOM_PPLL1, mode, id); - // TODO: check if ATOM_PPLL1 is used and use ATOM_PPLL2 if so + + // Set up PLL for connector + pll_pick(connectorIndex); + pll_info* pll = &gConnector[connectorIndex]->encoder.pll; + TRACE("%s: pll %d selected for connector %" B_PRIu32 "\n", __func__, + pll->id, connectorIndex); + pll_set(mode, id); + display_crtc_set_dtd(id, mode); display_crtc_fb_set(id, mode); diff --git a/src/add-ons/accelerants/radeon_hd/pll.cpp b/src/add-ons/accelerants/radeon_hd/pll.cpp index 829a367625..3ea25775e6 100644 --- a/src/add-ons/accelerants/radeon_hd/pll.cpp +++ b/src/add-ons/accelerants/radeon_hd/pll.cpp @@ -17,6 +17,7 @@ #include "accelerant_protos.h" #include "accelerant.h" #include "bios.h" +#include "connector.h" #include "display.h" #include "displayport.h" #include "encoder.h" @@ -650,13 +651,12 @@ pll_adjust(pll_info* pll, display_mode* mode, uint8 crtcID) status_t -pll_set(uint8 pllID, display_mode* mode, uint8 crtcID) +pll_set(display_mode* mode, uint8 crtcID) { uint32 connectorIndex = gDisplay[crtcID]->connectorIndex; pll_info* pll = &gConnector[connectorIndex]->encoder.pll; pll->pixelClock = mode->timing.pixel_clock; - pll->id = pllID; pll_setup_flags(pll, crtcID); // set up any special flags @@ -759,7 +759,7 @@ pll_set(uint8 pllID, display_mode* mode, uint8 crtcID) = gConnector[connectorIndex]->encoder.objectID; args.v5.ucEncoderMode = display_get_encoder_mode(connectorIndex); - args.v5.ucPpll = pllID; + args.v5.ucPpll = pll->id; break; case 6: args.v6.ulDispEngClkFreq @@ -790,7 +790,7 @@ pll_set(uint8 pllID, display_mode* mode, uint8 crtcID) args.v6.ucTransmitterID = gConnector[connectorIndex]->encoder.objectID; args.v6.ucEncoderMode = display_get_encoder_mode(connectorIndex); - args.v6.ucPpll = pllID; + args.v6.ucPpll = pll->id; break; default: TRACE("%s: ERROR: table version %" B_PRIu8 ".%" B_PRIu8 " TODO\n", @@ -808,3 +808,45 @@ pll_set(uint8 pllID, display_mode* mode, uint8 crtcID) return result; } + + +status_t +pll_pick(uint32 connectorIndex) +{ + pll_info* pll = &gConnector[connectorIndex]->encoder.pll; + radeon_shared_info &info = *gInfo->shared_info; + + bool linkB = gConnector[connectorIndex]->encoder.linkEnumeration + == GRAPH_OBJECT_ENUM_ID2 ? true : false; + + if (info.dceMajor == 6 && info.dceMinor == 1) { + // DCE 6.1 APU + if (gConnector[connectorIndex]->encoder.objectID + == ENCODER_OBJECT_ID_INTERNAL_UNIPHY && !linkB) { + pll->id = ATOM_PPLL2; + return B_OK; + } + // TODO: check for used PLL1 and use PLL2? + pll->id = ATOM_PPLL1; + return B_OK; + } else if (info.dceMajor >= 4) { + if (connector_is_dp(connectorIndex)) { + if (info.dceMajor >= 6) { + pll->id = ATOM_PPLL1; + return B_OK; + } else if (info.dceMajor >= 5) { + pll->id = ATOM_DCPLL; + return B_OK; + } else if (pll->dpExternalClock) { + pll->id = ATOM_PPLL_INVALID; + return B_OK; + } + } + pll->id = ATOM_PPLL1; + return B_OK; + } + + // TODO: Should return the CRTCID here. + pll->id = ATOM_PPLL1; + return B_OK; +} diff --git a/src/add-ons/accelerants/radeon_hd/pll.h b/src/add-ons/accelerants/radeon_hd/pll.h index 128e6c03ee..2be6e977c1 100644 --- a/src/add-ons/accelerants/radeon_hd/pll.h +++ b/src/add-ons/accelerants/radeon_hd/pll.h @@ -106,7 +106,8 @@ void pll_setup_flags(pll_info* pll, uint8 crtcID); status_t pll_limit_probe(pll_info* pll); status_t pll_dp_ss_probe(pll_info* pll); status_t pll_asic_ss_probe(pll_info* pll); -status_t pll_set(uint8 pllID, display_mode* mode, uint8 crtcID); +status_t pll_set(display_mode* mode, uint8 crtcID); +status_t pll_pick(uint32 connectorIndex); #endif /* RADEON_HD_PLL_H */