aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-09-13 10:56:16 -0400
committerAlex Deucher <alexander.deucher@amd.com>2012-09-20 13:10:44 -0400
commit19eca43e5a52a8e47fdd40e940912b2417c7c055 (patch)
tree9ca6f599f97728f13be6f4abe81829973d1c302a
parent2f454cf1261ba913e2f660b7555864b340502c60 (diff)
drm/radeon: rework crtc pll setup to better support PPLL sharing
We need the calculate the pixel clock before allocating a PPLL in order to insure the clocks really match. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c221
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h32
2 files changed, 150 insertions, 103 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 2f7cc9e3b175..cf8ac5a5d8ca 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -533,11 +533,9 @@ union adjust_pixel_clock {
533}; 533};
534 534
535static u32 atombios_adjust_pll(struct drm_crtc *crtc, 535static u32 atombios_adjust_pll(struct drm_crtc *crtc,
536 struct drm_display_mode *mode, 536 struct drm_display_mode *mode)
537 struct radeon_pll *pll,
538 bool ss_enabled,
539 struct radeon_atom_ss *ss)
540{ 537{
538 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
541 struct drm_device *dev = crtc->dev; 539 struct drm_device *dev = crtc->dev;
542 struct radeon_device *rdev = dev->dev_private; 540 struct radeon_device *rdev = dev->dev_private;
543 struct drm_encoder *encoder = NULL; 541 struct drm_encoder *encoder = NULL;
@@ -550,32 +548,32 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
550 bool is_duallink = false; 548 bool is_duallink = false;
551 549
552 /* reset the pll flags */ 550 /* reset the pll flags */
553 pll->flags = 0; 551 radeon_crtc->pll_flags = 0;
554 552
555 if (ASIC_IS_AVIVO(rdev)) { 553 if (ASIC_IS_AVIVO(rdev)) {
556 if ((rdev->family == CHIP_RS600) || 554 if ((rdev->family == CHIP_RS600) ||
557 (rdev->family == CHIP_RS690) || 555 (rdev->family == CHIP_RS690) ||
558 (rdev->family == CHIP_RS740)) 556 (rdev->family == CHIP_RS740))
559 pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ 557 radeon_crtc->pll_flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
560 RADEON_PLL_PREFER_CLOSEST_LOWER); 558 RADEON_PLL_PREFER_CLOSEST_LOWER);
561 559
562 if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */ 560 if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */
563 pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; 561 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
564 else 562 else
565 pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; 563 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
566 564
567 if (rdev->family < CHIP_RV770) 565 if (rdev->family < CHIP_RV770)
568 pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; 566 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
569 /* use frac fb div on APUs */ 567 /* use frac fb div on APUs */
570 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) 568 if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
571 pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; 569 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
572 } else { 570 } else {
573 pll->flags |= RADEON_PLL_LEGACY; 571 radeon_crtc->pll_flags |= RADEON_PLL_LEGACY;
574 572
575 if (mode->clock > 200000) /* range limits??? */ 573 if (mode->clock > 200000) /* range limits??? */
576 pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; 574 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
577 else 575 else
578 pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; 576 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
579 } 577 }
580 578
581 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 579 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -598,12 +596,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
598 596
599 /* use recommended ref_div for ss */ 597 /* use recommended ref_div for ss */
600 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 598 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
601 if (ss_enabled) { 599 if (radeon_crtc->ss_enabled) {
602 if (ss->refdiv) { 600 if (radeon_crtc->ss.refdiv) {
603 pll->flags |= RADEON_PLL_USE_REF_DIV; 601 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
604 pll->reference_div = ss->refdiv; 602 radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
605 if (ASIC_IS_AVIVO(rdev)) 603 if (ASIC_IS_AVIVO(rdev))
606 pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; 604 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
607 } 605 }
608 } 606 }
609 } 607 }
@@ -613,14 +611,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
613 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) 611 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
614 adjusted_clock = mode->clock * 2; 612 adjusted_clock = mode->clock * 2;
615 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) 613 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
616 pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; 614 radeon_crtc->pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
617 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) 615 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
618 pll->flags |= RADEON_PLL_IS_LCD; 616 radeon_crtc->pll_flags |= RADEON_PLL_IS_LCD;
619 } else { 617 } else {
620 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) 618 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
621 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; 619 radeon_crtc->pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
622 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) 620 if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
623 pll->flags |= RADEON_PLL_USE_REF_DIV; 621 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
624 } 622 }
625 break; 623 break;
626 } 624 }
@@ -650,7 +648,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
650 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); 648 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
651 args.v1.ucTransmitterID = radeon_encoder->encoder_id; 649 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
652 args.v1.ucEncodeMode = encoder_mode; 650 args.v1.ucEncodeMode = encoder_mode;
653 if (ss_enabled && ss->percentage) 651 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
654 args.v1.ucConfig |= 652 args.v1.ucConfig |=
655 ADJUST_DISPLAY_CONFIG_SS_ENABLE; 653 ADJUST_DISPLAY_CONFIG_SS_ENABLE;
656 654
@@ -663,7 +661,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
663 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; 661 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
664 args.v3.sInput.ucEncodeMode = encoder_mode; 662 args.v3.sInput.ucEncodeMode = encoder_mode;
665 args.v3.sInput.ucDispPllConfig = 0; 663 args.v3.sInput.ucDispPllConfig = 0;
666 if (ss_enabled && ss->percentage) 664 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
667 args.v3.sInput.ucDispPllConfig |= 665 args.v3.sInput.ucDispPllConfig |=
668 DISPPLL_CONFIG_SS_ENABLE; 666 DISPPLL_CONFIG_SS_ENABLE;
669 if (ENCODER_MODE_IS_DP(encoder_mode)) { 667 if (ENCODER_MODE_IS_DP(encoder_mode)) {
@@ -695,14 +693,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
695 index, (uint32_t *)&args); 693 index, (uint32_t *)&args);
696 adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; 694 adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
697 if (args.v3.sOutput.ucRefDiv) { 695 if (args.v3.sOutput.ucRefDiv) {
698 pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; 696 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
699 pll->flags |= RADEON_PLL_USE_REF_DIV; 697 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
700 pll->reference_div = args.v3.sOutput.ucRefDiv; 698 radeon_crtc->pll_reference_div = args.v3.sOutput.ucRefDiv;
701 } 699 }
702 if (args.v3.sOutput.ucPostDiv) { 700 if (args.v3.sOutput.ucPostDiv) {
703 pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; 701 radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
704 pll->flags |= RADEON_PLL_USE_POST_DIV; 702 radeon_crtc->pll_flags |= RADEON_PLL_USE_POST_DIV;
705 pll->post_div = args.v3.sOutput.ucPostDiv; 703 radeon_crtc->pll_post_div = args.v3.sOutput.ucPostDiv;
706 } 704 }
707 break; 705 break;
708 default: 706 default:
@@ -910,21 +908,17 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
910 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 908 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
911} 909}