summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/radeon.h1
-rw-r--r--src/radeon_crtc.c25
2 files changed, 17 insertions, 9 deletions
diff --git a/src/radeon.h b/src/radeon.h
index 24a592c7..706f26ef 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -261,6 +261,7 @@ typedef struct {
#define RADEON_PLL_PREFER_HIGH_FB_DIV (1 << 7)
#define RADEON_PLL_PREFER_LOW_POST_DIV (1 << 8)
#define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9)
+#define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10)
typedef struct {
uint16_t reference_freq;
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 51f361d9..4b687708 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -136,6 +136,8 @@ RADEONComputePLL(RADEONPLLPtr pll,
{
uint32_t min_ref_div = pll->min_ref_div;
uint32_t max_ref_div = pll->max_ref_div;
+ uint32_t min_fractional_feed_div = 0;
+ uint32_t max_fractional_feed_div = 0;
uint32_t best_vco = pll->best_vco;
uint32_t best_post_div = 1;
uint32_t best_ref_div = 1;
@@ -164,6 +166,11 @@ RADEONComputePLL(RADEONPLLPtr pll,
}
}
+ if (flags & RADEON_PLL_USE_FRAC_FB_DIV) {
+ min_fractional_feed_div = pll->min_frac_feedback_div;
+ max_fractional_feed_div = pll->max_frac_feedback_div;
+ }
+
for (post_div = pll->min_post_div; post_div <= pll->max_post_div; ++post_div) {
uint32_t ref_div;
@@ -191,10 +198,10 @@ RADEONComputePLL(RADEONPLLPtr pll,
while (min_feed_div < max_feed_div) {
uint32_t vco;
- uint32_t min_frac_feed_div = pll->min_frac_feedback_div;
- uint32_t max_frac_feed_div = pll->max_frac_feedback_div+1;
- uint32_t frac_feedback_div;
- CARD64 tmp;
+ uint32_t min_frac_feed_div = min_fractional_feed_div;
+ uint32_t max_frac_feed_div = max_fractional_feed_div+1;
+ uint32_t frac_feedback_div;
+ CARD64 tmp;
feedback_div = (min_feed_div+max_feed_div)/2;
@@ -211,8 +218,8 @@ RADEONComputePLL(RADEONPLLPtr pll,
while (min_frac_feed_div < max_frac_feed_div) {
frac_feedback_div = (min_frac_feed_div+max_frac_feed_div)/2;
- tmp = (CARD64)pll->reference_freq * 10000 * feedback_div;
- tmp += (CARD64)pll->reference_freq * 1000 * frac_feedback_div;
+ tmp = (CARD64)pll->reference_freq * 10000 * feedback_div;
+ tmp += (CARD64)pll->reference_freq * 1000 * frac_feedback_div;
current_freq = RADEONDiv(tmp, ref_div * post_div);
error = abs(current_freq - freq);
@@ -254,9 +261,9 @@ RADEONComputePLL(RADEONPLLPtr pll,
}
}
if (current_freq < freq)
- min_frac_feed_div = frac_feedback_div+1;
- else
- max_frac_feed_div = frac_feedback_div;
+ min_frac_feed_div = frac_feedback_div+1;
+ else
+ max_frac_feed_div = frac_feedback_div;
}
if (current_freq < freq)
min_feed_div = feedback_div+1;