aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_crtc.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-01-12 17:54:34 -0500
committerDave Airlie <airlied@redhat.com>2010-02-08 18:44:02 -0500
commitbcc1c2a1d22974215e39dc87ce746ba9a39223e5 (patch)
tree62ae9dfab266202240307fc3998806c1d4655552 /drivers/gpu/drm/radeon/atombios_crtc.c
parente97bd974448ce90f8e4720499d84580bcd6a2f7a (diff)
drm/radeon/kms: add initial Evergreen support (Radeon HD 5xxx)
This adds initial Evergreen KMS support, it doesn't include any acceleration features or interrupt handling yet. Major changes are DCE4 handling for PLLs for the > 2 crtcs. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c370
1 files changed, 342 insertions, 28 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index bb45517719ae..7e7c0b32bb65 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -249,13 +249,17 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
249 if (ASIC_IS_DCE3(rdev)) 249 if (ASIC_IS_DCE3(rdev))
250 atombios_enable_crtc_memreq(crtc, 1); 250 atombios_enable_crtc_memreq(crtc, 1);
251 atombios_blank_crtc(crtc, 0); 251 atombios_blank_crtc(crtc, 0);
252 drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); 252 /* XXX re-enable when interrupt support is added */
253 if (!ASIC_IS_DCE4(rdev))
254 drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
253 radeon_crtc_load_lut(crtc); 255 radeon_crtc_load_lut(crtc);
254 break; 256 break;
255 case DRM_MODE_DPMS_STANDBY: 257 case DRM_MODE_DPMS_STANDBY:
256 case DRM_MODE_DPMS_SUSPEND: 258 case DRM_MODE_DPMS_SUSPEND:
257 case DRM_MODE_DPMS_OFF: 259 case DRM_MODE_DPMS_OFF:
258 drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); 260 /* XXX re-enable when interrupt support is added */
261 if (!ASIC_IS_DCE4(rdev))
262 drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
259 atombios_blank_crtc(crtc, 1); 263 atombios_blank_crtc(crtc, 1);
260 if (ASIC_IS_DCE3(rdev)) 264 if (ASIC_IS_DCE3(rdev))
261 atombios_enable_crtc_memreq(crtc, 0); 265 atombios_enable_crtc_memreq(crtc, 0);
@@ -367,6 +371,10 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
367 uint16_t percentage = 0; 371 uint16_t percentage = 0;
368 uint8_t type = 0, step = 0, delay = 0, range = 0; 372 uint8_t type = 0, step = 0, delay = 0, range = 0;
369 373
374 /* XXX add ss support for DCE4 */
375 if (ASIC_IS_DCE4(rdev))
376 return;
377
370 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 378 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
371 if (encoder->crtc == crtc) { 379 if (encoder->crtc == crtc) {
372 radeon_encoder = to_radeon_encoder(encoder); 380 radeon_encoder = to_radeon_encoder(encoder);
@@ -411,6 +419,7 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
411 419
412union adjust_pixel_clock { 420union adjust_pixel_clock {
413 ADJUST_DISPLAY_PLL_PS_ALLOCATION v1; 421 ADJUST_DISPLAY_PLL_PS_ALLOCATION v1;
422 ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 v3;
414}; 423};
415 424
416static u32 atombios_adjust_pll(struct drm_crtc *crtc, 425static u32 atombios_adjust_pll(struct drm_crtc *crtc,
@@ -422,6 +431,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
422 struct drm_encoder *encoder = NULL; 431 struct drm_encoder *encoder = NULL;
423 struct radeon_encoder *radeon_encoder = NULL; 432 struct radeon_encoder *radeon_encoder = NULL;
424 u32 adjusted_clock = mode->clock; 433 u32 adjusted_clock = mode->clock;
434 int encoder_mode = 0;
425 435
426 /* reset the pll flags */ 436 /* reset the pll flags */
427 pll->flags = 0; 437 pll->flags = 0;
@@ -459,6 +469,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
459 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 469 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
460 if (encoder->crtc == crtc) { 470 if (encoder->crtc == crtc) {
461 radeon_encoder = to_radeon_encoder(encoder); 471 radeon_encoder = to_radeon_encoder(encoder);
472 encoder_mode = atombios_get_encoder_mode(encoder);
462 if (ASIC_IS_AVIVO(rdev)) { 473 if (ASIC_IS_AVIVO(rdev)) {
463 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ 474 /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
464 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) 475 if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
@@ -484,14 +495,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
484 */ 495 */
485 if (ASIC_IS_DCE3(rdev)) { 496 if (ASIC_IS_DCE3(rdev)) {
486 union adjust_pixel_clock args; 497 union adjust_pixel_clock args;
487 struct radeon_encoder_atom_dig *dig;
488 u8 frev, crev; 498 u8 frev, crev;
489 int index; 499 int index;
490 500
491 if (!radeon_encoder->enc_priv)
492 return adjusted_clock;
493 dig = radeon_encoder->enc_priv;
494
495 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); 501 index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
496 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, 502 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
497 &crev); 503 &crev);
@@ -505,12 +511,51 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
505 case 2: 511 case 2:
506 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); 512 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
507 args.v1.ucTransmitterID = radeon_encoder->encoder_id; 513 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
508 args.v1.ucEncodeMode = atombios_get_encoder_mode(encoder); 514 args.v1.ucEncodeMode = encoder_mode;
509 515
510 atom_execute_table(rdev->mode_info.atom_context, 516 atom_execute_table(rdev->mode_info.atom_context,
511 index, (uint32_t *)&args); 517 index, (uint32_t *)&args);
512 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; 518 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
513 break; 519 break;
520 case 3:
521 args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10);
522 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
523 args.v3.sInput.ucEncodeMode = encoder_mode;
524 args.v3.sInput.ucDispPllConfig = 0;
525 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
526 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
527
528 if (encoder_mode == ATOM_ENCODER_MODE_DP)
529 args.v3.sInput.ucDispPllConfig |=
530 DISPPLL_CONFIG_COHERENT_MODE;
531 else {
532 if (dig->coherent_mode)
533 args.v3.sInput.ucDispPllConfig |=
534 DISPPLL_CONFIG_COHERENT_MODE;
535 if (mode->clock > 165000)
536 args.v3.sInput.ucDispPllConfig |=
537 DISPPLL_CONFIG_DUAL_LINK;
538 }
539 } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
540 /* may want to enable SS on DP/eDP eventually */
541 args.v3.sInput.ucDispPllConfig |=
542 DISPPLL_CONFIG_SS_ENABLE;
543 if (mode->clock > 165000)
544 args.v3.sInput.ucDispPllConfig |=
545 DISPPLL_CONFIG_DUAL_LINK;
546 }
547 atom_execute_table(rdev->mode_info.atom_context,
548 index, (uint32_t *)&args);
549 adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
550 if (args.v3.sOutput.ucRefDiv) {
551 pll->flags |= RADEON_PLL_USE_REF_DIV;
552 pll->reference_div = args.v3.sOutput.ucRefDiv;
553 }
554 if (args.v3.sOutput.ucPostDiv) {
555 pll->flags |= RADEON_PLL_USE_POST_DIV;
556 pll->post_div = args.v3.sOutput.ucPostDiv;
557 }
558 break;
514 default: 559 default:
515 DRM_ERROR("Unknown table version %d %d\n", frev, crev); 560 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
516 return adjusted_clock; 561 return adjusted_clock;
@@ -529,9 +574,47 @@ union set_pixel_clock {
529 PIXEL_CLOCK_PARAMETERS v1; 574 PIXEL_CLOCK_PARAMETERS v1;
530 PIXEL_CLOCK_PARAMETERS_V2 v2; 575 PIXEL_CLOCK_PARAMETERS_V2 v2;
531 PIXEL_CLOCK_PARAMETERS_V3 v3; 576 PIXEL_CLOCK_PARAMETERS_V3 v3;
577 PIXEL_CLOCK_PARAMETERS_V5 v5;
532}; 578};
533 579
534void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) 580static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
581{
582 struct drm_device *dev = crtc->dev;
583 struct radeon_device *rdev = dev->dev_private;
584 u8 frev, crev;
585 int index;
586 union set_pixel_clock args;
587
588 memset(&args, 0, sizeof(args));
589
590 index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
591 atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
592 &crev);
593
594 switch (frev) {
595 case 1:
596 switch (crev) {
597 case 5:
598 /* if the default dcpll clock is specified,
599 * SetPixelClock provides the dividers
600 */
601 args.v5.ucCRTC = ATOM_CRTC_INVALID;
602 args.v5.usPixelClock = rdev->clock.default_dispclk;
603 args.v5.ucPpll = ATOM_DCPLL;
604 break;
605 default:
606 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
607 return;
608 }
609 break;
610 default:
611 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
612 return;
613 }
614 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
615}
616
617static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
535{ 618{
536 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 619 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
537 struct drm_device *dev = crtc->dev; 620 struct drm_device *dev = crtc->dev;
@@ -545,12 +628,14 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
545 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; 628 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
546 struct radeon_pll *pll; 629 struct radeon_pll *pll;
547 u32 adjusted_clock; 630 u32 adjusted_clock;
631 int encoder_mode = 0;
548 632
549 memset(&args, 0, sizeof(args)); 633 memset(&args, 0, sizeof(args));
550 634
551 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 635 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
552 if (encoder->crtc == crtc) { 636 if (encoder->crtc == crtc) {
553 radeon_encoder = to_radeon_encoder(encoder); 637 radeon_encoder = to_radeon_encoder(encoder);
638 encoder_mode = atombios_get_encoder_mode(encoder);
554 break; 639 break;
555 } 640 }
556 } 641 }
@@ -558,10 +643,18 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
558 if (!radeon_encoder) 643 if (!radeon_encoder)
559 return; 644 return;
560 645
561 if (radeon_crtc->crtc_id == 0) 646 switch (radeon_crtc->pll_id) {
647 case ATOM_PPLL1:
562 pll = &rdev->clock.p1pll; 648 pll = &rdev->clock.p1pll;
563 else 649 break;
650 case ATOM_PPLL2:
564 pll = &rdev->clock.p2pll; 651 pll = &rdev->clock.p2pll;
652 break;
653 case ATOM_DCPLL:
654 case ATOM_PPLL_INVALID:
655 pll = &rdev->clock.dcpll;
656 break;
657 }
565 658
566 /* adjust pixel clock as needed */ 659 /* adjust pixel clock as needed */
567 adjusted_clock = atombios_adjust_pll(crtc, mode, pll); 660 adjusted_clock = atombios_adjust_pll(crtc, mode, pll);
@@ -582,8 +675,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
582 args.v1.usFbDiv = cpu_to_le16(fb_div); 675 args.v1.usFbDiv = cpu_to_le16(fb_div);
583 args.v1.ucFracFbDiv = frac_fb_div; 676 args.v1.ucFracFbDiv = frac_fb_div;
584 args.v1.ucPostDiv = post_div; 677 args.v1.ucPostDiv = post_div;
585 args.v1.ucPpll = 678 args.v1.ucPpll = radeon_crtc->pll_id;
586 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
587 args.v1.ucCRTC = radeon_crtc->crtc_id; 679 args.v1.ucCRTC = radeon_crtc->crtc_id;
588 args.v1.ucRefDivSrc = 1; 680 args.v1.ucRefDivSrc = 1;
589 break; 681 break;
@@ -593,8 +685,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
593 args.v2.usFbDiv = cpu_to_le16(fb_div); 685 args.v2.usFbDiv = cpu_to_le16(fb_div);
594 args.v2.ucFracFbDiv = frac_fb_div; 686 args.v2.ucFracFbDiv = frac_fb_div;
595 args.v2.ucPostDiv = post_div; 687 args.v2.ucPostDiv = post_div;
596 args.v2.ucPpll = 688 args.v2.ucPpll = radeon_crtc->pll_id;
597 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
598 args.v2.ucCRTC = radeon_crtc->crtc_id; 689 args.v2.ucCRTC = radeon_crtc->crtc_id;
599 args.v2.ucRefDivSrc = 1; 690 args.v2.ucRefDivSrc = 1;
600 break; 691 break;
@@ -604,12 +695,22 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
604 args.v3.usFbDiv = cpu_to_le16(fb_div); 695 args.v3.usFbDiv = cpu_to_le16(fb_div);
605 args.v3.ucFracFbDiv = frac_fb_div; 696 args.v3.ucFracFbDiv = frac_fb_div;
606 args.v3.ucPostDiv = post_div; 697 args.v3.ucPostDiv = post_div;
607 args.v3.ucPpll = 698 args.v3.ucPpll = radeon_crtc->pll_id;
608 radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; 699 args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2);
609 args.v3.ucMiscInfo = (radeon_crtc->crtc_id << 2);
610 args.v3.ucTransmitterId = radeon_encoder->encoder_id; 700 args.v3.ucTransmitterId = radeon_encoder->encoder_id;
611 args.v3.ucEncoderMode = 701 args.v3.ucEncoderMode = encoder_mode;
612 atombios_get_encoder_mode(encoder); 702 break;
703 case 5:
704 args.v5.ucCRTC = radeon_crtc->crtc_id;
705 args.v5.usPixelClock = cpu_to_le16(mode->clock / 10);
706 args.v5.ucRefDiv = ref_div;
707 args.v5.usFbDiv = cpu_to_le16(fb_div);
708 args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
709 args.v5.ucPostDiv = post_div;
710 args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
711 args.v5.ucTransmitterID = radeon_encoder->encoder_id;
712 args.v5.ucEncoderMode = encoder_mode;
713 args.v5.ucPpll = radeon_crtc->pll_id;
613 break; 714 break;
614 default: 715 default:
615 DRM_ERROR("Unknown table version %d %d\n", frev, crev); 716 DRM_ERROR("Unknown table version %d %d\n", frev, crev);
@@ -624,6 +725,140 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
624 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 725 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
625} 726}
626 727
728static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y,
729 struct drm_framebuffer *old_fb)
730{
731 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
732 struct drm_device *dev = crtc->dev;
733 struct radeon_device *rdev = dev->dev_private;
734 struct radeon_framebuffer *radeon_fb;
735 struct drm_gem_object *obj;
736 struct radeon_bo *rbo;
737 uint64_t fb_location;
738 uint32_t fb_format, fb_pitch_pixels, tiling_flags;
739 int r;
740
741 /* no fb bound */
742 if (!crtc->fb) {
743 DRM_DEBUG("No FB bound\n");
744 return 0;
745 }
746
747 radeon_fb = to_radeon_framebuffer(crtc->fb);
748
749 /* Pin framebuffer & get tilling informations */
750 obj = radeon_fb->obj;
751 rbo = obj->driver_private;
752 r = radeon_bo_reserve(rbo, false);
753 if (unlikely(r != 0))
754 return r;
755 r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
756 if (unlikely(r != 0)) {
757 radeon_bo_unreserve(rbo);
758 return -EINVAL;
759 }
760 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
761 radeon_bo_unreserve(rbo);
762
763 switch (crtc->fb->bits_per_pixel) {
764 case 8:
765 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
766 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
767 break;
768 case 15:
769 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
770 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
771 break;
772 case 16:
773 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
774 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
775 break;
776 case 24:
777 case 32:
778 fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
779 EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
780 break;
781 default:
782 DRM_ERROR("Unsupported screen depth %d\n",
783 crtc->fb->bits_per_pixel);
784 return -EINVAL;
785 }
786
787 switch (radeon_crtc->crtc_id) {
788 case 0:
789 WREG32(AVIVO_D1VGA_CONTROL, 0);
790 break;
791 case 1:
792 WREG32(AVIVO_D2VGA_CONTROL, 0);
793 break;
794 case 2:
795 WREG32(EVERGREEN_D3VGA_CONTROL, 0);
796 break;
797 case 3:
798 WREG32(EVERGREEN_D4VGA_CONTROL, 0);
799 break;
800 case 4:
801 WREG32(EVERGREEN_D5VGA_CONTROL, 0);
802 break;
803 case 5:
804 WREG32(EVERGREEN_D6VGA_CONTROL, 0);
805 break;
806 default:
807 break;
808 }
809
810 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
811 upper_32_bits(fb_location));
812 WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
813 upper_32_bits(fb_location));
814 WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
815 (u32)fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
816 WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
817 (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
818 WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
819
820 WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
821 WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
822 WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0);
823 WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0);
824 WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width);
825 WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height);
826
827 fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8);
828 WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
829 WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
830
831 WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
832 crtc->mode.vdisplay);
833 x &= ~3;
834 y &= ~1;
835 WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
836 (x << 16) | y);
837 WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
838 (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
839
840 if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
841 WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
842 EVERGREEN_INTERLEAVE_EN);
843 else
844 WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
845
846 if (old_fb && old_fb != crtc->fb) {
847 radeon_fb = to_radeon_framebuffer(old_fb);
848 rbo = radeon_fb->obj->driver_private;
849 r = radeon_bo_reserve(rbo, false);
850 if (unlikely(r != 0))
851 return r;
852 radeon_bo_unpin(rbo);
853 radeon_bo_unreserve(rbo);
854 }
855
856 /* Bytes per pixel may have changed */
857 radeon_bandwidth_update(rdev);
858
859 return 0;
860}
861
627static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, 862static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y,
628 struct drm_framebuffer *old_fb) 863 struct drm_framebuffer *old_fb)
629{ 864{
@@ -761,7 +996,9 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
761 struct drm_device *dev = crtc->dev; 996 struct drm_device *dev = crtc->dev;
762 struct radeon_device *rdev = dev->dev_private; 997 struct radeon_device *rdev = dev->dev_private;
763 998
764 if (ASIC_IS_AVIVO(rdev)) 999 if (ASIC_IS_DCE4(rdev))
1000 return evergreen_crtc_set_base(crtc, x, y, old_fb);
1001 else if (ASIC_IS_AVIVO(rdev))
765 return avivo_crtc_set_base(crtc, x, y, old_fb); 1002 return avivo_crtc_set_base(crtc, x, y, old_fb);
766 else 1003 else
767 return radeon_crtc_set_base(crtc, x, y, old_fb); 1004 return radeon_crtc_set_base(crtc, x, y, old_fb);
@@ -791,6 +1028,46 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
791 } 1028 }
792} 1029}
793 1030
1031static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1032{
1033 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1034 struct drm_device *dev = crtc->dev;
1035 struct radeon_device *rdev = dev->dev_private;
1036 struct drm_encoder *test_encoder;
1037 struct drm_crtc *test_crtc;
1038 uint32_t pll_in_use = 0;
1039
1040 if (ASIC_IS_DCE4(rdev)) {
1041 /* if crtc is driving DP and we have an ext clock, use that */
1042 list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1043 if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
1044 if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) {
1045 if (rdev->clock.dp_extclk)
1046 return ATOM_PPLL_INVALID;
1047 }
1048 }
1049 }
1050
1051 /* otherwise, pick one of the plls */
1052 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1053 struct radeon_crtc *radeon_test_crtc;
1054
1055 if (crtc == test_crtc)
1056 continue;
1057
1058 radeon_test_crtc = to_radeon_crtc(test_crtc);
1059 if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
1060 (radeon_test_crtc->pll_id <= ATOM_PPLL2))
1061 pll_in_use |= (1 << radeon_test_crtc->pll_id);
1062 }
1063 if (!(pll_in_use & 1))
1064 return ATOM_PPLL1;
1065 return ATOM_PPLL2;
1066 } else
1067 return radeon_crtc->crtc_id;
1068
1069}
1070
794int atombios_crtc_mode_set(struct drm_crtc *crtc, 1071int atombios_crtc_mode_set(struct drm_crtc *crtc,
795 struct drm_display_mode *mode, 1072 struct drm_display_mode *mode,
796 struct drm_display_mode *adjusted_mode, 1073 struct drm_display_mode *adjusted_mode,
@@ -802,19 +1079,27 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
802 1079
803 /* TODO color tiling */ 1080 /* TODO color tiling */
804 1081
1082 /* pick pll */
1083 radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
1084
805 atombios_set_ss(crtc, 0); 1085 atombios_set_ss(crtc, 0);
1086 /* always set DCPLL */
1087 if (ASIC_IS_DCE4(rdev))
1088 atombios_crtc_set_dcpll(crtc);
806 atombios_crtc_set_pll(crtc, adjusted_mode); 1089 atombios_crtc_set_pll(crtc, adjusted_mode);
807 atombios_set_ss(crtc, 1); 1090 atombios_set_ss(crtc, 1);
808 atombios_crtc_set_timing(crtc, adjusted_mode);
809 1091
810 if (ASIC_IS_AVIVO(rdev)) 1092 if (ASIC_IS_DCE4(rdev))
811 atombios_crtc_set_base(crtc, x, y, old_fb); 1093 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
1094 else if (ASIC_IS_AVIVO(rdev))
1095 atombios_crtc_set_timing(crtc, adjusted_mode);
812 else { 1096 else {
1097 atombios_crtc_set_timing(crtc, adjusted_mode);
813 if (radeon_crtc->crtc_id == 0) 1098 if (radeon_crtc->crtc_id == 0)
814 atombios_set_crtc_dtd_timing(crtc, adjusted_mode); 1099 atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
815 atombios_crtc_set_base(crtc, x, y, old_fb);
816 radeon_legacy_atom_fixup(crtc); 1100 radeon_legacy_atom_fixup(crtc);
817 } 1101 }
1102 atombios_crtc_set_base(crtc, x, y, old_fb);
818 atombios_overscan_setup(crtc, mode, adjusted_mode); 1103 atombios_overscan_setup(crtc, mode, adjusted_mode);
819 atombios_scaler_setup(crtc); 1104 atombios_scaler_setup(crtc);
820 return 0; 1105 return 0;
@@ -854,8 +1139,37 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
854void radeon_atombios_init_crtc(struct drm_device *dev, 1139void radeon_atombios_init_crtc(struct drm_device *dev,
855 struct radeon_crtc *radeon_crtc) 1140 struct radeon_crtc *radeon_crtc)
856{ 1141{
857 if (radeon_crtc->crtc_id == 1) 1142 struct radeon_device *rdev = dev->dev_private;
858 radeon_crtc->crtc_offset = 1143
859 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL; 1144 if (ASIC_IS_DCE4(rdev)) {
1145 switch (radeon_crtc->crtc_id) {
1146 case 0:
1147 default:
1148 radeon_crtc->crtc_id = EVERGREEN_CRTC0_REGISTER_OFFSET;
1149 break;
1150 case 1:
1151 radeon_crtc->crtc_id = EVERGREEN_CRTC1_REGISTER_OFFSET;
1152 break;
1153 case 2:
1154 radeon_crtc->crtc_id = EVERGREEN_CRTC2_REGISTER_OFFSET;
1155 break;
1156 case 3:
1157 radeon_crtc->crtc_id = EVERGREEN_CRTC3_REGISTER_OFFSET;
1158 break;
1159 case 4:
1160 radeon_crtc->crtc_id = EVERGREEN_CRTC4_REGISTER_OFFSET;
1161 break;
1162 case 5:
1163 radeon_crtc->crtc_id = EVERGREEN_CRTC5_REGISTER_OFFSET;
1164 break;
1165 }
1166 } else {
1167 if (radeon_crtc->crtc_id == 1)
1168 radeon_crtc->crtc_offset =
1169 AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
1170 else
1171 radeon_crtc->crtc_offset = 0;
1172 }
1173 radeon_crtc->pll_id = -1;
860 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); 1174 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
861} 1175}