mirror of
https://github.com/hardkernel/linux.git
synced 2026-04-03 11:43:03 +09:00
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 <nanxin.qin@amlogic.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/amlogic/media/codec_mm/codec_mm.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/page-flags.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
#include <linux/amlogic/media/video_sink/video.h>
|
||||
@@ -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);
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
|
||||
#ifndef __TVIN_VDIN_CTL_H
|
||||
#define __TVIN_VDIN_CTL_H
|
||||
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/page-flags.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
#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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -135,7 +135,7 @@ MODULE_PARM_DESC(game_mode_phlock_switch_frames,
|
||||
"game mode switch <n> 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);
|
||||
|
||||
Reference in New Issue
Block a user