aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sprite.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-09-27 19:37:51 -0400
committerDave Airlie <airlied@redhat.com>2018-09-27 19:37:55 -0400
commitdb9825c95498280718c4687fcf712016f5b6f5f6 (patch)
tree01661a811bcd16a7b6f3ee9790e77da75fd178b0 /drivers/gpu/drm/i915/intel_sprite.c
parent156e60bc71aa31a3b42b1d66a822c2999bd0994c (diff)
parent448626103dad54ec5d06722e955586b5d557625d (diff)
Merge tag 'drm-intel-next-2018-09-21' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
Driver Changes: - Bugzilla 107600: Fix stuttering video playback on MythTV on old hardware (Chris) - Avoid black screen when using CSC coefficient matrix (Raviraj) - Hammer PDs on Baytrail to make sure they reload (Chris) - Capture some objects if unable to capture all, on error (Chris) - Add W/A for 16 GB DIMMs on SKL+ (Mahesh) - Only enable IPC for symmetric memory configurations on KBL+ (Mahesh) - Assume pipe A to have maximum stride limits (Ville) - Always update update OA contexts via context image (Tvrtko) - Icelake enabling patches (Madhav, Dhinakaran) - Add Icelake DMC firmware (Anusha) - Fixes for CI found corner cases (Chris) - Limit the backpressure for request allocation (Chris) - Park GPU on module load so usage starts from known state (Chris) - Flush tasklet when checking for idle (Chris) - Use coherent write into the context image on BSW+ (Chris) - Fix possible integer overflow for framebuffers that get aligned past 4GiB (Ville) - Downgrade fence timeout from warn to notice and add debug hint (Chris) - Fixes to multi function encoder code (Ville) - Fix sprite plane check logic (Dan, Ville) - PAGE_SIZE vs. I915_GTT_PAGE_SIZE fixes (Ville) - Decode memory bandwidth and parameters for BXT and SKL+ (Mahesh) - Overwrite BIOS set IPC value from KMS (Mahesh) - Multiple pipe handling code cleanups/restructurings/optimizations (Ville) - Spare low 4G address for non-48bit objects (Chris) - Free context_setparam of struct_mutex (Chris) - Delay updating ring register state on resume (Chris) - Avoid unnecessarily copying overlay IOCTL parameters (Chris) - Update GuC power domain states even without submission (Michal) - Restore GuC preempt-context across S3/S4 (Chris) - Add kernel selftest for rapid context switching (Chris) - Keep runtime power management ref for live selftests (Chris) - GEM code cleanups (Matt) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180927095933.GA11458@jlahtine-desk.ger.corp.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sprite.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c494
1 files changed, 355 insertions, 139 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 9600ccfc5b76..d4c8e10fc90b 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -230,6 +230,56 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
230#endif 230#endif
231} 231}
232 232
233int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
234{
235 const struct drm_framebuffer *fb = plane_state->base.fb;
236 struct drm_rect *src = &plane_state->base.src;
237 u32 src_x, src_y, src_w, src_h;
238
239 /*
240 * Hardware doesn't handle subpixel coordinates.
241 * Adjust to (macro)pixel boundary, but be careful not to
242 * increase the source viewport size, because that could
243 * push the downscaling factor out of bounds.
244 */
245 src_x = src->x1 >> 16;
246 src_w = drm_rect_width(src) >> 16;
247 src_y = src->y1 >> 16;
248 src_h = drm_rect_height(src) >> 16;
249
250 src->x1 = src_x << 16;
251 src->x2 = (src_x + src_w) << 16;
252 src->y1 = src_y << 16;
253 src->y2 = (src_y + src_h) << 16;
254
255 if (fb->format->is_yuv &&
256 fb->format->format != DRM_FORMAT_NV12 &&
257 (src_x & 1 || src_w & 1)) {
258 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
259 src_x, src_w);
260 return -EINVAL;
261 }
262
263 return 0;
264}
265
266unsigned int
267skl_plane_max_stride(struct intel_plane *plane,
268 u32 pixel_format, u64 modifier,
269 unsigned int rotation)
270{
271 int cpp = drm_format_plane_cpp(pixel_format, 0);
272
273 /*
274 * "The stride in bytes must not exceed the
275 * of the size of 8K pixels and 32K bytes."
276 */
277 if (drm_rotation_90_or_270(rotation))
278 return min(8192, 32768 / cpp);
279 else
280 return min(8192 * cpp, 32768);
281}
282
233void 283void
234skl_update_plane(struct intel_plane *plane, 284skl_update_plane(struct intel_plane *plane,
235 const struct intel_crtc_state *crtc_state, 285 const struct intel_crtc_state *crtc_state,
@@ -241,16 +291,15 @@ skl_update_plane(struct intel_plane *plane,
241 enum pipe pipe = plane->pipe; 291 enum pipe pipe = plane->pipe;
242 u32 plane_ctl = plane_state->ctl; 292 u32 plane_ctl = plane_state->ctl;
243 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 293 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
244 u32 surf_addr = plane_state->main.offset; 294 u32 surf_addr = plane_state->color_plane[0].offset;
245 unsigned int rotation = plane_state->base.rotation; 295 u32 stride = skl_plane_stride(plane_state, 0);
246 u32 stride = skl_plane_stride(fb, 0, rotation); 296 u32 aux_stride = skl_plane_stride(plane_state, 1);
247 u32 aux_stride = skl_plane_stride(fb, 1, rotation);
248 int crtc_x = plane_state->base.dst.x1; 297 int crtc_x = plane_state->base.dst.x1;
249 int crtc_y = plane_state->base.dst.y1; 298 int crtc_y = plane_state->base.dst.y1;
250 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 299 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
251 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 300 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
252 uint32_t x = plane_state->main.x; 301 uint32_t x = plane_state->color_plane[0].x;
253 uint32_t y = plane_state->main.y; 302 uint32_t y = plane_state->color_plane[0].y;
254 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; 303 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
255 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; 304 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
256 unsigned long irqflags; 305 unsigned long irqflags;
@@ -277,9 +326,10 @@ skl_update_plane(struct intel_plane *plane,
277 I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride); 326 I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
278 I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); 327 I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
279 I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), 328 I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
280 (plane_state->aux.offset - surf_addr) | aux_stride); 329 (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
281 I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id), 330 I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
282 (plane_state->aux.y << 16) | plane_state->aux.x); 331 (plane_state->color_plane[1].y << 16) |
332 plane_state->color_plane[1].x);
283 333
284 /* program plane scaler */ 334 /* program plane scaler */
285 if (plane_state->scaler_id >= 0) { 335 if (plane_state->scaler_id >= 0) {
@@ -545,15 +595,15 @@ vlv_update_plane(struct intel_plane *plane,
545 enum pipe pipe = plane->pipe; 595 enum pipe pipe = plane->pipe;
546 enum plane_id plane_id = plane->id; 596 enum plane_id plane_id = plane->id;
547 u32 sprctl = plane_state->ctl; 597 u32 sprctl = plane_state->ctl;
548 u32 sprsurf_offset = plane_state->main.offset; 598 u32 sprsurf_offset = plane_state->color_plane[0].offset;
549 u32 linear_offset; 599 u32 linear_offset;
550 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 600 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
551 int crtc_x = plane_state->base.dst.x1; 601 int crtc_x = plane_state->base.dst.x1;
552 int crtc_y = plane_state->base.dst.y1; 602 int crtc_y = plane_state->base.dst.y1;
553 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 603 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
554 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 604 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
555 uint32_t x = plane_state->main.x; 605 uint32_t x = plane_state->color_plane[0].x;
556 uint32_t y = plane_state->main.y; 606 uint32_t y = plane_state->color_plane[0].y;
557 unsigned long irqflags; 607 unsigned long irqflags;
558 608
559 /* Sizes are 0 based */ 609 /* Sizes are 0 based */
@@ -574,7 +624,8 @@ vlv_update_plane(struct intel_plane *plane,
574 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value); 624 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
575 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask); 625 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
576 } 626 }
577 I915_WRITE_FW(SPSTRIDE(pipe, plane_id), fb->pitches[0]); 627 I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
628 plane_state->color_plane[0].stride);
578 I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x); 629 I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
579 630
580 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 631 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
@@ -704,15 +755,15 @@ ivb_update_plane(struct intel_plane *plane,
704 const struct drm_framebuffer *fb = plane_state->base.fb; 755 const struct drm_framebuffer *fb = plane_state->base.fb;
705 enum pipe pipe = plane->pipe; 756 enum pipe pipe = plane->pipe;
706 u32 sprctl = plane_state->ctl, sprscale = 0; 757 u32 sprctl = plane_state->ctl, sprscale = 0;
707 u32 sprsurf_offset = plane_state->main.offset; 758 u32 sprsurf_offset = plane_state->color_plane[0].offset;
708 u32 linear_offset; 759 u32 linear_offset;
709 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 760 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
710 int crtc_x = plane_state->base.dst.x1; 761 int crtc_x = plane_state->base.dst.x1;
711 int crtc_y = plane_state->base.dst.y1; 762 int crtc_y = plane_state->base.dst.y1;
712 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 763 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
713 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 764 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
714 uint32_t x = plane_state->main.x; 765 uint32_t x = plane_state->color_plane[0].x;
715 uint32_t y = plane_state->main.y; 766 uint32_t y = plane_state->color_plane[0].y;
716 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; 767 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
717 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; 768 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
718 unsigned long irqflags; 769 unsigned long irqflags;
@@ -736,7 +787,7 @@ ivb_update_plane(struct intel_plane *plane,
736 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask); 787 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
737 } 788 }
738 789
739 I915_WRITE_FW(SPRSTRIDE(pipe), fb->pitches[0]); 790 I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
740 I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x); 791 I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
741 792
742 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET 793 /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
@@ -749,7 +800,7 @@ ivb_update_plane(struct intel_plane *plane,
749 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset); 800 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
750 801
751 I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); 802 I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
752 if (plane->can_scale) 803 if (IS_IVYBRIDGE(dev_priv))
753 I915_WRITE_FW(SPRSCALE(pipe), sprscale); 804 I915_WRITE_FW(SPRSCALE(pipe), sprscale);
754 I915_WRITE_FW(SPRCTL(pipe), sprctl); 805 I915_WRITE_FW(SPRCTL(pipe), sprctl);
755 I915_WRITE_FW(SPRSURF(pipe), 806 I915_WRITE_FW(SPRSURF(pipe),
@@ -770,7 +821,7 @@ ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
770 821
771 I915_WRITE_FW(SPRCTL(pipe), 0); 822 I915_WRITE_FW(SPRCTL(pipe), 0);
772 /* Can't leave the scaler enabled... */ 823 /* Can't leave the scaler enabled... */
773 if (plane->can_scale) 824 if (IS_IVYBRIDGE(dev_priv))
774 I915_WRITE_FW(SPRSCALE(pipe), 0); 825 I915_WRITE_FW(SPRSCALE(pipe), 0);
775 826
776 I915_WRITE_FW(SPRSURF(pipe), 0); 827 I915_WRITE_FW(SPRSURF(pipe), 0);
@@ -800,6 +851,14 @@ ivb_plane_get_hw_state(struct intel_plane *plane,
800 return ret; 851 return ret;
801} 852}
802 853
854static unsigned int
855g4x_sprite_max_stride(struct intel_plane *plane,
856 u32 pixel_format, u64 modifier,
857 unsigned int rotation)
858{
859 return 16384;
860}
861
803static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, 862static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
804 const struct intel_plane_state *plane_state) 863 const struct intel_plane_state *plane_state)
805{ 864{
@@ -868,15 +927,15 @@ g4x_update_plane(struct intel_plane *plane,
868 const struct drm_framebuffer *fb = plane_state->base.fb; 927 const struct drm_framebuffer *fb = plane_state->base.fb;
869 enum pipe pipe = plane->pipe; 928 enum pipe pipe = plane->pipe;
870 u32 dvscntr = plane_state->ctl, dvsscale = 0; 929 u32 dvscntr = plane_state->ctl, dvsscale = 0;
871 u32 dvssurf_offset = plane_state->main.offset; 930 u32 dvssurf_offset = plane_state->color_plane[0].offset;
872 u32 linear_offset; 931 u32 linear_offset;
873 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; 932 const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
874 int crtc_x = plane_state->base.dst.x1; 933 int crtc_x = plane_state->base.dst.x1;
875 int crtc_y = plane_state->base.dst.y1; 934 int crtc_y = plane_state->base.dst.y1;
876 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); 935 uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
877 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); 936 uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
878 uint32_t x = plane_state->main.x; 937 uint32_t x = plane_state->color_plane[0].x;
879 uint32_t y = plane_state->main.y; 938 uint32_t y = plane_state->color_plane[0].y;
880 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; 939 uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
881 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16; 940 uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
882 unsigned long irqflags; 941 unsigned long irqflags;
@@ -900,7 +959,7 @@ g4x_update_plane(struct intel_plane *plane,
900 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask); 959 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
901 } 960 }
902 961
903 I915_WRITE_FW(DVSSTRIDE(pipe), fb->pitches[0]); 962 I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
904 I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x); 963 I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
905 964
906 if (fb->modifier == I915_FORMAT_MOD_X_TILED) 965 if (fb->modifier == I915_FORMAT_MOD_X_TILED)
@@ -959,144 +1018,309 @@ g4x_plane_get_hw_state(struct intel_plane *plane,
959} 1018}
960 1019
961static int 1020static int
962intel_check_sprite_plane(struct intel_crtc_state *crtc_state, 1021g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
963 struct intel_plane_state *state) 1022 struct intel_plane_state *plane_state)
964{ 1023{
965 struct intel_plane *plane = to_intel_plane(state->base.plane); 1024 const struct drm_framebuffer *fb = plane_state->base.fb;
966 struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1025 const struct drm_rect *src = &plane_state->base.src;
967 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); 1026 const struct drm_rect *dst = &plane_state->base.dst;
968 struct drm_framebuffer *fb = state->base.fb; 1027 int src_x, src_y, src_w, src_h, crtc_w, crtc_h;
969 int max_stride = INTEL_GEN(dev_priv) >= 9 ? 32768 : 16384; 1028 const struct drm_display_mode *adjusted_mode =
970 int max_scale, min_scale; 1029 &crtc_state->base.adjusted_mode;
971 bool can_scale; 1030 unsigned int cpp = fb->format->cpp[0];
972 int ret; 1031 unsigned int width_bytes;
973 uint32_t pixel_format = 0; 1032 int min_width, min_height;
974 1033
975 if (!fb) { 1034 crtc_w = drm_rect_width(dst);
976 state->base.visible = false; 1035 crtc_h = drm_rect_height(dst);
1036
1037 src_x = src->x1 >> 16;
1038 src_y = src->y1 >> 16;
1039 src_w = drm_rect_width(src) >> 16;
1040 src_h = drm_rect_height(src) >> 16;
1041
1042 if (src_w == crtc_w && src_h == crtc_h)
977 return 0; 1043 return 0;
1044
1045 min_width = 3;
1046
1047 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1048 if (src_h & 1) {
1049 DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1050 return -EINVAL;
1051 }
1052 min_height = 6;
1053 } else {
1054 min_height = 3;
978 } 1055 }
979 1056
980 /* Don't modify another pipe's plane */ 1057 width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
981 if (plane->pipe != crtc->pipe) { 1058
982 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n"); 1059 if (src_w < min_width || src_h < min_height ||
1060 src_w > 2048 || src_h > 2048) {
1061 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1062 src_w, src_h, min_width, min_height, 2048, 2048);
983 return -EINVAL; 1063 return -EINVAL;
984 } 1064 }
985 1065
986 /* FIXME check all gen limits */ 1066 if (width_bytes > 4096) {
987 if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > max_stride) { 1067 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
988 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n"); 1068 width_bytes, 4096);
989 return -EINVAL; 1069 return -EINVAL;
990 } 1070 }
991 1071
992 /* setup can_scale, min_scale, max_scale */ 1072 if (width_bytes > 4096 || fb->pitches[0] > 4096) {
993 if (INTEL_GEN(dev_priv) >= 9) { 1073 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
994 if (state->base.fb) 1074 fb->pitches[0], 4096);
995 pixel_format = state->base.fb->format->format; 1075 return -EINVAL;
996 /* use scaler when colorkey is not required */ 1076 }
997 if (!state->ckey.flags) { 1077
998 can_scale = 1; 1078 return 0;
999 min_scale = 1; 1079}
1000 max_scale = 1080
1001 skl_max_scale(crtc, crtc_state, pixel_format); 1081static int
1002 } else { 1082g4x_sprite_check(struct intel_crtc_state *crtc_state,
1003 can_scale = 0; 1083 struct intel_plane_state *plane_state)
1004 min_scale = DRM_PLANE_HELPER_NO_SCALING; 1084{
1005 max_scale = DRM_PLANE_HELPER_NO_SCALING; 1085 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1006 } 1086 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1087 int max_scale, min_scale;
1088 int ret;
1089
1090 if (INTEL_GEN(dev_priv) < 7) {
1091 min_scale = 1;
1092 max_scale = 16 << 16;
1093 } else if (IS_IVYBRIDGE(dev_priv)) {
1094 min_scale = 1;
1095 max_scale = 2 << 16;
1007 } else { 1096 } else {
1008 can_scale = plane->can_scale; 1097 min_scale = DRM_PLANE_HELPER_NO_SCALING;
1009 max_scale = plane->max_downscale << 16; 1098 max_scale = DRM_PLANE_HELPER_NO_SCALING;
1010 min_scale = plane->can_scale ? 1 : (1 << 16);
1011 } 1099 }
1012 1100
1013 ret = drm_atomic_helper_check_plane_state(&state->base, 1101 ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1014 &crtc_state->base, 1102 &crtc_state->base,
1015 min_scale, max_scale, 1103 min_scale, max_scale,
1016 true, true); 1104 true, true);
1017 if (ret) 1105 if (ret)
1018 return ret; 1106 return ret;
1019 1107
1020 if (state->base.visible) { 1108 if (!plane_state->base.visible)
1021 struct drm_rect *src = &state->base.src; 1109 return 0;
1022 struct drm_rect *dst = &state->base.dst; 1110
1023 unsigned int crtc_w = drm_rect_width(dst); 1111 ret = intel_plane_check_src_coordinates(plane_state);
1024 unsigned int crtc_h = drm_rect_height(dst); 1112 if (ret)
1025 uint32_t src_x, src_y, src_w, src_h; 1113 return ret;
1114
1115 ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1116 if (ret)
1117 return ret;
1118
1119 ret = i9xx_check_plane_surface(plane_state);
1120 if (ret)
1121 return ret;
1122
1123 if (INTEL_GEN(dev_priv) >= 7)
1124 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1125 else
1126 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1127
1128 return 0;
1129}
1130
1131int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1132{
1133 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1134 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1135 unsigned int rotation = plane_state->base.rotation;
1136
1137 /* CHV ignores the mirror bit when the rotate bit is set :( */
1138 if (IS_CHERRYVIEW(dev_priv) &&
1139 rotation & DRM_MODE_ROTATE_180 &&
1140 rotation & DRM_MODE_REFLECT_X) {
1141 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
1142 return -EINVAL;
1143 }
1144
1145 return 0;
1146}
1147
1148static int
1149vlv_sprite_check(struct intel_crtc_state *crtc_state,
1150 struct intel_plane_state *plane_state)
1151{
1152 int ret;
1153
1154 ret = chv_plane_check_rotation(plane_state);
1155 if (ret)
1156 return ret;
1157
1158 ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1159 &crtc_state->base,
1160 DRM_PLANE_HELPER_NO_SCALING,
1161 DRM_PLANE_HELPER_NO_SCALING,
1162 true, true);
1163 if (ret)
1164 return ret;
1165
1166 if (!plane_state->base.visible)
1167 return 0;
1168
1169 ret = intel_plane_check_src_coordinates(plane_state);
1170 if (ret)
1171 return ret;
1172
1173 ret = i9xx_check_plane_surface(plane_state);
1174 if (ret)
1175 return ret;
1176
1177 plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1178
1179 return 0;
1180}
1181
1182static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1183 const struct intel_plane_state *plane_state)
1184{
1185 const struct drm_framebuffer *fb = plane_state->base.fb;
1186 unsigned int rotation = plane_state->base.rotation;
1187 struct drm_format_name_buf format_name;
1188
1189 if (!fb)
1190 return 0;
1191
1192 if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1193 is_ccs_modifier(fb->modifier)) {
1194 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
1195 rotation);
1196 return -EINVAL;
1197 }
1198
1199 if (rotation & DRM_MODE_REFLECT_X &&
1200 fb->modifier == DRM_FORMAT_MOD_LINEAR) {
1201 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
1202 return -EINVAL;
1203 }
1204
1205 if (drm_rotation_90_or_270(rotation)) {
1206 if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
1207 fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
1208 DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
1209 return -EINVAL;
1210 }
1026 1211
1027 /* 1212 /*
1028 * Hardware doesn't handle subpixel coordinates. 1213 * 90/270 is not allowed with RGB64 16:16:16:16,
1029 * Adjust to (macro)pixel boundary, but be careful not to 1214 * RGB 16-bit 5:6:5, and Indexed 8-bit.
1030 * increase the source viewport size, because that could 1215 * TBD: Add RGB64 case once its added in supported format list.
1031 * push the downscaling factor out of bounds.
1032 */ 1216 */
1033 src_x = src->x1 >> 16; 1217 switch (fb->format->format) {
1034 src_w = drm_rect_width(src) >> 16; 1218 case DRM_FORMAT_C8:
1035 src_y = src->y1 >> 16; 1219 case DRM_FORMAT_RGB565:
1036 src_h = drm_rect_height(src) >> 16; 1220 DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1037 1221 drm_get_format_name(fb->format->format,
1038 src->x1 = src_x << 16; 1222 &format_name));
1039 src->x2 = (src_x + src_w) << 16;
1040 src->y1 = src_y << 16;
1041 src->y2 = (src_y + src_h) << 16;
1042
1043 if (fb->format->is_yuv &&
1044 fb->format->format != DRM_FORMAT_NV12 &&
1045 (src_x % 2 || src_w % 2)) {
1046 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
1047 src_x, src_w);
1048 return -EINVAL; 1223 return -EINVAL;
1224 default:
1225 break;
1049 } 1226 }
1227 }
1050 1228
1051 /* Check size restrictions when scaling */ 1229 /* Y-tiling is not supported in IF-ID Interlace mode */
1052 if (src_w != crtc_w || src_h != crtc_h) { 1230 if (crtc_state->base.enable &&
1053 unsigned int width_bytes; 1231 crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1054 int cpp = fb->format->cpp[0]; 1232 (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1233 fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
1234 fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1235 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
1236 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
1237 return -EINVAL;
1238 }
1055 1239
1056 WARN_ON(!can_scale); 1240 return 0;
1241}
1057 1242
1058 width_bytes = ((src_x * cpp) & 63) + src_w * cpp; 1243static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
1244 const struct intel_plane_state *plane_state)
1245{
1246 struct drm_i915_private *dev_priv =
1247 to_i915(plane_state->base.plane->dev);
1248 int crtc_x = plane_state->base.dst.x1;
1249 int crtc_w = drm_rect_width(&plane_state->base.dst);
1250 int pipe_src_w = crtc_state->pipe_src_w;
1059 1251
1060 /* FIXME interlacing min height is 6 */ 1252 /*
1061 if (INTEL_GEN(dev_priv) < 9 && ( 1253 * Display WA #1175: cnl,glk
1062 src_w < 3 || src_h < 3 || 1254 * Planes other than the cursor may cause FIFO underflow and display
1063 src_w > 2048 || src_h > 2048 || 1255 * corruption if starting less than 4 pixels from the right edge of
1064 crtc_w < 3 || crtc_h < 3 || 1256 * the screen.
1065 width_bytes > 4096 || fb->pitches[0] > 4096)) { 1257 * Besides the above WA fix the similar problem, where planes other
1066 DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); 1258 * than the cursor ending less than 4 pixels from the left edge of the
1067 return -EINVAL; 1259 * screen may cause FIFO underflow and display corruption.
1068 } 1260 */
1069 } 1261 if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
1262 (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
1263 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
1264 crtc_x + crtc_w < 4 ? "end" : "start",
1265 crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
1266 4, pipe_src_w - 4);
1267 return -ERANGE;
1070 } 1268 }
1071 1269
1072 if (INTEL_GEN(dev_priv) >= 9) { 1270 return 0;
1073 ret = skl_check_plane_surface(crtc_state, state); 1271}
1074 if (ret)
1075 return ret;
1076 1272
1077 state->ctl = skl_plane_ctl(crtc_state, state); 1273int skl_plane_check(struct intel_crtc_state *crtc_state,
1078 } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 1274 struct intel_plane_state *plane_state)
1079 ret = i9xx_check_plane_surface(state); 1275{
1080 if (ret) 1276 struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1081 return ret; 1277 struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1278 int max_scale, min_scale;
1279 int ret;
1082 1280
1083 state->ctl = vlv_sprite_ctl(crtc_state, state); 1281 ret = skl_plane_check_fb(crtc_state, plane_state);
1084 } else if (INTEL_GEN(dev_priv) >= 7) { 1282 if (ret)
1085 ret = i9xx_check_plane_surface(state); 1283 return ret;
1086 if (ret)
1087 return ret;
1088 1284
1089 state->ctl = ivb_sprite_ctl(crtc_state, state); 1285 /* use scaler when colorkey is not required */
1090 } else { 1286 if (!plane_state->ckey.flags) {
1091 ret = i9xx_check_plane_surface(state); 1287 const struct drm_framebuffer *fb = plane_state->base.fb;
1092 if (ret)
1093 return ret;
1094 1288
1095 state->ctl = g4x_sprite_ctl(crtc_state, state); 1289 min_scale = 1;
1290 max_scale = skl_max_scale(crtc_state,
1291 fb ? fb->format->format : 0);
1292 } else {
1293 min_scale = DRM_PLANE_HELPER_NO_SCALING;
1294 max_scale = DRM_PLANE_HELPER_NO_SCALING;
1096 } 1295 }
1097 1296
1297 ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1298 &crtc_state->base,
1299 min_scale, max_scale,
1300 true, true);
1301 if (ret)
1302 return ret;
1303
1304 if (!plane_state->base.visible)
1305 return 0;
1306
1307 ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
1308 if (ret)
1309 return ret;
1310
1311 ret = intel_plane_check_src_coordinates(plane_state);
1312 if (ret)
1313 return ret;
1314
1315 ret = skl_check_plane_surface(plane_state);
1316 if (ret)
1317 return ret;
1318
1319 plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1320
1098 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) 1321 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1099 state->color_ctl = glk_plane_color_ctl(crtc_state, state); 1322 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
1323 plane_state);
1100 1324
1101 return 0; 1325 return 0;
1102} 1326}
@@ -1523,15 +1747,16 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1523 intel_plane->base.state = &state->base; 1747 intel_plane->base.state = &state->base;
1524 1748
1525 if (INTEL_GEN(dev_priv) >= 9) { 1749 if (INTEL_GEN(dev_priv) >= 9) {
1526 intel_plane->can_scale = true;
1527 state->scaler_id = -1; 1750 state->scaler_id = -1;
1528 1751
1529 intel_plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, 1752 intel_plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe,
1530 PLANE_SPRITE0 + plane); 1753 PLANE_SPRITE0 + plane);
1531 1754
1755 intel_plane->max_stride = skl_plane_max_stride;
1532 intel_plane->update_plane = skl_update_plane; 1756 intel_plane->update_plane = skl_update_plane;
1533 intel_plane->disable_plane = skl_disable_plane; 1757 intel_plane->disable_plane = skl_disable_plane;
1534 intel_plane->get_hw_state = skl_plane_get_hw_state; 1758 intel_plane->get_hw_state = skl_plane_get_hw_state;
1759 intel_plane->check_plane = skl_plane_check;
1535 1760
1536 if (skl_plane_has_planar(dev_priv, pipe, 1761 if (skl_plane_has_planar(dev_priv, pipe,
1537 PLANE_SPRITE0 + plane)) { 1762 PLANE_SPRITE0 + plane)) {
@@ -1549,12 +1774,11 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1549 1774
1550 plane_funcs = &skl_plane_funcs; 1775 plane_funcs = &skl_plane_funcs;
1551 } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 1776 } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1552 intel_plane->can_scale = false; 1777 intel_plane->max_stride = i9xx_plane_max_stride;
1553 intel_plane->max_downscale = 1;
1554
1555 intel_plane->update_plane = vlv_update_plane; 1778 intel_plane->update_plane = vlv_update_plane;
1556 intel_plane->disable_plane = vlv_disable_plane; 1779 intel_plane->disable_plane = vlv_disable_plane;
1557 intel_plane->get_hw_state = vlv_plane_get_hw_state; 1780 intel_plane->get_hw_state = vlv_plane_get_hw_state;
1781 intel_plane->check_plane = vlv_sprite_check;
1558 1782
1559 plane_formats = vlv_plane_formats; 1783 plane_formats = vlv_plane_formats;
1560 num_plane_formats = ARRAY_SIZE(vlv_plane_formats); 1784 num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
@@ -1562,17 +1786,11 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1562 1786
1563 plane_funcs = &vlv_sprite_funcs; 1787 plane_funcs = &vlv_sprite_funcs;
1564 } else if (INTEL_GEN(dev_priv) >= 7) { 1788 } else if (INTEL_GEN(dev_priv) >= 7) {
1565 if (IS_IVYBRIDGE(dev_priv)) { 1789 intel_plane->max_stride = g4x_sprite_max_stride;
1566 intel_plane->can_scale = true;
1567 intel_plane->max_downscale = 2;
1568 } else {
1569 intel_plane->can_scale = false;
1570 intel_plane->max_downscale = 1;
1571 }
1572
1573 intel_plane->update_plane = ivb_update_plane; 1790 intel_plane->update_plane = ivb_update_plane;
1574 intel_plane->disable_plane = ivb_disable_plane; 1791 intel_plane->disable_plane = ivb_disable_plane;
1575 intel_plane->get_hw_state = ivb_plane_get_hw_state; 1792 intel_plane->get_hw_state = ivb_plane_get_hw_state;
1793 intel_plane->check_plane = g4x_sprite_check;
1576 1794
1577 plane_formats = snb_plane_formats; 1795 plane_formats = snb_plane_formats;
1578 num_plane_formats = ARRAY_SIZE(snb_plane_formats); 1796 num_plane_formats = ARRAY_SIZE(snb_plane_formats);
@@ -1580,12 +1798,11 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1580 1798
1581 plane_funcs = &snb_sprite_funcs; 1799 plane_funcs = &snb_sprite_funcs;
1582 } else { 1800 } else {
1583 intel_plane->can_scale = true; 1801 intel_plane->max_stride = g4x_sprite_max_stride;
1584 intel_plane->max_downscale = 16;
1585
1586 intel_plane->update_plane = g4x_update_plane; 1802 intel_plane->update_plane = g4x_update_plane;
1587 intel_plane->disable_plane = g4x_disable_plane; 1803 intel_plane->disable_plane = g4x_disable_plane;
1588 intel_plane->get_hw_state = g4x_plane_get_hw_state; 1804 intel_plane->get_hw_state = g4x_plane_get_hw_state;
1805 intel_plane->check_plane = g4x_sprite_check;
1589 1806
1590 modifiers = i9xx_plane_format_modifiers; 1807 modifiers = i9xx_plane_format_modifiers;
1591 if (IS_GEN6(dev_priv)) { 1808 if (IS_GEN6(dev_priv)) {
@@ -1618,7 +1835,6 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1618 intel_plane->i9xx_plane = plane; 1835 intel_plane->i9xx_plane = plane;
1619 intel_plane->id = PLANE_SPRITE0 + plane; 1836 intel_plane->id = PLANE_SPRITE0 + plane;
1620 intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, intel_plane->id); 1837 intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, intel_plane->id);
1621 intel_plane->check_plane = intel_check_sprite_plane;
1622 1838
1623 possible_crtcs = (1 << pipe); 1839 possible_crtcs = (1 << pipe);
1624 1840