vdin: support dynamic dest_cfmt changing [1/1]

PD#TV-4306

Problem:
vdin afbc will show green screen when hdmirx change dest_cfmt after stable

Solution:
dynamic config vdin afbc with cfmt

Verify:
x301

Change-Id: I404c47934f090222a2cdd7cf98b619826cd92cc7
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
Evoke Zhang
2019-04-15 19:30:10 +08:00
committed by Jianxin Pan
parent 81c1e1449c
commit fbb84a750f
4 changed files with 90 additions and 2 deletions

View File

@@ -116,6 +116,15 @@ static inline uint32_t R_APB_BIT(uint32_t reg,
return val;
}
static inline void W_VCBUS(uint32_t reg, const uint32_t value)
{
aml_write_vcbus(reg, value);
}
static inline uint32_t R_VCBUS(uint32_t reg)
{
return aml_read_vcbus(reg);
}
static inline void W_VCBUS_BIT(uint32_t reg,
const uint32_t value,

View File

@@ -409,10 +409,76 @@ static void afbce_wr(uint32_t reg, const uint32_t val)
wr(0, reg, val);
}
*/
#define VDIN_AFBCE_HOLD_LINE_NUM 4
void vdin_afbce_update(struct vdin_dev_s *devp)
{
int hold_line_num = VDIN_AFBCE_HOLD_LINE_NUM;
int reg_format_mode;/* 0:444 1:422 2:420 */
int reg_fmt444_comb;
int sblk_num;
int uncmp_bits;
int uncmp_size;
if (devp->index != 0) {
pr_info("cat not use afbce on vdin1 at the moment\n");
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
if ((devp->prop.dest_cfmt == TVIN_YUV444) && (devp->h_active > 2048))
reg_fmt444_comb = 1;
else
reg_fmt444_comb = 0;
if ((devp->prop.dest_cfmt == TVIN_NV12) ||
(devp->prop.dest_cfmt == TVIN_NV21)) {
reg_format_mode = 2;
sblk_num = 12;
} else if ((devp->prop.dest_cfmt == TVIN_YUV422) ||
(devp->prop.dest_cfmt == TVIN_YUYV422) ||
(devp->prop.dest_cfmt == TVIN_YVYU422) ||
(devp->prop.dest_cfmt == TVIN_UYVY422) ||
(devp->prop.dest_cfmt == TVIN_VYUY422)) {
reg_format_mode = 1;
sblk_num = 16;
} else {
reg_format_mode = 0;
sblk_num = 24;
}
uncmp_bits = devp->source_bitdepth;
/* bit size of uncompression mode */
uncmp_size = (((((16*uncmp_bits*sblk_num)+7)>>3)+31)/32)<<1;
/*
*pr_info("%s: dest_cfmt=%d, reg_format_mode=%d, uncmp_bits=%d,
* sblk_num=%d, uncmp_size=%d\n",
* __func__, devp->prop.dest_cfmt, reg_format_mode,
* uncmp_bits, sblk_num, uncmp_size);
*/
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));
rdma_write_reg_bits(devp->rdma_handle,
AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);/* uncmp_size */
rdma_write_reg(devp->rdma_handle, AFBCE_FORMAT,
(reg_format_mode & 0x3) << 8 |
(uncmp_bits & 0xf) << 4 |
(uncmp_bits & 0xf));
}
void vdin_afbce_config(struct vdin_dev_s *devp)
{
unsigned int offset = devp->addr_offset;
int hold_line_num = 4;
int hold_line_num = VDIN_AFBCE_HOLD_LINE_NUM;
int lbuf_depth = 256;
int lossy_luma_en = 0;
int lossy_chrm_en = 0;

View File

@@ -304,6 +304,7 @@ extern void vdin_write_mif_or_afbce(struct vdin_dev_s *devp,
enum vdin_output_mif_e sel);
extern unsigned int vdin_afbce_cma_alloc(struct vdin_dev_s *devp);
extern void vdin_afbce_cma_release(struct vdin_dev_s *devp);
extern void vdin_afbce_update(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,

View File

@@ -1670,8 +1670,13 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
pre_prop = &devp->pre_prop;
if ((prop->color_format != pre_prop->color_format) ||
(prop->vdin_hdr_Flag != pre_prop->vdin_hdr_Flag) ||
(prop->color_fmt_range != pre_prop->color_fmt_range))
(prop->color_fmt_range != pre_prop->color_fmt_range)) {
vdin_set_matrix(devp);
if (skip_frame_debug) {
pr_info("vdin.%d color_format changed\n",
devp->index);
}
}
if (prop->dest_cfmt != pre_prop->dest_cfmt) {
vdin_set_bitdepth(devp);
vdin_source_bitdepth_reinit(devp);
@@ -1682,6 +1687,13 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
vdin_set_top(devp->addr_offset, devp->parm.port,
devp->prop.color_format, devp->h_active,
devp->bt_path);
if (devp->afbce_mode)
vdin_afbce_update(devp);
if (skip_frame_debug) {
pr_info("vdin.%d dest_cfmt changed: %d->%d\n",
devp->index,
pre_prop->dest_cfmt, prop->dest_cfmt);
}
}
pre_prop->color_format = prop->color_format;
pre_prop->vdin_hdr_Flag = prop->vdin_hdr_Flag;