OSDN Git Service

drm/i915/overlay: Use the ioctl parameters directly
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 6 Sep 2018 19:01:44 +0000 (20:01 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 11 Sep 2018 14:51:27 +0000 (15:51 +0100)
The user parameters to put_image are not copied back to userspace
(DRM_IOW), and so we can modify the ioctl parameters (having already been
copied to a temporary kernel struct) directly and use those in place,
avoiding another temporary malloc and lots of manual copying.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180906190144.1272-2-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/intel_overlay.c

index 443dfae..72eb7e4 100644 (file)
@@ -487,23 +487,6 @@ void intel_overlay_reset(struct drm_i915_private *dev_priv)
        overlay->active = false;
 }
 
-struct put_image_params {
-       int format;
-       short dst_x;
-       short dst_y;
-       short dst_w;
-       short dst_h;
-       short src_w;
-       short src_scan_h;
-       short src_scan_w;
-       short src_h;
-       short stride_Y;
-       short stride_UV;
-       int offset_Y;
-       int offset_U;
-       int offset_V;
-};
-
 static int packed_depth_bytes(u32 format)
 {
        switch (format & I915_OVERLAY_DEPTH_MASK) {
@@ -618,25 +601,25 @@ static void update_polyphase_filter(struct overlay_registers __iomem *regs)
 
 static bool update_scaling_factors(struct intel_overlay *overlay,
                                   struct overlay_registers __iomem *regs,
-                                  struct put_image_params *params)
+                                  struct drm_intel_overlay_put_image *params)
 {
        /* fixed point with a 12 bit shift */
        u32 xscale, yscale, xscale_UV, yscale_UV;
 #define FP_SHIFT 12
 #define FRACT_MASK 0xfff
        bool scale_changed = false;
-       int uv_hscale = uv_hsubsampling(params->format);
-       int uv_vscale = uv_vsubsampling(params->format);
+       int uv_hscale = uv_hsubsampling(params->flags);
+       int uv_vscale = uv_vsubsampling(params->flags);
 
-       if (params->dst_w > 1)
-               xscale = ((params->src_scan_w - 1) << FP_SHIFT)
-                       /(params->dst_w);
+       if (params->dst_width > 1)
+               xscale = ((params->src_scan_width - 1) << FP_SHIFT) /
+                       params->dst_width;
        else
                xscale = 1 << FP_SHIFT;
 
-       if (params->dst_h > 1)
-               yscale = ((params->src_scan_h - 1) << FP_SHIFT)
-                       /(params->dst_h);
+       if (params->dst_height > 1)
+               yscale = ((params->src_scan_height - 1) << FP_SHIFT) /
+                       params->dst_height;
        else
                yscale = 1 << FP_SHIFT;
 
@@ -713,12 +696,12 @@ static void update_colorkey(struct intel_overlay *overlay,
        iowrite32(flags, &regs->DCLRKM);
 }
 
-static u32 overlay_cmd_reg(struct put_image_params *params)
+static u32 overlay_cmd_reg(struct drm_intel_overlay_put_image *params)
 {
        u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
 
-       if (params->format & I915_OVERLAY_YUV_PLANAR) {
-               switch (params->format & I915_OVERLAY_DEPTH_MASK) {
+       if (params->flags & I915_OVERLAY_YUV_PLANAR) {
+               switch (params->flags & I915_OVERLAY_DEPTH_MASK) {
                case I915_OVERLAY_YUV422:
                        cmd |= OCMD_YUV_422_PLANAR;
                        break;
@@ -731,7 +714,7 @@ static u32 overlay_cmd_reg(struct put_image_params *params)
                        break;
                }
        } else { /* YUV packed */
-               switch (params->format & I915_OVERLAY_DEPTH_MASK) {
+               switch (params->flags & I915_OVERLAY_DEPTH_MASK) {
                case I915_OVERLAY_YUV422:
                        cmd |= OCMD_YUV_422_PACKED;
                        break;
@@ -740,7 +723,7 @@ static u32 overlay_cmd_reg(struct put_image_params *params)
                        break;
                }
 
-               switch (params->format & I915_OVERLAY_SWAP_MASK) {
+               switch (params->flags & I915_OVERLAY_SWAP_MASK) {
                case I915_OVERLAY_NO_SWAP:
                        break;
                case I915_OVERLAY_UV_SWAP:
@@ -760,7 +743,7 @@ static u32 overlay_cmd_reg(struct put_image_params *params)
 
 static int intel_overlay_do_put_image(struct intel_overlay *overlay,
                                      struct drm_i915_gem_object *new_bo,
-                                     struct put_image_params *params)
+                                     struct drm_intel_overlay_put_image *params)
 {
        struct overlay_registers __iomem *regs = overlay->regs;
        struct drm_i915_private *dev_priv = overlay->i915;
@@ -806,35 +789,40 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
                        goto out_unpin;
        }
 
-       iowrite32((params->dst_y << 16) | params->dst_x, &regs->DWINPOS);
-       iowrite32((params->dst_h << 16) | params->dst_w, &regs->DWINSZ);
+       iowrite32(params->dst_y << 16 | params->dst_x, &regs->DWINPOS);
+       iowrite32(params->dst_height << 16 | params->dst_width, &regs->DWINSZ);
 
-       if (params->format & I915_OVERLAY_YUV_PACKED)
-               tmp_width = packed_width_bytes(params->format, params->src_w);
+       if (params->flags & I915_OVERLAY_YUV_PACKED)
+               tmp_width = packed_width_bytes(params->flags,
+                                              params->src_width);
        else
-               tmp_width = params->src_w;
+               tmp_width = params->src_width;
 
-       swidth = params->src_w;
+       swidth = params->src_width;
        swidthsw = calc_swidthsw(dev_priv, params->offset_Y, tmp_width);
-       sheight = params->src_h;
+       sheight = params->src_height;
        iowrite32(i915_ggtt_offset(vma) + params->offset_Y, &regs->OBUF_0Y);
        ostride = params->stride_Y;
 
-       if (params->format & I915_OVERLAY_YUV_PLANAR) {
-               int uv_hscale = uv_hsubsampling(params->format);
-               int uv_vscale = uv_vsubsampling(params->format);
+       if (params->flags & I915_OVERLAY_YUV_PLANAR) {
+               int uv_hscale = uv_hsubsampling(params->flags);
+               int uv_vscale = uv_vsubsampling(params->flags);
                u32 tmp_U, tmp_V;
-               swidth |= (params->src_w/uv_hscale) << 16;
+
+               swidth |= (params->src_width / uv_hscale) << 16;
+               sheight |= (params->src_height / uv_vscale) << 16;
+
                tmp_U = calc_swidthsw(dev_priv, params->offset_U,
-                                     params->src_w/uv_hscale);
+                                     params->src_width / uv_hscale);
                tmp_V = calc_swidthsw(dev_priv, params->offset_V,
-                                     params->src_w/uv_hscale);
-               swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
-               sheight |= (params->src_h/uv_vscale) << 16;
+                                     params->src_width / uv_hscale);
+               swidthsw |= max(tmp_U, tmp_V) << 16;
+
                iowrite32(i915_ggtt_offset(vma) + params->offset_U,
                          &regs->OBUF_0U);
                iowrite32(i915_ggtt_offset(vma) + params->offset_V,
                          &regs->OBUF_0V);
+
                ostride |= params->stride_UV << 16;
        }
 
@@ -938,15 +926,16 @@ static int check_overlay_dst(struct intel_overlay *overlay,
                return -EINVAL;
 }
 
-static int check_overlay_scaling(struct put_image_params *rec)
+static int check_overlay_scaling(struct drm_intel_overlay_put_image *rec)
 {
        u32 tmp;
 
        /* downscaling limit is 8.0 */
-       tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
+       tmp = ((rec->src_scan_height << 16) / rec->dst_height) >> 16;
        if (tmp > 7)
                return -EINVAL;
-       tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
+
+       tmp = ((rec->src_scan_width << 16) / rec->dst_width) >> 16;
        if (tmp > 7)
                return -EINVAL;
 
@@ -1067,13 +1056,12 @@ static int check_overlay_src(struct drm_i915_private *dev_priv,
 int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
                                  struct drm_file *file_priv)
 {
-       struct drm_intel_overlay_put_image *put_image_rec = data;
+       struct drm_intel_overlay_put_image *params = data;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_overlay *overlay;
        struct drm_crtc *drmmode_crtc;
        struct intel_crtc *crtc;
        struct drm_i915_gem_object *new_bo;
-       struct put_image_params *params;
        int ret;
 
        overlay = dev_priv->overlay;
@@ -1082,7 +1070,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
                return -ENODEV;
        }
 
-       if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
+       if (!(params->flags & I915_OVERLAY_ENABLE)) {
                drm_modeset_lock_all(dev);
                mutex_lock(&dev->struct_mutex);
 
@@ -1094,22 +1082,14 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
                return ret;
        }
 
-       params = kmalloc(sizeof(*params), GFP_KERNEL);
-       if (!params)
-               return -ENOMEM;
-
-       drmmode_crtc = drm_crtc_find(dev, file_priv, put_image_rec->crtc_id);
-       if (!drmmode_crtc) {
-               ret = -ENOENT;
-               goto out_free;
-       }
+       drmmode_crtc = drm_crtc_find(dev, file_priv, params->crtc_id);
+       if (!drmmode_crtc)
+               return -ENOENT;
        crtc = to_intel_crtc(drmmode_crtc);
 
-       new_bo = i915_gem_object_lookup(file_priv, put_image_rec->bo_handle);
-       if (!new_bo) {
-               ret = -ENOENT;
-               goto out_free;
-       }
+       new_bo = i915_gem_object_lookup(file_priv, params->bo_handle);
+       if (!new_bo)
+               return -ENOENT;
 
        drm_modeset_lock_all(dev);
        mutex_lock(&dev->struct_mutex);
@@ -1145,42 +1125,27 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
                        overlay->pfit_active = false;
        }
 
-       ret = check_overlay_dst(overlay, put_image_rec);
+       ret = check_overlay_dst(overlay, params);
        if (ret != 0)
                goto out_unlock;
 
        if (overlay->pfit_active) {
-               params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
+               params->dst_y = (((u32)params->dst_y << 12) /
                                 overlay->pfit_vscale_ratio);
                /* shifting right rounds downwards, so add 1 */
-               params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
+               params->dst_height = (((u32)params->dst_height << 12) /
                                 overlay->pfit_vscale_ratio) + 1;
-       } else {
-               params->dst_y = put_image_rec->dst_y;
-               params->dst_h = put_image_rec->dst_height;
        }
-       params->dst_x = put_image_rec->dst_x;
-       params->dst_w = put_image_rec->dst_width;
-
-       params->src_w = put_image_rec->src_width;
-       params->src_h = put_image_rec->src_height;
-       params->src_scan_w = put_image_rec->src_scan_width;
-       params->src_scan_h = put_image_rec->src_scan_height;
-       if (params->src_scan_h > params->src_h ||
-           params->src_scan_w > params->src_w) {
+
+       if (params->src_scan_height > params->src_height ||
+           params->src_scan_width > params->src_width) {
                ret = -EINVAL;
                goto out_unlock;
        }
 
-       ret = check_overlay_src(dev_priv, put_image_rec, new_bo);
+       ret = check_overlay_src(dev_priv, params, new_bo);
        if (ret != 0)
                goto out_unlock;
-       params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
-       params->stride_Y = put_image_rec->stride_Y;
-       params->stride_UV = put_image_rec->stride_UV;
-       params->offset_Y = put_image_rec->offset_Y;
-       params->offset_U = put_image_rec->offset_U;
-       params->offset_V = put_image_rec->offset_V;
 
        /* Check scaling after src size to prevent a divide-by-zero. */
        ret = check_overlay_scaling(params);
@@ -1195,16 +1160,12 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
        drm_modeset_unlock_all(dev);
        i915_gem_object_put(new_bo);
 
-       kfree(params);
-
        return 0;
 
 out_unlock:
        mutex_unlock(&dev->struct_mutex);
        drm_modeset_unlock_all(dev);
        i915_gem_object_put(new_bo);
-out_free:
-       kfree(params);
 
        return ret;
 }