video: rockchip: mpp: fix dma buf sync start dma address

Locate the start dma address with the dma address from the first sg and
the offset, since the sg_dma_address for the other sg will return a
invalid mapping address (-1).

Unable to handle kernel paging request at virtual address ffffff8000000000
Mem abort info:
  ESR = 0x96000146
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
Data abort info:
  ISV = 0, ISS = 0x00000146
  CM = 1, WnR = 1
swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000001caa000
[ffffff8000000000] pgd=000000007fffb003, p4d=000000007fffb003, pud=000000007fffb003, pmd=0000000000000000
Internal error: Oops: 96000146 [#1] PREEMPT SMP
Modules linked in: rk_vcodec [last unloaded: rk_vcodec]
CPU: 0 PID: 2173 Comm: mpp_mjpege_217 Not tainted 5.10.110 #389
Hardware name: Rockchip PX30 mini evb ddr3 board (DT)
pstate: 80400005 (Nzcv daif +PAN -UAO -TCO BTYPE=--)
pc : __clean_dcache_area_poc+0x20/0x38
lr : arch_sync_dma_for_device+0x20/0x2c
sp : ffffffc0136fbb90
x29: ffffffc0136fbb90 x28: 000000000000026f
x27: 0000000000000000 x26: ffffff805fa22c00
x25: 0000000000000000 x24: ffffff8045543800
x23: 0000000000100000 x22: 0000000000000000
x21: 0000000041100000 x20: 000000000000026f
x19: 0000000000000001 x18: ffffffc012139060
x17: 0000000000000000 x16: 00000000000000c0
x15: 0000000000000004 x14: 0000000000003fff
x13: ffffffc011c8c7f0 x12: 0000000000000000
x11: 0000000000000000 x10: 0000000000000001
x9 : 0000000100000000 x8 : 0000000000000000
x7 : 7320302074657366 x6 : ffffffc011e764a0
x5 : ffffffffffffffff x4 : 0000000000000000
x3 : 000000000000003f x2 : 0000000000000040
x1 : ffffff800000026f x0 : ffffff8000000000
Call trace:
 __clean_dcache_area_poc+0x20/0x38
 iommu_dma_sync_single_for_device+0x40/0x54
 dma_sync_single_for_device+0x2c/0xe8
 mpp_dma_buf_sync+0x138/0x184 [rk_vcodec]
 vepu_alloc_task+0x2a0/0x390 [rk_vcodec]
 mpp_process_task_default+0x5c/0x218 [rk_vcodec]
 mpp_dev_ioctl+0x39c/0x5e0 [rk_vcodec]
 __arm64_compat_sys_ioctl+0x104/0x158
 el0_svc_common+0xac/0x1ac
 do_el0_svc_compat+0x1c/0x28
 el0_svc_compat+0x10/0x1c
 el0_sync_compat_handler+0x60/0x8c
 el0_sync_compat+0x164/0x180

Fixes: 3fb2e28edd ("video: rockchip: mpp: change the way to refresh the dma cache")
Signed-off-by: Yandong Lin <yandong.lin@rock-chips.com>
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Change-Id: I7d9fc844df602e38ee8fa0e303a0e251a58b072a
This commit is contained in:
Jianqun Xu
2023-03-02 10:26:48 +08:00
committed by Tao Huang
parent b3cfdcd677
commit 3c65f6f3c3

View File

@@ -382,21 +382,21 @@ mpp_dma_session_create(struct device *dev, u32 max_buffers)
void mpp_dma_buf_sync(struct mpp_dma_buffer *buffer, u32 offset, u32 length,
enum dma_data_direction dir, bool for_cpu)
{
struct scatterlist *sg;
unsigned int len = 0;
dma_addr_t sg_dma_addr;
int i;
struct sg_table *sgt = buffer->sgt;
struct device *dev = buffer->dma->dev;
struct sg_table *sgt = buffer->sgt;
struct scatterlist *sg = sgt->sgl;
dma_addr_t sg_dma_addr = sg_dma_address(sg);
unsigned int len = 0;
int i;
for_each_sgtable_sg(sgt, sg, i) {
unsigned int sg_offset, sg_left, size = 0;
sg_dma_addr = sg_dma_address(sg);
len += sg->length;
if (len <= offset)
if (len <= offset) {
sg_dma_addr += sg->length;
continue;
}
sg_left = len - offset;
sg_offset = sg->length - sg_left;
@@ -412,6 +412,7 @@ void mpp_dma_buf_sync(struct mpp_dma_buffer *buffer, u32 offset, u32 length,
offset += size;
length -= size;
sg_dma_addr += sg->length;
if (length == 0)
break;