[PATCH 06/12] drm/tegra: Move common plane code to separate file
Thierry Reding
thierry.reding at gmail.com
Mon Nov 27 10:09:46 UTC 2017
From: Thierry Reding <treding at nvidia.com>
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 at nvidia.com>
---
drivers/gpu/drm/tegra/Makefile | 1 +
drivers/gpu/drm/tegra/dc.c | 199 ++---------------------------------------
drivers/gpu/drm/tegra/plane.c | 180 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/tegra/plane.h | 59 ++++++++++++
4 files changed, 245 insertions(+), 194 deletions(-)
create mode 100644 drivers/gpu/drm/tegra/plane.c
create mode 100644 drivers/gpu/drm/tegra/plane.h
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
index 46d65d39214d..a47784765217 100644
--- a/drivers/gpu/drm/tegra/Makefile
+++ b/drivers/gpu/drm/tegra/Makefile
@@ -5,6 +5,7 @@ tegra-drm-y := \
drm.o \
gem.o \
fb.o \
+ plane.o \
dc.o \
output.o \
rgb.o \
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 88b8d137726e..d2c7a3481022 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -19,38 +19,12 @@
#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, ©->base);
- copy->tiling = state->tiling;
- copy->format = state->format;
- copy->swap = state->swap;
-
- return ©->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_plane_helper_check_state(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
index 000000000000..1847d0204e46
--- /dev/null
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -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, ©->base);
+ copy->tiling = state->tiling;
+ copy->format = state->format;
+ copy->swap = state->swap;
+
+ return ©->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_plane_helper_check_state(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
index 000000000000..8237b885acd7
--- /dev/null
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -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 */
--
2.15.0
More information about the dri-devel
mailing list