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>
This commit is contained in:

committed by
Daniel Vetter

parent
b2784e1519
commit
76eebda727
@@ -164,6 +164,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:
|
||||
@@ -236,6 +237,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;
|
||||
}
|
||||
|
||||
atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
|
||||
|
||||
intel_update_primary_plane(intel_crtc);
|
||||
@@ -365,6 +374,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:
|
||||
@@ -427,6 +437,18 @@ 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 and BDW does this automagically in hardware */
|
||||
if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
|
||||
x += src_w;
|
||||
y += src_h;
|
||||
linear_offset += src_h * fb->pitches[0] +
|
||||
src_w * pixel_size;
|
||||
}
|
||||
}
|
||||
|
||||
atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
|
||||
|
||||
intel_update_primary_plane(intel_crtc);
|
||||
@@ -572,6 +594,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:
|
||||
@@ -629,6 +652,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;
|
||||
}
|
||||
|
||||
atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
|
||||
|
||||
intel_update_primary_plane(intel_crtc);
|
||||
@@ -896,6 +927,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);
|
||||
|
||||
@@ -934,6 +968,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 ||
|
||||
@@ -1311,6 +1348,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,
|
||||
|
Reference in New Issue
Block a user