drm/tegra: Move common plane code to separate file
authorThierry Reding <treding@nvidia.com>
Fri, 10 Nov 2017 14:27:25 +0000 (15:27 +0100)
committerThierry Reding <treding@nvidia.com>
Wed, 13 Dec 2017 12:42:22 +0000 (13:42 +0100)
Subsequent patches will add support for Tegra186 which has a different
architecture and needs different plane code but which can share a lot of
code with earlier Tegra support.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/Makefile
drivers/gpu/drm/tegra/dc.c
drivers/gpu/drm/tegra/plane.c [new file with mode: 0644]
drivers/gpu/drm/tegra/plane.h [new file with mode: 0644]

index 46d65d39214d94fc973ad2539ff3613132a34397..a47784765217ec1b624b46613de7c73a66629921 100644 (file)
@@ -5,6 +5,7 @@ tegra-drm-y := \
        drm.o \
        gem.o \
        fb.o \
+       plane.o \
        dc.o \
        output.o \
        rgb.o \
index 7b017c03feb3510706f5895a7872faa4f8f13123..3aa0da6244db9c9cd3ea67c5a6bbb8f5b66e94f9 100644 (file)
 #include "dc.h"
 #include "drm.h"
 #include "gem.h"
+#include "plane.h"
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
 
-struct tegra_plane {
-       struct drm_plane base;
-       unsigned int index;
-};
-
-static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane)
-{
-       return container_of(plane, struct tegra_plane, base);
-}
-
-struct tegra_plane_state {
-       struct drm_plane_state base;
-
-       struct tegra_bo_tiling tiling;
-       u32 format;
-       u32 swap;
-};
-
-static inline struct tegra_plane_state *
-to_tegra_plane_state(struct drm_plane_state *state)
-{
-       if (state)
-               return container_of(state, struct tegra_plane_state, base);
-
-       return NULL;
-}
-
 static void tegra_dc_stats_reset(struct tegra_dc_stats *stats)
 {
        stats->frames = 0;
@@ -97,81 +71,6 @@ void tegra_dc_commit(struct tegra_dc *dc)
        tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
 }
 
