drm/i915: Make intel_plane_restore() return an error
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_sprite.c
index 396c1e843956aea54e7b029bdf8a17a004490327..611826209c99462c57d23ea6f08aaaf45bcaf75c 100644 (file)
@@ -53,6 +53,7 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl
        enum pipe pipe = crtc->pipe;
        long timeout = msecs_to_jiffies_timeout(1);
        int scanline, min, max, vblank_start;
+       wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
        DEFINE_WAIT(wait);
 
        WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
@@ -81,7 +82,7 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl
                 * other CPUs can see the task state update by the time we
                 * read the scanline.
                 */
-               prepare_to_wait(&crtc->vbl_wait, &wait, TASK_UNINTERRUPTIBLE);
+               prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
 
                scanline = intel_get_crtc_scanline(crtc);
                if (scanline < min || scanline > max)
@@ -100,7 +101,7 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl
                local_irq_disable();
        }
 
-       finish_wait(&crtc->vbl_wait, &wait);
+       finish_wait(wq, &wait);
 
        drm_vblank_put(dev, pipe);
 
@@ -163,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:
@@ -235,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);
@@ -364,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:
@@ -426,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);
@@ -571,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:
@@ -628,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);
@@ -895,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);
 
@@ -933,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 ||
@@ -1126,7 +1164,6 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
                              struct drm_file *file_priv)
 {
        struct drm_intel_sprite_colorkey *set = data;
-       struct drm_mode_object *obj;
        struct drm_plane *plane;
        struct intel_plane *intel_plane;
        int ret = 0;
@@ -1140,13 +1177,12 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
 
        drm_modeset_lock_all(dev);
 
-       obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
-       if (!obj) {
+       plane = drm_plane_find(dev, set->plane_id);
+       if (!plane) {
                ret = -ENOENT;
                goto out_unlock;
        }
 
-       plane = obj_to_plane(obj);
        intel_plane = to_intel_plane(plane);
        ret = intel_plane->update_colorkey(plane, set);
 
@@ -1159,7 +1195,6 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
                              struct drm_file *file_priv)
 {
        struct drm_intel_sprite_colorkey *get = data;
-       struct drm_mode_object *obj;
        struct drm_plane *plane;
        struct intel_plane *intel_plane;
        int ret = 0;
@@ -1169,13 +1204,12 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
 
        drm_modeset_lock_all(dev);
 
-       obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
-       if (!obj) {
+       plane = drm_plane_find(dev, get->plane_id);
+       if (!plane) {
                ret = -ENOENT;
                goto out_unlock;
        }
 
-       plane = obj_to_plane(obj);
        intel_plane = to_intel_plane(plane);
        intel_plane->get_colorkey(plane, get);
 
@@ -1184,18 +1218,18 @@ out_unlock:
        return ret;
 }
 
-void intel_plane_restore(struct drm_plane *plane)
+int intel_plane_restore(struct drm_plane *plane)
 {
        struct intel_plane *intel_plane = to_intel_plane(plane);
 
        if (!plane->crtc || !plane->fb)
-               return;
+               return 0;
 
-       intel_update_plane(plane, plane->crtc, plane->fb,
-                          intel_plane->crtc_x, intel_plane->crtc_y,
-                          intel_plane->crtc_w, intel_plane->crtc_h,
-                          intel_plane->src_x, intel_plane->src_y,
-                          intel_plane->src_w, intel_plane->src_h);
+       return intel_update_plane(plane, plane->crtc, plane->fb,
+                                 intel_plane->crtc_x, intel_plane->crtc_y,
+                                 intel_plane->crtc_w, intel_plane->crtc_h,
+                                 intel_plane->src_x, intel_plane->src_y,
+                                 intel_plane->src_w, intel_plane->src_h);
 }
 
 void intel_plane_disable(struct drm_plane *plane)
@@ -1314,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,
This page took 0.029737 seconds and 5 git commands to generate.