[PATCH v2] drm/sun4i: Align VI buffer addresses for subsampled formats
Chen-Yu Tsai
wenst at chromium.org
Mon Sep 7 22:17:13 PDT 2026
On Tue, Sep 8, 2026 at 1:02 PM Chen-Yu Tsai <wenst at chromium.org> wrote:
>
> Commit 79ac1c945ab8 ("drm/sun4i: layers: Use drm_fb_dma_get_gem_addr() to
> get display memory") dropped the code to calculate the framebuffer's DMA
> address in favor of drm_fb_dma_get_gem_addr().
>
> This turned out to be wrong in a couple ways. The hardware can handle
> pixel offsets within a sub-sampling block, but the buffer address must
> start at the beginning of the subsampled block for all planes. The
> hardware then does the interpolation internally. However the helper
> gives the address exact pixel for luma, which messes up the result.
>
> Instead of reverting the commit, calculate the intra-block offset and
> adjust the buffer address so that it points to the start of the block.
>
> Fixes: 79ac1c945ab8 ("drm/sun4i: layers: Use drm_fb_dma_get_gem_addr() to get display memory")
> Cc: <stable at vger.kernel.org> # 7.1+
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
Please ignore this one. As Sashiko pointed out, this could underflow the
buffer address.
Instead this should be sent along with another fix I have that switches
this back to the clipped buffer address.
Sorry for the noise.
> ---
> This is an alternative to Jernej's original revert:
> https://lore.kernel.org/all/3980ea1aeb3f7fe8b4700e36560deeba3d050664.1785772659.git.jernej.skrabec@gmail.com/
> ---
> drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> index 2e9cda45c04e..185e9e5211c1 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> @@ -207,6 +207,20 @@ static void sun8i_vi_layer_update_buffer(struct sun8i_layer *layer,
> /* Get the start of the displayed memory */
> dma_addr = drm_fb_dma_get_gem_addr(fb, state, i);
>
> + /*
> + * The mixer can handle odd offsets into sub-sampled YUV
> + * planes, but needs the address of the first pixel in each
> + * sub-sampled block. Adjust the luma buffer address backwards.
> + */
> + if (i == 0) {
> + u32 x_diff, y_diff;
> +
> + x_diff = (state->src.x1 >> 16) & (format->hsub - 1);
> + y_diff = (state->src.y1 >> 16) & (format->vsub - 1);
> + dma_addr -= y_diff * fb->pitches[i];
> + dma_addr -= x_diff * format->cpp[i];
> + }
> +
> /* Set the line width */
> DRM_DEBUG_DRIVER("Layer %d. line width: %d bytes\n",
> i + 1, fb->pitches[i]);
> --
> 2.55.0.979.g7e5102b832-goog
>
More information about the linux-arm-kernel
mailing list