mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mikko Perttunen <mperttunen@nvidia.com>
To: Thierry Reding <thierry.reding@kernel.org>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	webgeek1234@gmail.com
Cc: dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, Aaron Kling <webgeek1234@gmail.com>
Subject: Re: [PATCH v2 1/2] drm/tegra: Support swapping chroma planes
Date: Tue, 20 Oct 2026 14:08:48 +0900	[thread overview]
Message-ID: <HmrilxC8QwiAQGw2IQ1Ztw@nvidia.com> (raw)
In-Reply-To: <20261018-tegra-drm-yvu420-v2-1-512889103ab4@gmail.com>

On Monday, October 19, 2026 7:03 AM Aaron Kling via B4 Relay wrote:
> From: Aaron Kling <webgeek1234@gmail.com>
> 
> The Tegra display controller supports some yuv types, but not their
> chroma swapped variants. For example, yuv420 is supported but yvu420 is
> not. This can be efficiently worked around by just passing the hardware
> said chroma planes backwards. Add a flag to the plane state struct and
> handling to both tegradc and nvdisplay paths.
> 
> Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> ---
>  drivers/gpu/drm/tegra/dc.c    |  6 +++++-
>  drivers/gpu/drm/tegra/hub.c   | 14 +++++++++-----
>  drivers/gpu/drm/tegra/plane.c |  5 ++++-
>  drivers/gpu/drm/tegra/plane.h |  3 ++-
>  4 files changed, 20 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
> index b0bfa946e6979..39c2e920d76a6 100644
> --- a/drivers/gpu/drm/tegra/dc.c
> +++ b/drivers/gpu/drm/tegra/dc.c
> @@ -740,7 +740,8 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
>  
>  	err = tegra_plane_format(new_plane_state->fb->format->format,
>  				 &plane_state->format,
> -				 &plane_state->swap);
> +				 &plane_state->swap,
> +				 &plane_state->swap_uv);
>  	if (err < 0)
>  		return err;
>  
> @@ -872,6 +873,9 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
>  			window.stride[i] = fb->pitches[i];
>  	}
>  
> +	if (tegra_plane_state->swap_uv)
> +		swap(window.base[1], window.base[2]);
> +
>  	tegra_dc_setup_window(p, &window);
>  }
>  
> diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
> index 448f49f3a7d7e..6427155ac4fdf 100644
> --- a/drivers/gpu/drm/tegra/hub.c
> +++ b/drivers/gpu/drm/tegra/hub.c
> @@ -440,7 +440,8 @@ static int tegra_shared_plane_atomic_check(struct drm_plane *plane,
>  
>  	err = tegra_plane_format(new_plane_state->fb->format->format,
>  				 &plane_state->format,
> -				 &plane_state->swap);
> +				 &plane_state->swap,
> +				 &plane_state->swap_uv);
>  	if (err < 0)
>  		return err;
>  
> @@ -664,24 +665,27 @@ static void tegra_shared_plane_atomic_update(struct drm_plane *plane,
>  	tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE);
>  
>  	if (yuv && planes > 1) {
> -		base = tegra_plane_state->iova[1] + fb->offsets[1];
> +		uint8_t u = tegra_plane_state->swap_uv ? 2 : 1;
> +		uint8_t v = tegra_plane_state->swap_uv ? 1 : 2;
> +
> +		base = tegra_plane_state->iova[u] + fb->offsets[u];
>  		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);
>  
>  		if (planes > 2) {
> -			base = tegra_plane_state->iova[2] + fb->offsets[2];
> +			base = tegra_plane_state->iova[v] + fb->offsets[v];
>  			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]);
> +		value = PITCH_U(fb->pitches[u]);
>  
>  		if (planes > 2)
> -			value |= PITCH_V(fb->pitches[2]);
> +			value |= PITCH_V(fb->pitches[v]);
>  
>  		tegra_plane_writel(p, value, DC_WIN_PLANAR_STORAGE_UV);
>  	} else {

I noticed DC_WIN_PRECOMP_WGRP_PARAMS has a SWAP_UV bit. This is already 
defined in dc.h. So we can use that for the hub.c implementation instead 
of manually swapping.

Otherwise everything looks good to me. We could also enable the swap_uv 
logic for other UV formats.

Cheers
Mikko

> diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
> index 2148b0c59815c..757bc552809fe 100644
> --- a/drivers/gpu/drm/tegra/plane.c
> +++ b/drivers/gpu/drm/tegra/plane.c
> @@ -59,6 +59,7 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
>  	copy->tiling = state->tiling;
>  	copy->format = state->format;
>  	copy->swap = state->swap;
> +	copy->swap_uv = state->swap_uv;
>  	copy->reflect_x = state->reflect_x;
>  	copy->reflect_y = state->reflect_y;
>  	copy->opaque = state->opaque;
> @@ -319,11 +320,13 @@ int tegra_plane_state_add(struct tegra_plane *plane,
>  	return 0;
>  }
>  
> -int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap)
> +int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap, bool *swap_uv)
>  {
>  	/* assume no swapping of fetched data */
>  	if (swap)
>  		*swap = BYTE_SWAP_NOSWAP;
> +	if (swap_uv)
> +		*swap_uv = false;
>  
>  	switch (fourcc) {
>  	case DRM_FORMAT_ARGB4444:
> diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
> index e33a581e6490e..dba5f1b254e98 100644
> --- a/drivers/gpu/drm/tegra/plane.h
> +++ b/drivers/gpu/drm/tegra/plane.h
> @@ -49,6 +49,7 @@ struct tegra_plane_state {
>  	struct tegra_bo_tiling tiling;
>  	u32 format;
>  	u32 swap;
> +	bool swap_uv;
>  
>  	bool reflect_x;
>  	bool reflect_y;
> @@ -88,7 +89,7 @@ void tegra_plane_cleanup_fb(struct drm_plane *plane,
>  int tegra_plane_state_add(struct tegra_plane *plane,
>  			  struct drm_plane_state *state);
>  
> -int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap);
> +int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap, bool *swap_uv);
>  bool tegra_plane_format_is_indexed(unsigned int format);
>  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,
> 
> -- 
> 2.54.0
> 
> 
> 





  reply	other threads:[~2026-10-20  5:08 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-18 22:03 [PATCH v2 0/2] drm/tegra: Support YVU420 Aaron Kling via B4 Relay
2026-10-18 22:03 ` [PATCH v2 1/2] drm/tegra: Support swapping chroma planes Aaron Kling via B4 Relay
2026-10-20  5:08   ` Mikko Perttunen [this message]
2026-10-20  5:59     ` Aaron Kling
2026-10-18 22:03 ` [PATCH v2 2/2] drm/tegra: Support YVU420 Aaron Kling via B4 Relay

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=HmrilxC8QwiAQGw2IQ1Ztw@nvidia.com \
    --to=mperttunen@nvidia.com \
    --cc=airlied@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jonathanh@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=simona@ffwll.ch \
    --cc=thierry.reding@kernel.org \
    --cc=webgeek1234@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®