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.c212
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
85static void atombios_scaler_setup(struct drm_crtc *crtc) 79static 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
672static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) 666static 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
750static 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
785static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, 800static 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
1219static 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
1194static const struct drm_crtc_helper_funcs atombios_helper_funcs = { 1237static 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
1204void radeon_atombios_init_crtc(struct drm_device *dev, 1248void radeon_atombios_init_crtc(struct drm_device *dev,