From d1f81490a2e29770ae174a15eecc90680b5d8cfc Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Thu, 28 Mar 2019 23:43:08 +0800 Subject: [PATCH] vdin: fixed the issue of mem mapping from vmap. [1/1] PD#SWPL-6196 Problem: the memory issue cause to kernel crash. Solution: 1. add flush cache when the mem oper end. 2. unmap addr which from vmap in vdin driver. Verify: X301 Change-Id: Id6efe2b009fe64ad753d51eb06784bd4e66f5e87 Signed-off-by: Nanxin Qin --- .../media/video_processor/pic_dev/picdec.c | 2 + .../amlogic/media/vin/tvin/vdin/vdin_afbce.c | 28 +- .../amlogic/media/vin/tvin/vdin/vdin_ctl.c | 106 +++++++- .../amlogic/media/vin/tvin/vdin/vdin_ctl.h | 12 +- .../amlogic/media/vin/tvin/vdin/vdin_debug.c | 242 +++++++----------- .../amlogic/media/vin/tvin/vdin/vdin_drv.c | 91 ++++--- 6 files changed, 285 insertions(+), 196 deletions(-) diff --git a/drivers/amlogic/media/video_processor/pic_dev/picdec.c b/drivers/amlogic/media/video_processor/pic_dev/picdec.c index 7d28ea390ed1..451718bf9fe0 100644 --- a/drivers/amlogic/media/video_processor/pic_dev/picdec.c +++ b/drivers/amlogic/media/video_processor/pic_dev/picdec.c @@ -778,6 +778,7 @@ static int picdec_memset_phyaddr(ulong phys, u32 size, u32 val) if (!p) return -1; memset(p, val, span); + codec_mm_dma_flush(p, span, DMA_TO_DEVICE); codec_mm_unmap_phyaddr(p); } return 0; @@ -887,6 +888,7 @@ static int copy_phybuf_to_file(ulong phys, u32 size, p = codec_mm_vmap(addr, span); if (!p) return -1; + codec_mm_dma_flush(p, span, DMA_FROM_DEVICE); vfs_write(fp, (char *)p, span, &pos); pos += span; diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c index aa29b323755d..eecaea520f5b 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c @@ -580,6 +580,7 @@ void vdin_afbce_maptable_init(struct vdin_dev_s *devp) unsigned int *vtable = NULL; unsigned int body; unsigned int size; + void *p = NULL; size = roundup(devp->afbce_info->frame_body_size, 4096); @@ -599,19 +600,40 @@ void vdin_afbce_maptable_init(struct vdin_dev_s *devp) else vtable = phys_to_virt(ptable); } else { - vtable = (unsigned int *)codec_mm_vmap( - ptable, + vtable = (unsigned int *)vdin_vmap(ptable, devp->afbce_info->frame_table_size); + if (vdin_dbg_en) { + pr_err("----vdin vmap v: %p, p: %lx, size: %d\n", + vtable, ptable, + devp->afbce_info->frame_table_size); + } + if (!vtable) { + pr_err("vmap fail, size: %d.\n", + devp->afbce_info->frame_table_size); + return; + } + } + p = vtable; body = devp->afbce_info->fm_body_paddr[i]&0xffffffff; for (j = 0; j < size; j += 4096) { *vtable = ((j + body) >> 12) & 0x000fffff; vtable++; } + /* clean tail data. */ + memset(vtable, 0, devp->afbce_info->frame_table_size - + ((char *)vtable - (char *)p)); + + vdin_dma_flush(devp, p, + devp->afbce_info->frame_table_size, + DMA_TO_DEVICE); + if (highmem_flag) - codec_mm_unmap_phyaddr((void *)vtable); + vdin_unmap_phyaddr(p); + + vtable = NULL; } } diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c index 47435be42184..f551ce0b0849 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -160,6 +163,79 @@ static unsigned int vpu_reg_27af = 0x3; #define pr_info(fmt, ...) #endif +u8 *vdin_vmap(ulong addr, u32 size) +{ + u8 *vaddr = NULL; + struct page **pages = NULL; + u32 i, npages, offset = 0; + ulong phys, page_start; + /*pgprot_t pgprot = pgprot_noncached(PAGE_KERNEL);*/ + pgprot_t pgprot = PAGE_KERNEL; + + if (!PageHighMem(phys_to_page(addr))) + return phys_to_virt(addr); + + offset = offset_in_page(addr); + page_start = addr - offset; + npages = DIV_ROUND_UP(size + offset, PAGE_SIZE); + + pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + if (!pages) + return NULL; + + for (i = 0; i < npages; i++) { + phys = page_start + i * PAGE_SIZE; + pages[i] = pfn_to_page(phys >> PAGE_SHIFT); + } + + vaddr = vmap(pages, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + page_start, npages << PAGE_SHIFT); + kfree(pages); + return NULL; + } + + kfree(pages); + + if (vdin_dbg_en) { + pr_info("[vdin HIGH-MEM-MAP] %s, pa(%lx) to va(%p), size: %d\n", + __func__, page_start, vaddr, npages << PAGE_SHIFT); + } + + return vaddr + offset; +} + +void vdin_unmap_phyaddr(u8 *vaddr) +{ + void *addr = (void *)(PAGE_MASK & (ulong)vaddr); + + if (is_vmalloc_or_module_addr(vaddr)) { + if (vdin_dbg_en) + pr_info("----vdin unmap v: %p\n", addr); + vunmap(addr); + } +} + +void vdin_dma_flush(struct vdin_dev_s *devp, void *vaddr, + int size, enum dma_data_direction dir) +{ + ulong phy_addr; + + if (is_vmalloc_or_module_addr(vaddr)) { + phy_addr = page_to_phys(vmalloc_to_page(vaddr)) + + offset_in_page(vaddr); + if (phy_addr && PageHighMem(phys_to_page(phy_addr))) { + if (vdin_dbg_en) + pr_info("----vdin flush v: %p, p: %lx\n", + vaddr, phy_addr); + dma_sync_single_for_device(&devp->this_pdev->dev, + phy_addr, size, dir); + } + return; + } +} + /*reset reg mif value of vdin0: * VDIN_WR_CTRL \VDIN_COM_CTRL0\ VDIN_MISC_CTRL */ @@ -3550,12 +3626,12 @@ void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size) if ((devp->cma_config_flag & 0x100) && devp->cma_config_en) devp->vfp->dv_buf_ori[index] = - codec_mm_vmap(devp->vfmem_start[index] + + vdin_vmap(devp->vfmem_start[index] + devp->vfmem_size-dolby_size_byte, dolby_size_byte); else devp->vfp->dv_buf_ori[index] = - codec_mm_vmap(devp->mem_start + + vdin_vmap(devp->mem_start + devp->mem_size - dolby_size_byte * (devp->canvas_max_num - index), @@ -3572,15 +3648,32 @@ void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size) void vdin_dolby_addr_release(struct vdin_dev_s *devp, unsigned int size) { unsigned int alloc_size; + int highmem_flag; + int index; alloc_size = dolby_size_byte*size; if (devp->dv.dv_dma_vaddr) dma_free_coherent(&devp->this_pdev->dev, alloc_size, devp->dv.dv_dma_vaddr, devp->dv.dv_dma_paddr); devp->dv.dv_dma_vaddr = NULL; + + if (devp->cma_config_flag & 0x100) + highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0])); + else + highmem_flag = PageHighMem(phys_to_page(devp->mem_start)); + + if (highmem_flag) { + for (index = 0; index < size; index++) { + if (devp->vfp->dv_buf_ori[index]) { + vdin_unmap_phyaddr( + devp->vfp->dv_buf_ori[index]); + devp->vfp->dv_buf_ori[index] = NULL; + } + } + } } -static void vdin_dolby_metadata_swap(char *buf) +static void vdin_dolby_metadata_swap(struct vdin_dev_s *devp, char *buf) { char ext; unsigned int i, j; @@ -3592,6 +3685,8 @@ static void vdin_dolby_metadata_swap(char *buf) buf[i*16+15-j] = ext; } } + + vdin_dma_flush(devp, buf, dolby_size_byte, DMA_TO_DEVICE); } #define swap32(num) \ @@ -3689,7 +3784,8 @@ void vdin_dolby_buffer_update(struct vdin_dev_s *devp, unsigned int index) for (count = 0; count < META_RETRY_MAX; count++) { if (dv_dbg_mask & DV_READ_MODE_AXI) { memcpy(p, devp->vfp->dv_buf_vmem[index], 128); - vdin_dolby_metadata_swap(c); + vdin_dma_flush(devp, p, 128, DMA_TO_DEVICE); + vdin_dolby_metadata_swap(devp, c); } else { wr(offset, VDIN_DOLBY_DSC_CTRL3, 0); wr(offset, VDIN_DOLBY_DSC_CTRL2, 0xd180c0d5); @@ -3702,7 +3798,9 @@ void vdin_dolby_buffer_update(struct vdin_dev_s *devp, unsigned int index) if ((i == 31) && (multimeta_flag == 0)) break; } + vdin_dma_flush(devp, p, 128, DMA_TO_DEVICE); } + meta_size = (c[3] << 8) | c[4]; crc = p[31]; crc_result = crc32(0, p, 124); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h index 178c74a0a387..fcdf2974d439 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h @@ -17,7 +17,11 @@ #ifndef __TVIN_VDIN_CTL_H #define __TVIN_VDIN_CTL_H - +#include +#include +#include +#include +#include #include "vdin_drv.h" #define DV_SWAP_EN (1 << 0) @@ -111,10 +115,16 @@ struct ldim_max_s { #endif extern unsigned int game_mode; +extern bool vdin_dbg_en; /* ************************************************************************ */ /* ******** GLOBAL FUNCTION CLAIM ******** */ /* ************************************************************************ */ +extern u8 *vdin_vmap(ulong addr, u32 size); +extern void vdin_unmap_phyaddr(u8 *vaddr); +extern void vdin_dma_flush(struct vdin_dev_s *devp, void *vaddr, + int size, enum dma_data_direction dir); + extern void vdin_set_vframe_prop_info(struct vframe_s *vf, struct vdin_dev_s *devp); extern void LDIM_Initial_2(int pic_h, int pic_v, int BLK_Vnum, diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c index 6798f884772b..f29067ab9241 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c @@ -343,14 +343,15 @@ static void vdin_dump_one_buf_mem(char *path, struct vdin_dev_s *devp, for (j = 0; j < count; j++) { highaddr = phys + j * devp->canvas_w; - buf = codec_mm_vmap(highaddr, span); + buf = vdin_vmap(highaddr, span); if (!buf) { - pr_info("codec_mm_vmap error\n"); + pr_info("vdin_vmap error\n"); return; } + vdin_dma_flush(devp, buf, span, DMA_FROM_DEVICE); vfs_write(filp, buf, span, &pos); - codec_mm_unmap_phyaddr(buf); + vdin_unmap_phyaddr(buf); } pr_info("high-mem write buffer %2d of %2u to %s.\n", buf_num, devp->canvas_max_num, path); @@ -448,14 +449,16 @@ static void vdin_dump_mem(char *path, struct vdin_dev_s *devp) for (j = 0; j < count; j++) { highaddr = phys + j * devp->canvas_w; - buf = codec_mm_vmap(highaddr, span); + buf = vdin_vmap(highaddr, span); if (!buf) { - pr_info("codec_mm_vmap error\n"); + pr_info("vdin_vmap error\n"); return; } + vdin_dma_flush(devp, buf, span, + DMA_FROM_DEVICE); vfs_write(filp, buf, span, &pos); - codec_mm_unmap_phyaddr(buf); + vdin_unmap_phyaddr(buf); } pr_info("high-mem write buffer %2d of %2u to %s.\n", i, devp->canvas_max_num, path); @@ -496,10 +499,8 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, return; } - if (devp->cma_config_flag == 0x101) - highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0])); - else - highmem_flag = PageHighMem(phys_to_page(devp->mem_start)); + highmem_flag = PageHighMem( + phys_to_page(devp->afbce_info->fm_body_paddr[0])); if (highmem_flag == 0) { /*low mem area*/ @@ -532,11 +533,11 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, } else { /*high mem area*/ pr_info("high mem area\n"); - buf_head = codec_mm_vmap( + buf_head = vdin_vmap( devp->afbce_info->fm_head_paddr[buf_num], devp->afbce_info->frame_head_size); - buf_table = codec_mm_vmap( + buf_table = vdin_vmap( devp->afbce_info->fm_table_paddr[buf_num], devp->afbce_info->frame_table_size); @@ -557,8 +558,12 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, return; } + vdin_dma_flush(devp, buf_head, + devp->afbce_info->frame_head_size, + DMA_FROM_DEVICE); vfs_write(filp, buf_head, devp->afbce_info->frame_head_size, &pos); - codec_mm_unmap_phyaddr(buf_head); + if (highmem_flag) + vdin_unmap_phyaddr(buf_head); pr_info("write buffer %2d of %2u head to %s.\n", buf_num, devp->canvas_max_num, buff); vfs_fsync(filp, 0); @@ -573,8 +578,12 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, pr_info("create %s table error.\n", buff); return; } + vdin_dma_flush(devp, buf_table, + devp->afbce_info->frame_table_size, + DMA_FROM_DEVICE); vfs_write(filp, buf_table, devp->afbce_info->frame_table_size, &pos); - codec_mm_unmap_phyaddr(buf_table); + if (highmem_flag) + vdin_unmap_phyaddr(buf_table); pr_info("write buffer %2d of %2u table to %s.\n", buf_num, devp->canvas_max_num, buff); vfs_fsync(filp, 0); @@ -600,27 +609,29 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, for (j = 0; j < count; j++) { highaddr = phys + j * span; - vbuf = codec_mm_vmap(highaddr, span); + vbuf = vdin_vmap(highaddr, span); if (!vbuf) { - pr_info("codec_mm_vmap error\n"); + pr_info("vdin_vmap error\n"); return; } + vdin_dma_flush(devp, vbuf, span, DMA_FROM_DEVICE); vfs_write(filp, vbuf, span, &pos); - codec_mm_unmap_phyaddr(vbuf); + vdin_unmap_phyaddr(vbuf); } if (remain) { span = devp->afbce_info->frame_body_size - remain; highaddr = phys + span; - vbuf = codec_mm_vmap(highaddr, remain); + vbuf = vdin_vmap(highaddr, remain); if (!vbuf) { - pr_info("codec_mm_vmap1 error\n"); + pr_info("vdin_vmap1 error\n"); return; } - vfs_write(filp, vbuf, span, &pos); - codec_mm_unmap_phyaddr(vbuf); + vdin_dma_flush(devp, vbuf, remain, DMA_FROM_DEVICE); + vfs_write(filp, vbuf, remain, &pos); + vdin_unmap_phyaddr(vbuf); } } pr_info("write buffer %2d of %2u body to %s.\n", @@ -631,119 +642,6 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, set_fs(old_fs); } -static void vdin_dump_afbce_mem(char *path, struct vdin_dev_s *devp) -{ - struct file *filp = NULL; - loff_t pos = 0; - void *buf_head = NULL; - void *buf_table = NULL; - void *buf_body = NULL; - unsigned char buff[100]; - unsigned int i; - mm_segment_t old_fs = get_fs(); - - if ((devp->cma_config_flag & 0x1) && - (devp->cma_mem_alloc == 0)) { - pr_info("%s:no cma alloc mem!!!\n", __func__); - return; - } - - if (devp->cma_config_flag == 0x101) { - buf_head = codec_mm_phys_to_virt( - devp->afbce_info->head_paddr); - buf_table = codec_mm_phys_to_virt( - devp->afbce_info->table_paddr); - buf_body = codec_mm_phys_to_virt( - devp->afbce_info->fm_body_paddr[0]); - - pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", - devp->afbce_info->head_paddr, - (devp->afbce_info->table_paddr), - devp->afbce_info->fm_body_paddr[0]); - } else if (devp->cma_config_flag == 0) { - buf_head = phys_to_virt( - devp->afbce_info->head_paddr); - buf_table = phys_to_virt( - devp->afbce_info->table_paddr); - buf_body = phys_to_virt( - devp->afbce_info->fm_body_paddr[0]); - - pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", - devp->afbce_info->head_paddr, - (devp->afbce_info->table_paddr), - devp->afbce_info->fm_body_paddr[0]); - } - - set_fs(KERNEL_DS); - - /* write header bin start */ - strcpy(buff, path); - strcat(buff, "_header.bin"); - filp = filp_open(buff, O_RDWR|O_CREAT, 0666); - if (IS_ERR(filp)) { - pr_info("create %s header error.\n", buff); - return; - } - - for (i = 0; i < devp->vfmem_max_cnt; i++) { - vfs_write(filp, buf_head, - devp->afbce_info->frame_head_size, &pos); - buf_head += devp->afbce_info->frame_head_size; - pr_info("write buffer %2d(0x%x bytes) of %2u head to %s.\n", - i, devp->afbce_info->frame_head_size, - devp->canvas_max_num, buff); - } - vfs_fsync(filp, 0); - filp_close(filp, NULL); - /* write header bin end */ - - /* write table bin start */ - pos = 0; - strcpy(buff, path); - strcat(buff, "_table.bin"); - filp = filp_open(buff, O_RDWR|O_CREAT, 0666); - if (IS_ERR(filp)) { - pr_info("create %s table error.\n", buff); - return; - } - - for (i = 0; i < devp->vfmem_max_cnt; i++) { - vfs_write(filp, buf_table, - devp->afbce_info->frame_table_size, &pos); - buf_table += devp->afbce_info->frame_table_size; - pr_info("write buffer %2d(0x%x bytes) of %2u table to %s.\n", - i, devp->afbce_info->frame_table_size, - devp->canvas_max_num, buff); - } - vfs_fsync(filp, 0); - filp_close(filp, NULL); - /* write table bin end */ - - /* write body bin start */ - pos = 0; - strcpy(buff, path); - strcat(buff, "_body.bin"); - filp = filp_open(buff, O_RDWR|O_CREAT, 0666); - if (IS_ERR(filp)) { - pr_info("create %s body error.\n", buff); - return; - } - - for (i = 0; i < devp->vfmem_max_cnt; i++) { - vfs_write(filp, buf_body, - devp->afbce_info->frame_body_size, &pos); - buf_body += devp->afbce_info->frame_body_size; - pr_info("write buffer %2d(0x%x bytes) of %2u body to %s.\n", - i, devp->afbce_info->frame_body_size, - devp->canvas_max_num, buff); - } - vfs_fsync(filp, 0); - filp_close(filp, NULL); - /* write body bin end */ - - set_fs(old_fs); -} - static void dump_other_mem(char *path, unsigned int start, unsigned int offset) { @@ -1101,21 +999,30 @@ static void vdin_dump_histgram(struct vdin_dev_s *devp) } /*type: 1:nv21 2:yuv422 3:yuv444*/ -static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type) +static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type, + char *path) { - char *md_path_head = "/storage/B8F7-DBD0/afbce/a0_1header.bin"; - char *md_path_body = "/storage/B8F7-DBD0/afbce/a0_1body.bin"; - unsigned int i; + char md_path_head[100], md_path_body[100]; + unsigned int i, j; + int highmem_flag = 0; unsigned int size = 0; + unsigned int span = 0; + unsigned int remain = 0; + unsigned int count = 0; + unsigned long highaddr; + unsigned long phys; long val; struct file *filp = NULL; loff_t pos = 0; mm_segment_t old_fs; void *head_dts = NULL; void *body_dts = NULL; + void *vbuf = NULL; if (kstrtol(type, 10, &val) < 0) return; + if (!path) + return; if (!devp->curr_wr_vfe) { devp->curr_wr_vfe = provider_vf_get(devp->vfp); @@ -1125,6 +1032,9 @@ static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type) } } + sprintf(md_path_head, "%s_1header.bin", path); + sprintf(md_path_body, "%s_1body.bin", path); + i = devp->curr_wr_vfe->af_num; devp->curr_wr_vfe->vf.type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_FIELD | VIDTYPE_COMPRESS | VIDTYPE_SCATTER; @@ -1146,8 +1056,18 @@ static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type) devp->curr_wr_vfe->vf.compHeadAddr = devp->afbce_info->fm_head_paddr[i]; devp->curr_wr_vfe->vf.compBodyAddr = devp->afbce_info->fm_body_paddr[i]; - head_dts = codec_mm_phys_to_virt(devp->afbce_info->fm_head_paddr[i]); - body_dts = codec_mm_phys_to_virt(devp->afbce_info->fm_body_paddr[i]); + highmem_flag = PageHighMem( + phys_to_page(devp->afbce_info->fm_body_paddr[0])); + if (highmem_flag == 0) { + pr_info("low mem area\n"); + head_dts = codec_mm_phys_to_virt( + devp->afbce_info->fm_head_paddr[i]); + } else { + pr_info("high mem area\n"); + head_dts = vdin_vmap( + devp->afbce_info->fm_head_paddr[i], + devp->afbce_info->frame_head_size); + } old_fs = get_fs(); set_fs(KERNEL_DS); @@ -1160,6 +1080,8 @@ static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type) size = vfs_read(filp, head_dts, devp->afbce_info->frame_head_size, &pos); + if (highmem_flag) + vdin_unmap_phyaddr(head_dts); vfs_fsync(filp, 0); filp_close(filp, NULL); @@ -1175,8 +1097,30 @@ static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type) return; } - size = vfs_read(filp, body_dts, - devp->afbce_info->frame_body_size, &pos); + if (highmem_flag == 0) { + body_dts = codec_mm_phys_to_virt( + devp->afbce_info->fm_body_paddr[i]); + + size = vfs_read(filp, body_dts, + devp->afbce_info->frame_body_size, &pos); + } else { + span = SZ_1M; + count = devp->afbce_info->frame_body_size/PAGE_ALIGN(span); + remain = devp->afbce_info->frame_body_size%PAGE_ALIGN(span); + phys = devp->afbce_info->fm_body_paddr[i]; + + + for (j = 0; j < count; j++) { + highaddr = phys + j * span; + vbuf = vdin_vmap(highaddr, span); + if (!vbuf) { + pr_info("vdin_vmap error\n"); + return; + } + vfs_read(filp, vbuf, span, &pos); + vdin_unmap_phyaddr(vbuf); + } + } vfs_fsync(filp, 0); filp_close(filp, NULL); @@ -1187,6 +1131,7 @@ static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type) vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } + static void vdin_write_mem( struct vdin_dev_s *devp, char *type, char *path, char *md_path) @@ -1272,13 +1217,14 @@ static void vdin_write_mem( span = devp->canvas_active_w; for (j = 0; j < count; j++) { highaddr = addr + j * devp->canvas_w; - dts = codec_mm_vmap(highaddr, span); + dts = vdin_vmap(highaddr, span); if (!dts) { - pr_info("codec_mm_vmap error\n"); + pr_info("vdin_vmap error\n"); return; } vfs_read(filp, dts, span, &pos); - codec_mm_unmap_phyaddr(dts); + vdin_dma_flush(devp, dts, span, DMA_TO_DEVICE); + vdin_unmap_phyaddr(dts); } vfs_fsync(filp, 0); filp_close(filp, NULL); @@ -1802,8 +1748,8 @@ start_chk: } else if (!strcmp(parm[0], "force_recycle")) { devp->flags |= VDIN_FLAG_FORCE_RECYCLE; } else if (!strcmp(parm[0], "read_pic_afbce")) { - if (parm[1]) - vdin_write_afbce_mem(devp, parm[1]); + if (parm[1] && parm[2]) + vdin_write_afbce_mem(devp, parm[1], parm[2]); else pr_err("miss parameters.\n"); } else if (!strcmp(parm[0], "read_pic")) { @@ -2172,7 +2118,7 @@ start_chk: buf_num = val; vdin_dump_one_afbce_mem(parm[1], devp, buf_num); } else if (parm[1] != NULL) { - vdin_dump_afbce_mem(parm[1], devp); + vdin_dump_one_afbce_mem(parm[1], devp, 0); } } else { pr_info("unknown command\n"); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c index 52491bc2f9f3..6bbc95152534 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c @@ -135,7 +135,7 @@ MODULE_PARM_DESC(game_mode_phlock_switch_frames, "game mode switch frames for phase_lock"); #endif -static bool vdin_dbg_en; +bool vdin_dbg_en; module_param(vdin_dbg_en, bool, 0664); MODULE_PARM_DESC(vdin_dbg_en, "enable/disable vdin debug information"); @@ -642,14 +642,6 @@ void vdin_start_dec(struct vdin_dev_s *devp) #endif vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_START, NULL); - if ((devp->parm.port != TVIN_PORT_VIU1) || - (viu_hw_irq != 0)) { - /*enable irq */ - enable_irq(devp->irq); - if (vdin_dbg_en) - pr_info("****[%s]enable_irq ifdef VDIN_V2****\n", - __func__); - } if (vdin_dbg_en) pr_info("****[%s]ok!****\n", __func__); @@ -675,7 +667,6 @@ void vdin_start_dec(struct vdin_dev_s *devp) if ((devp->afbce_mode == 1) && is_meson_tl1_cpu() && (devp->h_active >= 1920) && (devp->v_active >= 1080)) { - spin_lock_init(&tl1_preview_lock); tl1_vdin1_preview_flag = 1; max_ignore_frames[devp->index] = 9; } @@ -745,14 +736,16 @@ void vdin_stop_dec(struct vdin_dev_s *devp) if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) vdin_afbce_hw_disable(); +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + vdin_dolby_addr_release(devp, devp->vfp->size); +#endif + #ifdef CONFIG_CMA if (devp->afbce_mode == 1) vdin_afbce_cma_release(devp); else if (devp->afbce_mode == 0) vdin_cma_release(devp); #endif - vdin_dolby_addr_release(devp, devp->vfp->size); - switch_vpu_mem_pd_vmod(devp->addr_offset?VPU_VIU_VDIN1:VPU_VIU_VDIN0, VPU_MEM_POWER_DOWN); memset(&devp->prop, 0, sizeof(struct tvin_sig_property_s)); @@ -824,18 +817,7 @@ int start_tvin_service(int no, struct vdin_parm_s *para) else return -EBUSY; } - if ((para->port != TVIN_PORT_VIU1) || - (viu_hw_irq != 0)) { - ret = request_irq(devp->irq, vdin_v4l2_isr, IRQF_SHARED, - devp->irq_name, (void *)devp); - if (ret != 0) { - pr_info("vdin_v4l2_isr request irq error.\n"); - return -1; - } - devp->flags |= VDIN_FLAG_ISR_REQ; - /*disable vsync irq until vdin configured completely*/ - disable_irq_nosync(devp->irq); - } + vdin_clk_onoff(devp, true); /*config the vdin use default value*/ vdin_set_default_regmap(devp->addr_offset); @@ -917,6 +899,16 @@ int start_tvin_service(int no, struct vdin_parm_s *para) devp->flags |= VDIN_FLAG_DEC_OPENED; devp->flags |= VDIN_FLAG_DEC_STARTED; + if ((para->port != TVIN_PORT_VIU1) || + (viu_hw_irq != 0)) { + ret = request_irq(devp->irq, vdin_v4l2_isr, IRQF_SHARED, + devp->irq_name, (void *)devp); + if (ret != 0) { + pr_info("vdin_v4l2_isr request irq error.\n"); + return -1; + } + devp->flags |= VDIN_FLAG_ISR_REQ; + } return 0; } EXPORT_SYMBOL(start_tvin_service); @@ -2373,6 +2365,16 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } vdin_start_dec(devp); + + if ((devp->parm.port != TVIN_PORT_VIU1) || + (viu_hw_irq != 0)) { + /*enable irq */ + enable_irq(devp->irq); + if (vdin_dbg_en) + pr_info("****[%s]enable_irq ifdef VDIN_V2****\n", + __func__); + } + devp->flags |= VDIN_FLAG_DEC_STARTED; if (vdin_dbg_en) pr_info("TVIN_IOC_START_DEC port %s, decode started ok\n\n", @@ -2383,29 +2385,19 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) mutex_lock(&devp_vdin1->fe_lock); if ((tl1_vdin1_preview_flag == 1) && !(devp_vdin1->flags & VDIN_FLAG_DEC_STARTED)) { - msleep(150); + /*msleep(150);*/ devp_vdin1->flags |= VDIN_FLAG_FS_OPENED; - if (!(devp_vdin1->flags & VDIN_FLAG_ISR_REQ)) { - ret = request_irq(devp_vdin1->irq, vdin_isr, - IRQF_SHARED, - devp_vdin1->irq_name, - (void *)devp_vdin1); - if (ret != 0) { - pr_info("tl1_vdin1_preview request irq error.\n"); - return -1; - } - devp_vdin1->flags |= VDIN_FLAG_ISR_REQ; - disable_irq_nosync(devp_vdin1->irq); - /*init queue*/ - init_waitqueue_head(&devp_vdin1->queue); - } devp_vdin1->unstable_flag = false; devp_vdin1->parm.info.fmt = fmt; devp_vdin1->parm.port = devp->parm.port; devp_vdin1->fmt_info_p = (struct tvin_format_s *) - tvin_get_fmt_info(fmt); + tvin_get_fmt_info(fmt); + if (!(devp_vdin1->flags & VDIN_FLAG_DEC_OPENED)) { + /*init queue*/ + init_waitqueue_head(&devp_vdin1->queue); + ret = vdin_open_fe(devp_vdin1->parm.port, 0, devp_vdin1); if (ret) { @@ -2430,6 +2422,23 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) vdin_start_dec(devp_vdin1); devp_vdin1->flags |= VDIN_FLAG_DEC_STARTED; + if (!(devp_vdin1->flags & VDIN_FLAG_ISR_REQ)) { + ret = request_irq(devp_vdin1->irq, vdin_isr, + IRQF_SHARED, + devp_vdin1->irq_name, + (void *)devp_vdin1); + if (ret != 0) { + pr_info("tl1_vdin1_preview request irq error.\n"); + return -1; + } + devp_vdin1->flags |= VDIN_FLAG_ISR_REQ; + } else { + enable_irq(devp_vdin1->irq); + if (vdin_dbg_en) + pr_info("****[%s]enable_vdin1_irq****\n", + __func__); + } + pr_info("TVIN_IOC_START_DEC port %s, vdin1 used for preview\n", tvin_port_str(devp_vdin1->parm.port)); } @@ -3112,6 +3121,8 @@ static int vdin_drv_probe(struct platform_device *pdev) else vdevp->color_depth_mode = 0; + /* use for tl1 vdin1 preview */ + spin_lock_init(&tl1_preview_lock); /*set afbce mode*/ ret = of_property_read_u32(pdev->dev.of_node, "afbce_bit_mode", &val); -- 2.34.1