aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-03-08 12:55:16 -0500
committerDave Airlie <airlied@redhat.com>2010-03-14 19:56:46 -0400
commit86cb2bbfda2cf402aee46779ee90bbb7d915482b (patch)
tree341bcd42fe9bc49498905f97f2e61b2def21f22b /drivers/gpu
parentb792210e7d1f9fb102061e2016da96cf2ad5cdbd (diff)
drm/radeon/kms: use lcd pll limits when available
The bios has alternate pll output limits for LCD panels. If available, use these for pll divider calculations. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c37
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h3
5 files changed, 52 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 0c676696a0dd..a8cd637d92fa 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -525,6 +525,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
525 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { 525 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
526 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 526 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
527 pll->algo = dig->pll_algo; 527 pll->algo = dig->pll_algo;
528 pll->flags |= RADEON_PLL_IS_LCD;
528 } 529 }
529 } else { 530 } else {
530 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) 531 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 93783b15c81d..e4540b2b859c 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -887,6 +887,20 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
887 p1pll->pll_out_max = 887 p1pll->pll_out_max =
888 le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); 888 le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
889 889
890 if (crev >= 4) {
891 p1pll->lcd_pll_out_min =
892 le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
893 if (p1pll->lcd_pll_out_min == 0)
894 p1pll->lcd_pll_out_min = p1pll->pll_out_min;
895 p1pll->lcd_pll_out_max =
896 le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100;
897 if (p1pll->lcd_pll_out_max == 0)
898 p1pll->lcd_pll_out_max = p1pll->pll_out_max;
899 } else {
900 p1pll->lcd_pll_out_min = p1pll->pll_out_min;
901 p1pll->lcd_pll_out_max = p1pll->pll_out_max;
902 }
903
890 if (p1pll->pll_out_min == 0) { 904 if (p1pll->pll_out_min == 0) {
891 if (ASIC_IS_AVIVO(rdev)) 905 if (ASIC_IS_AVIVO(rdev))
892 p1pll->pll_out_min = 64800; 906 p1pll->pll_out_min = 64800;
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 69af81d9f5ae..30a84ae56811 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -633,6 +633,8 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
633 p1pll->reference_div = RBIOS16(pll_info + 0x10); 633 p1pll->reference_div = RBIOS16(pll_info + 0x10);
634 p1pll->pll_out_min = RBIOS32(pll_info + 0x12); 634 p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
635 p1pll->pll_out_max = RBIOS32(pll_info + 0x16); 635 p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
636 p1pll->lcd_pll_out_min = p1pll->pll_out_min;
637 p1pll->lcd_pll_out_max = p1pll->pll_out_max;
636 638
637 if (rev > 9) { 639 if (rev > 9) {
638 p1pll->pll_in_min = RBIOS32(pll_info + 0x36); 640 p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index ba8d806dcf39..ff5f09953c0a 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -469,10 +469,19 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
469 uint32_t best_error = 0xffffffff; 469 uint32_t best_error = 0xffffffff;
470 uint32_t best_vco_diff = 1; 470 uint32_t best_vco_diff = 1;
471 uint32_t post_div; 471 uint32_t post_div;
472 u32 pll_out_min, pll_out_max;
472 473
473 DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); 474 DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
474 freq = freq * 1000; 475 freq = freq * 1000;
475 476
477 if (pll->flags & RADEON_PLL_IS_LCD) {
478 pll_out_min = pll->lcd_pll_out_min;
479 pll_out_max = pll->lcd_pll_out_max;
480 } else {
481 pll_out_min = pll->pll_out_min;
482 pll_out_max = pll->pll_out_max;
483 }
484
476 if (pll->flags & RADEON_PLL_USE_REF_DIV) 485 if (pll->flags & RADEON_PLL_USE_REF_DIV)
477 min_ref_div = max_ref_div = pll->reference_div; 486 min_ref_div = max_ref_div = pll->reference_div;
478 else { 487 else {
@@ -536,10 +545,10 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
536 tmp = (uint64_t)pll->reference_freq * feedback_div; 545 tmp = (uint64_t)pll->reference_freq * feedback_div;
537 vco = radeon_div(tmp, ref_div); 546 vco = radeon_div(tmp, ref_div);
538 547
539 if (vco < pll->pll_out_min) { 548 if (vco < pll_out_min) {
540 min_feed_div = feedback_div + 1; 549 min_feed_div = feedback_div + 1;
541 continue; 550 continue;
542 } else if (vco > pll->pll_out_max) { 551 } else if (vco > pll_out_max) {
543 max_feed_div = feedback_div; 552 max_feed_div = feedback_div;
544 continue; 553 continue;
545 } 554 }
@@ -675,6 +684,15 @@ calc_fb_ref_div(struct radeon_pll *pll,
675{ 684{
676 fixed20_12 ffreq, max_error, error, pll_out, a; 685 fixed20_12 ffreq, max_error, error, pll_out, a;
677 u32 vco; 686 u32 vco;
687 u32 pll_out_min, pll_out_max;
688
689 if (pll->flags & RADEON_PLL_IS_LCD) {
690 pll_out_min = pll->lcd_pll_out_min;
691 pll_out_max = pll->lcd_pll_out_max;
692 } else {
693 pll_out_min = pll->pll_out_min;
694 pll_out_max = pll->pll_out_max;
695 }
678 696
679 ffreq.full = rfixed_const(freq); 697 ffreq.full = rfixed_const(freq);
680 /* max_error = ffreq * 0.0025; */ 698 /* max_error = ffreq * 0.0025; */
@@ -686,7 +704,7 @@ calc_fb_ref_div(struct radeon_pll *pll,
686 vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac)); 704 vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac));
687 vco = vco / ((*ref_div) * 10); 705 vco = vco / ((*ref_div) * 10);
688 706
689 if ((vco < pll->pll_out_min) || (vco > pll->pll_out_max)) 707 if ((vco < pll_out_min) || (vco > pll_out_max))
690 continue; 708 continue;
691 709
692 /* pll_out = vco / post_div; */ 710 /* pll_out = vco / post_div; */
@@ -714,6 +732,15 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
714{ 732{
715 u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0; 733 u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0;
716 u32 best_freq = 0, vco_frequency; 734 u32 best_freq = 0, vco_frequency;
735 u32 pll_out_min, pll_out_max;
736
737 if (pll->flags & RADEON_PLL_IS_LCD) {
738 pll_out_min = pll->lcd_pll_out_min;
739 pll_out_max = pll->lcd_pll_out_max;
740 } else {
741 pll_out_min = pll->pll_out_min;
742 pll_out_max = pll->pll_out_max;
743 }
717 744
718 /* freq = freq / 10; */ 745 /* freq = freq / 10; */
719 do_div(freq, 10); 746 do_div(freq, 10);
@@ -724,7 +751,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
724 goto done; 751 goto done;
725 752
726 vco_frequency = freq * post_div; 753 vco_frequency = freq * post_div;
727 if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) 754 if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
728 goto done; 755 goto done;
729 756
730 if (pll->flags & RADEON_PLL_USE_REF_DIV) { 757 if (pll->flags & RADEON_PLL_USE_REF_DIV) {
@@ -749,7 +776,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
749 continue; 776 continue;
750 777
751 vco_frequency = freq * post_div; 778 vco_frequency = freq * post_div;
752 if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) 779 if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
753 continue; 780 continue;
754 if (pll->flags & RADEON_PLL_USE_REF_DIV) { 781 if (pll->flags & RADEON_PLL_USE_REF_DIV) {
755 ref_div = pll->reference_div; 782 ref_div = pll->reference_div;
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 1702b820aa4d..b868ffad8beb 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -129,6 +129,7 @@ struct radeon_tmds_pll {
129#define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10) 129#define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10)
130#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) 130#define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
131#define RADEON_PLL_USE_POST_DIV (1 << 12) 131#define RADEON_PLL_USE_POST_DIV (1 << 12)
132#define RADEON_PLL_IS_LCD (1 << 13)
132 133
133/* pll algo */ 134/* pll algo */
134enum radeon_pll_algo { 135enum radeon_pll_algo {
@@ -149,6 +150,8 @@ struct radeon_pll {
149 uint32_t pll_in_max; 150 uint32_t pll_in_max;
150 uint32_t pll_out_min; 151 uint32_t pll_out_min;
151 uint32_t pll_out_max; 152 uint32_t pll_out_max;
153 uint32_t lcd_pll_out_min;
154 uint32_t lcd_pll_out_max;
152 uint32_t best_vco; 155 uint32_t best_vco;
153 156
154 /* divider limits */ 157 /* divider limits */