[haiku-commits] haiku: hrev44489 - src/add-ons/accelerants/radeon_hd

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 7 Aug 2012 20:24:25 +0200 (CEST)

hrev44489 adds 1 changeset to branch 'master'
old head: 63624e404b5eb6fc11a503331e67ce29af074021
new head: 817c114de7e2e71d98adccb66358e94244a1486a

----------------------------------------------------------------------------

817c114: radeon_hd: rework some pll code
  
  * Force fractional feedback divider on APU's
  * Spread Spectrum is now probed more correctly
    across multiple encoders and cards
  * SS still disabled however.

                          [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev44489
Commit:      817c114de7e2e71d98adccb66358e94244a1486a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=817c114
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Tue Aug  7 18:20:52 2012 UTC

----------------------------------------------------------------------------

8 files changed, 100 insertions(+), 37 deletions(-)
src/add-ons/accelerants/radeon_hd/accelerant.cpp |    3 -
src/add-ons/accelerants/radeon_hd/accelerant.h   |    2 +
src/add-ons/accelerants/radeon_hd/connector.cpp  |    3 +
src/add-ons/accelerants/radeon_hd/display.cpp    |    3 +-
src/add-ons/accelerants/radeon_hd/gpu.cpp        |   68 ++++++++++++------
src/add-ons/accelerants/radeon_hd/gpu.h          |    5 +-
src/add-ons/accelerants/radeon_hd/pll.cpp        |   49 ++++++++++---
src/add-ons/accelerants/radeon_hd/pll.h          |    4 +-

----------------------------------------------------------------------------

diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.cpp 
b/src/add-ons/accelerants/radeon_hd/accelerant.cpp
index fa6b9c4..c6bd9f0 100644
--- a/src/add-ons/accelerants/radeon_hd/accelerant.cpp
+++ b/src/add-ons/accelerants/radeon_hd/accelerant.cpp
@@ -255,9 +255,6 @@ radeon_init_accelerant(int device)
        // probe firmware information
        radeon_gpu_probe();
 
-       // disable spread spectrum as it requires lots of extra calculations
-       radeon_gpu_ss_disable();
-
        // program external pll clock
        pll_external_init();
 
diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.h 
b/src/add-ons/accelerants/radeon_hd/accelerant.h
index 6b3d720..4f5379a 100644
--- a/src/add-ons/accelerants/radeon_hd/accelerant.h
+++ b/src/add-ons/accelerants/radeon_hd/accelerant.h
@@ -76,6 +76,8 @@ struct accelerant_info {
        uint32                  displayClockFrequency;
        uint32                  dpExternalClock;
 
+       uint32                  lvdsSpreadSpectrumID;
+
        RingQueue*              ringQueue[RADEON_QUEUE_MAX]; // Ring buffer 
command processor
 };
 
diff --git a/src/add-ons/accelerants/radeon_hd/connector.cpp 
b/src/add-ons/accelerants/radeon_hd/connector.cpp
index 5cc325f..31e303f 100644
--- a/src/add-ons/accelerants/radeon_hd/connector.cpp
+++ b/src/add-ons/accelerants/radeon_hd/connector.cpp
@@ -200,6 +200,9 @@ connector_read_mode_lvds(uint32 connectorIndex, 
display_mode* mode)
                // Store special lvds flags the encoder setup needs
                gConnector[connectorIndex]->lvdsFlags = 
lvdsInfo->info.ucLVDS_Misc;
 
+               // Spread Spectrum ID (in SS table)
+               gInfo->lvdsSpreadSpectrumID = lvdsInfo->info.ucSS_Id;
+
                uint16 flags = B_LENDIAN_TO_HOST_INT16(
                        lvdsInfo->info.sLCDTiming.susModeMiscInfo.usAccess);
 
diff --git a/src/add-ons/accelerants/radeon_hd/display.cpp 
b/src/add-ons/accelerants/radeon_hd/display.cpp
index 8f3c747..4f79734 100644
--- a/src/add-ons/accelerants/radeon_hd/display.cpp
+++ b/src/add-ons/accelerants/radeon_hd/display.cpp
@@ -951,8 +951,7 @@ display_crtc_ss(uint8 crtcID, int command)
        } else if (info.dceMajor >= 2) {
                if ((command == ATOM_DISABLE) || (pll->ssPercentage == 0)
                        || (pll->ssType & ATOM_EXTERNAL_SS_MASK)) {
-                       // TODO: gpu_ss_disable needs pll id
-                       radeon_gpu_ss_disable();
+                       radeon_gpu_ss_control(pll, false);
                        return;
                }
                args.lvds_ss_2.usSpreadSpectrumPercentage
diff --git a/src/add-ons/accelerants/radeon_hd/gpu.cpp 
b/src/add-ons/accelerants/radeon_hd/gpu.cpp
index 85c50ca..3e006b6 100644
--- a/src/add-ons/accelerants/radeon_hd/gpu.cpp
+++ b/src/add-ons/accelerants/radeon_hd/gpu.cpp
@@ -16,6 +16,7 @@
 #include "accelerant.h"
 #include "atom.h"
 #include "bios.h"
+#include "pll.h"
 #include "utility.h"
 
 
@@ -715,7 +716,7 @@ radeon_gpu_ring_boot(uint32 ringType)
 
 
 status_t
-radeon_gpu_ss_disable()
+radeon_gpu_ss_control(pll_info* pll, bool enable)
 {
        TRACE("%s called\n", __func__);
 
@@ -723,25 +724,52 @@ radeon_gpu_ss_disable()
        uint32 ssControl;
 
        if (info.chipsetID >= RADEON_CEDAR) {
-               // PLL1
-               ssControl = Read32(OUT, EVERGREEN_P1PLL_SS_CNTL);
-               ssControl &= ~EVERGREEN_PxPLL_SS_EN;
-               Write32(OUT, EVERGREEN_P1PLL_SS_CNTL, ssControl);
-               // PLL2
-               ssControl = Read32(OUT, EVERGREEN_P2PLL_SS_CNTL);
-               ssControl &= ~EVERGREEN_PxPLL_SS_EN;
-               Write32(OUT, EVERGREEN_P2PLL_SS_CNTL, ssControl);
+               switch (pll->id) {
+                       case ATOM_PPLL1:
+                               // PLL1
+                               ssControl = Read32(OUT, 
EVERGREEN_P1PLL_SS_CNTL);
+                               if (enable)
+                                       ssControl |= EVERGREEN_PxPLL_SS_EN;
+                               else
+                                       ssControl &= ~EVERGREEN_PxPLL_SS_EN;
+                               Write32(OUT, EVERGREEN_P1PLL_SS_CNTL, 
ssControl);
+                               break;
+                       case ATOM_PPLL2:
+                               // PLL2
+                               ssControl = Read32(OUT, 
EVERGREEN_P2PLL_SS_CNTL);
+                               if (enable)
+                                       ssControl |= EVERGREEN_PxPLL_SS_EN;
+                               else
+                                       ssControl &= ~EVERGREEN_PxPLL_SS_EN;
+                               Write32(OUT, EVERGREEN_P2PLL_SS_CNTL, 
ssControl);
+                               break;
+               }
+               // DCPLL, no action
+               return B_OK;
        } else if (info.chipsetID >= RADEON_RS600) {
-               // PLL1
-               ssControl = Read32(OUT, AVIVO_P1PLL_INT_SS_CNTL);
-               ssControl &= ~1;
-               Write32(OUT, AVIVO_P1PLL_INT_SS_CNTL, ssControl);
-               // PLL2
-               ssControl = Read32(OUT, AVIVO_P2PLL_INT_SS_CNTL);
-               ssControl &= ~1;
-               Write32(OUT, AVIVO_P2PLL_INT_SS_CNTL, ssControl);
-       } else
-               return B_ERROR;
+               switch (pll->id) {
+                       case ATOM_PPLL1:
+                               // PLL1
+                               ssControl = Read32(OUT, 
AVIVO_P1PLL_INT_SS_CNTL);
+                               if (enable)
+                                       ssControl |= 1;
+                               else
+                                       ssControl &= ~1;
+                               Write32(OUT, AVIVO_P1PLL_INT_SS_CNTL, 
ssControl);
+                               break;
+                       case ATOM_PPLL2:
+                               // PLL2
+                               ssControl = Read32(OUT, 
AVIVO_P2PLL_INT_SS_CNTL);
+                               if (enable)
+                                       ssControl |= 1;
+                               else
+                                       ssControl &= ~1;
+                               Write32(OUT, AVIVO_P2PLL_INT_SS_CNTL, 
ssControl);
+                               break;
+               }
+               // DCPLL, no action
+               return B_OK;
+       }
 
-       return B_OK;
+       return B_ERROR;
 }
