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: 76f1416e64 ("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 <cl@rock-chips.com>
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
This commit is contained in:
Liang Chen
2023-09-25 16:24:42 +08:00
committed by Andy Yan
parent ebb7b1b888
commit 9fd9fb1e7b

View File

@@ -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);