aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-09-29 11:37:41 -0400
committerDave Airlie <airlied@redhat.com>2010-10-05 21:46:25 -0400
commit48dfaaeb6637240af3089bf9b7a00a6cf24e0182 (patch)
tree7f82ed838581ff1f8db41e4a9d3c41cb47dc46cc /drivers
parentf28488c282d8916b9b6190cc41714815bbaf97d5 (diff)
drm/radeon/kms: remove new pll algo
The recent changes to the old algo (prefer high post div) coupled with the range and precision limitations of using fixed point with the new algo make the new algo less useful. So drop the new algo. This should work as well or better than the old new/old combinations and simplifies the code a lot. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=30218 among others. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c15
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c222
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h9
7 files changed, 9 insertions, 278 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index ca04a1bdb75b..89600e344230 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -482,19 +482,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
482 /* reset the pll flags */ 482 /* reset the pll flags */
483 pll->flags = 0; 483 pll->flags = 0;
484 484
485 /* select the PLL algo */
486 if (ASIC_IS_AVIVO(rdev)) {
487 if (radeon_new_pll == 0)
488 pll->algo = PLL_ALGO_LEGACY;
489 else
490 pll->algo = PLL_ALGO_NEW;
491 } else {
492 if (radeon_new_pll == 1)
493 pll->algo = PLL_ALGO_NEW;
494 else
495 pll->algo = PLL_ALGO_LEGACY;
496 }
497
498 if (ASIC_IS_AVIVO(rdev)) { 485 if (ASIC_IS_AVIVO(rdev)) {
499 if ((rdev->family == CHIP_RS600) || 486 if ((rdev->family == CHIP_RS600) ||
500 (rdev->family == CHIP_RS690) || 487 (rdev->family == CHIP_RS690) ||
@@ -523,25 +510,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
523 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ 510 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
524 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) 511 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
525 adjusted_clock = mode->clock * 2; 512 adjusted_clock = mode->clock * 2;
526 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { 513 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
527 pll->algo = PLL_ALGO_LEGACY;
528 pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; 514 pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
529 }
530 /* There is some evidence (often anecdotal) that RV515/RV620 LVDS
531 * (on some boards at least) prefers the legacy algo. I'm not
532 * sure whether this should handled generically or on a
533 * case-by-case quirk basis. Both algos should work fine in the
534 * majority of cases.
535 */
536 if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) &&
537 ((rdev->family == CHIP_RV515) ||
538 (rdev->family == CHIP_RV620))) {
539 /* allow the user to overrride just in case */
540 if (radeon_new_pll == 1)
541 pll->algo = PLL_ALGO_NEW;
542 else
543 pll->algo = PLL_ALGO_LEGACY;
544 }
545 } else { 515 } else {
546 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) 516 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
547 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; 517 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 2bfae5679135..8e5cb2c4fa7e 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -88,7 +88,6 @@ extern int radeon_benchmarking;
88extern int radeon_testing; 88extern int radeon_testing;
89extern int radeon_connector_table; 89extern int radeon_connector_table;
90extern int radeon_tv; 90extern int radeon_tv;
91extern int radeon_new_pll;
92extern int radeon_audio; 91extern int radeon_audio;
93extern int radeon_disp_priority; 92extern int radeon_disp_priority;
94extern int radeon_hw_i2c; 93extern int radeon_hw_i2c;
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 68932ba7b8a4..89ce9b6d89d9 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1112,8 +1112,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
1112 * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per 1112 * pre-DCE 3.0 r6xx hardware. This might need to be adjusted per
1113 * family. 1113 * family.
1114 */ 1114 */
1115 if (!radeon_new_pll) 1115 p1pll->pll_out_min = 64800;
1116 p1pll->pll_out_min = 64800;
1117 } 1116 }
1118 1117
1119 p1pll->pll_in_min = 1118 p1pll->pll_in_min =
@@ -1390,18 +1389,6 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
1390 1389
1391 lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); 1390 lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id);
1392 1391
1393 if (ASIC_IS_AVIVO(rdev)) {
1394 if (radeon_new_pll == 0)
1395 lvds->pll_algo = PLL_ALGO_LEGACY;
1396 else
1397 lvds->pll_algo = PLL_ALGO_NEW;
1398 } else {
1399 if (radeon_new_pll == 1)
1400 lvds->pll_algo = PLL_ALGO_NEW;
1401 else
1402 lvds->pll_algo = PLL_ALGO_LEGACY;
1403 }
1404
1405 encoder->native_mode = lvds->native_mode; 1392 encoder->native_mode = lvds->native_mode;
1406 1393
1407 if (encoder_enum == 2) 1394 if (encoder_enum == 2)
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 20464659d3fa..325a07391b3c 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -454,13 +454,13 @@ static inline uint32_t radeon_div(uint64_t n, uint32_t d)
454 return n; 454 return n;
455} 455}
456 456
457static void radeon_compute_pll_legacy(struct radeon_pll *pll, 457void radeon_compute_pll(struct radeon_pll *pll,
458 uint64_t freq, 458 uint64_t freq,
459 uint32_t *dot_clock_p, 459 uint32_t *dot_clock_p,
460 uint32_t *fb_div_p, 460 uint32_t *fb_div_p,
461 uint32_t *frac_fb_div_p, 461 uint32_t *frac_fb_div_p,
462 uint32_t *ref_div_p, 462 uint32_t *ref_div_p,
463 uint32_t *post_div_p) 463 uint32_t *post_div_p)
464{ 464{
465 uint32_t min_ref_div = pll->min_ref_div; 465 uint32_t min_ref_div = pll->min_ref_div;
466 uint32_t max_ref_div = pll->max_ref_div; 466 uint32_t max_ref_div = pll->max_ref_div;
@@ -609,214 +609,6 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
609 *post_div_p = best_post_div; 609 *post_div_p = best_post_div;
610} 610}
611 611
612static bool
613calc_fb_div(struct radeon_pll *pll,
614 uint32_t freq,
615 uint32_t post_div,
616 uint32_t ref_div,
617 uint32_t *fb_div,
618 uint32_t *fb_div_frac)
619{
620 fixed20_12 feedback_divider, a, b;
621 u32 vco_freq;
622
623 vco_freq = freq * post_div;
624 /* feedback_divider = vco_freq * ref_div / pll->reference_freq; */
625 a.full = dfixed_const(pll->reference_freq);
626 feedback_divider.full = dfixed_const(vco_freq);
627 feedback_divider.full = dfixed_div(feedback_divider, a);
628 a.full = dfixed_const(ref_div);
629 feedback_divider.full = dfixed_mul(feedback_divider, a);
630
631 if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) {
632 /* feedback_divider = floor((feedback_divider * 10.0) + 0.5) * 0.1; */
633 a.full = dfixed_const(10);
634 feedback_divider.full = dfixed_mul(feedback_divider, a);
635 feedback_divider.full += dfixed_const_half(0);
636 feedback_divider.full = dfixed_floor(feedback_divider);
637 feedback_divider.full = dfixed_div(feedback_divider, a);
638
639 /* *fb_div = floor(feedback_divider); */
640 a.full = dfixed_floor(feedback_divider);
641 *fb_div = dfixed_trunc(a);
642 /* *fb_div_frac = fmod(feedback_divider, 1.0) * 10.0; */
643 a.full = dfixed_const(10);
644 b.full = dfixed_mul(feedback_divider, a);
645
646 feedback_divider.full = dfixed_floor(feedback_divider);
647 feedback_divider.full = dfixed_mul(feedback_divider, a);
648 feedback_divider.full = b.full - feedback_divider.full;
649 *fb_div_frac = dfixed_trunc(feedback_divider);
650 } else {
651 /* *fb_div = floor(feedback_divider + 0.5); */
652 feedback_divider.full += dfixed_const_half(0);
653 feedback_divider.full = dfixed_floor(feedback_divider);
654
655 *fb_div = dfixed_trunc(feedback_divider);
656 *fb_div_frac = 0;
657 }
658
659 if (((*fb_div) < pll->min_feedback_div) || ((*fb_div) > pll->max_feedback_div))
660 return false;
661 else
662 return true;
663}
664
665static bool
666calc_fb_ref_div(struct radeon_pll *pll,
667 uint32_t freq,
668 uint32_t post_div,
669 uint32_t *fb_div,
670 uint32_t *fb_div_frac,
671 uint32_t *ref_div)
672{
673 fixed20_12 ffreq, max_error, error, pll_out, a;
674 u32 vco;
675 u32 pll_out_min, pll_out_max;
676
677 if (pll->flags & RADEON_PLL_IS_LCD) {
678 pll_out_min = pll->lcd_pll_out_min;
679 pll_out_max = pll->lcd_pll_out_max;
680 } else {
681 pll_out_min = pll->pll_out_min;
682 pll_out_max = pll->pll_out_max;
683 }
684
685 ffreq.full = dfixed_const(freq);
686 /* max_error = ffreq * 0.0025; */
687 a.full = dfixed_const(400);
688 max_error.full = dfixed_div(ffreq, a);
689
690 for ((*ref_div) = pll->min_ref_div; (*ref_div) < pll->max_ref_div; ++(*ref_div)) {
691 if (calc_fb_div(pll, freq, post_div, (*ref_div), fb_div, fb_div_frac)) {
692 vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac));
693 vco = vco / ((*ref_div) * 10);
694
695 if ((vco < pll_out_min) || (vco > pll_out_max))
696 continue;
697
698 /* pll_out = vco / post_div; */
699 a.full = dfixed_const(post_div);
700 pll_out.full = dfixed_const(vco);
701 pll_out.full = dfixed_div(pll_out, a);
702
703 if (pll_out.full >= ffreq.full) {
704 error.full = pll_out.full - ffreq.full;
705 if (error.full <= max_error.full)
706 return true;
707 }
708 }
709 }
710 return false;
711}
712
713static void radeon_compute_pll_new(struct radeon_pll *pll,
714 uint64_t freq,
715 uint32_t *dot_clock_p,
716 uint32_t *fb_div_p,
717 uint32_t *frac_fb_div_p,
718 uint32_t *ref_div_p,
719 uint32_t *post_div_p)
720{
721 u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0;
722 u32 best_freq = 0, vco_frequency;
723 u32 pll_out_min, pll_out_max;
724
725 if (pll->flags & RADEON_PLL_IS_LCD) {
726 pll_out_min = pll->lcd_pll_out_min;
727 pll_out_max = pll->lcd_pll_out_max;
728 } else {
729 pll_out_min = pll->pll_out_min;
730 pll_out_max = pll->pll_out_max;
731 }
732
733 /* freq = freq / 10; */
734 do_div(freq, 10);
735
736 if (pll->flags & RADEON_PLL_USE_POST_DIV) {
737 post_div = pll->post_div;
738 if ((post_div < pll->min_post_div) || (post_div > pll->max_post_div))
739 goto done;
740
741 vco_frequency = freq * post_div;
742 if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
743 goto done;
744
745 if (pll->flags & RADEON_PLL_USE_REF_DIV) {
746 ref_div = pll->reference_div;
747 if ((ref_div < pll->min_ref_div) || (ref_div > pll->max_ref_div))
748 goto done;
749 if (!calc_fb_div(pll, freq, post_div, ref_div, &fb_div, &fb_div_frac))
750 goto done;
751 }
752 } else {
753 for (post_div = pll->max_post_div; post_div >= pll->min_post_div; --post_div) {
754 if (pll->flags & RADEON_PLL_LEGACY) {
755 if ((post_div == 5) ||
756 (post_div == 7) ||
757 (post_div == 9) ||
758 (post_div == 10) ||
759 (post_div == 11))
760 continue;
761 }
762
763 if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
764 continue;
765
766 vco_frequency = freq * post_div;
767 if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
768 continue;
769 if (pll->flags & RADEON_PLL_USE_REF_DIV) {
770 ref_div = pll->reference_div;
771 if ((ref_div < pll->min_ref_div) || (ref_div > pll->max_ref_div))
772 goto done;
773 if (calc_fb_div(pll, freq, post_div, ref_div, &fb_div, &fb_div_frac))
774 break;
775 } else {
776 if (calc_fb_ref_div(pll, freq, post_div, &fb_div, &fb_div_frac, &ref_div))
777 break;
778 }
779 }
780 }
781
782 best_freq = pll->reference_freq * 10 * fb_div;
783 best_freq += pll->reference_freq * fb_div_frac;
784 best_freq = best_freq / (ref_div * post_div);
785
786done:
787 if (best_freq == 0)
788 DRM_ERROR("Couldn't find valid PLL dividers\n");
789
790 *dot_clock_p = best_freq / 10;
791 *fb_div_p = fb_div;
792 *frac_fb_div_p = fb_div_frac;
793 *ref_div_p = ref_div;
794 *post_div_p = post_div;
795
796 DRM_DEBUG_KMS("%u %d.%d, %d, %d\n", *dot_clock_p, *fb_div_p, *frac_fb_div_p, *ref_div_p, *post_div_p);
797}
798
799void radeon_compute_pll(struct radeon_pll *pll,
800 uint64_t freq,
801 uint32_t *dot_clock_p,
802 uint32_t *fb_div_p,
803 uint32_t *frac_fb_div_p,
804 uint32_t *ref_div_p,
805 uint32_t *post_div_p)
806{
807 switch (pll->algo) {
808 case PLL_ALGO_NEW:
809 radeon_compute_pll_new(pll, freq, dot_clock_p, fb_div_p,
810 frac_fb_div_p, ref_div_p, post_div_p);
811 break;
812 case PLL_ALGO_LEGACY:
813 default:
814 radeon_compute_pll_legacy(pll, freq, dot_clock_p, fb_div_p,
815 frac_fb_div_p, ref_div_p, post_div_p);
816 break;
817 }
818}
819
820static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) 612static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
821{ 613{
822 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); 614 struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 663cdc10a5c2..f29a2695d961 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -93,7 +93,6 @@ int radeon_benchmarking = 0;
93int radeon_testing = 0; 93int radeon_testing = 0;
94int radeon_connector_table = 0; 94int radeon_connector_table = 0;
95int radeon_tv = 1; 95int radeon_tv = 1;
96int radeon_new_pll = -1;
97int radeon_audio = 1; 96int radeon_audio = 1;
98int radeon_disp_priority = 0; 97int radeon_disp_priority = 0;
99int radeon_hw_i2c = 0; 98int radeon_hw_i2c = 0;
@@ -131,9 +130,6 @@ module_param_named(connector_table, radeon_connector_table, int, 0444);
131MODULE_PARM_DESC(tv, "TV enable (0 = disable)"); 130MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
132module_param_named(tv, radeon_tv, int, 0444); 131module_param_named(tv, radeon_tv, int, 0444);
133 132
134MODULE_PARM_DESC(new_pll, "Select new PLL code");
135module_param_named(new_pll, radeon_new_pll, int, 0444);
136
137MODULE_PARM_DESC(audio, "Audio enable (0 = disable)"); 133MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
138module_param_named(audio, radeon_audio, int, 0444); 134module_param_named(audio, radeon_audio, int, 0444);
139 135
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index d60b31982845..28e0b1e9e5f1 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -717,10 +717,6 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
717 pll = &rdev->clock.p1pll; 717 pll = &rdev->clock.p1pll;
718 718
719 pll->flags = RADEON_PLL_LEGACY; 719 pll->flags = RADEON_PLL_LEGACY;
720 if (radeon_new_pll == 1)
721 pll->algo = PLL_ALGO_NEW;
722 else
723 pll->algo = PLL_ALGO_LEGACY;
724 720
725 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 721 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
726 if (encoder->crtc == crtc) { 722 if (encoder->crtc == crtc) {
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 8707cd61e58b..29f551769aaf 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -144,12 +144,6 @@ struct radeon_tmds_pll {
144#define RADEON_PLL_USE_POST_DIV (1 << 6) 144#define RADEON_PLL_USE_POST_DIV (1 << 6)
145#define RADEON_PLL_IS_LCD (1 << 7) 145#define RADEON_PLL_IS_LCD (1 << 7)
146 146
147/* pll algo */
148enum radeon_pll_algo {
149 PLL_ALGO_LEGACY,
150 PLL_ALGO_NEW
151};
152
153struct radeon_pll { 147struct radeon_pll {
154 /* reference frequency */ 148 /* reference frequency */
155 uint32_t reference_freq; 149 uint32_t reference_freq;
@@ -182,8 +176,6 @@ struct radeon_pll {
182 176
183 /* pll id */ 177 /* pll id */
184 uint32_t id; 178 uint32_t id;
185 /* pll algo */
186 enum radeon_pll_algo algo;
187}; 179};
188 180
189struct radeon_i2c_chan { 181struct radeon_i2c_chan {
@@ -346,7 +338,6 @@ struct radeon_encoder_atom_dig {
346 /* atom lvds */ 338 /* atom lvds */
347 uint32_t lvds_misc; 339 uint32_t lvds_misc;
348 uint16_t panel_pwr_delay; 340 uint16_t panel_pwr_delay;
349 enum radeon_pll_algo pll_algo;
350 struct radeon_atom_ss *ss; 341 struct radeon_atom_ss *ss;
351 /* panel mode */ 342 /* panel mode */
352 struct drm_display_mode native_mode; 343 struct drm_display_mode native_mode;