drm/tegra: Fix planar formats on Tegra186 and later
PATCH 1/2 drm/tegra: Fix planar formats on Tegra186 and later
From: Thierry Reding <[email protected]>
Use the correct pitch when programming the DC_WIN_PLANAR_STORAGE_UV register's PITCH_U field to ensure the correct value is used in all cases. This isn't currently causing any problems because the pitch for both U and V planes is always the same.
Signed-off-by Thierry Reding <[email protected]>
--- drivers/gpu/drm/tegra/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/tegra/hub.c +1 -1
@@ -673,7 +673,7 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,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[2 ]) |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 );
Signature · 1 line
2.34.1
PATCH 2/2 drm/tegra: Support semi-planar formats on Tegra114+
From: Thierry Reding <[email protected]>
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.
Signed-off-by Thierry Reding <[email protected]>
--- drivers/gpu/drm/tegra/dc.c | 30 ++++++++++++++++---- drivers/gpu/drm/tegra/dc.h | 6 ++++ drivers/gpu/drm/tegra/hub.c | 31 +++++++++++++++------ drivers/gpu/drm/tegra/plane.c | 52 ++++++++++++++++++++++++++++++----- drivers/gpu/drm/tegra/plane.h | 2 +- 5 files changed, 98 insertions(+), 23 deletions(-)
drivers/gpu/drm/tegra/dc.c +24 -6
@@ -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,
drivers/gpu/drm/tegra/dc.h +6 -0
@@ -637,6 +637,12 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);#define WIN_COLOR_DEPTH_A8B8G8R8 36#define WIN_COLOR_DEPTH_B8G8R8X8 37#define WIN_COLOR_DEPTH_R8G8B8X8 38 +#define WIN_COLOR_DEPTH_YCrCb420SP 42 +#define WIN_COLOR_DEPTH_YCbCr420SP 43 +#define WIN_COLOR_DEPTH_YCrCb422SP 44 +#define WIN_COLOR_DEPTH_YCbCr422SP 45 +#define WIN_COLOR_DEPTH_YCrCb444SP 48 +#define WIN_COLOR_DEPTH_YCbCr444SP 49#define WIN_COLOR_DEPTH_X8B8G8R8 65#define WIN_COLOR_DEPTH_X8R8G8B8 66
drivers/gpu/drm/tegra/hub.c +22 -9
@@ -47,6 +47,13 @@ static const u32 tegra_shared_plane_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 u64 tegra_shared_plane_modifiers[] = {
@@ -540,8 +547,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 +566,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 +667,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 );
drivers/gpu/drm/tegra/plane.c +45 -7
80 lines not on this page · raw message
drivers/gpu/drm/tegra/plane.h +1 -1
@@ -90,7 +90,7 @@ int tegra_plane_state_add(struct tegra_plane *plane,int tegra_plane_format (u32 fourcc,u32 *format,u32 *swap);bool tegra_plane_format_is_indexed (unsigned int format); -bool tegra_plane_format_is_yuv (unsigned int format,bool *planar,unsigned int *bpc); +bool tegra_plane_format_is_yuv (unsigned int format,unsigned int *planes,unsigned int *bpc);int tegra_plane_setup_legacy_state (struct tegra_plane *tegra,struct tegra_plane_state *state);int tegra_plane_interconnect_init (struct tegra_plane *plane);
Signature · 1 line
2.34.1