These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / i915 / intel_overlay.c
index dd92122..4445426 100644 (file)
@@ -172,10 +172,11 @@ struct intel_overlay {
        struct intel_crtc *crtc;
        struct drm_i915_gem_object *vid_bo;
        struct drm_i915_gem_object *old_vid_bo;
-       int active;
-       int pfit_active;
+       bool active;
+       bool pfit_active;
        u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
-       u32 color_key;
+       u32 color_key:24;
+       u32 color_key_enabled:1;
        u32 brightness, contrast, saturation;
        u32 old_xscale, old_yscale;
        /* register access */
@@ -209,25 +210,19 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
 }
 
 static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
+                                        struct drm_i915_gem_request *req,
                                         void (*tail)(struct intel_overlay *))
 {
-       struct drm_device *dev = overlay->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_engine_cs *ring = &dev_priv->ring[RCS];
        int ret;
 
-       BUG_ON(overlay->last_flip_req);
-       i915_gem_request_assign(&overlay->last_flip_req,
-                                            ring->outstanding_lazy_request);
-       ret = i915_add_request(ring);
-       if (ret)
-               return ret;
+       WARN_ON(overlay->last_flip_req);
+       i915_gem_request_assign(&overlay->last_flip_req, req);
+       i915_add_request(req);
 
        overlay->flip_tail = tail;
        ret = i915_wait_request(overlay->last_flip_req);
        if (ret)
                return ret;
-       i915_gem_retire_requests(dev);
 
        i915_gem_request_assign(&overlay->last_flip_req, NULL);
        return 0;
@@ -239,24 +234,31 @@ static int intel_overlay_on(struct intel_overlay *overlay)
        struct drm_device *dev = overlay->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_engine_cs *ring = &dev_priv->ring[RCS];
+       struct drm_i915_gem_request *req;
        int ret;
 
-       BUG_ON(overlay->active);
-       overlay->active = 1;
-
+       WARN_ON(overlay->active);
        WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
 
-       ret = intel_ring_begin(ring, 4);
+       ret = i915_gem_request_alloc(ring, ring->default_context, &req);
        if (ret)
                return ret;
 
+       ret = intel_ring_begin(req, 4);
+       if (ret) {
+               i915_gem_request_cancel(req);
+               return ret;
+       }
+
+       overlay->active = true;
+
        intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
        intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
        intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
        intel_ring_emit(ring, MI_NOOP);
        intel_ring_advance(ring);
 
-       return intel_overlay_do_wait_request(overlay, NULL);
+       return intel_overlay_do_wait_request(overlay, req, NULL);
 }
 
 /* overlay needs to be enabled in OCMD reg */
@@ -266,11 +268,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
        struct drm_device *dev = overlay->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_engine_cs *ring = &dev_priv->ring[RCS];
+       struct drm_i915_gem_request *req;
        u32 flip_addr = overlay->flip_addr;
        u32 tmp;
        int ret;
 
-       BUG_ON(!overlay->active);
+       WARN_ON(!overlay->active);
 
        if (load_polyphase_filter)
                flip_addr |= OFC_UPDATE;
@@ -280,18 +283,25 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
        if (tmp & (1 << 17))
                DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
 
-       ret = intel_ring_begin(ring, 2);
+       ret = i915_gem_request_alloc(ring, ring->default_context, &req);
        if (ret)
                return ret;
 
+       ret = intel_ring_begin(req, 2);
+       if (ret) {
+               i915_gem_request_cancel(req);
+               return ret;
+       }
+
        intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
        intel_ring_emit(ring, flip_addr);
        intel_ring_advance(ring);
 
        WARN_ON(overlay->last_flip_req);
-       i915_gem_request_assign(&overlay->last_flip_req,
-                                            ring->outstanding_lazy_request);
-       return i915_add_request(ring);
+       i915_gem_request_assign(&overlay->last_flip_req, req);
+       i915_add_request(req);
+
+       return 0;
 }
 
 static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
@@ -309,7 +319,8 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
        struct drm_i915_gem_object *obj = overlay->vid_bo;
 
        /* never have the overlay hw on without showing a frame */
-       BUG_ON(!overlay->vid_bo);
+       if (WARN_ON(!obj))
+               return;
 
        i915_gem_object_ggtt_unpin(obj);
        drm_gem_object_unreference(&obj->base);
@@ -317,7 +328,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
 
        overlay->crtc->overlay = NULL;
        overlay->crtc = NULL;
-       overlay->active = 0;
+       overlay->active = false;
 }
 
 /* overlay needs to be disabled in OCMD reg */
@@ -326,10 +337,11 @@ static int intel_overlay_off(struct intel_overlay *overlay)
        struct drm_device *dev = overlay->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_engine_cs *ring = &dev_priv->ring[RCS];
+       struct drm_i915_gem_request *req;
        u32 flip_addr = overlay->flip_addr;
        int ret;
 
-       BUG_ON(!overlay->active);
+       WARN_ON(!overlay->active);
 
        /* According to intel docs the overlay hw may hang (when switching
         * off) without loading the filter coeffs. It is however unclear whether
@@ -337,10 +349,16 @@ static int intel_overlay_off(struct intel_overlay *overlay)
         * of the hw. Do it in both cases */
        flip_addr |= OFC_UPDATE;
 
-       ret = intel_ring_begin(ring, 6);
+       ret = i915_gem_request_alloc(ring, ring->default_context, &req);
        if (ret)
                return ret;
 
+       ret = intel_ring_begin(req, 6);
+       if (ret) {
+               i915_gem_request_cancel(req);
+               return ret;
+       }
+
        /* wait for overlay to go idle */
        intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
        intel_ring_emit(ring, flip_addr);
