summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra/hub.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/hub.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/hub.c')
-rw-r--r--drivers/gpu/drm/tegra/hub.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
index fc9813e6b2c9..b8d3174c04c9 100644
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -540,8 +540,8 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
struct tegra_plane *p = to_tegra_plane(plane);
u32 value, min_width, bypass = 0;
dma_addr_t base, addr_flag = 0;
- unsigned int bpc;
- bool yuv, planar;
+ unsigned int bpc, planes;
+ bool yuv;
int err;
/* rien ne va plus */
@@ -559,7 +559,7 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
return;
}
- yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planar, &bpc);
+ yuv = tegra_plane_format_is_yuv(tegra_plane_state->format, &planes, &bpc);
tegra_dc_assign_shared_plane(dc, p);
@@ -660,20 +660,26 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
value = PITCH(fb->pitches[0]);
tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE);
- if (yuv && planar) {
+ if (yuv && planes > 1) {
base = tegra_plane_state->iova[1] + fb->offsets[1];
base |= addr_flag;
tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_U);
tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_U);
- base = tegra_plane_state->iova[2] + fb->offsets[2];
- base |= addr_flag;
+ if (planes > 2) {
+ base = tegra_plane_state->iova[2] + fb->offsets[2];
+ base |= addr_flag;
+
+ tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V);
+ tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V);
+ }
+
+ value = PITCH_U(fb->pitches[1]);
- tegra_plane_writel(p, upper_32_bits(base), DC_WINBUF_START_ADDR_HI_V);
- tegra_plane_writel(p, lower_32_bits(base), DC_WINBUF_START_ADDR_V);
+ if (planes > 2)
+ value |= PITCH_V(fb->pitches[2]);
- value = PITCH_U(fb->pitches[1]) | PITCH_V(fb->pitches[2]);
tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE_UV);
} else {
tegra_plane_writel(p, 0, DC_WINBUF_START_ADDR_U);