-static int tegra_dc_format(u32 fourcc, u32 *format, u32 *swap)
-{
-       /* assume no swapping of fetched data */
-       if (swap)
-               *swap = BYTE_SWAP_NOSWAP;
-
-       switch (fourcc) {
-       case DRM_FORMAT_XBGR8888:
-               *format = WIN_COLOR_DEPTH_R8G8B8A8;
-               break;
-
-       case DRM_FORMAT_XRGB8888:
-               *format = WIN_COLOR_DEPTH_B8G8R8A8;
-               break;
-
-       case DRM_FORMAT_RGB565:
-               *format = WIN_COLOR_DEPTH_B5G6R5;
-               break;
-
-       case DRM_FORMAT_UYVY:
-               *format = WIN_COLOR_DEPTH_YCbCr422;
-               break;
-
-       case DRM_FORMAT_YUYV:
-               if (swap)
-                       *swap = BYTE_SWAP_SWAP2;
-
-               *format = WIN_COLOR_DEPTH_YCbCr422;
-               break;
-
-       case DRM_FORMAT_YUV420:
-               *format = WIN_COLOR_DEPTH_YCbCr420P;
-               break;
-
-       case DRM_FORMAT_YUV422:
-               *format = WIN_COLOR_DEPTH_YCbCr422P;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar)
-{
-       switch (format) {
-       case WIN_COLOR_DEPTH_YCbCr422:
-       case WIN_COLOR_DEPTH_YUV422:
-               if (planar)
-                       *planar = false;
-
-               return true;
-
-       case WIN_COLOR_DEPTH_YCbCr420P:
-       case WIN_COLOR_DEPTH_YUV420P:
-       case WIN_COLOR_DEPTH_YCbCr422P:
-       case WIN_COLOR_DEPTH_YUV422P:
-       case WIN_COLOR_DEPTH_YCbCr422R:
-       case WIN_COLOR_DEPTH_YUV422R:
-       case WIN_COLOR_DEPTH_YCbCr422RA:
-       case WIN_COLOR_DEPTH_YUV422RA:
-               if (planar)
-                       *planar = true;
-
-               return true;
-       }
-
-       if (planar)
-               *planar = false;
-
-       return false;
-}
-
 static inline u32 compute_dda_inc(unsigned int in, unsigned int out, bool v,
                                  unsigned int bpp)
 {
@@ -223,7 +122,7 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
         * For YUV planar modes, the number of bytes per pixel takes into
         * account only the luma component and therefore is 1.
         */
-       yuv = tegra_dc_format_is_yuv(window->format, &planar);
+       yuv = tegra_plane_format_is_yuv(window->format, &planar);
        if (!yuv)
                bpp = window->bits_per_pixel / 8;
        else
@@ -385,101 +284,12 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
        spin_unlock_irqrestore(&dc->lock, flags);
 }
 
-static void tegra_plane_destroy(struct drm_plane *plane)
-{
-       struct tegra_plane *p = to_tegra_plane(plane);
-
-       drm_plane_cleanup(plane);
-       kfree(p);
-}
-
 static const u32 tegra_primary_plane_formats[] = {
        DRM_FORMAT_XBGR8888,
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_RGB565,
 };
 
-static void tegra_plane_reset(struct drm_plane *plane)
-{
-       struct tegra_plane_state *state;
-
-       if (plane->state)
-               __drm_atomic_helper_plane_destroy_state(plane->state);
-
-       kfree(plane->state);
-       plane->state = NULL;
-
-       state = kzalloc(sizeof(*state), GFP_KERNEL);
-       if (state) {
-               plane->state = &state->base;
-               plane->state->plane = plane;
-       }
-}
-
-static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
-{
-       struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
-       struct tegra_plane_state *copy;
-
-       copy = kmalloc(sizeof(*copy), GFP_KERNEL);
-       if (!copy)
-               return NULL;
-
-       __drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
-       copy->tiling = state->tiling;
-       copy->format = state->format;
-       copy->swap = state->swap;
-
-       return &copy->base;
-}
-
-static void tegra_plane_atomic_destroy_state(struct drm_plane *plane,
-                                            struct drm_plane_state *state)
-{
-       __drm_atomic_helper_plane_destroy_state(state);
-       kfree(state);
-}
-
-static const struct drm_plane_funcs tegra_plane_funcs = {
-       .update_plane = drm_atomic_helper_update_plane,
-       .disable_plane = drm_atomic_helper_disable_plane,
-       .destroy = tegra_plane_destroy,
-       .reset = tegra_plane_reset,
-       .atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
-       .atomic_destroy_state = tegra_plane_atomic_destroy_state,
-};
-
-static int tegra_plane_state_add(struct tegra_plane *plane,
-                                struct drm_plane_state *state)
-{
-       struct drm_crtc_state *crtc_state;
-       struct tegra_dc_state *tegra;
-       struct drm_rect clip;
-       int err;
-
-       /* Propagate errors from allocation or locking failures. */
-       crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
-       if (IS_ERR(crtc_state))
-               return PTR_ERR(crtc_state);
-
-       clip.x1 = 0;
-       clip.y1 = 0;
-       clip.x2 = crtc_state->mode.hdisplay;
-       clip.y2 = crtc_state->mode.vdisplay;
-
-       /* Check plane state for visibility and calculate clipping bounds */
-       err = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
-                                                 0, INT_MAX, true, true);
-       if (err < 0)
-               return err;
-
-       tegra = to_dc_state(crtc_state);
-
-       tegra->planes |= WIN_A_ACT_REQ << plane->index;
-
-       return 0;
-}
-
 static int tegra_plane_atomic_check(struct drm_plane *plane,
                                    struct drm_plane_state *state)
 {
@@ -493,8 +303,9 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
        if (!state->crtc)
                return 0;
 
-       err = tegra_dc_format(state->fb->format->format, &plane_state->format,
-                             &plane_state->swap);
+       err = tegra_plane_format(state->fb->format->format,
+                                &plane_state->format,
+                                &plane_state->swap);
        if (err < 0)
                return err;
 
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
new file mode 100644 (file)
index 0000000..78b24aa
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2017 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+
+#include "dc.h"
+#include "plane.h"
+
+static void tegra_plane_destroy(struct drm_plane *plane)
+{
+       struct tegra_plane *p = to_tegra_plane(plane);
+
+       drm_plane_cleanup(plane);
+       kfree(p);
+}
+
+static void tegra_plane_reset(struct drm_plane *plane)
+{
+       struct tegra_plane_state *state;
+
+       if (plane->state)
+               __drm_atomic_helper_plane_destroy_state(plane->state);
+
+       kfree(plane->state);
+       plane->state = NULL;
+
+       state = kzalloc(sizeof(*state), GFP_KERNEL);
+       if (state) {
+               plane->state = &state->base;
+               plane->state->plane = plane;
+       }
+}
+
+static struct drm_plane_state *
+tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
+{
+       struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
+       struct tegra_plane_state *copy;
+
+       copy = kmalloc(sizeof(*copy), GFP_KERNEL);
+       if (!copy)
+               return NULL;
+
+       __drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
+       copy->tiling = state->tiling;
+       copy->format = state->format;
+       copy->swap = state->swap;
+
+       return &copy->base;
+}
+
+static void tegra_plane_atomic_destroy_state(struct drm_plane *plane,
+                                            struct drm_plane_state *state)
+{
+       __drm_atomic_helper_plane_destroy_state(state);
+       kfree(state);
+}
+
+const struct drm_plane_funcs tegra_plane_funcs = {
+       .update_plane = drm_atomic_helper_update_plane,
+       .disable_plane = drm_atomic_helper_disable_plane,
+       .destroy = tegra_plane_destroy,
+       .reset = tegra_plane_reset,
+       .atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
+       .atomic_destroy_state = tegra_plane_atomic_destroy_state,
+};
+
+int tegra_plane_state_add(struct tegra_plane *plane,
+                         struct drm_plane_state *state)
+{
+       struct drm_crtc_state *crtc_state;
+       struct tegra_dc_state *tegra;
+       struct drm_rect clip;
+       int err;
+
+       /* Propagate errors from allocation or locking failures. */
+       crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
+       if (IS_ERR(crtc_state))
+               return PTR_ERR(crtc_state);
+
+       clip.x1 = 0;
+       clip.y1 = 0;
+       clip.x2 = crtc_state->mode.hdisplay;
+       clip.y2 = crtc_state->mode.vdisplay;
+
+       /* Check plane state for visibility and calculate clipping bounds */
+       err = drm_atomic_helper_check_plane_state(state, crtc_state, &clip,
+                                                 0, INT_MAX, true, true);
+       if (err < 0)
+               return err;
+
+       tegra = to_dc_state(crtc_state);
+
+       tegra->planes |= WIN_A_ACT_REQ << plane->index;
+
+       return 0;
+}
+
+int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
+{
+       /* assume no swapping of fetched data */
+       if (swap)
+               *swap = BYTE_SWAP_NOSWAP;
+
+       switch (fourcc) {
+       case DRM_FORMAT_XBGR8888:
+               *format = WIN_COLOR_DEPTH_R8G8B8A8;
+               break;
+
+       case DRM_FORMAT_XRGB8888:
+               *format = WIN_COLOR_DEPTH_B8G8R8A8;
+               break;
+
+       case DRM_FORMAT_RGB565:
+               *format = WIN_COLOR_DEPTH_B5G6R5;
+               break;
+
+       case DRM_FORMAT_UYVY:
+               *format = WIN_COLOR_DEPTH_YCbCr422;
+               break;
+
+       case DRM_FORMAT_YUYV:
+               if (!swap)
+                       return -EINVAL;
+
+               *format = WIN_COLOR_DEPTH_YCbCr422;
+               *swap = BYTE_SWAP_SWAP2;
+               break;
+
+       case DRM_FORMAT_YUV420:
+               *format = WIN_COLOR_DEPTH_YCbCr420P;
+               break;
+
+       case DRM_FORMAT_YUV422:
+               *format = WIN_COLOR_DEPTH_YCbCr422P;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+bool tegra_plane_format_is_yuv(unsigned int format, bool *planar)
+{
+       switch (format) {
+       case WIN_COLOR_DEPTH_YCbCr422:
+       case WIN_COLOR_DEPTH_YUV422:
+               if (planar)
+                       *planar = false;
+
+               return true;
+
+       case WIN_COLOR_DEPTH_YCbCr420P:
+       case WIN_COLOR_DEPTH_YUV420P:
+       case WIN_COLOR_DEPTH_YCbCr422P:
+       case WIN_COLOR_DEPTH_YUV422P:
+       case WIN_COLOR_DEPTH_YCbCr422R:
+       case WIN_COLOR_DEPTH_YUV422R:
+       case WIN_COLOR_DEPTH_YCbCr422RA:
+       case WIN_COLOR_DEPTH_YUV422RA:
+               if (planar)
+                       *planar = true;
+
+               return true;
+       }
+
+       if (planar)
+               *planar = false;
+
+       return false;
+}
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
new file mode 100644 (file)
index 0000000..8237b88
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef TEGRA_PLANE_H
+#define TEGRA_PLANE_H 1
+
+#include <drm/drm_plane.h>
+
+struct tegra_bo;
+
+struct tegra_plane {
+       struct drm_plane base;
+       unsigned int index;
+};
+
+struct tegra_cursor {
+       struct tegra_plane base;
+
+       struct tegra_bo *bo;
+       unsigned int width;
+       unsigned int height;
+};
+
+static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane)
+{
+       return container_of(plane, struct tegra_plane, base);
+}
+
+struct tegra_plane_state {
+       struct drm_plane_state base;
+
+       struct tegra_bo_tiling tiling;
+       u32 format;
+       u32 swap;
+};
+
+static inline struct tegra_plane_state *
+to_tegra_plane_state(struct drm_plane_state *state)
+{
+       if (state)
+               return container_of(state, struct tegra_plane_state, base);
+
+       return NULL;
+}
+
+extern const struct drm_plane_funcs tegra_plane_funcs;
+
+int tegra_plane_state_add(struct tegra_plane *plane,
+                         struct drm_plane_state *state);
+
+int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap);
+bool tegra_plane_format_is_yuv(unsigned int format, bool *planar);
+
+#endif /* TEGRA_PLANE_H */