tvin: vdin: add vdin afbce memory power ctrl [1/1]

PD#SWPL-3635

Problem:
Miss vdin afbce memory power ctrl.

Solution:
Add vdin afbce memory power ctrl.

Verify:
x301_tl1

Change-Id: I94946e3d16027083688735d68b9d023b6bc5c8bf
Signed-off-by: Xuhua Zhang <xuhua.zhang@amlogic.com>
This commit is contained in:
Xuhua Zhang
2018-12-28 14:58:49 +08:00
committed by Jianxin Pan
parent 2d3323c68c
commit 63f1b85767
4 changed files with 173 additions and 53 deletions

View File

@@ -367,35 +367,47 @@ void vdin_write_mif_or_afbce(struct vdin_dev_s *devp,
if (offset == 0) {
if (sel == VDIN_OUTPUT_TO_MIF) {
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_MIF_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_AFBCE_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
1, VDIN0_MIF_ENABLE_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
1, VDIN0_OUT_MIF_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
0, VDIN0_OUT_AFBCE_BIT, 1);
} else if (sel == VDIN_OUTPUT_TO_AFBCE) {
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_MIF_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_AFBCE_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
1, VDIN0_MIF_ENABLE_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
0, VDIN0_OUT_MIF_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
1, VDIN0_OUT_AFBCE_BIT, 1);
}
} else {
if (sel == VDIN_OUTPUT_TO_MIF) {
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_ENABLE_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_OUT_MIF_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_OUT_AFBCE_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
1, VDIN1_MIF_ENABLE_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
1, VDIN1_OUT_MIF_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
0, VDIN1_OUT_AFBCE_BIT, 1);
} else if (sel == VDIN_OUTPUT_TO_AFBCE) {
/*sel vdin1 afbce: not support in sw now,
*just reserved interface
*/
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_ENABLE_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_OUT_MIF_BIT, 1);
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_OUT_AFBCE_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
1, VDIN1_MIF_ENABLE_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
0, VDIN1_OUT_MIF_BIT, 1);
rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL,
1, VDIN1_OUT_AFBCE_BIT, 1);
}
}
}
/*
static void afbce_wr(uint32_t reg, const uint32_t val)
{
wr(0, reg, val);
}
*/
void vdin_afbce_config(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
@@ -429,6 +441,12 @@ void vdin_afbce_config(struct vdin_dev_s *devp)
return;
}
#ifndef CONFIG_AMLOGIC_MEDIA_RDMA
pr_info("##############################################\n");
pr_info("vdin afbce must use RDMA,but it not be opened\n");
pr_info("##############################################\n");
#endif
enc_win_bgn_h = 0;
enc_win_end_h = devp->h_active - 1;
enc_win_bgn_v = 0;
@@ -464,87 +482,100 @@ void vdin_afbce_config(struct vdin_dev_s *devp)
//bit size of uncompression mode
uncmp_size = (((((16*uncmp_bits*sblk_num)+7)>>3)+31)/32)<<1;
W_VCBUS_BIT(VDIN_WRARB_REQEN_SLV, 0x1, 3, 1);//vpu arb axi_enable
W_VCBUS_BIT(VDIN_WRARB_REQEN_SLV, 0x1, 7, 1);//vpu arb axi_enable
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WRARB_REQEN_SLV, 0x1, 3, 1);//vpu arb axi_enable
rdma_write_reg_bits(devp->rdma_handle,
VDIN_WRARB_REQEN_SLV, 0x1, 7, 1);//vpu arb axi_enable
afbce_wr(AFBCE_MODE,
rdma_write_reg(devp->rdma_handle, AFBCE_MODE,
(0 & 0x7) << 29 | (0 & 0x3) << 26 | (3 & 0x3) << 24 |
(hold_line_num & 0x7f) << 16 |
(2 & 0x3) << 14 | (reg_fmt444_comb & 0x1));
W_VCBUS_BIT(AFBCE_QUANT_ENABLE, (lossy_luma_en & 0x1), 0, 1);//loosy
W_VCBUS_BIT(AFBCE_QUANT_ENABLE, (lossy_chrm_en & 0x1), 4, 1);//loosy
rdma_write_reg_bits(devp->rdma_handle,
AFBCE_QUANT_ENABLE, (lossy_luma_en & 0x1), 0, 1);//loosy
rdma_write_reg_bits(devp->rdma_handle,
AFBCE_QUANT_ENABLE, (lossy_chrm_en & 0x1), 4, 1);//loosy
if (devp->afbce_lossy_en == 1) {
afbce_wr(AFBCE_QUANT_ENABLE, 0xc11);
rdma_write_reg(devp->rdma_handle,
AFBCE_QUANT_ENABLE, 0xc11);
pr_info("afbce use lossy compression mode\n");
}
afbce_wr(AFBCE_SIZE_IN,
rdma_write_reg(devp->rdma_handle, AFBCE_SIZE_IN,
((devp->h_active & 0x1fff) << 16) | // hsize_in of afbc input
((devp->v_active & 0x1fff) << 0) // vsize_in of afbc input
);
afbce_wr(AFBCE_BLK_SIZE_IN,
rdma_write_reg(devp->rdma_handle, AFBCE_BLK_SIZE_IN,
((hblksize_out & 0x1fff) << 16) | // out blk hsize
((vblksize_out & 0x1fff) << 0) // out blk vsize
);
//head addr of compressed data
afbce_wr(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[0]);
rdma_write_reg(devp->rdma_handle, AFBCE_HEAD_BADDR,
devp->afbce_info->fm_head_paddr[0]);
W_VCBUS_BIT(AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);//uncmp_size
rdma_write_reg_bits(devp->rdma_handle,
AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);//uncmp_size
/* how to set reg when we use crop ? */
// scope of hsize_in ,should be a integer multipe of 32
// scope of vsize_in ,should be a integer multipe of 4
afbce_wr(AFBCE_PIXEL_IN_HOR_SCOPE,
rdma_write_reg(devp->rdma_handle, AFBCE_PIXEL_IN_HOR_SCOPE,
((enc_win_end_h & 0x1fff) << 16) |
((enc_win_bgn_h & 0x1fff) << 0));
// scope of hsize_in ,should be a integer multipe of 32
// scope of vsize_in ,should be a integer multipe of 4
afbce_wr(AFBCE_PIXEL_IN_VER_SCOPE,
rdma_write_reg(devp->rdma_handle, AFBCE_PIXEL_IN_VER_SCOPE,
((enc_win_end_v & 0x1fff) << 16) |
((enc_win_bgn_v & 0x1fff) << 0));
afbce_wr(AFBCE_CONV_CTRL, lbuf_depth);//fix 256
rdma_write_reg(devp->rdma_handle,
AFBCE_CONV_CTRL, lbuf_depth);//fix 256
afbce_wr(AFBCE_MIF_HOR_SCOPE,
rdma_write_reg(devp->rdma_handle, AFBCE_MIF_HOR_SCOPE,
((blk_out_bgn_h & 0x3ff) << 16) | // scope of out blk hsize
((blk_out_end_h & 0xfff) << 0) // scope of out blk vsize
);
afbce_wr(AFBCE_MIF_VER_SCOPE,
rdma_write_reg(devp->rdma_handle, AFBCE_MIF_VER_SCOPE,
((blk_out_bgn_v & 0x3ff) << 16) | // scope of out blk hsize
((blk_out_end_v & 0xfff) << 0) // scope of out blk vsize
);
afbce_wr(AFBCE_FORMAT,
rdma_write_reg(devp->rdma_handle, AFBCE_FORMAT,
(reg_format_mode & 0x3) << 8 |
(uncmp_bits & 0xf) << 4 |
(uncmp_bits & 0xf));
afbce_wr(AFBCE_DEFCOLOR_1,
rdma_write_reg(devp->rdma_handle, AFBCE_DEFCOLOR_1,
((def_color_3 & 0xfff) << 12) | // def_color_a
((def_color_0 & 0xfff) << 0) // def_color_y
);
afbce_wr(AFBCE_DEFCOLOR_2,
rdma_write_reg(devp->rdma_handle, AFBCE_DEFCOLOR_2,
((def_color_2 & 0xfff) << 12) | // def_color_v
((def_color_1 & 0xfff) << 0) // def_color_u
);
W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4, devp->afbce_info->table_paddr, 0, 32);
W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12);
rdma_write_reg_bits(devp->rdma_handle,
AFBCE_MMU_RMIF_CTRL4, devp->afbce_info->table_paddr, 0, 32);
rdma_write_reg_bits(devp->rdma_handle,
AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12);
W_VCBUS_BIT(AFBCE_ENABLE, 1, 12, 1); //set afbce pulse mode
W_VCBUS_BIT(AFBCE_ENABLE, 1, 8, 1);//enable afbce
rdma_write_reg_bits(devp->rdma_handle,
AFBCE_ENABLE, 1, 12, 1); //set afbce pulse mode
rdma_write_reg_bits(devp->rdma_handle,
AFBCE_ENABLE, 0, 8, 1);//disable afbce
}
void vdin_afbce_maptable_init(struct vdin_dev_s *devp)
{
unsigned int i, j;
unsigned int highmem_flag = 0;
unsigned long ptable = 0;
unsigned int *vtable = NULL;
unsigned int body;
@@ -552,20 +583,35 @@ void vdin_afbce_maptable_init(struct vdin_dev_s *devp)
size = roundup(devp->afbce_info->frame_body_size, 4096);
ptable = devp->afbce_info->fm_table_paddr[0];
if (devp->cma_config_flag == 0x101)
highmem_flag = PageHighMem(phys_to_page(ptable));
else
highmem_flag = PageHighMem(phys_to_page(ptable));
for (i = 0; i < devp->vfmem_max_cnt; i++) {
ptable = devp->afbce_info->fm_table_paddr[i];
if (devp->cma_config_flag == 0x101)
vtable = codec_mm_phys_to_virt(ptable);
else if (devp->cma_config_flag == 0)
vtable = phys_to_virt(ptable);
else
vtable = phys_to_virt(ptable);
if (highmem_flag == 0) {
if (devp->cma_config_flag == 0x101)
vtable = codec_mm_phys_to_virt(ptable);
else if (devp->cma_config_flag == 0)
vtable = phys_to_virt(ptable);
else
vtable = phys_to_virt(ptable);
} else {
vtable = (unsigned int *)codec_mm_vmap(
ptable,
devp->afbce_info->frame_table_size);
}
body = devp->afbce_info->fm_body_paddr[i]&0xffffffff;
for (j = 0; j < size; j += 4096) {
*vtable = ((j + body) >> 12) & 0x000fffff;
vtable++;
}
if (highmem_flag)
codec_mm_unmap_phyaddr((void *)vtable);
}
}
@@ -588,10 +634,39 @@ void vdin_afbce_set_next_frame(struct vdin_dev_s *devp,
} else
#endif
{
afbce_wr(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[i]);
W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4,
devp->afbce_info->fm_table_paddr[i], 0, 32);
W_VCBUS_BIT(AFBCE_ENABLE, 1, 0, 1); //enable pulse mode
pr_info("afbce must use RDMA.\n");
}
vdin_afbce_clear_writedown_flag(devp);
}
void vdin_afbce_clear_writedown_flag(struct vdin_dev_s *devp)
{
rdma_write_reg(devp->rdma_handle, AFBCE_CLR_FLAG, 1);
}
/* return 1: write down*/
int vdin_afbce_read_writedown_flag(void)
{
int val1, val2;
val1 = rd_bits(0, AFBCE_STA_FLAGT, 0, 1);
val2 = rd_bits(0, AFBCE_STA_FLAGT, 2, 2);
if ((val1 == 1) || (val2 == 0))
return 1;
else
return 0;
}
void vdin_afbce_hw_disable(void)
{
/*can not use RDMA*/
W_VCBUS_BIT(AFBCE_ENABLE, 0, 8, 1);//disable afbce
}
void vdin_afbce_hw_enable(struct vdin_dev_s *devp)
{
//enable afbce
rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 8, 1);
}

View File

@@ -307,7 +307,10 @@ extern void vdin_afbce_cma_release(struct vdin_dev_s *devp);
extern void vdin_afbce_config(struct vdin_dev_s *devp);
extern void vdin_afbce_maptable_init(struct vdin_dev_s *devp);
extern void vdin_afbce_set_next_frame(struct vdin_dev_s *devp,
unsigned int rdma_enable, struct vf_entry *vfe);
unsigned int rdma_enable, struct vf_entry *vfe);
extern void vdin_afbce_clear_writedown_flag(struct vdin_dev_s *devp);
extern int vdin_afbce_read_writedown_flag(void);
extern void vdin_afbce_hw_disable(void);
extern void vdin_afbce_hw_enable(struct vdin_dev_s *devp);
#endif

View File

@@ -558,6 +558,7 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp,
}
vfs_write(filp, buf_head, devp->afbce_info->frame_head_size, &pos);
codec_mm_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,6 +574,7 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp,
return;
}
vfs_write(filp, buf_table, devp->afbce_info->frame_table_size, &pos);
codec_mm_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);