diff --git a/src/add-ons/accelerants/radeon_hd/gpu.h 
b/src/add-ons/accelerants/radeon_hd/gpu.h
index f0c0fb6..d39d7a4 100644
--- a/src/add-ons/accelerants/radeon_hd/gpu.h
+++ b/src/add-ons/accelerants/radeon_hd/gpu.h
@@ -13,6 +13,8 @@
 
 #include <video_configuration.h>
 
+#include "pll.h"
+
 
 // GPU Control registers. These are combined as
 // the registers exist on all models, some flags
@@ -172,7 +174,8 @@ status_t radeon_gpu_mc_idlewait();
 status_t radeon_gpu_mc_setup();
 status_t radeon_gpu_ring_setup();
 status_t radeon_gpu_ring_boot(uint32 ringType);
-status_t radeon_gpu_ss_disable();
+status_t radeon_gpu_ss_control(pll_info* pll, bool enable);
+
 
 
 #endif
diff --git a/src/add-ons/accelerants/radeon_hd/pll.cpp 
b/src/add-ons/accelerants/radeon_hd/pll.cpp
index 79b0cb7..3c0c94fd 100644
--- a/src/add-ons/accelerants/radeon_hd/pll.cpp
+++ b/src/add-ons/accelerants/radeon_hd/pll.cpp
@@ -128,7 +128,7 @@ pll_limit_probe(pll_info* pll)
 
 
 status_t
