aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_crtc.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-10-05 22:57:54 -0400
committerDave Airlie <airlied@redhat.com>2010-10-05 22:57:54 -0400
commit26bf62e47261142d528a6109fdd671a2e280b4ea (patch)
treed7f9622fba650ddd402df7614d8b7175d4be5227 /drivers/gpu/drm/radeon/atombios_crtc.c
parent96a03fce54af40b4f0820cd729608bc32c9b8949 (diff)
parentd7ccd8fc11700502b5a104b7bad595b492a3aa1b (diff)
Merge branch 'drm-radeon-next' of ../drm-radeon-next into drm-core-next
* 'drm-radeon-next' of ../drm-radeon-next: drm/radeon/kms: add drm blit support for evergreen drm/radeon: Modify radeon_pm_in_vbl to use radeon_get_crtc_scanoutpos() drm/radeon: Add function for display scanout position query. drm/radeon/kms: rework spread spectrum handling drm/radeon/kms: remove new pll algo drm/radeon/kms: remove some pll algo flags drm/radeon/kms: prefer high post dividers in legacy pll algo drm/radeon/kms: properly handle 40 bit MC addresses in the cursor code drm/radeon: add properties to configure the width of the underscan borders drm/radeon/kms/r6xx+: use new style fencing (v3) drm/radeon/kms: enable writeback (v2) drm/radeon/kms: clean up r6xx/r7xx blit init (v2)
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c301
1 files changed, 193 insertions, 108 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 501e5286ec3f..037e3260cb7c 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -398,65 +398,76 @@ static void atombios_disable_ss(struct drm_crtc *crtc)
398 398
399 399
400union atom_enable_ss { 400union atom_enable_ss {
401 ENABLE_LVDS_SS_PARAMETERS legacy; 401 ENABLE_LVDS_SS_PARAMETERS lvds_ss;
402 ENABLE_LVDS_SS_PARAMETERS_V2 lvds_ss_2;
402 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; 403 ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
404 ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 v2;
403}; 405};
404 406
405static void atombios_enable_ss(struct drm_crtc *crtc) 407static void atombios_crtc_program_ss(struct drm_crtc *crtc,
408 int enable,
409 int pll_id,
410 struct radeon_atom_ss *ss)
406{ 411{
407 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
408 struct drm_device *dev = crtc->dev; 412 struct drm_device *dev = crtc->dev;
409 struct radeon_device *rdev = dev->dev_private; 413 struct radeon_device *rdev = dev->dev_private;
410 struct drm_encoder *encoder = NULL;
411 struct radeon_encoder *radeon_encoder = NULL;
412 struct radeon_encoder_atom_dig *dig = NULL;
413 int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); 414 int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
414 union atom_enable_ss args; 415 union atom_enable_ss args;
415 uint16_t percentage = 0;
416 uint8_t type = 0, step = 0, delay = 0, range = 0;
417 416
418 /* XXX add ss support for DCE4 */ 417 memset(&args, 0, sizeof(args));
419 if (ASIC_IS_DCE4(rdev))
420 return;
421 418
422 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 419 if (ASIC_IS_DCE4(rdev)) {
423 if (encoder->crtc == crtc) { 420 args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
424 radeon_encoder = to_radeon_encoder(encoder); 421 args.v2.ucSpreadSpectrumType = ss->type;
425 /* only enable spread spectrum on LVDS */ 422 switch (pll_id) {
426 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 423 case ATOM_PPLL1:
427 dig = radeon_encoder->enc_priv; 424 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL;
428 if (dig && dig->ss) { 425 args.v2.usSpreadSpectrumAmount = ss->amount;
429 percentage = dig->ss->percentage; 426 args.v2.usSpreadSpectrumStep = ss->step;
430 type = dig->ss->type; 427 break;
431 step = dig->ss->step; 428 case ATOM_PPLL2:
432 delay = dig->ss->delay; 429 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL;
433 range = dig->ss->range; 430 args.v2.usSpreadSpectrumAmount = ss->amount;
434 } else 431 args.v2.usSpreadSpectrumStep = ss->step;
435 return;
436 } else
437 return;
438 break; 432 break;
433 case ATOM_DCPLL:
434 args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL;
435 args.v2.usSpreadSpectrumAmount = 0;
436 args.v2.usSpreadSpectrumStep = 0;
437 break;
438 case ATOM_PPLL_INVALID:
439 return;
439 } 440 }
440 } 441 args.v2.ucEnable = enable;
441 442 } else if (ASIC_IS_DCE3(rdev)) {
442 if (!radeon_encoder) 443 args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
443 return; 444 args.v1.ucSpreadSpectrumType = ss->type;
444 445 args.v1.ucSpreadSpectrumStep = ss->step;
445 memset(&args, 0, sizeof(args)); 446 args.v1.ucSpreadSpectrumDelay = ss->delay;
446 if (ASIC_IS_AVIVO(rdev)) { 447 args.v1.ucSpreadSpectrumRange = ss->range;
447 args.v1.usSpreadSpectrumPercentage = cpu_to_le16(percentage); 448 args.v1.ucPpll = pll_id;
448 args.v1.ucSpreadSpectrumType = type; 449 args.v1.ucEnable = enable;
449 args.v1.ucSpreadSpectrumStep = step; 450 } else if (ASIC_IS_AVIVO(rdev)) {
450 args.v1.ucSpreadSpectrumDelay = delay; 451 if (enable == ATOM_DISABLE) {
451 args.v1.ucSpreadSpectrumRange = range; 452 atombios_disable_ss(crtc);
452 args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 453 return;
453 args.v1.ucEnable = ATOM_ENABLE; 454 }
455 args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
456 args.lvds_ss_2.ucSpreadSpectrumType = ss->type;
457 args.lvds_ss_2.ucSpreadSpectrumStep = ss->step;
458 args.lvds_ss_2.ucSpreadSpectrumDelay = ss->delay;
459 args.lvds_ss_2.ucSpreadSpectrumRange = ss->range;
460 args.lvds_ss_2.ucEnable = enable;
454 } else { 461 } else {
455 args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage); 462 if (enable == ATOM_DISABLE) {
456 args.legacy.ucSpreadSpectrumType = type; 463 atombios_disable_ss(crtc);
457 args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; 464 return;
458 args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; 465 }
459 args.legacy.ucEnable = ATOM_ENABLE; 466 args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
467 args.lvds_ss.ucSpreadSpectrumType = ss->type;
468 args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2;
469 args.lvds_ss.ucSpreadSpectrumStepSize_Delay |= (ss->delay & 7) << 4;
470 args.lvds_ss.ucEnable = enable;
460 } 471 }
461 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 472 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
462} 473}
@@ -468,7 +479,9 @@ union adjust_pixel_clock {
468 479
469static u32 atombios_adjust_pll(struct drm_crtc *crtc, 480static u32 atombios_adjust_pll(struct drm_crtc *crtc,
470 struct drm_display_mode *mode, 481 struct drm_display_mode *mode,
471 struct radeon_pll *pll) 482 struct radeon_pll *pll,
483 bool ss_enabled,
484 struct radeon_atom_ss *ss)
472{ 485{
473 struct drm_device *dev = crtc->dev; 486 struct drm_device *dev = crtc->dev;
474 struct radeon_device *rdev = dev->dev_private; 487 struct radeon_device *rdev = dev->dev_private;
@@ -482,40 +495,15 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
482 /* reset the pll flags */ 495 /* reset the pll flags */
483 pll->flags = 0; 496 pll->flags = 0;
484 497
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)) { 498 if (ASIC_IS_AVIVO(rdev)) {
499 if ((rdev->family == CHIP_RS600) || 499 if ((rdev->family == CHIP_RS600) ||
500 (rdev->family == CHIP_RS690) || 500 (rdev->family == CHIP_RS690) ||
501 (rdev->family == CHIP_RS740)) 501 (rdev->family == CHIP_RS740))
502 pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/ 502 pll->flags |= (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
503 RADEON_PLL_PREFER_CLOSEST_LOWER); 503 RADEON_PLL_PREFER_CLOSEST_LOWER);
504 504 } else
505 if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /* range limits??? */
506 pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
507 else
508 pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
509 } else {
510 pll->flags |= RADEON_PLL_LEGACY; 505 pll->flags |= RADEON_PLL_LEGACY;
511 506
512 if (mode->clock > 200000) /* range limits??? */
513 pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
514 else
515 pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
516
517 }
518
519 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 507 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
520 if (encoder->crtc == crtc) { 508 if (encoder->crtc == crtc) {
521 radeon_encoder = to_radeon_encoder(encoder); 509 radeon_encoder = to_radeon_encoder(encoder);
@@ -531,29 +519,22 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
531 } 519 }
532 } 520 }
533 521
522 /* use recommended ref_div for ss */
523 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
524 if (ss_enabled) {
525 if (ss->refdiv) {
526 pll->flags |= RADEON_PLL_USE_REF_DIV;
527 pll->reference_div = ss->refdiv;
528 }
529 }
530 }
531
534 if (ASIC_IS_AVIVO(rdev)) { 532 if (ASIC_IS_AVIVO(rdev)) {
535 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ 533 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
536 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) 534 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
537 adjusted_clock = mode->clock * 2; 535 adjusted_clock = mode->clock * 2;
538 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { 536 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
539 pll->algo = PLL_ALGO_LEGACY;
540 pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; 537 pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
541 }
542 /* There is some evidence (often anecdotal) that RV515/RV620 LVDS
543 * (on some boards at least) prefers the legacy algo. I'm not
544 * sure whether this should handled generically or on a
545 * case-by-case quirk basis. Both algos should work fine in the
546 * majority of cases.
547 */
548 if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) &&
549 ((rdev->family == CHIP_RV515) ||
550 (rdev->family == CHIP_RV620))) {
551 /* allow the user to overrride just in case */
552 if (radeon_new_pll == 1)
553 pll->algo = PLL_ALGO_NEW;
554 else
555 pll->algo = PLL_ALGO_LEGACY;
556 }
557 } else { 538 } else {
558 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) 539 if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
559 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; 540 pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
@@ -589,9 +570,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
589 args.v1.ucTransmitterID = radeon_encoder->encoder_id; 570 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
590 args.v1.ucEncodeMode = encoder_mode; 571 args.v1.ucEncodeMode = encoder_mode;
591 if (encoder_mode == ATOM_ENCODER_MODE_DP) { 572 if (encoder_mode == ATOM_ENCODER_MODE_DP) {
592 /* may want to enable SS on DP eventually */ 573 if (ss_enabled)
593 /* args.v1.ucConfig |= 574 args.v1.ucConfig |=
594 ADJUST_DISPLAY_CONFIG_SS_ENABLE;*/ 575 ADJUST_DISPLAY_CONFIG_SS_ENABLE;
595 } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { 576 } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) {
596 args.v1.ucConfig |= 577 args.v1.ucConfig |=
597 ADJUST_DISPLAY_CONFIG_SS_ENABLE; 578 ADJUST_DISPLAY_CONFIG_SS_ENABLE;
@@ -608,11 +589,10 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
608 args.v3.sInput.ucDispPllConfig = 0; 589 args.v3.sInput.ucDispPllConfig = 0;
609 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { 590 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
610 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 591 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
611
612 if (encoder_mode == ATOM_ENCODER_MODE_DP) { 592 if (encoder_mode == ATOM_ENCODER_MODE_DP) {
613 /* may want to enable SS on DP/eDP eventually */ 593 if (ss_enabled)
614 /*args.v3.sInput.ucDispPllConfig |= 594 args.v3.sInput.ucDispPllConfig |=
615 DISPPLL_CONFIG_SS_ENABLE;*/ 595 DISPPLL_CONFIG_SS_ENABLE;
616 args.v3.sInput.ucDispPllConfig |= 596 args.v3.sInput.ucDispPllConfig |=
617 DISPPLL_CONFIG_COHERENT_MODE; 597 DISPPLL_CONFIG_COHERENT_MODE;
618 /* 16200 or 27000 */ 598 /* 16200 or 27000 */
@@ -632,17 +612,17 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
632 } 612 }
633 } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 613 } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
634 if (encoder_mode == ATOM_ENCODER_MODE_DP) { 614 if (encoder_mode == ATOM_ENCODER_MODE_DP) {
635 /* may want to enable SS on DP/eDP eventually */ 615 if (ss_enabled)
636 /*args.v3.sInput.ucDispPllConfig |= 616 args.v3.sInput.ucDispPllConfig |=
637 DISPPLL_CONFIG_SS_ENABLE;*/ 617 DISPPLL_CONFIG_SS_ENABLE;
638 args.v3.sInput.ucDispPllConfig |= 618 args.v3.sInput.ucDispPllConfig |=
639 DISPPLL_CONFIG_COHERENT_MODE; 619 DISPPLL_CONFIG_COHERENT_MODE;
640 /* 16200 or 27000 */ 620 /* 16200 or 27000 */
641 args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); 621 args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
642 } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { 622 } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) {
643 /* want to enable SS on LVDS eventually */ 623 if (ss_enabled)
644 /*args.v3.sInput.ucDispPllConfig |= 624 args.v3.sInput.ucDispPllConfig |=
645 DISPPLL_CONFIG_SS_ENABLE;*/ 625 DISPPLL_CONFIG_SS_ENABLE;
646 } else { 626 } else {
647 if (mode->clock > 165000) 627 if (mode->clock > 165000)
648 args.v3.sInput.ucDispPllConfig |= 628 args.v3.sInput.ucDispPllConfig |=
@@ -816,6 +796,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
816 struct radeon_pll *pll; 796 struct radeon_pll *pll;
817 u32 adjusted_clock; 797 u32 adjusted_clock;
818 int encoder_mode = 0; 798 int encoder_mode = 0;
799 struct radeon_atom_ss ss;
800 bool ss_enabled = false;
819 801
820 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 802 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
821 if (encoder->crtc == crtc) { 803 if (encoder->crtc == crtc) {
@@ -842,16 +824,112 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
842 break; 824 break;
843 } 825 }
844 826
827 if (radeon_encoder->active_device &
828 (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) {
829 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
830 struct drm_connector *connector =
831 radeon_get_connector_for_encoder(encoder);
832 struct radeon_connector *radeon_connector =
833 to_radeon_connector(connector);
834 struct radeon_connector_atom_dig *dig_connector =
835 radeon_connector->con_priv;
836 int dp_clock;
837
838 switch (encoder_mode) {
839 case ATOM_ENCODER_MODE_DP:
840 /* DP/eDP */
841 dp_clock = dig_connector->dp_clock / 10;
842 if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
843 if (ASIC_IS_DCE4(rdev))
844 ss_enabled =
845 radeon_atombios_get_asic_ss_info(rdev, &ss,
846 dig->lcd_ss_id,
847 dp_clock);
848 else
849 ss_enabled =
850 radeon_atombios_get_ppll_ss_info(rdev, &ss,
851 dig->lcd_ss_id);
852 } else {
853 if (ASIC_IS_DCE4(rdev))
854 ss_enabled =
855 radeon_atombios_get_asic_ss_info(rdev, &ss,
856 ASIC_INTERNAL_SS_ON_DP,
857 dp_clock);
858 else {
859 if (dp_clock == 16200) {
860 ss_enabled =
861 radeon_atombios_get_ppll_ss_info(rdev, &ss,
862 ATOM_DP_SS_ID2);
863 if (!ss_enabled)
864 ss_enabled =
865 radeon_atombios_get_ppll_ss_info(rdev, &ss,
866 ATOM_DP_SS_ID1);
867 } else
868 ss_enabled =
869 radeon_atombios_get_ppll_ss_info(rdev, &ss,
870 ATOM_DP_SS_ID1);
871 }
872 }
873 break;
874 case ATOM_ENCODER_MODE_LVDS:
875 if (ASIC_IS_DCE4(rdev))
876 ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
877 dig->lcd_ss_id,
878 mode->clock / 10);
879 else
880 ss_enabled = radeon_atombios_get_ppll_ss_info(rdev, &ss,
881 dig->lcd_ss_id);
882 break;
883 case ATOM_ENCODER_MODE_DVI:
884 if (ASIC_IS_DCE4(rdev))
885 ss_enabled =
886 radeon_atombios_get_asic_ss_info(rdev, &ss,
887 ASIC_INTERNAL_SS_ON_TMDS,
888 mode->clock / 10);
889 break;
890 case ATOM_ENCODER_MODE_HDMI:
891 if (ASIC_IS_DCE4(rdev))
892 ss_enabled =
893 radeon_atombios_get_asic_ss_info(rdev, &ss,
894 ASIC_INTERNAL_SS_ON_HDMI,
895 mode->clock / 10);
896 break;
897 default:
898 break;
899 }
900 }
901
845 /* adjust pixel clock as needed */ 902 /* adjust pixel clock as needed */
846 adjusted_clock = atombios_adjust_pll(crtc, mode, pll); 903 adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
847 904
848 radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, 905 radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
849 &ref_div, &post_div); 906 &ref_div, &post_div);
850 907
908 atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
909
851 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, 910 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
852 encoder_mode, radeon_encoder->encoder_id, mode->clock, 911 encoder_mode, radeon_encoder->encoder_id, mode->clock,
853 ref_div, fb_div, frac_fb_div, post_div); 912 ref_div, fb_div, frac_fb_div, post_div);
854 913
914 if (ss_enabled) {
915 /* calculate ss amount and step size */
916 if (ASIC_IS_DCE4(rdev)) {
917 u32 step_size;
918 u32 amount = (((fb_div * 10) + frac_fb_div) * ss.percentage) / 10000;
919 ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
920 ss.amount |= ((amount - (ss.amount * 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
921 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
922 if (ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
923 step_size = (4 * amount * ref_div * (ss.rate * 2048)) /
924 (125 * 25 * pll->reference_freq / 100);
925 else
926 step_size = (2 * amount * ref_div * (ss.rate * 2048)) /
927 (125 * 25 * pll->reference_freq / 100);
928 ss.step = step_size;
929 }
930
931 atombios_crtc_program_ss(crtc, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
932 }
855} 933}
856 934
857static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, 935static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
@@ -1278,12 +1356,19 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
1278 } 1356 }
1279 } 1357 }
1280 1358
1281 atombios_disable_ss(crtc);
1282 /* always set DCPLL */ 1359 /* always set DCPLL */
1283 if (ASIC_IS_DCE4(rdev)) 1360 if (ASIC_IS_DCE4(rdev)) {
1361 struct radeon_atom_ss ss;
1362 bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
1363 ASIC_INTERNAL_SS_ON_DCPLL,
1364 rdev->clock.default_dispclk);
1365 if (ss_enabled)
1366 atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss);
1284 atombios_crtc_set_dcpll(crtc); 1367 atombios_crtc_set_dcpll(crtc);
1368 if (ss_enabled)
1369 atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss);
1370 }
1285 atombios_crtc_set_pll(crtc, adjusted_mode); 1371 atombios_crtc_set_pll(crtc, adjusted_mode);
1286 atombios_enable_ss(crtc);
1287 1372
1288 if (ASIC_IS_DCE4(rdev)) 1373 if (ASIC_IS_DCE4(rdev))
1289 atombios_set_crtc_dtd_timing(crtc, adjusted_mode); 1374 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);