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;