drm/exynos/gsc: Add rotation hardware limits of gscaler 37/123837/15 submit/tizen/20170710.070742
authorHoegeun Kwon <hoegeun.kwon@samsung.com>
Fri, 7 Apr 2017 06:11:14 +0000 (15:11 +0900)
committerHoegeun Kwon <hoegeun.kwon@samsung.com>
Wed, 5 Jul 2017 05:56:15 +0000 (14:56 +0900)
The gscaler has hardware rotation limits that need to be imported from
dts. Parse them and add them to the property list.

The rotation hardware limits are related to the cropped source size.
When swap occurs, use rot_max size instead of crop_max size.

Also the scaling limits are related to post size, use pos size to
check the limits.

Change-Id: I081568c20ac5b30e5decd76498b39bacf29829b6
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
drivers/gpu/drm/exynos/exynos_drm_gsc.c
include/uapi/drm/exynos_drm.h

index 1e12beef51692e4303b37f4adcf3822b5552b3ab..51db07986c70eb48b319a1beeb653f9bccc9b208 100644 (file)
@@ -1501,6 +1501,23 @@ static int gsc_ippdrv_check_property(struct device *dev,
        bool swap;
        int i;
 
+       config = &property->config[EXYNOS_DRM_OPS_DST];
+
+       /* check for degree */
+       switch (config->degree) {
+       case EXYNOS_DRM_DEGREE_90:
+       case EXYNOS_DRM_DEGREE_270:
+               swap = true;
+               break;
+       case EXYNOS_DRM_DEGREE_0:
+       case EXYNOS_DRM_DEGREE_180:
+               swap = false;
+               break;
+       default:
+               DRM_ERROR("invalid degree.\n");
+               goto err_property;
+       }
+
        for_each_ipp_ops(i) {
                if ((i == EXYNOS_DRM_OPS_SRC) &&
                        (property->cmd == IPP_CMD_WB))
@@ -1516,21 +1533,6 @@ static int gsc_ippdrv_check_property(struct device *dev,
                        goto err_property;
                }
 
-               /* check for degree */
-               switch (config->degree) {
-               case EXYNOS_DRM_DEGREE_90:
-               case EXYNOS_DRM_DEGREE_270:
-                       swap = true;
-                       break;
-               case EXYNOS_DRM_DEGREE_0:
-               case EXYNOS_DRM_DEGREE_180:
-                       swap = false;
-                       break;
-               default:
-                       DRM_ERROR("invalid degree.\n");
-                       goto err_property;
-               }
-
                /* check for buffer bound */
                if ((pos->x + pos->w > sz->hsize) ||
                        (pos->y + pos->h > sz->vsize)) {
@@ -1538,21 +1540,27 @@ static int gsc_ippdrv_check_property(struct device *dev,
                        goto err_property;
                }
 
+               /*
+                * The rotation hardware limits are related to the cropped
+                * source size. So use rot_max size to check the limits when
+                * swap happens. And also the scaling limits are related to pos
+                * size, use pos size to check the limits.
+                */
                /* check for crop */
                if ((i == EXYNOS_DRM_OPS_SRC) && (pp->crop)) {
                        if (swap) {
                                if ((pos->h < pp->crop_min.hsize) ||
-                                       (sz->vsize > pp->crop_max.hsize) ||
+                                       (pos->h > pp->rot_max.hsize) ||
                                        (pos->w < pp->crop_min.vsize) ||
-                                       (sz->hsize > pp->crop_max.vsize)) {
+                                       (pos->w > pp->rot_max.vsize)) {
                                        DRM_ERROR("out of crop size.\n");
                                        goto err_property;
                                }
                        } else {
                                if ((pos->w < pp->crop_min.hsize) ||
-                                       (sz->hsize > pp->crop_max.hsize) ||
+                                       (pos->w > pp->crop_max.hsize) ||
                                        (pos->h < pp->crop_min.vsize) ||
-                                       (sz->vsize > pp->crop_max.vsize)) {
+                                       (pos->h > pp->crop_max.vsize)) {
                                        DRM_ERROR("out of crop size.\n");
                                        goto err_property;
                                }
@@ -1563,17 +1571,17 @@ static int gsc_ippdrv_check_property(struct device *dev,
                if ((i == EXYNOS_DRM_OPS_DST) && (pp->scale)) {
                        if (swap) {
                                if ((pos->h < pp->scale_min.hsize) ||
-                                       (sz->vsize > pp->scale_max.hsize) ||
+                                       (pos->h > pp->scale_max.hsize) ||
                                        (pos->w < pp->scale_min.vsize) ||
-                                       (sz->hsize > pp->scale_max.vsize)) {
+                                       (pos->w > pp->scale_max.vsize)) {
                                        DRM_ERROR("out of scale size.\n");
                                        goto err_property;
                                }
                        } else {
                                if ((pos->w < pp->scale_min.hsize) ||
-                                       (sz->hsize > pp->scale_max.hsize) ||
+                                       (pos->w > pp->scale_max.hsize) ||
                                        (pos->h < pp->scale_min.vsize) ||
-                                       (sz->vsize > pp->scale_max.vsize)) {
+                                       (pos->h > pp->scale_max.vsize)) {
                                        DRM_ERROR("out of scale size.\n");
                                        goto err_property;
                                }
@@ -1815,6 +1823,15 @@ static int gsc_probe(struct platform_device *pdev)
 
                ctx->num_clocks = driver_data->num_clocks;
                ctx->clk_names = driver_data->clk_names;
+
+               ret = of_property_read_u32(dev->of_node, "rot-max-hsize",
+                                       &ctx->ippdrv.prop_list.rot_max.hsize);
+               ret |= of_property_read_u32(dev->of_node, "rot-max-vsize",
+                                       &ctx->ippdrv.prop_list.rot_max.vsize);
+               if (ret) {
+                       dev_err(dev, "rot-max property should be provided by device tree.\n");
+                       return -EINVAL;
+               }
        } else {
                return -ENODEV;
        }
index 18f0601f84d1b8a159ea4fd886fb51f55f3a8276..7d31ad7c0957749c44e7d2ee05bb4d06fefc09a2 100644 (file)
@@ -188,6 +188,7 @@ enum drm_exynos_planer {
  * @crop_max: crop max resolution.
  * @scale_min: scale min resolution.
  * @scale_max: scale max resolution.
+ * @rot_max: rotation max resolution.
  */
 struct drm_exynos_ipp_prop_list {
        __u32   version;
@@ -206,6 +207,7 @@ struct drm_exynos_ipp_prop_list {
        struct drm_exynos_sz    crop_max;
        struct drm_exynos_sz    scale_min;
        struct drm_exynos_sz    scale_max;
+       struct drm_exynos_sz    rot_max;
 };
 
 /**