From 9fd9fb1e7bd1635289e53f1aeeac835d8a55dee0 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Mon, 25 Sep 2023 16:24:42 +0800 Subject: [PATCH] drm/rockchip: vop: fix error for memcpy of vop regs It will cause an error when use memcpy(), so use for(;;) instead, and need find out the root cause later. For upstream reference: 76f1416e6428 ("drm/rockchip: Do not use memcpy for MMIO addresses") For px30, the reg len is 0x1fc, this will trigger a none 8 byte alignment address in _memcpy. Error log when use memcpy() as below: vop_power_enable regsbak: 0xffffff80050ad040 regs: 0xffffffc00a85d000 len: 0x1fc Unable to handle kernel paging request at virtual address ffffffc00a55d1bc Mem abort info: ESR = 0x0000000096000021 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x21: alignment fault Data abort info: ISV = 0, ISS = 0x00000021 CM = 0, WnR = 0 swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000001cc4000 [ffffffc00a55d1bc] pgd=100000007ffff003, p4d=100000007ffff003, pud=100000007ffff003, pmd=1000000002d7c003, pte=00680000ff460713 Internal error: Oops: 0000000096000021 [#1] PREEMPT SMP Modules linked in: CPU: 2 PID: 112 Comm: recovery Not tainted 6.1.25 #1091 Hardware name: Rockchip PX30 evb ddr3 board (DT) pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __memcpy+0x168/0x250 lr : vop_initial+0x218/0x9e8 sp : ffffffc00ab1b920 x29: ffffffc00ab1b920 x28: 000000000000032a x27: ffffff8006611780 x26: ffffff80033f3c00 x25: ffffffc00994d6ac x24: ffffff8002eae010 x23: ffffff80033f3c18 x22: 00000000000002d0 x21: ffffff8004938100 x20: ffffffc009979341 x19: ffffff8004ae0040 x18: ffffffffffffffff x17: 0000000000000000 x16: 00000000000000c0 x15: 0000000000000004 x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000080000000000 x5 : ffffff8005e0ca3c x4 : ffffffc00a55d1fc x3 : ffffff8005e0c9c0 x2 : ffffffffffffffec x1 : ffffffc00a55d1c0 x0 : ffffff8005e0c840 Call trace: __memcpy+0x168/0x250 vop_crtc_atomic_enable+0x120/0x2c30 drm_atomic_helper_commit_modeset_enables+0x50/0x268 rockchip_drm_atomic_helper_commit_tail_rpm+0x48/0x190 commit_tail+0x108/0x1f4 drm_atomic_helper_commit+0x204/0x220 drm_atomic_commit+0xa0/0xc8 drm_atomic_helper_set_config+0x60/0xdc drm_mode_setcrtc+0x29c/0x6cc drm_ioctl+0x248/0x3b8 drm_compat_ioctl+0xd8/0xe8 __arm64_compat_sys_ioctl+0x14c/0x168 invoke_syscall+0x3c/0xfc el0_svc_common+0xb8/0x160 do_el0_svc_compat+0x18/0x20 el0_svc_compat+0x24/0x8c el0t_32_sync_handler+0x70/0xa8 el0t_32_sync+0x17c/0x180 Change-Id: I4e13298e66797df39233b91a3163c156a4e175bc Signed-off-by: Liang Chen Signed-off-by: Andy Yan --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 2017b1ca4983..032117943e6a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1559,6 +1559,17 @@ static int vop_crtc_atomic_gamma_set(struct drm_crtc *crtc, return 0; } +static void vop_regsbak(struct vop *vop) +{ + int i; + + /* + * No need to backup DSC/GAMMA_LUT/BPP_LUT/MMU + */ + for (i = 0; i < vop->len; i += sizeof(u32)) + vop->regsbak[i / 4] = readl_relaxed(vop->regs + i); +} + static void vop_power_enable(struct drm_crtc *crtc) { struct vop *vop = to_vop(crtc); @@ -1588,7 +1599,7 @@ static void vop_power_enable(struct drm_crtc *crtc) return; } - memcpy(vop->regsbak, vop->regs, vop->len); + vop_regsbak(vop); if (VOP_CTRL_SUPPORT(vop, version)) { uint32_t version = VOP_CTRL_GET(vop, version);