diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-02-02 12:05:01 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-02-08 18:31:21 -0500 |
commit | 7c27f87d2bde885e9bcda74c208a7aae8bef8e76 (patch) | |
tree | 5490fe9d6ed83bc36c2ac3da7dedee4de3730806 /drivers/gpu/drm/radeon | |
parent | 4612dc97991a09e1a9e4d5d981e16589d7cb150c (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.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 18 |
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 | ||
408 | void radeon_compute_pll(struct radeon_pll *pll, | 408 | static 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 | ||
574 | void radeon_compute_pll_avivo(struct radeon_pll *pll, | 574 | static 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 | ||
665 | void 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 | |||
665 | static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | 686 | static 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 */ | ||
132 | enum radeon_pll_algo { | ||
133 | PLL_ALGO_LEGACY, | ||
134 | PLL_ALGO_AVIVO | ||
135 | }; | ||
136 | |||
130 | struct radeon_pll { | 137 | struct 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 | ||
162 | struct i2c_algo_radeon_data { | 171 | struct 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 | ||
442 | extern 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 | |||
450 | extern void radeon_setup_encoder_clones(struct drm_device *dev); | 452 | extern void radeon_setup_encoder_clones(struct drm_device *dev); |
451 | 453 | ||
452 | struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); | 454 | struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index); |