deinterlace: fix CMA layout adaptation di_cma_reserved [1/1]

PD#SWPL-2308

Problem:
CMA layout adaptation di_cma_reserved cause crash

Solution:
fix CMA layout adaptation di_cma_reserved

Verify:
P321

Change-Id: Ia24e811a02d47d70afa1c06361fd0852c357394c
Signed-off-by: wenfeng.guo <wenfeng.guo@amlogic.com>
This commit is contained in:
wenfeng.guo
2018-11-20 19:38:43 +08:00
committed by Luan Yuan
parent 877657ed55
commit 8860abb5e8
4 changed files with 96 additions and 7 deletions

View File

@@ -1243,7 +1243,61 @@ static bool is_in_queue(struct di_buf_s *di_buf, int queue_idx)
}
return ret;
}
//---------------------------
u8 *di_vmap(ulong addr, u32 size, bool *bflg)
{
u8 *vaddr = NULL;
ulong phys = addr;
u32 offset = phys & ~PAGE_MASK;
u32 npages = PAGE_ALIGN(size) / PAGE_SIZE;
struct page **pages = NULL;
pgprot_t pgprot;
int i;
if (!PageHighMem(phys_to_page(phys)))
return phys_to_virt(phys);
if (offset)
npages++;
pages = vmalloc(sizeof(struct page *) * npages);
if (!pages)
return NULL;
for (i = 0; i < npages; i++) {
pages[i] = phys_to_page(phys);
phys += PAGE_SIZE;
}
/*nocache*/
pgprot = pgprot_writecombine(PAGE_KERNEL);
vaddr = vmap(pages, npages, VM_MAP, pgprot);
if (!vaddr) {
pr_err("the phy(%lx) vmaped fail, size: %d\n",
addr - offset, npages << PAGE_SHIFT);
vfree(pages);
return NULL;
}
vfree(pages);
// if (debug_mode & 0x20) {
// di_print("[HIGH-MEM-MAP] %s, pa(%lx) to va(%p), size: %d\n",
// __func__, addr, vaddr + offset, npages << PAGE_SHIFT);
// }
*bflg = true;
return vaddr + offset;
}
void di_unmap_phyaddr(u8 *vaddr)
{
void *addr = (void *)(PAGE_MASK & (ulong)vaddr);
vunmap(addr);
}
//-------------------------
static ssize_t
store_dump_mem(struct device *dev, struct device_attribute *attr,
const char *buf, size_t len)
@@ -1260,6 +1314,7 @@ store_dump_mem(struct device *dev, struct device_attribute *attr,
loff_t pos = 0;
void *buff = NULL;
mm_segment_t old_fs;
bool bflg_vmap = false;
buf_orig = kstrdup(buf, GFP_KERNEL);
ps = buf_orig;
@@ -1306,10 +1361,18 @@ store_dump_mem(struct device *dev, struct device_attribute *attr,
return len;
}
dump_state_flag = 1;
if (de_devp->flags & DI_MAP_FLAG)
buff = (void *)phys_to_virt(dump_adr);
else
if (de_devp->flags & DI_MAP_FLAG) {
//buff = (void *)phys_to_virt(dump_adr);
buff = di_vmap(dump_adr, nr_size, &bflg_vmap);
if (buff == NULL) {
pr_info("di_vap err\n");
filp_close(filp, NULL);
return len;
}
} else {
buff = ioremap(dump_adr, nr_size);
}
if (IS_ERR_OR_NULL(buff))
pr_err("%s: ioremap error.\n", __func__);
vfs_write(filp, buff, nr_size, &pos);
@@ -1333,6 +1396,10 @@ store_dump_mem(struct device *dev, struct device_attribute *attr,
*/
vfs_fsync(filp, 0);
pr_info("write buffer 0x%lx to %s.\n", dump_adr, parm[1]);
if (bflg_vmap)
di_unmap_phyaddr(buff);
if (!(de_devp->flags & DI_MAP_FLAG))
iounmap(buff);
dump_state_flag = 0;
@@ -4200,7 +4267,8 @@ static irqreturn_t de_irq(int irq, void *dev_instance)
is_meson_txhd_cpu())
mc_pre_mv_irq();
calc_lmv_base_mcinfo((di_pre_stru.cur_height>>1),
di_pre_stru.di_wr_buf->mcinfo_adr);
di_pre_stru.di_wr_buf->mcinfo_adr,
di_pre_stru.mcinfo_size);
}
nr_process_in_irq();
if ((data32&0x200) && de_devp->nrds_enable)

View File

@@ -419,6 +419,8 @@ struct di_buf_s *get_di_recovery_log_di_buf(void);
int get_di_video_peek_cnt(void);
unsigned long get_di_reg_unreg_timeout_cnt(void);
struct vframe_s **get_di_vframe_in(void);
/*---------------------*/
struct di_buf_s *get_di_buf(int queue_idx, int *start_pos);

View File

@@ -314,17 +314,29 @@ static struct mcinfo_lmv_s lines_mv[540];
static short offset_lmv = 100;
module_param_named(offset_lmv, offset_lmv, short, 0644);
void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr)
void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr,
unsigned int mcinfo_size)
{
unsigned short i, top_str, bot_str, top_end, bot_end, j = 0;
unsigned short *mcinfo_vadr = NULL, lck_num;
unsigned short flg_m1 = 0, flg_i = 0, nLmvLckSt = 0;
unsigned short lmv_lckstext[3] = {0, 0, 0}, nLmvLckEd;
unsigned short lmv_lckedext[3] = {0, 0, 0}, nLmvLckNum;
bool bflg_vmap = false;
u8 *tmp;
//mcinfo_vadr = (unsigned short *)phys_to_virt(mcinfo_adr);
mcinfo_vadr = (unsigned short *)phys_to_virt(mcinfo_adr);
if (!lmv_lock_win_en)
return;
tmp = di_vmap(mcinfo_adr, mcinfo_size, &bflg_vmap);
if (tmp == NULL) {
di_print("err:di_vmap failed\n");
return;
}
mcinfo_vadr = (unsigned short *)tmp;
for (i = 0; i < (vf_height>>1); i++) {
lmvs_init(&lines_mv[i], *(mcinfo_vadr+i));
j = i + (vf_height>>1);
@@ -337,6 +349,9 @@ void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr)
pr_info("\n");
}
}
if (bflg_vmap)
di_unmap_phyaddr(tmp);
pr_mcinfo_cnt ? pr_mcinfo_cnt-- : (pr_mcinfo_cnt = 0);
top_str = 0;
top_end = offset_lmv;

View File

@@ -165,7 +165,8 @@ void enable_di_post_mif(enum gate_mode_e mode);
void di_hw_uninit(void);
void combing_pd22_window_config(unsigned int width, unsigned int height);
void calc_lmv_init(void);
void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr);
void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr,
unsigned int mcinfo_size);
void init_field_mode(unsigned short height);
void film_mode_win_config(unsigned int width, unsigned int height);
void pulldown_vof_win_config(struct pulldown_detected_s *wins);
@@ -182,5 +183,8 @@ extern void afbc_reg_sw(bool on);
extern void afbc_sw_trig(bool on);
extern void dump_vd2_afbc(void);
extern u8 *di_vmap(ulong addr, u32 size, bool *bflg);
extern void di_unmap_phyaddr(u8 *vaddr);
extern int di_print(const char *fmt, ...);
#endif