diff --git a/drivers/amlogic/media/vin/tvin/tvin_global.h b/drivers/amlogic/media/vin/tvin/tvin_global.h index f321fbbac6c2..78f4b4029f1a 100644 --- a/drivers/amlogic/media/vin/tvin/tvin_global.h +++ b/drivers/amlogic/media/vin/tvin/tvin_global.h @@ -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, diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c index 5ed4ab99a390..14dd11f39557 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c @@ -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; diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h index b2a6882eea2f..08ad76fcf68c 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h @@ -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, diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c index 90227f178418..a3d97b41c2dc 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c @@ -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;