aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c144
1 files changed, 35 insertions, 109 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index e17c26a1cff1..344228b640b9 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -935,21 +935,11 @@ intel_check_sprite_plane(struct intel_plane *plane,
935 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 935 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
936 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); 936 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
937 struct drm_framebuffer *fb = state->base.fb; 937 struct drm_framebuffer *fb = state->base.fb;
938 int crtc_x, crtc_y;
939 unsigned int crtc_w, crtc_h;
940 uint32_t src_x, src_y, src_w, src_h;
941 struct drm_rect *src = &state->base.src;
942 struct drm_rect *dst = &state->base.dst;
943 struct drm_rect clip = {};
944 int max_stride = INTEL_GEN(dev_priv) >= 9 ? 32768 : 16384; 938 int max_stride = INTEL_GEN(dev_priv) >= 9 ? 32768 : 16384;
945 int hscale, vscale;
946 int max_scale, min_scale; 939 int max_scale, min_scale;
947 bool can_scale; 940 bool can_scale;
948 int ret; 941 int ret;
949 942
950 *src = drm_plane_state_src(&state->base);
951 *dst = drm_plane_state_dest(&state->base);
952
953 if (!fb) { 943 if (!fb) {
954 state->base.visible = false; 944 state->base.visible = false;
955 return 0; 945 return 0;
@@ -985,64 +975,19 @@ intel_check_sprite_plane(struct intel_plane *plane,
985 min_scale = plane->can_scale ? 1 : (1 << 16); 975 min_scale = plane->can_scale ? 1 : (1 << 16);
986 } 976 }
987 977
988 /* 978 ret = drm_atomic_helper_check_plane_state(&state->base,
989 * FIXME the following code does a bunch of fuzzy adjustments to the 979 &crtc_state->base,
990 * coordinates and sizes. We probably need some way to decide whether 980 min_scale, max_scale,
991 * more strict checking should be done instead. 981 true, true);
992 */ 982 if (ret)
993 drm_rect_rotate(src, fb->width << 16, fb->height << 16, 983 return ret;
994 state->base.rotation);
995
996 hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
997 BUG_ON(hscale < 0);
998
999 vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
1000 BUG_ON(vscale < 0);
1001
1002 if (crtc_state->base.enable)
1003 drm_mode_get_hv_timing(&crtc_state->base.mode,
1004 &clip.x2, &clip.y2);
1005
1006 state->base.visible = drm_rect_clip_scaled(src, dst, &clip);
1007
1008 crtc_x = dst->x1;
1009 crtc_y = dst->y1;
1010 crtc_w = drm_rect_width(dst);
1011 crtc_h = drm_rect_height(dst);
1012 984
1013 if (state->base.visible) { 985 if (state->base.visible) {
1014 /* check again in case clipping clamped the results */ 986 struct drm_rect *src = &state->base.src;
1015 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); 987 struct drm_rect *dst = &state->base.dst;
1016 if (hscale < 0) { 988 unsigned int crtc_w = drm_rect_width(dst);
1017 DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); 989 unsigned int crtc_h = drm_rect_height(dst);
1018 drm_rect_debug_print("src: ", src, true); 990 uint32_t src_x, src_y, src_w, src_h;
1019 drm_rect_debug_print("dst: ", dst, false);
1020
1021 return hscale;
1022 }
1023
1024 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
1025 if (vscale < 0) {
1026 DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
1027 drm_rect_debug_print("src: ", src, true);
1028 drm_rect_debug_print("dst: ", dst, false);
1029
1030 return vscale;
1031 }
1032
1033 /* Make the source viewport size an exact multiple of the scaling factors. */
1034 drm_rect_adjust_size(src,
1035 drm_rect_width(dst) * hscale - drm_rect_width(src),
1036 drm_rect_height(dst) * vscale - drm_rect_height(src));
1037
1038 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
1039 state->base.rotation);
1040
1041 /* sanity check to make sure the src viewport wasn't enlarged */
1042 WARN_ON(src->x1 < (int) state->base.src_x ||
1043 src->y1 < (int) state->base.src_y ||
1044 src->x2 > (int) state->base.src_x + state->base.src_w ||
1045 src->y2 > (int) state->base.src_y + state->base.src_h);
1046 991
1047 /* 992 /*
1048 * Hardware doesn't handle subpixel coordinates. 993 * Hardware doesn't handle subpixel coordinates.
@@ -1055,58 +1000,39 @@ intel_check_sprite_plane(struct intel_plane *plane,
1055 src_y = src->y1 >> 16; 1000 src_y = src->y1 >> 16;
1056 src_h = drm_rect_height(src) >> 16; 1001 src_h = drm_rect_height(src) >> 16;
1057 1002
1058 if (intel_format_is_yuv(fb->format->format)) { 1003 src->x1 = src_x << 16;
1059 src_x &= ~1; 1004 src->x2 = (src_x + src_w) << 16;
1060 src_w &= ~1; 1005 src->y1 = src_y << 16;
1061 1006 src->y2 = (src_y + src_h) << 16;
1062 /*
1063 * Must keep src and dst the
1064 * same if we can't scale.
1065 */
1066 if (!can_scale)
1067 crtc_w &= ~1;
1068 1007
1069 if (crtc_w == 0) 1008 if (intel_format_is_yuv(fb->format->format) &&
1070 state->base.visible = false; 1009 (src_x % 2 || src_w % 2)) {
1010 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
1011 src_x, src_w);
1012 return -EINVAL;
1071 } 1013 }
1072 }
1073 1014
1074 /* Check size restrictions when scaling */ 1015 /* Check size restrictions when scaling */
1075 if (state->base.visible && (src_w != crtc_w || src_h != crtc_h)) { 1016 if (src_w != crtc_w || src_h != crtc_h) {
1076 unsigned int width_bytes; 1017 unsigned int width_bytes;
1077 int cpp = fb->format->cpp[0]; 1018 int cpp = fb->format->cpp[0];
1078 1019
1079 WARN_ON(!can_scale); 1020 WARN_ON(!can_scale);
1080 1021
1081 /* FIXME interlacing min height is 6 */ 1022 width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1082 1023
1083 if (crtc_w < 3 || crtc_h < 3) 1024 /* FIXME interlacing min height is 6 */
1084 state->base.visible = false; 1025 if (INTEL_GEN(dev_priv) < 9 && (
1085 1026 src_w < 3 || src_h < 3 ||
1086 if (src_w < 3 || src_h < 3) 1027 src_w > 2048 || src_h > 2048 ||
1087 state->base.visible = false; 1028 crtc_w < 3 || crtc_h < 3 ||
1088 1029 width_bytes > 4096 || fb->pitches[0] > 4096)) {
1089 width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 1030 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
1090 1031 return -EINVAL;
1091 if (INTEL_GEN(dev_priv) < 9 && (src_w > 2048 || src_h > 2048 || 1032 }
1092 width_bytes > 4096 || fb->pitches[0] > 4096)) {
1093 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
1094 return -EINVAL;
1095 } 1033 }
1096 } 1034 }
1097 1035
1098 if (state->base.visible) {
1099 src->x1 = src_x << 16;
1100 src->x2 = (src_x + src_w) << 16;
1101 src->y1 = src_y << 16;
1102 src->y2 = (src_y + src_h) << 16;
1103 }
1104
1105 dst->x1 = crtc_x;
1106 dst->x2 = crtc_x + crtc_w;
1107 dst->y1 = crtc_y;
1108 dst->y2 = crtc_y + crtc_h;
1109
1110 if (INTEL_GEN(dev_priv) >= 9) { 1036 if (INTEL_GEN(dev_priv) >= 9) {
1111 ret = skl_check_plane_surface(crtc_state, state); 1037 ret = skl_check_plane_surface(crtc_state, state);
1112 if (ret) 1038 if (ret)