vdin: support dynamic dest_cfmt changing [1/1]
authorEvoke Zhang <evoke.zhang@amlogic.com>
Mon, 15 Apr 2019 11:30:10 +0000 (19:30 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Tue, 16 Apr 2019 12:11:29 +0000 (05:11 -0700)
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>
drivers/amlogic/media/vin/tvin/tvin_global.h
drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c
drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h
drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c

index f321fbb..78f4b40 100644 (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,
index 5ed4ab9..14dd11f 100644 (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;
index b2a6882..08ad76f 100644 (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,
index 90227f1..a3d97b4 100644 (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;