|
@@ -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,
|