These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / i915 / intel_atomic_plane.c
index 976b891..a119806 100644 (file)
@@ -56,6 +56,7 @@ intel_create_plane_state(struct drm_plane *plane)
 
        state->base.plane = plane;
        state->base.rotation = BIT(DRM_ROTATE_0);
+       state->ckey.flags = I915_SET_COLORKEY_NONE;
 
        return state;
 }
@@ -75,18 +76,14 @@ intel_plane_duplicate_state(struct drm_plane *plane)
        struct drm_plane_state *state;
        struct intel_plane_state *intel_state;
 
-       if (WARN_ON(!plane->state))
-               intel_state = intel_create_plane_state(plane);
-       else
-               intel_state = kmemdup(plane->state, sizeof(*intel_state),
-                                     GFP_KERNEL);
+       intel_state = kmemdup(plane->state, sizeof(*intel_state), GFP_KERNEL);
 
        if (!intel_state)
                return NULL;
 
        state = &intel_state->base;
-       if (state->fb)
-               drm_framebuffer_reference(state->fb);
+
+       __drm_atomic_helper_plane_duplicate_state(plane, state);
 
        return state;
 }
@@ -111,10 +108,13 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
 {
        struct drm_crtc *crtc = state->crtc;
        struct intel_crtc *intel_crtc;
+       struct intel_crtc_state *crtc_state;
        struct intel_plane *intel_plane = to_intel_plane(plane);
        struct intel_plane_state *intel_state = to_intel_plane_state(state);
+       struct drm_crtc_state *drm_crtc_state;
+       int ret;
 
-       crtc = crtc ? crtc : plane->crtc;
+       crtc = crtc ? crtc : plane->state->crtc;
        intel_crtc = to_intel_crtc(crtc);
 
        /*
@@ -126,6 +126,12 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
        if (!crtc)
                return 0;
 
+       drm_crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
+       if (WARN_ON(!drm_crtc_state))
+               return -EINVAL;
+
+       crtc_state = to_intel_crtc_state(drm_crtc_state);
+
        /*
         * The original src/dest coordinates are stored in state->base, but
         * we want to keep another copy internal to our driver that we can
@@ -144,25 +150,40 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
        intel_state->clip.x1 = 0;
        intel_state->clip.y1 = 0;
        intel_state->clip.x2 =
-               intel_crtc->active ? intel_crtc->config->pipe_src_w : 0;
+               crtc_state->base.active ? crtc_state->pipe_src_w : 0;
        intel_state->clip.y2 =
-               intel_crtc->active ? intel_crtc->config->pipe_src_h : 0;
+               crtc_state->base.active ? crtc_state->pipe_src_h : 0;
+
+       if (state->fb && intel_rotation_90_or_270(state->rotation)) {
+               if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+                       state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
+                       DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
+                       return -EINVAL;
+               }
 
-       /*
-        * Disabling a plane is always okay; we just need to update
-        * fb tracking in a special way since cleanup_fb() won't
-        * get called by the plane helpers.
-        */
-       if (state->fb == NULL && plane->state->fb != NULL) {
                /*
-                * 'prepare' is never called when plane is being disabled, so
-                * we need to handle frontbuffer tracking as a special case
+                * 90/270 is not allowed with RGB64 16:16:16:16,
+                * RGB 16-bit 5:6:5, and Indexed 8-bit.
+                * TBD: Add RGB64 case once its added in supported format list.
                 */
-               intel_crtc->atomic.disabled_planes |=
-                       (1 << drm_plane_index(plane));
+               switch (state->fb->pixel_format) {
+               case DRM_FORMAT_C8:
+               case DRM_FORMAT_RGB565:
+                       DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
+                                       drm_get_format_name(state->fb->pixel_format));
+                       return -EINVAL;
+
+               default:
+                       break;
+               }
        }
 
-       return intel_plane->check_plane(plane, intel_state);
+       intel_state->visible = false;
+       ret = intel_plane->check_plane(plane, crtc_state, intel_state);
+       if (ret)
+               return ret;
+
+       return intel_plane_atomic_calc_changes(&crtc_state->base, state);
 }
 
 static void intel_plane_atomic_update(struct drm_plane *plane,
@@ -172,10 +193,6 @@ static void intel_plane_atomic_update(struct drm_plane *plane,
        struct intel_plane_state *intel_state =
                to_intel_plane_state(plane->state);
 
-       /* Don't disable an already disabled plane */
-       if (!plane->state->fb && !old_state->fb)
-               return;
-
        intel_plane->commit_plane(plane, intel_state);
 }