On Tue, Sep 8, 2026 at 1:02 PM Chen-Yu Tsai <[email protected]> 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: <[email protected]> # 7.1+ > Signed-off-by: Chen-Yu Tsai <[email protected]>
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.skra...@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 >