@@ -359,7 +377,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
        }
        intel_ring_advance(ring);
 
-       return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
+       return intel_overlay_do_wait_request(overlay, req, intel_overlay_off_tail);
 }
 
 /* recover from an interruption due to a signal
@@ -374,7 +392,6 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
        ret = i915_wait_request(overlay->last_flip_req);
        if (ret)
                return ret;
-       i915_gem_retire_requests(overlay->dev);
 
        if (overlay->flip_tail)
                overlay->flip_tail(overlay);
@@ -404,15 +421,23 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
 
        if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
                /* synchronous slowpath */
-               ret = intel_ring_begin(ring, 2);
+               struct drm_i915_gem_request *req;
+
+               ret = i915_gem_request_alloc(ring, ring->default_context, &req);
                if (ret)
                        return ret;
 
+               ret = intel_ring_begin(req, 2);
+               if (ret) {
+                       i915_gem_request_cancel(req);
+                       return ret;
+               }
+
                intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
                intel_ring_emit(ring, MI_NOOP);
                intel_ring_advance(ring);
 
-               ret = intel_overlay_do_wait_request(overlay,
+               ret = intel_overlay_do_wait_request(overlay, req,
                                                    intel_overlay_release_old_vid_tail);
                if (ret)
                        return ret;
@@ -629,31 +654,36 @@ static void update_colorkey(struct intel_overlay *overlay,
                            struct overlay_registers __iomem *regs)
 {
        u32 key = overlay->color_key;
+       u32 flags;
+
+       flags = 0;
+       if (overlay->color_key_enabled)
+               flags |= DST_KEY_ENABLE;
 
        switch (overlay->crtc->base.primary->fb->bits_per_pixel) {
        case 8:
-               iowrite32(0, &regs->DCLRKV);
-               iowrite32(CLK_RGB8I_MASK | DST_KEY_ENABLE, &regs->DCLRKM);
+               key = 0;
+               flags |= CLK_RGB8I_MASK;
                break;
 
        case 16:
                if (overlay->crtc->base.primary->fb->depth == 15) {
-                       iowrite32(RGB15_TO_COLORKEY(key), &regs->DCLRKV);
-                       iowrite32(CLK_RGB15_MASK | DST_KEY_ENABLE,
-                                 &regs->DCLRKM);
+                       key = RGB15_TO_COLORKEY(key);
+                       flags |= CLK_RGB15_MASK;
                } else {
-                       iowrite32(RGB16_TO_COLORKEY(key), &regs->DCLRKV);
-                       iowrite32(CLK_RGB16_MASK | DST_KEY_ENABLE,
-                                 &regs->DCLRKM);
+                       key = RGB16_TO_COLORKEY(key);
+                       flags |= CLK_RGB16_MASK;
                }
                break;
 
        case 24:
        case 32:
-               iowrite32(key, &regs->DCLRKV);
-               iowrite32(CLK_RGB24_MASK | DST_KEY_ENABLE, &regs->DCLRKM);
+               flags |= CLK_RGB24_MASK;
                break;
        }
+
+       iowrite32(key, &regs->DCLRKV);
+       iowrite32(flags, &regs->DCLRKM);
 }
 
 static u32 overlay_cmd_reg(struct put_image_params *params)
@@ -712,15 +742,14 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
        u32 swidth, swidthsw, sheight, ostride;
        enum pipe pipe = overlay->crtc->pipe;
 
-       BUG_ON(!mutex_is_locked(&dev->struct_mutex));
-       BUG_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
-       BUG_ON(!overlay);
+       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+       WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 
        ret = intel_overlay_release_old_vid(overlay);
        if (ret != 0)
                return ret;
 
-       ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL,
+       ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL, NULL,
                                                   &i915_ggtt_view_normal);
        if (ret != 0)
                return ret;
@@ -824,8 +853,8 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
        struct drm_device *dev = overlay->dev;
        int ret;
 
-       BUG_ON(!mutex_is_locked(&dev->struct_mutex));
-       BUG_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+       WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
 
        ret = intel_overlay_recover_from_interrupt(overlay);
        if (ret != 0)
@@ -1131,10 +1160,10 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
                /* line too wide, i.e. one-line-mode */
                if (mode->hdisplay > 1024 &&
                    intel_panel_fitter_pipe(dev) == crtc->pipe) {
-                       overlay->pfit_active = 1;
+                       overlay->pfit_active = true;
                        update_pfit_vscale_ratio(overlay);
                } else
-                       overlay->pfit_active = 0;
+                       overlay->pfit_active = false;
        }
 
        ret = check_overlay_dst(overlay, put_image_rec);
@@ -1329,6 +1358,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
                        I915_WRITE(OGAMC5, attrs->gamma5);
                }
        }
+       overlay->color_key_enabled = (attrs->flags & I915_OVERLAY_DISABLE_DEST_COLORKEY) == 0;
 
        ret = 0;
 out_unlock:
@@ -1392,6 +1422,7 @@ void intel_setup_overlay(struct drm_device *dev)
 
        /* init all values */
        overlay->color_key = 0x0101fe;
+       overlay->color_key_enabled = true;
        overlay->brightness = -19;
        overlay->contrast = 75;
        overlay->saturation = 146;
@@ -1432,7 +1463,7 @@ void intel_cleanup_overlay(struct drm_device *dev)
        /* The bo's should be free'd by the generic code already.
         * Furthermore modesetting teardown happens beforehand so the
         * hardware should be off already */
-       BUG_ON(dev_priv->overlay->active);
+       WARN_ON(dev_priv->overlay->active);
 
        drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
        kfree(dev_priv->overlay);