aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 9fbabaa6ee44..b0ab185b86f6 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -403,6 +403,7 @@ union atom_enable_ss {
403 ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2; 403 ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2;
404 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; 404 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
405 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2; 405 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2;
406 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
406}; 407};
407 408
408static void atombios_crtc_program_ss(struct drm_crtc *crtc, 409static void atombios_crtc_program_ss(struct drm_crtc *crtc,
@@ -417,7 +418,30 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
417 418
418 memset(&args, 0, sizeof(args)); 419 memset(&args, 0, sizeof(args));
419 420
420 if (ASIC_IS_DCE4(rdev)) { 421 if (ASIC_IS_DCE5(rdev)) {
422 args.v3.usSpreadSpectrumAmountFrac = 0;
423 args.v3.ucSpreadSpectrumType = ss->type;
424 switch (pll_id) {
425 case ATOM_PPLL1:
426 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
427 args.v3.usSpreadSpectrumAmount = ss->amount;
428 args.v3.usSpreadSpectrumStep = ss->step;
429 break;
430 case ATOM_PPLL2:
431 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL;
432 args.v3.usSpreadSpectrumAmount = ss->amount;
433 args.v3.usSpreadSpectrumStep = ss->step;
434 break;
435 case ATOM_DCPLL:
436 args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL;
437 args.v3.usSpreadSpectrumAmount = 0;
438 args.v3.usSpreadSpectrumStep = 0;
439 break;
440 case ATOM_PPLL_INVALID:
441 return;
442 }
443 args.v2.ucEnable = enable;
444 } else if (ASIC_IS_DCE4(rdev)) {
421 args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); 445 args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
422 args.v2.ucSpreadSpectrumType = ss->type; 446 args.v2.ucSpreadSpectrumType = ss->type;
423 switch (pll_id) { 447 switch (pll_id) {
@@ -673,9 +697,14 @@ union set_pixel_clock {
673 PIXEL_CLOCK_PARAMETERS_V2 v2; 697 PIXEL_CLOCK_PARAMETERS_V2 v2;
674 PIXEL_CLOCK_PARAMETERS_V3 v3; 698 PIXEL_CLOCK_PARAMETERS_V3 v3;
675 PIXEL_CLOCK_PARAMETERS_V5 v5; 699 PIXEL_CLOCK_PARAMETERS_V5 v5;
700 PIXEL_CLOCK_PARAMETERS_V6 v6;
676}; 701};
677 702
678static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) 703/* on DCE5, make sure the voltage is high enough to support the
704 * required disp clk.
705 */
706static void atombios_crtc_set_dcpll(struct drm_crtc *crtc,
707 u32 dispclk)
679{ 708{
680 struct drm_device *dev = crtc->dev; 709 struct drm_device *dev = crtc->dev;
681 struct radeon_device *rdev = dev->dev_private; 710 struct radeon_device *rdev = dev->dev_private;
@@ -698,9 +727,16 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
698 * SetPixelClock provides the dividers 727 * SetPixelClock provides the dividers
699 */ 728 */
700 args.v5.ucCRTC = ATOM_CRTC_INVALID; 729 args.v5.ucCRTC = ATOM_CRTC_INVALID;
701 args.v5.usPixelClock = rdev->clock.default_dispclk; 730 args.v5.usPixelClock = dispclk;
702 args.v5.ucPpll = ATOM_DCPLL; 731 args.v5.ucPpll = ATOM_DCPLL;
703 break; 732 break;
733 case 6:
734 /* if the default dcpll clock is specified,
735 * SetPixelClock provides the dividers
736 */
737 args.v6.ulDispEngClkFreq = dispclk;
738 args.v6.ucPpll = ATOM_DCPLL;
739 break;
704 default: 740 default:
705 DRM_ERROR("Unknown table version %d %d\n", frev, crev); 741 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
706 return; 742 return;
@@ -784,6 +820,18 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
784 args.v5.ucEncoderMode = encoder_mode; 820 args.v5.ucEncoderMode = encoder_mode;
785 args.v5.ucPpll = pll_id; 821 args.v5.ucPpll = pll_id;
786 break; 822 break;
823 case 6:
824 args.v6.ulCrtcPclkFreq.ucCRTC = crtc_id;
825 args.v6.ulCrtcPclkFreq.ulPixelClock = cpu_to_le32(clock / 10);
826 args.v6.ucRefDiv = ref_div;
827 args.v6.usFbDiv = cpu_to_le16(fb_div);
828 args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
829 args.v6.ucPostDiv = post_div;
830 args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
831 args.v6.ucTransmitterID = encoder_id;
832 args.v6.ucEncoderMode = encoder_mode;
833 args.v6.ucPpll = pll_id;
834 break;
787 default: 835 default:
788 DRM_ERROR("Unknown table version %d %d\n", frev, crev); 836 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
789 return; 837 return;
@@ -1377,7 +1425,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
1377 rdev->clock.default_dispclk); 1425 rdev->clock.default_dispclk);
1378 if (ss_enabled) 1426 if (ss_enabled)
1379 atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss); 1427 atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss);
1380 atombios_crtc_set_dcpll(crtc); 1428 /* XXX: DCE5, make sure voltage, dispclk is high enough */
1429 atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk);
1381 if (ss_enabled) 1430 if (ss_enabled)
1382 atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss); 1431 atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss);
1383 } 1432 }