-pll_dp_ss_probe(pll_info* pll)
+pll_ppll_ss_probe(pll_info* pll, uint32 ssID)
 {
        uint8 tableMajor;
        uint8 tableMinor;
@@ -151,7 +151,7 @@ pll_dp_ss_probe(pll_info* pll)
 
        int i;
        for (i = 0; i < indices; i++) {
-               if (ss_info->asSS_Info[i].ucSS_Id == pll->id) {
+               if (ss_info->asSS_Info[i].ucSS_Id == ssID) {
                        pll->ssPercentage = B_LENDIAN_TO_HOST_INT16(
                                
ss_info->asSS_Info[i].usSpreadSpectrumPercentage);
                        pll->ssType = 
ss_info->asSS_Info[i].ucSpreadSpectrumType;
@@ -175,7 +175,7 @@ pll_dp_ss_probe(pll_info* pll)
 
 
 status_t
-pll_asic_ss_probe(pll_info* pll)
+pll_asic_ss_probe(pll_info* pll, uint32 ssID)
 {
        uint8 tableMajor;
        uint8 tableMinor;
@@ -207,7 +207,7 @@ pll_asic_ss_probe(pll_info* pll)
 
                        for (i = 0; i < indices; i++) {
                                if 
(ss_info->info.asSpreadSpectrum[i].ucClockIndication
-                                       != pll->id) {
+                                       != ssID) {
                                        continue;
                                }
                                TRACE("%s: ss match found\n", __func__);
@@ -234,7 +234,7 @@ pll_asic_ss_probe(pll_info* pll)
 
                        for (i = 0; i < indices; i++) {
                                if 
(ss_info->info_2.asSpreadSpectrum[i].ucClockIndication
-                                       != pll->id) {
+                                       != ssID) {
                                        continue;
                                }
                                TRACE("%s: ss match found\n", __func__);
@@ -262,7 +262,7 @@ pll_asic_ss_probe(pll_info* pll)
 
                        for (i = 0; i < indices; i++) {
                                if 
(ss_info->info_3.asSpreadSpectrum[i].ucClockIndication
-                                       != pll->id) {
+                                       != ssID) {
                                        continue;
                                }
                                TRACE("%s: ss match found\n", __func__);
@@ -492,6 +492,11 @@ pll_setup_flags(pll_info* pll, uint8 crtcID)
 
        if ((encoderFlags & ATOM_DEVICE_TV_SUPPORT) != 0)
                pll->flags |= PLL_PREFER_CLOSEST_LOWER;
+
+       if ((info.chipsetFlags & CHIP_APU) != 0) {
+               // Use fractional feedback on APU's
+               pll->flags |= PLL_USE_FRAC_FB_DIV;
+       }
 }
 
 
@@ -657,12 +662,38 @@ pll_set(display_mode* mode, uint8 crtcID)
        pll_compute(pll);
                // compute dividers
 
-       pll_asic_ss_probe(pll);
-               // probe spread spectrum metrics (TODO: pll_dp_ss_probe)
+       radeon_shared_info &info = *gInfo->shared_info;
+       pll->ssType = 0;
+
+       switch (display_get_encoder_mode(connectorIndex)) {
+               case ATOM_ENCODER_MODE_DP_MST:
+               case ATOM_ENCODER_MODE_DP:
+                       if (info.dceMajor >= 4)
+                               pll_asic_ss_probe(pll, ASIC_INTERNAL_SS_ON_DP);
+                       else {
+                               // TODO: DP Clock == 1.62Ghz?
+                               pll_ppll_ss_probe(pll, ATOM_DP_SS_ID1);
+                       }
+                       break;
+               case ATOM_ENCODER_MODE_LVDS:
+                       if (info.dceMajor >= 4)
+                               pll_asic_ss_probe(pll, 
gInfo->lvdsSpreadSpectrumID);
+                       else
+                               pll_ppll_ss_probe(pll, 
gInfo->lvdsSpreadSpectrumID);
+                       break;
+               case ATOM_ENCODER_MODE_DVI:
+                       if (info.dceMajor >= 4)
+                               pll_asic_ss_probe(pll, 
ASIC_INTERNAL_SS_ON_TMDS);
+                       break;
+               case ATOM_ENCODER_MODE_HDMI:
+                       if (info.dceMajor >= 4)
+                               pll_asic_ss_probe(pll, 
ASIC_INTERNAL_SS_ON_HDMI);
+                       break;
+       }
+
        display_crtc_ss(crtcID, ATOM_DISABLE);
                // disable ss
 
-
        uint8 tableMajor;
        uint8 tableMinor;
 
diff --git a/src/add-ons/accelerants/radeon_hd/pll.h 
b/src/add-ons/accelerants/radeon_hd/pll.h
index c04f042..899aca3 100644
--- a/src/add-ons/accelerants/radeon_hd/pll.h
+++ b/src/add-ons/accelerants/radeon_hd/pll.h
@@ -103,8 +103,8 @@ status_t pll_adjust(pll_info* pll, display_mode* mode, 
uint8 crtcID);
 status_t pll_compute(pll_info* pll);
 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_ppll_ss_probe(pll_info* pll, uint32 ssID);
+status_t pll_asic_ss_probe(pll_info* pll, uint32 ssID);
 status_t pll_set(display_mode* mode, uint8 crtcID);
 status_t pll_pick(uint32 connectorIndex);
 


Other related posts:

  • » [haiku-commits] haiku: hrev44489 - src/add-ons/accelerants/radeon_hd - kallisti5