diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 212 |
1 files changed, 128 insertions, 84 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 8c2d6478a221..12ad512bd3d3 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -44,10 +44,6 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, | |||
44 | 44 | ||
45 | memset(&args, 0, sizeof(args)); | 45 | memset(&args, 0, sizeof(args)); |
46 | 46 | ||
47 | args.usOverscanRight = 0; | ||
48 | args.usOverscanLeft = 0; | ||
49 | args.usOverscanBottom = 0; | ||
50 | args.usOverscanTop = 0; | ||
51 | args.ucCRTC = radeon_crtc->crtc_id; | 47 | args.ucCRTC = radeon_crtc->crtc_id; |
52 | 48 | ||
53 | switch (radeon_crtc->rmx_type) { | 49 | switch (radeon_crtc->rmx_type) { |
@@ -56,7 +52,6 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, | |||
56 | args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; | 52 | args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; |
57 | args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; | 53 | args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; |
58 | args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; | 54 | args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; |
59 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
60 | break; | 55 | break; |
61 | case RMX_ASPECT: | 56 | case RMX_ASPECT: |
62 | a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; | 57 | a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; |
@@ -69,17 +64,16 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, | |||
69 | args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; | 64 | args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; |
70 | args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; | 65 | args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; |
71 | } | 66 | } |
72 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
73 | break; | 67 | break; |
74 | case RMX_FULL: | 68 | case RMX_FULL: |
75 | default: | 69 | default: |
76 | args.usOverscanRight = 0; | 70 | args.usOverscanRight = radeon_crtc->h_border; |
77 | args.usOverscanLeft = 0; | 71 | args.usOverscanLeft = radeon_crtc->h_border; |
78 | args.usOverscanBottom = 0; | 72 | args.usOverscanBottom = radeon_crtc->v_border; |
79 | args.usOverscanTop = 0; | 73 | args.usOverscanTop = radeon_crtc->v_border; |
80 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
81 | break; | 74 | break; |
82 | } | 75 | } |
76 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
83 | } | 77 | } |
84 | 78 | ||
85 | static void atombios_scaler_setup(struct drm_crtc *crtc) | 79 | static void atombios_scaler_setup(struct drm_crtc *crtc) |
@@ -282,22 +276,22 @@ atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, | |||
282 | u16 misc = 0; | 276 | u16 misc = 0; |
283 | 277 | ||
284 | memset(&args, 0, sizeof(args)); | 278 | memset(&args, 0, sizeof(args)); |
285 | args.usH_Size = cpu_to_le16(mode->crtc_hdisplay); | 279 | args.usH_Size = cpu_to_le16(mode->crtc_hdisplay - (radeon_crtc->h_border * 2)); |
286 | args.usH_Blanking_Time = | 280 | args.usH_Blanking_Time = |
287 | cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay); | 281 | cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay + (radeon_crtc->h_border * 2)); |
288 | args.usV_Size = cpu_to_le16(mode->crtc_vdisplay); | 282 | args.usV_Size = cpu_to_le16(mode->crtc_vdisplay - (radeon_crtc->v_border * 2)); |
289 | args.usV_Blanking_Time = | 283 | args.usV_Blanking_Time = |
290 | cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay); | 284 | cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay + (radeon_crtc->v_border * 2)); |
291 | args.usH_SyncOffset = | 285 | args.usH_SyncOffset = |
292 | cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay); | 286 | cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay + radeon_crtc->h_border); |
293 | args.usH_SyncWidth = | 287 | args.usH_SyncWidth = |
294 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); | 288 | cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
295 | args.usV_SyncOffset = | 289 | args.usV_SyncOffset = |
296 | cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay); | 290 | cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay + radeon_crtc->v_border); |
297 | args.usV_SyncWidth = | 291 | args.usV_SyncWidth = |
298 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | 292 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
299 | /*args.ucH_Border = mode->hborder;*/ | 293 | args.ucH_Border = radeon_crtc->h_border; |
300 | /*args.ucV_Border = mode->vborder;*/ | 294 | args.ucV_Border = radeon_crtc->v_border; |
301 | 295 | ||
302 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | 296 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
303 | misc |= ATOM_VSYNC_POLARITY; | 297 | misc |= ATOM_VSYNC_POLARITY; |
@@ -669,56 +663,25 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) | |||
669 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 663 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
670 | } | 664 | } |
671 | 665 | ||
672 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | 666 | static void atombios_crtc_program_pll(struct drm_crtc *crtc, |
667 | int crtc_id, | ||
668 | int pll_id, | ||
669 | u32 encoder_mode, | ||
670 | u32 encoder_id, | ||
671 | u32 clock, | ||
672 | u32 ref_div, | ||
673 | u32 fb_div, | ||
674 | u32 frac_fb_div, | ||
675 | u32 post_div) | ||
673 | { | 676 | { |
674 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
675 | struct drm_device *dev = crtc->dev; | 677 | struct drm_device *dev = crtc->dev; |
676 | struct radeon_device *rdev = dev->dev_private; | 678 | struct radeon_device *rdev = dev->dev_private; |
677 | struct drm_encoder *encoder = NULL; | ||
678 | struct radeon_encoder *radeon_encoder = NULL; | ||
679 | u8 frev, crev; | 679 | u8 frev, crev; |
680 | int index; | 680 | int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); |
681 | union set_pixel_clock args; | 681 | union set_pixel_clock args; |
682 | u32 pll_clock = mode->clock; | ||
683 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | ||
684 | struct radeon_pll *pll; | ||
685 | u32 adjusted_clock; | ||
686 | int encoder_mode = 0; | ||
687 | 682 | ||
688 | memset(&args, 0, sizeof(args)); | 683 | memset(&args, 0, sizeof(args)); |
689 | 684 | ||
690 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
691 | if (encoder->crtc == crtc) { | ||
692 | radeon_encoder = to_radeon_encoder(encoder); | ||
693 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
694 | break; | ||
695 | } | ||
696 | } | ||
697 | |||
698 | if (!radeon_encoder) | ||
699 | return; | ||
700 | |||
701 | switch (radeon_crtc->pll_id) { | ||
702 | case ATOM_PPLL1: | ||
703 | pll = &rdev->clock.p1pll; | ||
704 | break; | ||
705 | case ATOM_PPLL2: | ||
706 | pll = &rdev->clock.p2pll; | ||
707 | break; | ||
708 | case ATOM_DCPLL: | ||
709 | case ATOM_PPLL_INVALID: | ||
710 | default: | ||
711 | pll = &rdev->clock.dcpll; | ||
712 | break; | ||
713 | } | ||
714 | |||
715 | /* adjust pixel clock as needed */ | ||
716 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll); | ||
717 | |||
718 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | ||
719 | &ref_div, &post_div); | ||
720 | |||
721 | index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); | ||
722 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, | 685 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
723 | &crev)) | 686 | &crev)) |
724 | return; | 687 | return; |
@@ -727,47 +690,49 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
727 | case 1: | 690 | case 1: |
728 | switch (crev) { | 691 | switch (crev) { |
729 | case 1: | 692 | case 1: |
730 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 693 | if (clock == ATOM_DISABLE) |
694 | return; | ||
695 | args.v1.usPixelClock = cpu_to_le16(clock / 10); | ||
731 | args.v1.usRefDiv = cpu_to_le16(ref_div); | 696 | args.v1.usRefDiv = cpu_to_le16(ref_div); |
732 | args.v1.usFbDiv = cpu_to_le16(fb_div); | 697 | args.v1.usFbDiv = cpu_to_le16(fb_div); |
733 | args.v1.ucFracFbDiv = frac_fb_div; | 698 | args.v1.ucFracFbDiv = frac_fb_div; |
734 | args.v1.ucPostDiv = post_div; | 699 | args.v1.ucPostDiv = post_div; |
735 | args.v1.ucPpll = radeon_crtc->pll_id; | 700 | args.v1.ucPpll = pll_id; |
736 | args.v1.ucCRTC = radeon_crtc->crtc_id; | 701 | args.v1.ucCRTC = crtc_id; |
737 | args.v1.ucRefDivSrc = 1; | 702 | args.v1.ucRefDivSrc = 1; |
738 | break; | 703 | break; |
739 | case 2: | 704 | case 2: |
740 | args.v2.usPixelClock = cpu_to_le16(mode->clock / 10); | 705 | args.v2.usPixelClock = cpu_to_le16(clock / 10); |
741 | args.v2.usRefDiv = cpu_to_le16(ref_div); | 706 | args.v2.usRefDiv = cpu_to_le16(ref_div); |
742 | args.v2.usFbDiv = cpu_to_le16(fb_div); | 707 | args.v2.usFbDiv = cpu_to_le16(fb_div); |
743 | args.v2.ucFracFbDiv = frac_fb_div; | 708 | args.v2.ucFracFbDiv = frac_fb_div; |
744 | args.v2.ucPostDiv = post_div; | 709 | args.v2.ucPostDiv = post_div; |
745 | args.v2.ucPpll = radeon_crtc->pll_id; | 710 | args.v2.ucPpll = pll_id; |
746 | args.v2.ucCRTC = radeon_crtc->crtc_id; | 711 | args.v2.ucCRTC = crtc_id; |
747 | args.v2.ucRefDivSrc = 1; | 712 | args.v2.ucRefDivSrc = 1; |
748 | break; | 713 | break; |
749 | case 3: | 714 | case 3: |
750 | args.v3.usPixelClock = cpu_to_le16(mode->clock / 10); | 715 | args.v3.usPixelClock = cpu_to_le16(clock / 10); |
751 | args.v3.usRefDiv = cpu_to_le16(ref_div); | 716 | args.v3.usRefDiv = cpu_to_le16(ref_div); |
752 | args.v3.usFbDiv = cpu_to_le16(fb_div); | 717 | args.v3.usFbDiv = cpu_to_le16(fb_div); |
753 | args.v3.ucFracFbDiv = frac_fb_div; | 718 | args.v3.ucFracFbDiv = frac_fb_div; |
754 | args.v3.ucPostDiv = post_div; | 719 | args.v3.ucPostDiv = post_div; |
755 | args.v3.ucPpll = radeon_crtc->pll_id; | 720 | args.v3.ucPpll = pll_id; |
756 | args.v3.ucMiscInfo = (radeon_crtc->pll_id << 2); | 721 | args.v3.ucMiscInfo = (pll_id << 2); |
757 | args.v3.ucTransmitterId = radeon_encoder->encoder_id; | 722 | args.v3.ucTransmitterId = encoder_id; |
758 | args.v3.ucEncoderMode = encoder_mode; | 723 | args.v3.ucEncoderMode = encoder_mode; |
759 | break; | 724 | break; |
760 | case 5: | 725 | case 5: |
761 | args.v5.ucCRTC = radeon_crtc->crtc_id; | 726 | args.v5.ucCRTC = crtc_id; |
762 | args.v5.usPixelClock = cpu_to_le16(mode->clock / 10); | 727 | args.v5.usPixelClock = cpu_to_le16(clock / 10); |
763 | args.v5.ucRefDiv = ref_div; | 728 | args.v5.ucRefDiv = ref_div; |
764 | args.v5.usFbDiv = cpu_to_le16(fb_div); | 729 | args.v5.usFbDiv = cpu_to_le16(fb_div); |
765 | args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); | 730 | args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); |
766 | args.v5.ucPostDiv = post_div; | 731 | args.v5.ucPostDiv = post_div; |
767 | args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ | 732 | args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ |
768 | args.v5.ucTransmitterID = radeon_encoder->encoder_id; | 733 | args.v5.ucTransmitterID = encoder_id; |
769 | args.v5.ucEncoderMode = encoder_mode; | 734 | args.v5.ucEncoderMode = encoder_mode; |
770 | args.v5.ucPpll = radeon_crtc->pll_id; | 735 | args.v5.ucPpll = pll_id; |
771 | break; | 736 | break; |
772 | default: | 737 | default: |
773 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); | 738 | DRM_ERROR("Unknown table version %d %d\n", frev, crev); |
@@ -782,6 +747,56 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
782 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 747 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
783 | } | 748 | } |
784 | 749 | ||
750 | static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | ||
751 | { | ||
752 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
753 | struct drm_device *dev = crtc->dev; | ||
754 | struct radeon_device *rdev = dev->dev_private; | ||
755 | struct drm_encoder *encoder = NULL; | ||
756 | struct radeon_encoder *radeon_encoder = NULL; | ||
757 | u32 pll_clock = mode->clock; | ||
758 | u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; | ||
759 | struct radeon_pll *pll; | ||
760 | u32 adjusted_clock; | ||
761 | int encoder_mode = 0; | ||
762 | |||
763 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
764 | if (encoder->crtc == crtc) { | ||
765 | radeon_encoder = to_radeon_encoder(encoder); | ||
766 | encoder_mode = atombios_get_encoder_mode(encoder); | ||
767 | break; | ||
768 | } | ||
769 | } | ||
770 | |||
771 | if (!radeon_encoder) | ||
772 | return; | ||
773 | |||
774 | switch (radeon_crtc->pll_id) { | ||
775 | case ATOM_PPLL1: | ||
776 | pll = &rdev->clock.p1pll; | ||
777 | break; | ||
778 | case ATOM_PPLL2: | ||
779 | pll = &rdev->clock.p2pll; | ||
780 | break; | ||
781 | case ATOM_DCPLL: | ||
782 | case ATOM_PPLL_INVALID: | ||
783 | default: | ||
784 | pll = &rdev->clock.dcpll; | ||
785 | break; | ||
786 | } | ||
787 | |||
788 | /* adjust pixel clock as needed */ | ||
789 | adjusted_clock = atombios_adjust_pll(crtc, mode, pll); | ||
790 | |||
791 | radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | ||
792 | &ref_div, &post_div); | ||
793 | |||
794 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | ||
795 | encoder_mode, radeon_encoder->encoder_id, mode->clock, | ||
796 | ref_div, fb_div, frac_fb_div, post_div); | ||
797 | |||
798 | } | ||
799 | |||
785 | static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 800 | static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
786 | struct drm_framebuffer *old_fb) | 801 | struct drm_framebuffer *old_fb) |
787 | { | 802 | { |
@@ -797,7 +812,7 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
797 | 812 | ||
798 | /* no fb bound */ | 813 | /* no fb bound */ |
799 | if (!crtc->fb) { | 814 | if (!crtc->fb) { |
800 | DRM_DEBUG("No FB bound\n"); | 815 | DRM_DEBUG_KMS("No FB bound\n"); |
801 | return 0; | 816 | return 0; |
802 | } | 817 | } |
803 | 818 | ||
@@ -841,6 +856,11 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
841 | return -EINVAL; | 856 | return -EINVAL; |
842 | } | 857 | } |
843 | 858 | ||
859 | if (tiling_flags & RADEON_TILING_MACRO) | ||
860 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); | ||
861 | else if (tiling_flags & RADEON_TILING_MICRO) | ||
862 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); | ||
863 | |||
844 | switch (radeon_crtc->crtc_id) { | 864 | switch (radeon_crtc->crtc_id) { |
845 | case 0: | 865 | case 0: |
846 | WREG32(AVIVO_D1VGA_CONTROL, 0); | 866 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
@@ -931,7 +951,7 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
931 | 951 | ||
932 | /* no fb bound */ | 952 | /* no fb bound */ |
933 | if (!crtc->fb) { | 953 | if (!crtc->fb) { |
934 | DRM_DEBUG("No FB bound\n"); | 954 | DRM_DEBUG_KMS("No FB bound\n"); |
935 | return 0; | 955 | return 0; |
936 | } | 956 | } |
937 | 957 | ||
@@ -979,11 +999,18 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
979 | return -EINVAL; | 999 | return -EINVAL; |
980 | } | 1000 | } |
981 | 1001 | ||
982 | if (tiling_flags & RADEON_TILING_MACRO) | 1002 | if (rdev->family >= CHIP_R600) { |
983 | fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; | 1003 | if (tiling_flags & RADEON_TILING_MACRO) |
1004 | fb_format |= R600_D1GRPH_ARRAY_MODE_2D_TILED_THIN1; | ||
1005 | else if (tiling_flags & RADEON_TILING_MICRO) | ||
1006 | fb_format |= R600_D1GRPH_ARRAY_MODE_1D_TILED_THIN1; | ||
1007 | } else { | ||
1008 | if (tiling_flags & RADEON_TILING_MACRO) | ||
1009 | fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE; | ||
984 | 1010 | ||
985 | if (tiling_flags & RADEON_TILING_MICRO) | 1011 | if (tiling_flags & RADEON_TILING_MICRO) |
986 | fb_format |= AVIVO_D1GRPH_TILED; | 1012 | fb_format |= AVIVO_D1GRPH_TILED; |
1013 | } | ||
987 | 1014 | ||
988 | if (radeon_crtc->crtc_id == 0) | 1015 | if (radeon_crtc->crtc_id == 0) |
989 | WREG32(AVIVO_D1VGA_CONTROL, 0); | 1016 | WREG32(AVIVO_D1VGA_CONTROL, 0); |
@@ -1143,10 +1170,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1143 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1170 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1144 | atombios_enable_ss(crtc); | 1171 | atombios_enable_ss(crtc); |
1145 | 1172 | ||
1146 | if (ASIC_IS_DCE4(rdev)) | 1173 | if (ASIC_IS_AVIVO(rdev)) |
1147 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1174 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
1148 | else if (ASIC_IS_AVIVO(rdev)) | ||
1149 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
1150 | else { | 1175 | else { |
1151 | atombios_crtc_set_timing(crtc, adjusted_mode); | 1176 | atombios_crtc_set_timing(crtc, adjusted_mode); |
1152 | if (radeon_crtc->crtc_id == 0) | 1177 | if (radeon_crtc->crtc_id == 0) |
@@ -1191,6 +1216,24 @@ static void atombios_crtc_commit(struct drm_crtc *crtc) | |||
1191 | atombios_lock_crtc(crtc, ATOM_DISABLE); | 1216 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
1192 | } | 1217 | } |
1193 | 1218 | ||
1219 | static void atombios_crtc_disable(struct drm_crtc *crtc) | ||
1220 | { | ||
1221 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1222 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | ||
1223 | |||
1224 | switch (radeon_crtc->pll_id) { | ||
1225 | case ATOM_PPLL1: | ||
1226 | case ATOM_PPLL2: | ||
1227 | /* disable the ppll */ | ||
1228 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | ||
1229 | 0, 0, ATOM_DISABLE, 0, 0, 0, 0); | ||
1230 | break; | ||
1231 | default: | ||
1232 | break; | ||
1233 | } | ||
1234 | radeon_crtc->pll_id = -1; | ||
1235 | } | ||
1236 | |||
1194 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | 1237 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { |
1195 | .dpms = atombios_crtc_dpms, | 1238 | .dpms = atombios_crtc_dpms, |
1196 | .mode_fixup = atombios_crtc_mode_fixup, | 1239 | .mode_fixup = atombios_crtc_mode_fixup, |
@@ -1199,6 +1242,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | |||
1199 | .prepare = atombios_crtc_prepare, | 1242 | .prepare = atombios_crtc_prepare, |
1200 | .commit = atombios_crtc_commit, | 1243 | .commit = atombios_crtc_commit, |
1201 | .load_lut = radeon_crtc_load_lut, | 1244 | .load_lut = radeon_crtc_load_lut, |
1245 | .disable = atombios_crtc_disable, | ||
1202 | }; | 1246 | }; |
1203 | 1247 | ||
1204 | void radeon_atombios_init_crtc(struct drm_device *dev, | 1248 | void radeon_atombios_init_crtc(struct drm_device *dev, |