hrev51404 adds 1 changeset to branch 'master'
old head: 66a16010b77cd29b5e65e43cd4eb2433626c0b9b
new head: 1121a23254b4ec12d5f2c6e0368fa5cce74fa58a
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=1121a23254b4+%5E66a16010b77c
----------------------------------------------------------------------------
1121a23254b4: radeon_hd: Improve external/dce PLL programming
* Bug fix around pll_external_set. We prepared all the args,
but never actually executed the AtomBIOS table.
* Add new AtomBIOS methods in Polaris to set external PLL
clock frequencies.
* Implement new 1.7 PLL set table on Polaris.
[ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev51404
Commit: 1121a23254b4ec12d5f2c6e0368fa5cce74fa58a
URL: http://cgit.haiku-os.org/haiku/commit/?id=1121a23254b4
Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date: Sat Sep 9 02:05:43 2017 UTC
----------------------------------------------------------------------------
2 files changed, 113 insertions(+), 8 deletions(-)
src/add-ons/accelerants/radeon_hd/pll.cpp | 117 ++++++++++++++++++++++++--
src/add-ons/accelerants/radeon_hd/pll.h | 4 +-
----------------------------------------------------------------------------
diff --git a/src/add-ons/accelerants/radeon_hd/pll.cpp
b/src/add-ons/accelerants/radeon_hd/pll.cpp
index 9c2db30..0949d9a 100644
--- a/src/add-ons/accelerants/radeon_hd/pll.cpp
+++ b/src/add-ons/accelerants/radeon_hd/pll.cpp
@@ -746,8 +746,10 @@ status_t
pll_set(display_mode* mode, uint8 crtcID)
{
uint32 connectorIndex = gDisplay[crtcID]->connectorIndex;
+ uint32 encoderMode = display_get_encoder_mode(connectorIndex);
pll_info* pll = &gConnector[connectorIndex]->encoder.pll;
uint32 dp_clock = gConnector[connectorIndex]->dpInfo.linkRate;
+
pll->ssEnabled = false;
pll->pixelClock = mode->timing.pixel_clock;
@@ -762,7 +764,7 @@ pll_set(display_mode* mode, uint8 crtcID)
pll->ssRange = 0;
pll->ssReferenceDiv = 0;
- switch (display_get_encoder_mode(connectorIndex)) {
+ switch (encoderMode) {
case ATOM_ENCODER_MODE_DP_MST:
case ATOM_ENCODER_MODE_DP:
if (info.dceMajor >= 4)
@@ -820,6 +822,7 @@ pll_set(display_mode* mode, uint8 crtcID)
PIXEL_CLOCK_PARAMETERS_V3 v3;
PIXEL_CLOCK_PARAMETERS_V5 v5;
PIXEL_CLOCK_PARAMETERS_V6 v6;
+ PIXEL_CLOCK_PARAMETERS_V7 v7;
};
union setPixelClock args;
memset(&args, 0, sizeof(args));
@@ -926,6 +929,41 @@ pll_set(display_mode* mode, uint8 crtcID)
args.v6.ucEncoderMode =
display_get_encoder_mode(connectorIndex);
args.v6.ucPpll = pll->id;
break;
+ case 7:
+ args.v7.ulPixelClock
+ = B_HOST_TO_LENDIAN_INT32(pll->pixelClock / 10);
+ args.v7.ucMiscInfo = 0;
+ if (gConnector[connectorIndex]->type ==
VIDEO_CONNECTOR_DVID
+ && pll->pixelClock > 165000) {
+ args.v7.ucMiscInfo |=
PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
+ }
+ args.v7.ucCRTC = crtcID;
+ if (encoderMode == ATOM_ENCODER_MODE_HDMI) {
+ switch (bitsPerColor) {
+ case 8:
+ default:
+ args.v7.ucDeepColorRatio
+ =
PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_DIS;
+ break;
+ case 10:
+ args.v7.ucDeepColorRatio
+ =
PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_5_4;
+ break;
+ case 12:
+ args.v7.ucDeepColorRatio
+ =
PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_3_2;
+ break;
+ case 16:
+ args.v7.ucDeepColorRatio
+ =
PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_2_1;
+ break;
+ }
+ }
+ args.v7.ucTransmitterID
+ = gConnector[connectorIndex]->encoder.objectID;
+ args.v7.ucEncoderMode =
display_get_encoder_mode(connectorIndex);
+ args.v7.ucPpll = pll->id;
+ break;
default:
TRACE("%s: ERROR: table version %" B_PRIu8 ".%" B_PRIu8
" TODO\n",
__func__, tableMajor, tableMinor);
@@ -946,8 +984,13 @@ pll_set(display_mode* mode, uint8 crtcID)
}
+/**
+ * pll_set_external - Sets external default pll via SetPixelClock
+ *
+ * Applies a clock frequency to card's external PLL clock.
+ */
status_t
-pll_external_set(uint32 clock)
+pll_set_external(uint32 clock)
{
TRACE("%s: set external pll clock to %" B_PRIu32 "\n", __func__, clock);
@@ -971,6 +1014,7 @@ pll_external_set(uint32 clock)
PIXEL_CLOCK_PARAMETERS_V3 v3;
PIXEL_CLOCK_PARAMETERS_V5 v5;
PIXEL_CLOCK_PARAMETERS_V6 v6;
+ PIXEL_CLOCK_PARAMETERS_V7 v7;
};
union setPixelClock args;
memset(&args, 0, sizeof(args));
@@ -979,7 +1023,7 @@ pll_external_set(uint32 clock)
uint32 dceVersion = (info.dceMajor * 100) + info.dceMinor;
switch (tableMajor) {
case 1:
- switch(tableMinor) {
+ switch (tableMinor) {
case 5:
// If the default DC PLL clock is
specified,
// SetPixelClock provides the dividers.
@@ -1008,7 +1052,61 @@ pll_external_set(uint32 clock)
ERROR("%s: Unknown table version %" B_PRIu8
".%" B_PRIu8 "\n", __func__,
tableMajor, tableMinor);
}
- return B_OK;
+ return atom_execute_table(gAtomContext, index, (uint32*)&args);
+}
+
+
+/**
+ * pll_set_dce - Sets external default pll via DCE Clock Allocation
+ *
+ * Applies a clock frequency to card's external PLL clock via SetDCEClock
+ * Used on Polaris.
+ */
+status_t
+pll_set_dce(uint32 clock, uint8 clockType, uint8 clockSource)
+{
+ TRACE("%s: set external pll clock to %" B_PRIu32 "\n", __func__, clock);
+
+ if (clock == 0)
+ ERROR("%s: Warning: default display clock is 0?\n", __func__);
+
+ uint8 tableMajor;
+ uint8 tableMinor;
+
+ int index = GetIndexIntoMasterTable(COMMAND, SetDCEClock);
+ atom_parse_cmd_header(gAtomContext, index, &tableMajor, &tableMinor);
+
+ TRACE("%s: table %" B_PRIu8 ".%" B_PRIu8 "\n", __func__,
+ tableMajor, tableMinor);
+
+ union setDCEClock {
+ SET_DCE_CLOCK_PS_ALLOCATION_V1_1 v1;
+ SET_DCE_CLOCK_PS_ALLOCATION_V2_1 v2;
+ };
+ union setDCEClock args;
+ memset(&args, 0, sizeof(args));
+
+ switch (tableMajor) {
+ case 2:
+ switch (tableMinor) {
+ case 1:
+ args.v2.asParam.ulDCEClkFreq
+ = B_HOST_TO_LENDIAN_INT32(clock
/ 10);
+ args.v2.asParam.ucDCEClkType =
clockType;
+ args.v2.asParam.ucDCEClkSrc =
clockSource;
+ break;
+ default:
+ ERROR("%s: Unknown table version %"
B_PRIu8
+ ".%" B_PRIu8 "\n", __func__,
tableMajor, tableMinor);
+ return B_ERROR;
+ }
+ break;
+ default:
+ ERROR("%s: Unknown table version %" B_PRIu8
+ ".%" B_PRIu8 "\n", __func__, tableMajor,
tableMinor);
+ return B_ERROR;
+ }
+ return atom_execute_table(gAtomContext, index, (uint32*)&args);
}
@@ -1023,8 +1121,13 @@ pll_external_init()
{
radeon_shared_info &info = *gInfo->shared_info;
- if (info.dceMajor >= 6) {
- pll_external_set(gInfo->displayClockFrequency);
+ if (info.dceMajor >= 12) {
+ pll_set_dce(gInfo->displayClockFrequency,
+ DCE_CLOCK_TYPE_DISPCLK, ATOM_GCK_DFS);
+ pll_set_dce(gInfo->displayClockFrequency,
+ DCE_CLOCK_TYPE_DPREFCLK, ATOM_GCK_DFS);
+ } else if (info.dceMajor >= 6) {
+ pll_set_external(gInfo->displayClockFrequency);
} else if (info.dceMajor >= 4) {
// Create our own pseudo pll
pll_info pll;
@@ -1033,7 +1136,7 @@ pll_external_init()
pll_asic_ss_probe(&pll, ASIC_INTERNAL_SS_ON_DCPLL);
if (pll.ssEnabled)
display_crtc_ss(&pll, ATOM_DISABLE);
- pll_external_set(pll.pixelClock);
+ pll_set_external(pll.pixelClock);
if (pll.ssEnabled)
display_crtc_ss(&pll, ATOM_ENABLE);
}
diff --git a/src/add-ons/accelerants/radeon_hd/pll.h
b/src/add-ons/accelerants/radeon_hd/pll.h
index ed09138..2879e69 100644
--- a/src/add-ons/accelerants/radeon_hd/pll.h
+++ b/src/add-ons/accelerants/radeon_hd/pll.h
@@ -102,7 +102,9 @@ struct pll_info {
void pll_external_init();
-status_t pll_external_set(uint32 clock);
+status_t pll_set_external(uint32 clock);
+status_t pll_set_dce(uint32 clock, uint8 clockType, uint8 clockSource);
+
status_t pll_adjust(pll_info* pll, display_mode* mode, uint8 crtcID);
uint32 pll_usage_mask();
uint32 pll_usage_count(uint32 pllID);