[PATCH 8/8] drm/rockchip: vop2: Fix the AFBC offsets of a source that starts inside a superblock

Arun Iyengar via B4 Relay devnull+aiyengar1990.gmail.com at kernel.org
Mon Nov 9 23:18:56 PST 2026


From: Arun Iyengar <aiyengar1990 at gmail.com>

The AFBC decoder of a window takes the position of the source in the
framebuffer (AFBC_PIC_OFFSET), the number of superblock columns to
decode (AFBC_TILE_NUM) and the offset of the first pixel inside its
superblock (the transform offset). For a source that doesn't start at
x = 0:

- The tile number only counts the superblocks of the source width, one
  short when the source starts inside a superblock and ends inside
  another one.
- The transform offset is the whole x position, truncated to the 8 bit
  field, instead of the position in the 16 pixel wide superblock.

Count the superblock columns from the first one the source touches, and
take the x offset in the superblock, like the vendor kernel does for the
not mirrored cases. The X mirrored and rotated cases are left as they are.

Signed-off-by: Arun Iyengar <aiyengar1990 at gmail.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 9ad138457204..dfb76bfbc358 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -486,7 +486,7 @@ static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate,
 		ty = act_yoffset;
 		break;
 	case DRM_MODE_REFLECT_Y:
-		tx = act_xoffset;
+		tx = act_xoffset & 0xf;
 		ty = bottom_crop_line_num - act_yoffset;
 		break;
 	case DRM_MODE_ROTATE_90:
@@ -498,7 +498,7 @@ static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate,
 		ty = vir_width - width - act_xoffset;
 		break;
 	case 0:
-		tx = act_xoffset;
+		tx = act_xoffset & 0xf;
 		ty = act_yoffset;
 		break;
 	}
@@ -1577,7 +1577,8 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		if (fb->modifier & AFBC_FORMAT_MOD_YTR)
 			afbc_format |= (1 << 4);
 
-		afbc_tile_num = ALIGN(src_w, block_w) / block_w;
+		/* Superblock columns the source covers, the first one partly */
+		afbc_tile_num = ALIGN(src_w + (src->x1 >> 16) % block_w, block_w) / block_w;
 
 		/*
 		 * AFBC pic_vir_width is count by pixel, this is different

-- 
2.55.0





More information about the Linux-rockchip mailing list