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

  • From: julian.harnath@xxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 2 Mar 2014 16:26:46 +0100 (CET)

hrev46957 adds 2 changesets to branch 'master'
old head: edf15527703bef4301932864d601f1e055adc6e0
new head: de26f2e76291e3e6953d950709617c57a76bbeaa
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=de26f2e+%5Eedf1552

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

34d3dff: Fix feedback divider value approximation
  
  * The rounding algorithm here expects to start with the 2 digits
    after the decimal point in pll->feedbackDivFrac. Multiplying with
    1000 instead of 100 filled it with 3 digits.
    The last step then set the fractional part to zero because it was
    still too large.

de26f2e: Make code a bit easier to read, add some comments
  
  * No functional change intended

                          [ Julian Harnath <julian.harnath@xxxxxxxxxxxxxx> ]

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

1 file changed, 36 insertions(+), 8 deletions(-)
src/add-ons/accelerants/radeon_hd/pll.cpp | 44 ++++++++++++++++++++++-----

############################################################################

Commit:      34d3dff3f5caef59b67669535a6f535dcaad7827
URL:         http://cgit.haiku-os.org/haiku/commit/?id=34d3dff
Author:      Julian Harnath <julian.harnath@xxxxxxxxxxxxxx>
Date:        Sun Mar  2 15:20:07 2014 UTC

Fix feedback divider value approximation

* The rounding algorithm here expects to start with the 2 digits
  after the decimal point in pll->feedbackDivFrac. Multiplying with
  1000 instead of 100 filled it with 3 digits.
  The last step then set the fractional part to zero because it was
  still too large.

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

diff --git a/src/add-ons/accelerants/radeon_hd/pll.cpp 
b/src/add-ons/accelerants/radeon_hd/pll.cpp
index ec8a1f0..ce46b6d 100644
--- a/src/add-ons/accelerants/radeon_hd/pll.cpp
+++ b/src/add-ons/accelerants/radeon_hd/pll.cpp
@@ -374,7 +374,7 @@ pll_compute(pll_info* pll)
                        pll->feedbackDiv = pll->minFeedbackDiv;
 
                pll->feedbackDivFrac
-                       = (1000 * pll->feedbackDivFrac) / pll->referenceFreq;
+                       = (100 * pll->feedbackDivFrac) / pll->referenceFreq;
 
                if (pll->feedbackDivFrac >= 5) {
                        pll->feedbackDivFrac -= 5;

############################################################################

Revision:    hrev46957
Commit:      de26f2e76291e3e6953d950709617c57a76bbeaa
URL:         http://cgit.haiku-os.org/haiku/commit/?id=de26f2e
Author:      Julian Harnath <julian.harnath@xxxxxxxxxxxxxx>
Date:        Sun Mar  2 15:23:42 2014 UTC

Make code a bit easier to read, add some comments

* No functional change intended

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

diff --git a/src/add-ons/accelerants/radeon_hd/pll.cpp 
b/src/add-ons/accelerants/radeon_hd/pll.cpp
index ce46b6d..bc963b8 100644
--- a/src/add-ons/accelerants/radeon_hd/pll.cpp
+++ b/src/add-ons/accelerants/radeon_hd/pll.cpp
@@ -45,6 +45,28 @@ extern "C" void _sPrintf(const char* format, ...);
 //     AtomBIOS:       16200  * 10 Khz 0.162 * 10 Ghz
 
 
+/* The PLL allows to synthesize a clock signal with a range of frequencies
+ * based on a single input reference clock signal. It uses several dividers
+ * to create a rational factor multiple of the input frequency.
+ *
+ * The reference clock signal frequency is pll_info::referenceFreq (in kHz ? 
TODO).
+ * It is then, one after another...
+ *   (1) divided by the (integer) reference divider (pll_info::referenceDiv).
+ *   (2) multiplied by the fractional feedback divider, which sits in the
+ *       PLL's feedback loop and thus multiplies the frequency. It allows
+ *       using a rational number factor of the form "x.y", with
+ *       x = pll_info::feedbackDiv and y = pll_info::feedbackDivFrac.
+ *   (3) divided by the (integer) post divider (pll_info::postDiv).
+ *   Allowed ranges are given in the pll_info min/max values.
+ *
+ *   The resulting output pixel clock frequency is then:
+ * 
+ *                            feedbackDiv + (feedbackDivFrac/10)
+ *   f_out = referenceFreq * ------------------------------------
+ *                                  referenceDiv * postDiv
+ */
+
+
 status_t
 pll_limit_probe(pll_info* pll)
 {
@@ -342,16 +364,20 @@ pll_compute_post_divider(pll_info* pll)
 }
 
 
+/*! Compute values for the fractional feedback divider to match the desired
+ *  pixel clock frequency as closely as possible. Reference and post divider
+ *  values are already filled in (if used).
+ */
 status_t
 pll_compute(pll_info* pll)
 {
        pll_compute_post_divider(pll);
 
-       uint32 targetClock = pll->adjustedClock;
+       const uint32 targetClock = pll->adjustedClock;
 
        pll->feedbackDiv = 0;
        pll->feedbackDivFrac = 0;
-       uint32 referenceFrequency = pll->referenceFreq;
+       const uint32 referenceFrequency = pll->referenceFreq;
 
        if ((pll->flags & PLL_USE_REF_DIV) != 0) {
                TRACE("%s: using AtomBIOS reference divider\n", __func__);
@@ -363,19 +389,21 @@ pll_compute(pll_info* pll)
        if ((pll->flags & PLL_USE_FRAC_FB_DIV) != 0) {
                TRACE("%s: using AtomBIOS fractional feedback divider\n", 
__func__);
 
-               uint32 tmp = pll->postDiv * pll->referenceDiv;
-               tmp *= targetClock;
-               pll->feedbackDiv = tmp / pll->referenceFreq;
-               pll->feedbackDivFrac = tmp % pll->referenceFreq;
+               const uint32 numerator = pll->postDiv * pll->referenceDiv
+                       * targetClock;
+               pll->feedbackDiv = numerator / referenceFrequency;
+               pll->feedbackDivFrac = numerator % referenceFrequency;
 
                if (pll->feedbackDiv > pll->maxFeedbackDiv)
                        pll->feedbackDiv = pll->maxFeedbackDiv;
                else if (pll->feedbackDiv < pll->minFeedbackDiv)
                        pll->feedbackDiv = pll->minFeedbackDiv;
 
+               // Put first 2 digits after the decimal point into 
feedbackDivFrac
                pll->feedbackDivFrac
-                       = (100 * pll->feedbackDivFrac) / pll->referenceFreq;
-
+                       = (100 * pll->feedbackDivFrac) / referenceFrequency;
+               
+               // Now round it to one digit
                if (pll->feedbackDivFrac >= 5) {
                        pll->feedbackDivFrac -= 5;
                        pll->feedbackDivFrac /= 10;


Other related posts:

  • » [haiku-commits] haiku: hrev46957 - src/add-ons/accelerants/radeon_hd - julian . harnath