drm/exynos: ipp: Fix support for image rotation and buffer offset
authorMarek Szyprowski <m.szyprowski@samsung.com>
Fri, 30 Mar 2018 06:16:59 +0000 (08:16 +0200)
committerJunghoon Kim <jhoon20.kim@samsung.com>
Thu, 14 Feb 2019 05:56:49 +0000 (14:56 +0900)
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Change-Id: I4bf6b571d845f000ae3b2502bb37ae12b0cfabf7

drivers/gpu/drm/exynos/exynos_drm_gsc.c
drivers/gpu/drm/exynos/exynos_drm_ipp.c

index e9e8454..5491f7e 100644 (file)
@@ -532,12 +532,11 @@ static void gsc_src_set_transf(struct gsc_context *ctx, unsigned int rotation)
                        cfg |= GSC_IN_ROT_YFLIP;
                break;
        case DRM_MODE_ROTATE_90:
+               cfg |= GSC_IN_ROT_90;
                if (rotation & DRM_MODE_REFLECT_Y)
-                       cfg |= GSC_IN_ROT_90_XFLIP;
-               else if (rotation & DRM_MODE_REFLECT_X)
-                       cfg |= GSC_IN_ROT_90_YFLIP;
-               else
-                       cfg |= GSC_IN_ROT_90;
+                       cfg |= GSC_IN_ROT_XFLIP;
+               if (rotation & DRM_MODE_REFLECT_X)
+                       cfg |= GSC_IN_ROT_YFLIP;
                break;
        case DRM_MODE_ROTATE_180:
                cfg |= GSC_IN_ROT_180;
index 9b4ffec..4fcbef5 100644 (file)
@@ -370,8 +370,7 @@ static int exynos_drm_ipp_task_setup_buffer(struct exynos_drm_ipp_buffer *buf,
        for (i = 0; i < buf->format->num_planes; i++) {
                unsigned int height = (i == 0) ? buf->buf.height :
                             DIV_ROUND_UP(buf->buf.height, buf->format->vsub);
-               unsigned long size = height * buf->buf.pitch[i] +
-                                    buf->buf.offset[i];
+               unsigned long size = height * buf->buf.pitch[i];
                struct drm_gem_object *obj = drm_gem_object_lookup(filp,
                                                            buf->buf.gem_id[i]);
                if (!obj) {
@@ -380,7 +379,7 @@ static int exynos_drm_ipp_task_setup_buffer(struct exynos_drm_ipp_buffer *buf,
                }
                buf->exynos_gem[i] = to_exynos_gem(obj);
 
-               if (size > buf->exynos_gem[i]->size) {
+               if (size + buf->buf.offset[i] > buf->exynos_gem[i]->size) {
                        i++;
                        ret = -EINVAL;
                        goto gem_free;
@@ -540,6 +539,7 @@ static int exynos_drm_ipp_check_scale_limits(
                                unsigned int num_limits, bool swap)
 {
        const struct drm_exynos_ipp_limit_val *lh, *lv;
+       int dw, dh;
 
        for (; num_limits; limits++, num_limits--)
                if ((limits->type & DRM_EXYNOS_IPP_LIMIT_TYPE_MASK) ==
@@ -550,9 +550,11 @@ static int exynos_drm_ipp_check_scale_limits(
 
        lh = (!swap) ? &limits->h : &limits->v;
        lv = (!swap) ? &limits->v : &limits->h;
+       dw = (!swap) ? dst->w : dst->h;
+       dh = (!swap) ? dst->h : dst->w;
 
-       if (!__scale_limit_check(src->w, dst->w, lh->min, lh->max) ||
-           !__scale_limit_check(src->h, dst->h, lv->min, lv->max))
+       if (!__scale_limit_check(src->w, dw, lh->min, lh->max) ||
+           !__scale_limit_check(src->h, dh, lv->min, lv->max))
                return -EINVAL;
 
        return 0;
@@ -631,7 +633,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task,
        }
        ret = exynos_drm_ipp_check_size_limits(dst, dst_fmt->limits,
                                               dst_fmt->num_limits,
-                                              rotate, swap);
+                                              false, swap);
        if (ret)
                return ret;
        ret = exynos_drm_ipp_check_scale_limits(&src->rect, &dst->rect,
@@ -729,7 +731,7 @@ void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret)
        struct exynos_drm_ipp *ipp = task->ipp;
        unsigned long flags;
 
-       DRM_DEBUG_DRIVER("ipp: %d, task %pK done\n", ipp->id, task);
+       DRM_DEBUG_DRIVER("ipp: %d, task %pK done: %d\n", ipp->id, task, ret);
 
        spin_lock_irqsave(&ipp->lock, flags);
        if (ipp->task == task)