summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c26
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h14
4 files changed, 52 insertions, 7 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 037e3260cb7c..176f424975ac 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -501,9 +501,21 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
(rdev->family == CHIP_RS740))
pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
RADEON_PLL_PREFER_CLOSEST_LOWER);
- } else
+
+ if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */
+ pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+ } else {
pll->flags |= RADEON_PLL_LEGACY;
+ if (mode->clock > 200000) /* range limits??? */
+ pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+
+ }
+
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc == crtc) {
radeon_encoder = to_radeon_encoder(encoder);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 6c6846cdaa30..9151ded9c1cd 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -611,8 +611,7 @@ void radeon_compute_pll(struct radeon_pll *pll,
if ((best_vco == 0 && error < best_error) ||
(best_vco != 0 &&
((best_error > 100 && error < best_error - 100) ||
- (abs(error - best_error) < 100 &&
- vco_diff < best_vco_diff)))) {
+ (abs(error - best_error) < 100 && vco_diff < best_vco_diff)))) {
best_post_div = post_div;
best_ref_div = ref_div;
best_feedback_div = feedback_div;
@@ -620,6 +619,29 @@ void radeon_compute_pll(struct radeon_pll *pll,
best_freq = current_freq;
best_error = error;
best_vco_diff = vco_diff;
+ } else if (current_freq == freq) {
+ if (best_freq == -1) {
+ best_post_div = post_div;
+ best_ref_div = ref_div;
+ best_feedback_div = feedback_div;
+ best_frac_feedback_div = frac_feedback_div;
+ best_freq = current_freq;
+ best_error = error;
+ best_vco_diff = vco_diff;
+ } else if (((pll->flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
+ ((pll->flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
+ ((pll->flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
+ ((pll->flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
+ ((pll->flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
+ ((pll->flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
+ best_post_div = post_div;
+ best_ref_div = ref_div;
+ best_feedback_div = feedback_div;
+ best_frac_feedback_div = frac_feedback_div;
+ best_freq = current_freq;
+ best_error = error;
+ best_vco_diff = vco_diff;
+ }
}
if (current_freq < freq)
min_frac_feed_div = frac_feedback_div + 1;
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index c0bf8b7cc56c..f8dae717acc8 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -745,6 +745,11 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
pll->flags = RADEON_PLL_LEGACY;
+ if (mode->clock > 200000) /* range limits??? */
+ pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc == crtc) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 3cda63e37b28..d58b003e9a04 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -139,10 +139,16 @@ struct radeon_tmds_pll {
#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
#define RADEON_PLL_USE_REF_DIV (1 << 2)
#define RADEON_PLL_LEGACY (1 << 3)
-#define RADEON_PLL_USE_FRAC_FB_DIV (1 << 4)
-#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 5)
-#define RADEON_PLL_USE_POST_DIV (1 << 6)
-#define RADEON_PLL_IS_LCD (1 << 7)
+#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4)
+#define RADEON_PLL_PREFER_HIGH_REF_DIV (1 << 5)
+#define RADEON_PLL_PREFER_LOW_FB_DIV (1 << 6)
+#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)
+#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
+#define RADEON_PLL_USE_POST_DIV (1 << 12)
+#define RADEON_PLL_IS_LCD (1 << 13)
struct radeon_pll {
/* reference frequency */