diff options
author | Chris Ball <cjb@laptop.org> | 2010-09-26 07:47:23 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-10-05 21:50:08 -0400 |
commit | 4dd19b0dd79c2bfe04a7a19bea0caf9284695cb4 (patch) | |
tree | ddca5a8285fce21fd87aecd13b6495044ad855a6 /drivers/gpu/drm/radeon | |
parent | e6b46ee712b92db1cc2449cf4f65bc635366cad4 (diff) |
drm/radeon/kms: Implement KDB debug hooks for radeon KMS.
Signed-off-by: Chris Ball <cjb@laptop.org>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
CC: Jesse Barnes <jbarnes@virtuousgeek.org>
CC: dri-devel@lists.freedesktop.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 119 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 10 |
4 files changed, 129 insertions, 47 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index cd0290f946cf..2ab9b360d3c9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -854,13 +854,15 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
854 | 854 | ||
855 | } | 855 | } |
856 | 856 | ||
857 | static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 857 | static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, |
858 | struct drm_framebuffer *old_fb) | 858 | struct drm_framebuffer *fb, |
859 | int x, int y, int atomic) | ||
859 | { | 860 | { |
860 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 861 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
861 | struct drm_device *dev = crtc->dev; | 862 | struct drm_device *dev = crtc->dev; |
862 | struct radeon_device *rdev = dev->dev_private; | 863 | struct radeon_device *rdev = dev->dev_private; |
863 | struct radeon_framebuffer *radeon_fb; | 864 | struct radeon_framebuffer *radeon_fb; |
865 | struct drm_framebuffer *target_fb; | ||
864 | struct drm_gem_object *obj; | 866 | struct drm_gem_object *obj; |
865 | struct radeon_bo *rbo; | 867 | struct radeon_bo *rbo; |
866 | uint64_t fb_location; | 868 | uint64_t fb_location; |
@@ -868,28 +870,43 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
868 | int r; | 870 | int r; |
869 | 871 | ||
870 | /* no fb bound */ | 872 | /* no fb bound */ |
871 | if (!crtc->fb) { | 873 | if (!atomic && !crtc->fb) { |
872 | DRM_DEBUG_KMS("No FB bound\n"); | 874 | DRM_DEBUG_KMS("No FB bound\n"); |
873 | return 0; | 875 | return 0; |
874 | } | 876 | } |
875 | 877 | ||
876 | radeon_fb = to_radeon_framebuffer(crtc->fb); | 878 | if (atomic) { |
879 | radeon_fb = to_radeon_framebuffer(fb); | ||
880 | target_fb = fb; | ||
881 | } | ||
882 | else { | ||
883 | radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
884 | target_fb = crtc->fb; | ||
885 | } | ||
877 | 886 | ||
878 | /* Pin framebuffer & get tilling informations */ | 887 | /* If atomic, assume fb object is pinned & idle & fenced and |
888 | * just update base pointers | ||
889 | */ | ||
879 | obj = radeon_fb->obj; | 890 | obj = radeon_fb->obj; |
880 | rbo = obj->driver_private; | 891 | rbo = obj->driver_private; |
881 | r = radeon_bo_reserve(rbo, false); | 892 | r = radeon_bo_reserve(rbo, false); |
882 | if (unlikely(r != 0)) | 893 | if (unlikely(r != 0)) |
883 | return r; | 894 | return r; |
884 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | 895 | |
885 | if (unlikely(r != 0)) { | 896 | if (atomic) |
886 | radeon_bo_unreserve(rbo); | 897 | fb_location = radeon_bo_gpu_offset(rbo); |
887 | return -EINVAL; | 898 | else { |
899 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | ||
900 | if (unlikely(r != 0)) { | ||
901 | radeon_bo_unreserve(rbo); | ||
902 | return -EINVAL; | ||
903 | } | ||
888 | } | 904 | } |
905 | |||
889 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | 906 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); |
890 | radeon_bo_unreserve(rbo); | 907 | radeon_bo_unreserve(rbo); |
891 | 908 | ||
892 | switch (crtc->fb->bits_per_pixel) { | 909 | switch (target_fb->bits_per_pixel) { |
893 | case 8: | 910 | case 8: |
894 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | | 911 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | |
895 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); | 912 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); |
@@ -909,7 +926,7 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
909 | break; | 926 | break; |
910 | default: | 927 | default: |
911 | DRM_ERROR("Unsupported screen depth %d\n", | 928 | DRM_ERROR("Unsupported screen depth %d\n", |
912 | crtc->fb->bits_per_pixel); | 929 | target_fb->bits_per_pixel); |
913 | return -EINVAL; | 930 | return -EINVAL; |
914 | } | 931 | } |
915 | 932 | ||
@@ -955,10 +972,10 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
955 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 972 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
956 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); | 973 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); |
957 | WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); | 974 | WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
958 | WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); | 975 | WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); |
959 | WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); | 976 | WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); |
960 | 977 | ||
961 | fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); | 978 | fb_pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8); |
962 | WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); | 979 | WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
963 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | 980 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
964 | 981 | ||
@@ -977,8 +994,8 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
977 | else | 994 | else |
978 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | 995 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); |
979 | 996 | ||
980 | if (old_fb && old_fb != crtc->fb) { | 997 | if (!atomic && fb && fb != crtc->fb) { |
981 | radeon_fb = to_radeon_framebuffer(old_fb); | 998 | radeon_fb = to_radeon_framebuffer(fb); |
982 | rbo = radeon_fb->obj->driver_private; | 999 | rbo = radeon_fb->obj->driver_private; |
983 | r = radeon_bo_reserve(rbo, false); | 1000 | r = radeon_bo_reserve(rbo, false); |
984 | if (unlikely(r != 0)) | 1001 | if (unlikely(r != 0)) |
@@ -993,8 +1010,9 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
993 | return 0; | 1010 | return 0; |
994 | } | 1011 | } |
995 | 1012 | ||
996 | static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 1013 | static int avivo_crtc_do_set_base(struct drm_crtc *crtc, |
997 | struct drm_framebuffer *old_fb) | 1014 | struct drm_framebuffer *fb, |
1015 | int x, int y, int atomic) | ||
998 | { | 1016 | { |
999 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1017 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1000 | struct drm_device *dev = crtc->dev; | 1018 | struct drm_device *dev = crtc->dev; |
@@ -1002,33 +1020,48 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1002 | struct radeon_framebuffer *radeon_fb; | 1020 | struct radeon_framebuffer *radeon_fb; |
1003 | struct drm_gem_object *obj; | 1021 | struct drm_gem_object *obj; |
1004 | struct radeon_bo *rbo; | 1022 | struct radeon_bo *rbo; |
1023 | struct drm_framebuffer *target_fb; | ||
1005 | uint64_t fb_location; | 1024 | uint64_t fb_location; |
1006 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; | 1025 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
1007 | int r; | 1026 | int r; |
1008 | 1027 | ||
1009 | /* no fb bound */ | 1028 | /* no fb bound */ |
1010 | if (!crtc->fb) { | 1029 | if (!atomic && !crtc->fb) { |
1011 | DRM_DEBUG_KMS("No FB bound\n"); | 1030 | DRM_DEBUG_KMS("No FB bound\n"); |
1012 | return 0; | 1031 | return 0; |
1013 | } | 1032 | } |
1014 | 1033 | ||
1015 | radeon_fb = to_radeon_framebuffer(crtc->fb); | 1034 | if (atomic) { |
1035 | radeon_fb = to_radeon_framebuffer(fb); | ||
1036 | target_fb = fb; | ||
1037 | } | ||
1038 | else { | ||
1039 | radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
1040 | target_fb = crtc->fb; | ||
1041 | } | ||
1016 | 1042 | ||
1017 | /* Pin framebuffer & get tilling informations */ | ||
1018 | obj = radeon_fb->obj; | 1043 | obj = radeon_fb->obj; |
1019 | rbo = obj->driver_private; | 1044 | rbo = obj->driver_private; |
1020 | r = radeon_bo_reserve(rbo, false); | 1045 | r = radeon_bo_reserve(rbo, false); |
1021 | if (unlikely(r != 0)) | 1046 | if (unlikely(r != 0)) |
1022 | return r; | 1047 | return r; |
1023 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | 1048 | |
1024 | if (unlikely(r != 0)) { | 1049 | /* If atomic, assume fb object is pinned & idle & fenced and |
1025 | radeon_bo_unreserve(rbo); | 1050 | * just update base pointers |
1026 | return -EINVAL; | 1051 | */ |
1052 | if (atomic) | ||
1053 | fb_location = radeon_bo_gpu_offset(rbo); | ||
1054 | else { | ||
1055 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | ||
1056 | if (unlikely(r != 0)) { | ||
1057 | radeon_bo_unreserve(rbo); | ||
1058 | return -EINVAL; | ||
1059 | } | ||
1027 | } | 1060 | } |
1028 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | 1061 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); |
1029 | radeon_bo_unreserve(rbo); | 1062 | radeon_bo_unreserve(rbo); |
1030 | 1063 | ||
1031 | switch (crtc->fb->bits_per_pixel) { | 1064 | switch (target_fb->bits_per_pixel) { |
1032 | case 8: | 1065 | case 8: |
1033 | fb_format = | 1066 | fb_format = |
1034 | AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | | 1067 | AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | |
@@ -1052,7 +1085,7 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1052 | break; | 1085 | break; |
1053 | default: | 1086 | default: |
1054 | DRM_ERROR("Unsupported screen depth %d\n", | 1087 | DRM_ERROR("Unsupported screen depth %d\n", |
1055 | crtc->fb->bits_per_pixel); | 1088 | target_fb->bits_per_pixel); |
1056 | return -EINVAL; | 1089 | return -EINVAL; |
1057 | } | 1090 | } |
1058 | 1091 | ||
@@ -1093,10 +1126,10 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1093 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 1126 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
1094 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); | 1127 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); |
1095 | WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); | 1128 | WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
1096 | WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); | 1129 | WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); |
1097 | WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); | 1130 | WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); |
1098 | 1131 | ||
1099 | fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); | 1132 | fb_pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8); |
1100 | WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); | 1133 | WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
1101 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | 1134 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
1102 | 1135 | ||
@@ -1115,8 +1148,8 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1115 | else | 1148 | else |
1116 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | 1149 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); |
1117 | 1150 | ||
1118 | if (old_fb && old_fb != crtc->fb) { | 1151 | if (!atomic && fb && fb != crtc->fb) { |
1119 | radeon_fb = to_radeon_framebuffer(old_fb); | 1152 | radeon_fb = to_radeon_framebuffer(fb); |
1120 | rbo = radeon_fb->obj->driver_private; | 1153 | rbo = radeon_fb->obj->driver_private; |
1121 | r = radeon_bo_reserve(rbo, false); | 1154 | r = radeon_bo_reserve(rbo, false); |
1122 | if (unlikely(r != 0)) | 1155 | if (unlikely(r != 0)) |
@@ -1138,11 +1171,26 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1138 | struct radeon_device *rdev = dev->dev_private; | 1171 | struct radeon_device *rdev = dev->dev_private; |
1139 | 1172 | ||
1140 | if (ASIC_IS_DCE4(rdev)) | 1173 | if (ASIC_IS_DCE4(rdev)) |
1141 | return evergreen_crtc_set_base(crtc, x, y, old_fb); | 1174 | return evergreen_crtc_do_set_base(crtc, old_fb, x, y, 0); |
1175 | else if (ASIC_IS_AVIVO(rdev)) | ||
1176 | return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0); | ||
1177 | else | ||
1178 | return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0); | ||
1179 | } | ||
1180 | |||
1181 | int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, | ||
1182 | struct drm_framebuffer *fb, | ||
1183 | int x, int y) | ||
1184 | { | ||
1185 | struct drm_device *dev = crtc->dev; | ||
1186 | struct radeon_device *rdev = dev->dev_private; | ||
1187 | |||
1188 | if (ASIC_IS_DCE4(rdev)) | ||
1189 | return evergreen_crtc_do_set_base(crtc, fb, x, y, 1); | ||
1142 | else if (ASIC_IS_AVIVO(rdev)) | 1190 | else if (ASIC_IS_AVIVO(rdev)) |
1143 | return avivo_crtc_set_base(crtc, x, y, old_fb); | 1191 | return avivo_crtc_do_set_base(crtc, fb, x, y, 1); |
1144 | else | 1192 | else |
1145 | return radeon_crtc_set_base(crtc, x, y, old_fb); | 1193 | return radeon_crtc_do_set_base(crtc, fb, x, y, 1); |
1146 | } | 1194 | } |
1147 | 1195 | ||
1148 | /* properly set additional regs when using atombios */ | 1196 | /* properly set additional regs when using atombios */ |
@@ -1311,6 +1359,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | |||
1311 | .mode_fixup = atombios_crtc_mode_fixup, | 1359 | .mode_fixup = atombios_crtc_mode_fixup, |
1312 | .mode_set = atombios_crtc_mode_set, | 1360 | .mode_set = atombios_crtc_mode_set, |
1313 | .mode_set_base = atombios_crtc_set_base, | 1361 | .mode_set_base = atombios_crtc_set_base, |
1362 | .mode_set_base_atomic = atombios_crtc_set_base_atomic, | ||
1314 | .prepare = atombios_crtc_prepare, | 1363 | .prepare = atombios_crtc_prepare, |
1315 | .commit = atombios_crtc_commit, | 1364 | .commit = atombios_crtc_commit, |
1316 | .load_lut = radeon_crtc_load_lut, | 1365 | .load_lut = radeon_crtc_load_lut, |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 9cdf6a35bc2c..bc61c5adb56d 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -59,6 +59,8 @@ static struct fb_ops radeonfb_ops = { | |||
59 | .fb_pan_display = drm_fb_helper_pan_display, | 59 | .fb_pan_display = drm_fb_helper_pan_display, |
60 | .fb_blank = drm_fb_helper_blank, | 60 | .fb_blank = drm_fb_helper_blank, |
61 | .fb_setcmap = drm_fb_helper_setcmap, | 61 | .fb_setcmap = drm_fb_helper_setcmap, |
62 | .fb_debug_enter = drm_fb_helper_debug_enter, | ||
63 | .fb_debug_leave = drm_fb_helper_debug_leave, | ||
62 | }; | 64 | }; |
63 | 65 | ||
64 | 66 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 305049afde15..bfa090e1f512 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -348,10 +348,25 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
348 | int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 348 | int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
349 | struct drm_framebuffer *old_fb) | 349 | struct drm_framebuffer *old_fb) |
350 | { | 350 | { |
351 | return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0); | ||
352 | } | ||
353 | |||
354 | int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, | ||
355 | struct drm_framebuffer *fb, | ||
356 | int x, int y) | ||
357 | { | ||
358 | return radeon_crtc_do_set_base(crtc, fb, x, y, 1); | ||
359 | } | ||
360 | |||
361 | int radeon_crtc_do_set_base(struct drm_crtc *crtc, | ||
362 | struct drm_framebuffer *fb, | ||
363 | int x, int y, int atomic) | ||
364 | { | ||
351 | struct drm_device *dev = crtc->dev; | 365 | struct drm_device *dev = crtc->dev; |
352 | struct radeon_device *rdev = dev->dev_private; | 366 | struct radeon_device *rdev = dev->dev_private; |
353 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 367 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
354 | struct radeon_framebuffer *radeon_fb; | 368 | struct radeon_framebuffer *radeon_fb; |
369 | struct drm_framebuffer *target_fb; | ||
355 | struct drm_gem_object *obj; | 370 | struct drm_gem_object *obj; |
356 | struct radeon_bo *rbo; | 371 | struct radeon_bo *rbo; |
357 | uint64_t base; | 372 | uint64_t base; |
@@ -364,14 +379,21 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
364 | 379 | ||
365 | DRM_DEBUG_KMS("\n"); | 380 | DRM_DEBUG_KMS("\n"); |
366 | /* no fb bound */ | 381 | /* no fb bound */ |
367 | if (!crtc->fb) { | 382 | if (!atomic && !crtc->fb) { |
368 | DRM_DEBUG_KMS("No FB bound\n"); | 383 | DRM_DEBUG_KMS("No FB bound\n"); |
369 | return 0; | 384 | return 0; |
370 | } | 385 | } |
371 | 386 | ||
372 | radeon_fb = to_radeon_framebuffer(crtc->fb); | 387 | if (atomic) { |
388 | radeon_fb = to_radeon_framebuffer(fb); | ||
389 | target_fb = fb; | ||
390 | } | ||
391 | else { | ||
392 | radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
393 | target_fb = crtc->fb; | ||
394 | } | ||
373 | 395 | ||
374 | switch (crtc->fb->bits_per_pixel) { | 396 | switch (target_fb->bits_per_pixel) { |
375 | case 8: | 397 | case 8: |
376 | format = 2; | 398 | format = 2; |
377 | break; | 399 | break; |
@@ -415,10 +437,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
415 | 437 | ||
416 | crtc_offset_cntl = 0; | 438 | crtc_offset_cntl = 0; |
417 | 439 | ||
418 | pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); | 440 | pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8); |
419 | crtc_pitch = (((pitch_pixels * crtc->fb->bits_per_pixel) + | 441 | crtc_pitch = (((pitch_pixels * target_fb->bits_per_pixel) + |
420 | ((crtc->fb->bits_per_pixel * 8) - 1)) / | 442 | ((target_fb->bits_per_pixel * 8) - 1)) / |
421 | (crtc->fb->bits_per_pixel * 8)); | 443 | (target_fb->bits_per_pixel * 8)); |
422 | crtc_pitch |= crtc_pitch << 16; | 444 | crtc_pitch |= crtc_pitch << 16; |
423 | 445 | ||
424 | 446 | ||
@@ -443,14 +465,14 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
443 | crtc_tile_x0_y0 = x | (y << 16); | 465 | crtc_tile_x0_y0 = x | (y << 16); |
444 | base &= ~0x7ff; | 466 | base &= ~0x7ff; |
445 | } else { | 467 | } else { |
446 | int byteshift = crtc->fb->bits_per_pixel >> 4; | 468 | int byteshift = target_fb->bits_per_pixel >> 4; |
447 | int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11; | 469 | int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11; |
448 | base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8); | 470 | base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8); |
449 | crtc_offset_cntl |= (y % 16); | 471 | crtc_offset_cntl |= (y % 16); |
450 | } | 472 | } |
451 | } else { | 473 | } else { |
452 | int offset = y * pitch_pixels + x; | 474 | int offset = y * pitch_pixels + x; |
453 | switch (crtc->fb->bits_per_pixel) { | 475 | switch (target_fb->bits_per_pixel) { |
454 | case 8: | 476 | case 8: |
455 | offset *= 1; | 477 | offset *= 1; |
456 | break; | 478 | break; |
@@ -496,8 +518,8 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
496 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); | 518 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); |
497 | WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); | 519 | WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); |
498 | 520 | ||
499 | if (old_fb && old_fb != crtc->fb) { | 521 | if (!atomic && fb && fb != crtc->fb) { |
500 | radeon_fb = to_radeon_framebuffer(old_fb); | 522 | radeon_fb = to_radeon_framebuffer(fb); |
501 | rbo = radeon_fb->obj->driver_private; | 523 | rbo = radeon_fb->obj->driver_private; |
502 | r = radeon_bo_reserve(rbo, false); | 524 | r = radeon_bo_reserve(rbo, false); |
503 | if (unlikely(r != 0)) | 525 | if (unlikely(r != 0)) |
@@ -1040,6 +1062,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | |||
1040 | .mode_fixup = radeon_crtc_mode_fixup, | 1062 | .mode_fixup = radeon_crtc_mode_fixup, |
1041 | .mode_set = radeon_crtc_mode_set, | 1063 | .mode_set = radeon_crtc_mode_set, |
1042 | .mode_set_base = radeon_crtc_set_base, | 1064 | .mode_set_base = radeon_crtc_set_base, |
1065 | .mode_set_base_atomic = radeon_crtc_set_base_atomic, | ||
1043 | .prepare = radeon_crtc_prepare, | 1066 | .prepare = radeon_crtc_prepare, |
1044 | .commit = radeon_crtc_commit, | 1067 | .commit = radeon_crtc_commit, |
1045 | .load_lut = radeon_crtc_load_lut, | 1068 | .load_lut = radeon_crtc_load_lut, |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 17a6602b5885..9dd27c23a798 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -514,6 +514,9 @@ extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); | |||
514 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); | 514 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); |
515 | extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 515 | extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
516 | struct drm_framebuffer *old_fb); | 516 | struct drm_framebuffer *old_fb); |
517 | extern int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, | ||
518 | struct drm_framebuffer *fb, | ||
519 | int x, int y); | ||
517 | extern int atombios_crtc_mode_set(struct drm_crtc *crtc, | 520 | extern int atombios_crtc_mode_set(struct drm_crtc *crtc, |
518 | struct drm_display_mode *mode, | 521 | struct drm_display_mode *mode, |
519 | struct drm_display_mode *adjusted_mode, | 522 | struct drm_display_mode *adjusted_mode, |
@@ -523,7 +526,12 @@ extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode); | |||
523 | 526 | ||
524 | extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 527 | extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
525 | struct drm_framebuffer *old_fb); | 528 | struct drm_framebuffer *old_fb); |
526 | 529 | extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, | |
530 | struct drm_framebuffer *fb, | ||
531 | int x, int y); | ||
532 | extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, | ||
533 | struct drm_framebuffer *fb, | ||
534 | int x, int y, int atomic); | ||
527 | extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, | 535 | extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, |
528 | struct drm_file *file_priv, | 536 | struct drm_file *file_priv, |
529 | uint32_t handle, | 537 | uint32_t handle, |