drm/exynos: add GSCALER plane capability
authorAndrzej Hajda <a.hajda@samsung.com>
Fri, 15 Feb 2019 14:25:15 +0000 (15:25 +0100)
committerAndrzej Hajda <a.hajda@samsung.com>
Wed, 20 Mar 2019 12:52:04 +0000 (13:52 +0100)
This bit will indicate the plane is provided by GSCALER.
Tests shows that GSCALER does not like to convert from/to too small
buffers. Since exact constraints are not provided by documentation
rough estimate of 64 pixel has been applied.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_plane.c

index 5d06e796dc80ab1f3fd2fbdc6fae03ab5e46438d..7bdbac639b2b3f02080b3e0afc7f8bbf6146517c 100644 (file)
@@ -75,6 +75,7 @@ to_exynos_plane_state(struct drm_plane_state *state)
 #define EXYNOS_DRM_PLANE_CAP_TILE      (1 << 3)
 #define EXYNOS_DRM_PLANE_CAP_PIX_BLEND (1 << 4)
 #define EXYNOS_DRM_PLANE_CAP_WIN_BLEND (1 << 5)
+#define EXYNOS_DRM_PLANE_CAP_GSCALER   (1 << 6)
 
 struct exynos_drm_plane;
 struct exynos_drm_plane_ops {
index 5f8f56b693691c0469f360b15206480ba879977a..89168157e1e20055e76b014238751aea21ade5d0 100644 (file)
@@ -198,6 +198,11 @@ exynos_drm_plane_check_format(struct exynos_drm_plane_state *state)
        return 0;
 }
 
+static bool is_in_range(int val, int min, int max)
+{
+       return (val >= min) && (val < max);
+}
+
 static int
 exynos_drm_plane_check_size(struct exynos_drm_plane_state *state)
 {
@@ -205,7 +210,7 @@ exynos_drm_plane_check_size(struct exynos_drm_plane_state *state)
        bool width_ok = false, height_ok = false;
 
        if (plane->capabilities & EXYNOS_DRM_PLANE_CAP_SCALE)
-               return 0;
+               width_ok = height_ok = true;
 
        if (state->src.w == state->crtc.w)
                width_ok = true;
@@ -221,6 +226,13 @@ exynos_drm_plane_check_size(struct exynos_drm_plane_state *state)
            state->v_ratio == (1 << 15))
                height_ok = true;
 
+       if (plane->capabilities & EXYNOS_DRM_PLANE_CAP_GSCALER) {
+               width_ok = is_in_range(state->src.w, 64, 4800) &&
+                          is_in_range(state->crtc.w, 64, 4800);
+               height_ok = is_in_range(state->src.h, 64, 3344) &&
+                           is_in_range(state->crtc.h, 64, 3344);
+       }
+
        if (width_ok && height_ok)
                return 0;