[Intel-gfx] [PATCH 05/11] drm/i915: Add 180 degree sprite rotation support
Ville Syrjälä
ville.syrjala at linux.intel.com
Fri Jan 31 21:56:15 CET 2014
On Sat, Feb 01, 2014 at 12:40:41AM +0530, sagar.a.kamble at intel.com wrote:
> From: Sagar Kamble <sagar.a.kamble at intel.com>
>
> 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.
>
> Signed-off-by: Ville Syrjala<ville.syrjala at linux.intel.com>
> Tested-by: Sagar Kamble <sagar.a.kamble at intel.com>
I actually posted a v2 of this patch, which fixes HSW. But I guess now
we really need a v3 which extends that fix for BDW. Assuming BDW is like
HSW here.
> ---
> drivers/gpu/drm/i915/i915_reg.h | 3 +++
> drivers/gpu/drm/i915/intel_drv.h | 1 +
> drivers/gpu/drm/i915/intel_sprite.c | 34 ++++++++++++++++++++++++++++++++++
> 3 files changed, 38 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index abd18cd..57906c5 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3637,6 +3637,7 @@
> #define DVS_YUV_ORDER_UYVY (1<<16)
> #define DVS_YUV_ORDER_YVYU (2<<16)
> #define DVS_YUV_ORDER_VYUY (3<<16)
> +#define DVS_ROTATE_180 (1<<15)
> #define DVS_DEST_KEY (1<<2)
> #define DVS_TRICKLE_FEED_DISABLE (1<<14)
> #define DVS_TILED (1<<10)
> @@ -3707,6 +3708,7 @@
> #define SPRITE_YUV_ORDER_UYVY (1<<16)
> #define SPRITE_YUV_ORDER_YVYU (2<<16)
> #define SPRITE_YUV_ORDER_VYUY (3<<16)
> +#define SPRITE_ROTATE_180 (1<<15)
> #define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
> #define SPRITE_INT_GAMMA_ENABLE (1<<13)
> #define SPRITE_TILED (1<<10)
> @@ -3780,6 +3782,7 @@
> #define SP_YUV_ORDER_UYVY (1<<16)
> #define SP_YUV_ORDER_YVYU (2<<16)
> #define SP_YUV_ORDER_VYUY (3<<16)
> +#define SP_ROTATE_180 (1<<15)
> #define SP_TILED (1<<10)
> #define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184)
> #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 44067bc..85864fc 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -397,6 +397,7 @@ struct intel_plane {
> unsigned int crtc_w, crtc_h;
> uint32_t src_x, src_y;
> uint32_t src_w, src_h;
> + unsigned int rotation;
>
> /* Since we need to change the watermarks before/after
> * 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 336ae6c..f9c8c41 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -60,6 +60,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
> sprctl &= ~SP_PIXFORMAT_MASK;
> sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
> sprctl &= ~SP_TILED;
> + sprctl &= ~SP_ROTATE_180;
>
> switch (fb->pixel_format) {
> case DRM_FORMAT_YUYV:
> @@ -131,6 +132,14 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
> fb->pitches[0]);
> linear_offset -= sprsurf_offset;
>
> + if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
> + sprctl |= SP_ROTATE_180;
> +
> + x += src_w;
> + y += src_h;
> + linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
> + }
> +
> I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
> I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
>
> @@ -238,6 +247,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
> sprctl &= ~SPRITE_RGB_ORDER_RGBX;
> sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
> sprctl &= ~SPRITE_TILED;
> + sprctl &= ~SPRITE_ROTATE_180;
>
> switch (fb->pixel_format) {
> case DRM_FORMAT_XBGR8888:
> @@ -299,6 +309,14 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
> pixel_size, fb->pitches[0]);
> linear_offset -= sprsurf_offset;
>
> + if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
> + sprctl |= SPRITE_ROTATE_180;
> +
> + x += src_w;
> + y += src_h;
> + linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
> + }
> +
> I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
> I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
>
> @@ -422,6 +440,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
> dvscntr &= ~DVS_RGB_ORDER_XBGR;
> dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
> dvscntr &= ~DVS_TILED;
> + dvscntr &= ~DVS_ROTATE_180;
>
> switch (fb->pixel_format) {
> case DRM_FORMAT_XBGR8888:
> @@ -478,6 +497,14 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
> pixel_size, fb->pitches[0]);
> linear_offset -= dvssurf_offset;
>
> + if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
> + dvscntr |= DVS_ROTATE_180;
> +
> + x += src_w;
> + y += src_h;
> + linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
> + }
> +
> I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
> I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
>
> @@ -739,6 +766,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
> max_scale = intel_plane->max_downscale << 16;
> min_scale = intel_plane->can_scale ? 1 : (1 << 16);
>
> + drm_rect_rotate(&src, fb->width << 16, fb->height << 16,
> + intel_plane->rotation);
> +
> hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
> BUG_ON(hscale < 0);
>
> @@ -777,6 +807,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
> drm_rect_width(&dst) * hscale - drm_rect_width(&src),
> drm_rect_height(&dst) * vscale - drm_rect_height(&src));
>
> + drm_rect_rotate_inv(&src, fb->width << 16, fb->height << 16,
> + intel_plane->rotation);
> +
> /* sanity check to make sure the src viewport wasn't enlarged */
> WARN_ON(src.x1 < (int) src_x ||
> src.y1 < (int) src_y ||
> @@ -1141,6 +1174,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
>
> intel_plane->pipe = pipe;
> intel_plane->plane = plane;
> + intel_plane->rotation = BIT(DRM_ROTATE_0);
> possible_crtcs = (1 << pipe);
> ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
> &intel_plane_funcs,
> --
> 1.8.5
--
Ville Syrjälä
Intel OTC
More information about the Intel-gfx
mailing list