summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra/dc.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2022-01-12 09:36:29 +0100
committerThierry Reding <treding@nvidia.com>2022-03-01 11:13:09 +0100
commita649b133c3154f3d1d297cf85711957e61c0f070 (patch)
treefc0571b546048416112ebf965465ff27048b7662 /drivers/gpu/drm/tegra/dc.c
parent28aa30b08de6f4b346f25f7c8bb5ba3739c1879c (diff)
downloadlinux-a649b133c3154f3d1d297cf85711957e61c0f070.tar.bz2
drm/tegra: Support semi-planar formats on Tegra114+
The NV12, NV21, NV16, NV61, NV24 and NV42 formats are supported by Tegra114 and later display hardware. Add the necessary programming to allow them to be used. Note that this does not work for Tegra186 and later yet because those generations have a different display architecture that doesn't support the same formats. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/dc.c')
-rw-r--r--drivers/gpu/drm/tegra/dc.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 9435c867c865..9442d7ee84a0 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -345,18 +345,19 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
{
unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
struct tegra_dc *dc = plane->dc;
- bool yuv, planar;
+ unsigned int planes;
u32 value;
+ bool yuv;
/*
* For YUV planar modes, the number of bytes per pixel takes into
* account only the luma component and therefore is 1.
*/
- yuv = tegra_plane_format_is_yuv(window->format, &planar, NULL);
+ yuv = tegra_plane_format_is_yuv(window->format, &planes, NULL);
if (!yuv)
bpp = window->bits_per_pixel / 8;
else
- bpp = planar ? 1 : 2;
+ bpp = (planes > 1) ? 1 : 2;
tegra_plane_writel(plane, window->format, DC_WIN_COLOR_DEPTH);
tegra_plane_writel(plane, window->swap, DC_WIN_BYTE_SWAP);
@@ -385,7 +386,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
* For DDA computations the number of bytes per pixel for YUV planar
* modes needs to take into account all Y, U and V components.
*/
- if (yuv && planar)
+ if (yuv && planes > 1)
bpp = 2;
h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp);
@@ -405,9 +406,12 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
tegra_plane_writel(plane, window->base[0], DC_WINBUF_START_ADDR);
- if (yuv && planar) {
+ if (yuv && planes > 1) {
tegra_plane_writel(plane, window->base[1], DC_WINBUF_START_ADDR_U);
- tegra_plane_writel(plane, window->base[2], DC_WINBUF_START_ADDR_V);
+
+ if (planes > 2)
+ tegra_plane_writel(plane, window->base[2], DC_WINBUF_START_ADDR_V);
+
value = window->stride[1] << 16 | window->stride[0];
tegra_plane_writel(plane, value, DC_WIN_LINE_STRIDE);
} else {
@@ -1193,6 +1197,13 @@ static const u32 tegra114_overlay_formats[] = {
DRM_FORMAT_YUYV,
DRM_FORMAT_YUV420,
DRM_FORMAT_YUV422,
+ /* semi-planar formats */
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV42,
};
static const u32 tegra124_overlay_formats[] = {
@@ -1223,6 +1234,13 @@ static const u32 tegra124_overlay_formats[] = {
DRM_FORMAT_YUYV,
DRM_FORMAT_YUV420,
DRM_FORMAT_YUV422,
+ /* semi-planar formats */
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV61,
+ DRM_FORMAT_NV24,
+ DRM_FORMAT_NV42,
};
static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,