mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user