]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
drm/exynos: add generic check for plane state
authorMarek Szyprowski <m.szyprowski@samsung.com>
Mon, 30 Nov 2015 13:53:26 +0000 (14:53 +0100)
committerInki Dae <daeinki@gmail.com>
Sun, 13 Dec 2015 13:22:57 +0000 (22:22 +0900)
This patch adds generic check for plane state - display area dimensions,
so drivers can always assume that they get valid plane state to set.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_mixer.c

index 6f8a296a3115a483e389d981fb90a2b36fcec742..82bbd7f4b3167114f0405d829ae4e1edc5c56699 100644 (file)
@@ -89,6 +89,9 @@ struct exynos_drm_plane {
        struct drm_framebuffer *pending_fb;
 };
 
+#define EXYNOS_DRM_PLANE_CAP_DOUBLE    (1 << 0)
+#define EXYNOS_DRM_PLANE_CAP_SCALE     (1 << 1)
+
 /*
  * Exynos DRM plane configuration structure.
  *
index b620d7a76799c29f52336e273e6ae8964500f381..9eaa8627175f7ff49ee4ac05c4042a8b7a9c03f3 100644 (file)
@@ -173,6 +173,36 @@ static struct drm_plane_funcs exynos_plane_funcs = {
        .atomic_destroy_state = exynos_drm_plane_destroy_state,
 };
 
+static int
+exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config,
+                           struct exynos_drm_plane_state *state)
+{
+       bool width_ok = false, height_ok = false;
+
+       if (config->capabilities & EXYNOS_DRM_PLANE_CAP_SCALE)
+               return 0;
+
+       if (state->src.w == state->crtc.w)
+               width_ok = true;
+
+       if (state->src.h == state->crtc.h)
+               height_ok = true;
+
+       if ((config->capabilities & EXYNOS_DRM_PLANE_CAP_DOUBLE) &&
+           state->h_ratio == (1 << 15))
+               width_ok = true;
+
+       if ((config->capabilities & EXYNOS_DRM_PLANE_CAP_DOUBLE) &&
+           state->v_ratio == (1 << 15))
+               height_ok = true;
+
+       if (width_ok & height_ok)
+               return 0;
+
+       DRM_DEBUG_KMS("scaling mode is not supported");
+       return -ENOTSUPP;
+}
+
 static int exynos_plane_atomic_check(struct drm_plane *plane,
                                     struct drm_plane_state *state)
 {
@@ -187,6 +217,7 @@ static int exynos_plane_atomic_check(struct drm_plane *plane,
        /* translate state into exynos_state */
        exynos_plane_mode_set(exynos_state);
 
+       ret = exynos_drm_plane_check_size(exynos_plane->config, exynos_state);
        return ret;
 }
 
index a229f86d221adc79d947d71dbd70f63a1a278081..4190285798efc48ec56a9de7db24791277f57480 100644 (file)
@@ -117,16 +117,19 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
                .type = DRM_PLANE_TYPE_PRIMARY,
                .pixel_formats = mixer_formats,
                .num_pixel_formats = ARRAY_SIZE(mixer_formats),
+               .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE,
        }, {
                .zpos = 1,
                .type = DRM_PLANE_TYPE_CURSOR,
                .pixel_formats = mixer_formats,
                .num_pixel_formats = ARRAY_SIZE(mixer_formats),
+               .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE,
        }, {
                .zpos = 2,
                .type = DRM_PLANE_TYPE_OVERLAY,
                .pixel_formats = vp_formats,
                .num_pixel_formats = ARRAY_SIZE(vp_formats),
+               .capabilities = EXYNOS_DRM_PLANE_CAP_SCALE,
        },
 };