[PATCH v5 07/11] drm/i915: Add 180 degree sprite rotation support
Ville Syrjälä
ville.syrjala at linux.intel.com
Mon Feb 10 05:31:47 PST 2014
On Mon, Feb 10, 2014 at 01:01:14PM +0530, sagar.a.kamble at intel.com wrote:
> From: Ville Syrjälä <ville.syrjala at linux.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.
>
> v2: HSW handles the rotated buffer offset automagically
>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: Jani Nikula <jani.nikula at linux.intel.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: dri-devel at lists.freedesktop.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Signed-off-by: Sagar Kamble <sagar.a.kamble at intel.com>
> ---
> drivers/gpu/drm/i915/i915_reg.h | 3 +++
> drivers/gpu/drm/i915/intel_drv.h | 1 +
> drivers/gpu/drm/i915/intel_sprite.c | 37 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 41 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..477d4d7 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,17 @@ 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;
> +
> + /* HSW does this automagically in hardware */
> + if (!IS_HASWELL(dev)) {
Still missing the BDW check here.
> + 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 +443,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 +500,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 +769,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 +810,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 +1177,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 dri-devel
mailing list