aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-02-02 12:05:01 -0500
committerDave Airlie <airlied@redhat.com>2010-02-08 18:31:21 -0500
commit7c27f87d2bde885e9bcda74c208a7aae8bef8e76 (patch)
tree5490fe9d6ed83bc36c2ac3da7dedee4de3730806 /drivers/gpu/drm/radeon
parent4612dc97991a09e1a9e4d5d981e16589d7cb150c (diff)
drm/radeon/kms: rework pll algo selection
Rework the pll algo selection so that the pll algo in use can be selected more easily. This allows us to select different pll divider selection algos for specific monitors that work better with one algo or the other. This is needed for the next patch which adds an LVDS pll quirk for a specific notebook. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c28
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c49
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h18
5 files changed, 70 insertions, 34 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index af464e351fbd..4bae5511ea60 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -424,6 +424,15 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
424 /* reset the pll flags */ 424 /* reset the pll flags */
425 pll->flags = 0; 425 pll->flags = 0;
426 426
427 /* select the PLL algo */
428 if (ASIC_IS_AVIVO(rdev)) {
429 if (radeon_new_pll)
430 pll->algo = PLL_ALGO_AVIVO;
431 else
432 pll->algo = PLL_ALGO_LEGACY;
433 } else
434 pll->algo = PLL_ALGO_LEGACY;
435
427 if (ASIC_IS_AVIVO(rdev)) { 436 if (ASIC_IS_AVIVO(rdev)) {
428 if ((rdev->family == CHIP_RS600) || 437 if ((rdev->family == CHIP_RS600) ||
429 (rdev->family == CHIP_RS690) || 438 (rdev->family == CHIP_RS690) ||
@@ -452,6 +461,11 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
452 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ 461 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
453 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) 462 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
454 adjusted_clock = mode->clock * 2; 463 adjusted_clock = mode->clock * 2;
464 /* LVDS PLL quirks */
465 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
466 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
467 pll->algo = dig->pll_algo;
468 }
455 } else { 469 } else {
456 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) 470 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
457 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; 471 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
@@ -550,18 +564,8 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
550 /* adjust pixel clock as needed */ 564 /* adjust pixel clock as needed */
551 adjusted_clock = atombios_adjust_pll(crtc, mode, pll); 565 adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
552 566
553 if (ASIC_IS_AVIVO(rdev)) { 567 radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
554 if (radeon_new_pll) 568 &ref_div, &post_div);
555 radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
556 &fb_div, &frac_fb_div,
557 &ref_div, &post_div);
558 else
559 radeon_compute_pll(pll, adjusted_clock, &pll_clock,
560 &fb_div, &frac_fb_div,
561 &ref_div, &post_div);
562 } else
563 radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
564 &ref_div, &post_div);
565 569
566 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); 570 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
567 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 571 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index fa82ca74324e..667f099e84af 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1143,6 +1143,14 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
1143 1143
1144 lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); 1144 lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id);
1145 1145
1146 if (ASIC_IS_AVIVO(rdev)) {
1147 if (radeon_new_pll)
1148 lvds->pll_algo = PLL_ALGO_AVIVO;
1149 else
1150 lvds->pll_algo = PLL_ALGO_LEGACY;
1151 } else
1152 lvds->pll_algo = PLL_ALGO_LEGACY;
1153
1146 encoder->native_mode = lvds->native_mode; 1154 encoder->native_mode = lvds->native_mode;
1147 } 1155 }
1148 return lvds; 1156 return lvds;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 79634da7c311..62fe66c02341 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -405,13 +405,13 @@ static inline uint32_t radeon_div(uint64_t n, uint32_t d)
405 return n; 405 return n;
406} 406}
407 407
408void radeon_compute_pll(struct radeon_pll *pll, 408static void radeon_compute_pll_legacy(struct radeon_pll *pll,
409 uint64_t freq, 409 uint64_t freq,
410 uint32_t *dot_clock_p, 410 uint32_t *dot_clock_p,
411 uint32_t *fb_div_p, 411 uint32_t *fb_div_p,
412 uint32_t *frac_fb_div_p, 412 uint32_t *frac_fb_div_p,
413 uint32_t *ref_div_p, 413 uint32_t *ref_div_p,
414 uint32_t *post_div_p) 414 uint32_t *post_div_p)
415{ 415{
416 uint32_t min_ref_div = pll->min_ref_div; 416 uint32_t min_ref_div = pll->min_ref_div;
417 uint32_t max_ref_div = pll->max_ref_div; 417 uint32_t max_ref_div = pll->max_ref_div;
@@ -571,13 +571,13 @@ void radeon_compute_pll(struct radeon_pll *pll,
571 *post_div_p = best_post_div; 571 *post_div_p = best_post_div;
572} 572}
573 573
574void radeon_compute_pll_avivo(struct radeon_pll *pll, 574static void radeon_compute_pll_avivo(struct radeon_pll *pll,
575 uint64_t freq, 575 uint64_t freq,
576 uint32_t *dot_clock_p, 576 uint32_t *dot_clock_p,
577 uint32_t *fb_div_p, 577 uint32_t *fb_div_p,
578 uint32_t *frac_fb_div_p, 578 uint32_t *frac_fb_div_p,
579 uint32_t *ref_div_p, 579 uint32_t *ref_div_p,
580 uint32_t *post_div_p) 580 uint32_t *post_div_p)
581{ 581{
582 fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq; 582 fixed20_12 m, n, frac_n, p, f_vco, f_pclk, best_freq;
583 fixed20_12 pll_out_max, pll_out_min; 583 fixed20_12 pll_out_max, pll_out_min;
@@ -662,6 +662,27 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
662 DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p); 662 DRM_DEBUG("%u %d.%d, %d, %d\n", *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
663} 663}
664 664
665void radeon_compute_pll(struct radeon_pll *pll,
666 uint64_t freq,
667 uint32_t *dot_clock_p,
668 uint32_t *fb_div_p,
669 uint32_t *frac_fb_div_p,
670 uint32_t *ref_div_p,
671 uint32_t *post_div_p)
672{
673 switch (pll->algo) {
674 case PLL_ALGO_AVIVO:
675 radeon_compute_pll_avivo(pll, freq, dot_clock_p, fb_div_p,
676 frac_fb_div_p, ref_div_p, post_div_p);
677 break;
678 case PLL_ALGO_LEGACY:
679 default:
680 radeon_compute_pll_legacy(pll, freq, dot_clock_p, fb_div_p,
681 frac_fb_div_p, ref_div_p, post_div_p);
682 break;
683 }
684}
685
665static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) 686static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
666{ 687{
667 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); 688 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index d6d69bb2ecea..83d4dbd6d067 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -703,6 +703,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
703 pll = &rdev->clock.p1pll; 703 pll = &rdev->clock.p1pll;
704 704
705 pll->flags = RADEON_PLL_LEGACY; 705 pll->flags = RADEON_PLL_LEGACY;
706 pll->algo = PLL_ALGO_LEGACY;
706 707
707 if (mode->clock > 200000) /* range limits??? */ 708 if (mode->clock > 200000) /* range limits??? */
708 pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; 709 pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 71439ba2feeb..d1e859d1dbf9 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -113,6 +113,7 @@ struct radeon_tmds_pll {
113 113
114#define RADEON_MAX_BIOS_CONNECTOR 16 114#define RADEON_MAX_BIOS_CONNECTOR 16
115 115
116/* pll flags */
116#define RADEON_PLL_USE_BIOS_DIVS (1 << 0) 117#define RADEON_PLL_USE_BIOS_DIVS (1 << 0)
117#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1) 118#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
118#define RADEON_PLL_USE_REF_DIV (1 << 2) 119#define RADEON_PLL_USE_REF_DIV (1 << 2)
@@ -127,6 +128,12 @@ struct radeon_tmds_pll {
127#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) 128#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
128#define RADEON_PLL_USE_POST_DIV (1 << 12) 129#define RADEON_PLL_USE_POST_DIV (1 << 12)
129 130
131/* pll algo */
132enum radeon_pll_algo {
133 PLL_ALGO_LEGACY,
134 PLL_ALGO_AVIVO
135};
136
130struct radeon_pll { 137struct radeon_pll {
131 /* reference frequency */ 138 /* reference frequency */
132 uint32_t reference_freq; 139 uint32_t reference_freq;
@@ -157,6 +164,8 @@ struct radeon_pll {
157 164
158 /* pll id */ 165 /* pll id */
159 uint32_t id; 166 uint32_t id;
167 /* pll algo */
168 enum radeon_pll_algo algo;
160}; 169};
161 170
162struct i2c_algo_radeon_data { 171struct i2c_algo_radeon_data {
@@ -309,6 +318,7 @@ struct radeon_encoder_atom_dig {
309 /* atom lvds */ 318 /* atom lvds */
310 uint32_t lvds_misc; 319 uint32_t lvds_misc;
311 uint16_t panel_pwr_delay; 320 uint16_t panel_pwr_delay;
321 enum radeon_pll_algo pll_algo;
312 struct radeon_atom_ss *ss; 322 struct radeon_atom_ss *ss;
313 /* panel mode */ 323 /* panel mode */
314 struct drm_display_mode native_mode; 324 struct drm_display_mode native_mode;
@@ -439,14 +449,6 @@ extern void radeon_compute_pll(struct radeon_pll *pll,
439 uint32_t *ref_div_p, 449 uint32_t *ref_div_p,
440 uint32_t *post_div_p); 450 uint32_t *post_div_p);
441 451
442extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
443 uint64_t freq,
444 uint32_t *dot_clock_p,
445 uint32_t *fb_div_p,
446 uint32_t *frac_fb_div_p,
447 uint32_t *ref_div_p,
448 uint32_t *post_div_p);
449
450extern void radeon_setup_encoder_clones(struct drm_device *dev); 452extern void radeon_setup_encoder_clones(struct drm_device *dev);
451 453
452struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); 454struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index);