View File

@@ -78,6 +78,8 @@ static unsigned int vdin_addr_offset[VDIN_MAX_DEVS] = {0, 0x80};
static struct vdin_dev_s *vdin_devp[VDIN_MAX_DEVS];
static unsigned long mem_start, mem_end;
static unsigned int use_reserved_mem;
static int afbc_init_flag;
static int afbc_write_down_flag;
/*
* canvas_config_mode
* 0: canvas_config in driver probe
@@ -427,10 +429,10 @@ void vdin_start_dec(struct vdin_dev_s *devp)
pr_info("[vdin]%s null error.\n", __func__);
return;
}
if (devp->frontend && devp->frontend->sm_ops) {
sm_ops = devp->frontend->sm_ops;
sm_ops->get_sig_property(devp->frontend, &devp->prop);
if (!(devp->flags & VDIN_FLAG_V4L2_DEBUG))
devp->parm.info.cfmt = devp->prop.color_format;
if ((devp->parm.dest_width != 0) ||
@@ -453,7 +455,6 @@ void vdin_start_dec(struct vdin_dev_s *devp)
devp->prop.ve = devp->debug.cutwin.ve;
}
}
/*gxbb/gxl/gxm use clkb as vdin clk,
*for clkb is low speed,wich is enough for 1080p process,
*gxtvbb/txl use vpu clk for process 4k
@@ -479,7 +480,6 @@ void vdin_start_dec(struct vdin_dev_s *devp)
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)
vdin_fix_nonstd_vsync(devp);
/*reverse / disable reverse write buffer*/
vdin_wr_reverse(devp->addr_offset,
devp->parm.h_reverse,
@@ -500,6 +500,8 @@ void vdin_start_dec(struct vdin_dev_s *devp)
}
}
#endif
afbc_write_down_flag = 0;
/* h_active/v_active will be used by bellow calling */
if (devp->afbce_mode == 0) {
if (canvas_config_mode == 1)
@@ -510,6 +512,7 @@ void vdin_start_dec(struct vdin_dev_s *devp)
vdin_afbce_maptable_init(devp);
vdin_afbce_config(devp);
}
#if 0
if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21))
@@ -620,6 +623,7 @@ void vdin_start_dec(struct vdin_dev_s *devp)
devp->irq_cnt = 0;
devp->rdma_irq_cnt = 0;
devp->frame_cnt = 0;
if (time_en)
pr_info("vdin.%d start time: %ums, run time:%ums.\n",
devp->index, jiffies_to_msecs(jiffies),
@@ -636,6 +640,8 @@ void vdin_start_dec(struct vdin_dev_s *devp)
*/
void vdin_stop_dec(struct vdin_dev_s *devp)
{
int afbc_write_down_test_times = 7;
/* avoid null pointer oops */
if (!devp || !devp->frontend)
return;
@@ -646,7 +652,15 @@ void vdin_stop_dec(struct vdin_dev_s *devp)
}
#endif
disable_irq_nosync(devp->irq);
vdin_hw_disable(devp->addr_offset);
afbc_init_flag = 0;
while (++afbc_write_down_flag < afbc_write_down_test_times) {
if (vdin_afbce_read_writedown_flag() == 0)
usleep_range(5000, 5001);
else
break;
}
if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) &&
devp->frontend->dec_ops &&
devp->frontend->dec_ops->stop &&
@@ -654,6 +668,8 @@ void vdin_stop_dec(struct vdin_dev_s *devp)
((devp->flags & VDIN_FLAG_SNOW_FLAG) == 0)))
devp->frontend->dec_ops->stop(devp->frontend, devp->parm.port);
vdin_hw_disable(devp->addr_offset);
vdin_set_default_regmap(devp->addr_offset);
/*only for vdin0*/
if (devp->urgent_en && (devp->index == 0))
@@ -670,6 +686,10 @@ void vdin_stop_dec(struct vdin_dev_s *devp)
#endif
vf_unreg_provider(&devp->vprov);
devp->dv.dv_config = 0;
if (is_meson_tl1_cpu() && (devp->afbce_mode == 1))
vdin_afbce_hw_disable();
#ifdef CONFIG_CMA
if (devp->afbce_mode == 1)
vdin_afbce_cma_release(devp);
@@ -678,7 +698,6 @@ void vdin_stop_dec(struct vdin_dev_s *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));
@@ -1192,6 +1211,8 @@ static u64 func_div(u64 cur, u32 divid)
return cur;
}
/*
*VDIN_FLAG_RDMA_ENABLE=1
* provider_vf_put(devp->last_wr_vfe, devp->vfp);
@@ -1242,6 +1263,19 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
offset = devp->addr_offset;
if (afbc_init_flag == 0) {
afbc_init_flag = 1;
/*set mem power on*/
if (is_meson_tl1_cpu() && (devp->afbce_mode == 1)) {
vdin_afbce_hw_enable(devp);
return IRQ_HANDLED;
}
} else if (afbc_init_flag == 1) {
afbc_init_flag = 2;
if (is_meson_tl1_cpu() && (devp->afbce_mode == 1))
return IRQ_HANDLED;
}
isr_log(devp->vfp);
devp->irq_cnt++;
/* debug interrupt interval time
@@ -1865,6 +1899,9 @@ static int vdin_open(struct inode *inode, struct file *file)
return 0;
}
if (is_meson_tl1_cpu() && (devp->afbce_mode == 1))
switch_vpu_mem_pd_vmod(VPU_AFBCE, VPU_MEM_POWER_ON);
devp->flags |= VDIN_FLAG_FS_OPENED;
/* request irq */
@@ -1910,6 +1947,9 @@ static int vdin_release(struct inode *inode, struct file *file)
return 0;
}
if (is_meson_tl1_cpu() && (devp->afbce_mode == 1))
switch_vpu_mem_pd_vmod(VPU_AFBCE, VPU_MEM_POWER_DOWN);
devp->flags &= (~VDIN_FLAG_FS_OPENED);
if (devp->flags & VDIN_FLAG_DEC_STARTED) {
devp->flags |= VDIN_FLAG_DEC_STOP_ISR;