aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2014-08-05 01:56:52 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-08-08 11:43:51 -0400
commit76eebda727c76b5712f6ce75a45a9917d3873a37 (patch)
treecf3ccfbcebff814da175fba77dcbeb6e53673661
parentb2784e151903628a086d2ee12cf943690216cd6c (diff)
drm/i915: Add 180 degree sprite rotation support
The sprite planes (in fact all display planes starting from gen4) support 180 degree rotation. Add the relevant low level bits to the sprite code to make use of that feature. The upper layers are not yet plugged in. v2: HSW handles the rotated buffer offset automagically v3: BDW also handles the rotated buffer offset automagically Testcase: igt/kms_rotation_crc Cc: dri-devel@lists.freedesktop.org Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h3
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c38
3 files changed, 42 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7f9a81087ebc..5ebac620bbcd 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4218,6 +4218,7 @@ enum punit_power_well {
4218#define DVS_YUV_ORDER_UYVY (1<<16) 4218#define DVS_YUV_ORDER_UYVY (1<<16)
4219#define DVS_YUV_ORDER_YVYU (2<<16) 4219#define DVS_YUV_ORDER_YVYU (2<<16)
4220#define DVS_YUV_ORDER_VYUY (3<<16) 4220#define DVS_YUV_ORDER_VYUY (3<<16)
4221#define DVS_ROTATE_180 (1<<15)
4221#define DVS_DEST_KEY (1<<2) 4222#define DVS_DEST_KEY (1<<2)
4222#define DVS_TRICKLE_FEED_DISABLE (1<<14) 4223#define DVS_TRICKLE_FEED_DISABLE (1<<14)
4223#define DVS_TILED (1<<10) 4224#define DVS_TILED (1<<10)
@@ -4288,6 +4289,7 @@ enum punit_power_well {
4288#define SPRITE_YUV_ORDER_UYVY (1<<16) 4289#define SPRITE_YUV_ORDER_UYVY (1<<16)
4289#define SPRITE_YUV_ORDER_YVYU (2<<16) 4290#define SPRITE_YUV_ORDER_YVYU (2<<16)
4290#define SPRITE_YUV_ORDER_VYUY (3<<16) 4291#define SPRITE_YUV_ORDER_VYUY (3<<16)
4292#define SPRITE_ROTATE_180 (1<<15)
4291#define SPRITE_TRICKLE_FEED_DISABLE (1<<14) 4293#define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
4292#define SPRITE_INT_GAMMA_ENABLE (1<<13) 4294#define SPRITE_INT_GAMMA_ENABLE (1<<13)
4293#define SPRITE_TILED (1<<10) 4295#define SPRITE_TILED (1<<10)
@@ -4361,6 +4363,7 @@ enum punit_power_well {
4361#define SP_YUV_ORDER_UYVY (1<<16) 4363#define SP_YUV_ORDER_UYVY (1<<16)
4362#define SP_YUV_ORDER_YVYU (2<<16) 4364#define SP_YUV_ORDER_YVYU (2<<16)
4363#define SP_YUV_ORDER_VYUY (3<<16) 4365#define SP_YUV_ORDER_VYUY (3<<16)
4366#define SP_ROTATE_180 (1<<15)
4364#define SP_TILED (1<<10) 4367#define SP_TILED (1<<10)
4365#define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184) 4368#define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184)
4366#define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188) 4369#define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3198de3007be..b63df4416301 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -448,6 +448,7 @@ struct intel_plane {
448 unsigned int crtc_w, crtc_h; 448 unsigned int crtc_w, crtc_h;
449 uint32_t src_x, src_y; 449 uint32_t src_x, src_y;
450 uint32_t src_w, src_h; 450 uint32_t src_w, src_h;
451 unsigned int rotation;
451 452
452 /* Since we need to change the watermarks before/after 453 /* Since we need to change the watermarks before/after
453 * enabling/disabling the planes, we need to store the parameters here 454 * enabling/disabling the planes, we need to store the parameters here
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index d34a5696ffb6..f4d10c4b2781 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -164,6 +164,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
164 sprctl &= ~SP_PIXFORMAT_MASK; 164 sprctl &= ~SP_PIXFORMAT_MASK;
165 sprctl &= ~SP_YUV_BYTE_ORDER_MASK; 165 sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
166 sprctl &= ~SP_TILED; 166 sprctl &= ~SP_TILED;
167 sprctl &= ~SP_ROTATE_180;
167 168
168 switch (fb->pixel_format) { 169 switch (fb->pixel_format) {
169 case DRM_FORMAT_YUYV: 170 case DRM_FORMAT_YUYV:
@@ -236,6 +237,14 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
236 fb->pitches[0]); 237 fb->pitches[0]);
237 linear_offset -= sprsurf_offset; 238 linear_offset -= sprsurf_offset;
238 239
240 if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
241 sprctl |= SP_ROTATE_180;
242
243 x += src_w;
244 y += src_h;
245 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
246 }
247
239 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 248 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
240 249
241 intel_update_primary_plane(intel_crtc); 250 intel_update_primary_plane(intel_crtc);
@@ -365,6 +374,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
365 sprctl &= ~SPRITE_RGB_ORDER_RGBX; 374 sprctl &= ~SPRITE_RGB_ORDER_RGBX;
366 sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; 375 sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
367 sprctl &= ~SPRITE_TILED; 376 sprctl &= ~SPRITE_TILED;
377 sprctl &= ~SPRITE_ROTATE_180;
368 378
369 switch (fb->pixel_format) { 379 switch (fb->pixel_format) {
370 case DRM_FORMAT_XBGR8888: 380 case DRM_FORMAT_XBGR8888:
@@ -427,6 +437,18 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
427 pixel_size, fb->pitches[0]); 437 pixel_size, fb->pitches[0]);
428 linear_offset -= sprsurf_offset; 438 linear_offset -= sprsurf_offset;
429 439
440 if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
441 sprctl |= SPRITE_ROTATE_180;
442
443 /* HSW and BDW does this automagically in hardware */
444 if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
445 x += src_w;
446 y += src_h;
447 linear_offset += src_h * fb->pitches[0] +
448 src_w * pixel_size;
449 }
450 }
451
430 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 452 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
431 453
432 intel_update_primary_plane(intel_crtc); 454 intel_update_primary_plane(intel_crtc);
@@ -572,6 +594,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
572 dvscntr &= ~DVS_RGB_ORDER_XBGR; 594 dvscntr &= ~DVS_RGB_ORDER_XBGR;
573 dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; 595 dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
574 dvscntr &= ~DVS_TILED; 596 dvscntr &= ~DVS_TILED;
597 dvscntr &= ~DVS_ROTATE_180;
575 598
576 switch (fb->pixel_format) { 599 switch (fb->pixel_format) {
577 case DRM_FORMAT_XBGR8888: 600 case DRM_FORMAT_XBGR8888:
@@ -629,6 +652,14 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
629 pixel_size, fb->pitches[0]); 652 pixel_size, fb->pitches[0]);
630 linear_offset -= dvssurf_offset; 653 linear_offset -= dvssurf_offset;
631 654
655 if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
656 dvscntr |= DVS_ROTATE_180;
657
658 x += src_w;
659 y += src_h;
660 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
661 }
662
632 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); 663 atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
633 664
634 intel_update_primary_plane(intel_crtc); 665 intel_update_primary_plane(intel_crtc);
@@ -896,6 +927,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
896 max_scale = intel_plane->max_downscale << 16; 927 max_scale = intel_plane->max_downscale << 16;
897 min_scale = intel_plane->can_scale ? 1 : (1 << 16); 928 min_scale = intel_plane->can_scale ? 1 : (1 << 16);
898 929
930 drm_rect_rotate(&src, fb->width << 16, fb->height << 16,
931 intel_plane->rotation);
932
899 hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale); 933 hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
900 BUG_ON(hscale < 0); 934 BUG_ON(hscale < 0);
901 935
@@ -934,6 +968,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
934 drm_rect_width(&dst) * hscale - drm_rect_width(&src), 968 drm_rect_width(&dst) * hscale - drm_rect_width(&src),
935 drm_rect_height(&dst) * vscale - drm_rect_height(&src)); 969 drm_rect_height(&dst) * vscale - drm_rect_height(&src));
936 970
971 drm_rect_rotate_inv(&src, fb->width << 16, fb->height << 16,
972 intel_plane->rotation);
973
937 /* sanity check to make sure the src viewport wasn't enlarged */ 974 /* sanity check to make sure the src viewport wasn't enlarged */
938 WARN_ON(src.x1 < (int) src_x || 975 WARN_ON(src.x1 < (int) src_x ||
939 src.y1 < (int) src_y || 976 src.y1 < (int) src_y ||
@@ -1311,6 +1348,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1311 1348
1312 intel_plane->pipe = pipe; 1349 intel_plane->pipe = pipe;
1313 intel_plane->plane = plane; 1350 intel_plane->plane = plane;
1351 intel_plane->rotation = BIT(DRM_ROTATE_0);
1314 possible_crtcs = (1 << pipe); 1352 possible_crtcs = (1 << pipe);
1315 ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, 1353 ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
1316 &intel_plane_funcs, 1354 &intel_plane_funcs,