mvc/vc1: mvc/vc1 support in No-parser mode. [1/1]
authormiaohong chen <miaohong.chen@amlogic.com>
Thu, 3 Dec 2020 09:59:20 +0000 (17:59 +0800)
committerHui Zhang <hui.zhang@amlogic.com>
Fri, 11 Dec 2020 12:21:30 +0000 (04:21 -0800)
PD#SWPL-37951

Problem:
vc1/mvc does not support no-parser mode.

Solution:
Support no-parser mode in mvc/vc1

Verify:
AH212

Change-Id: I37b1705a7f840b9805b66f758da21967ceb03552
Signed-off-by: miaohong chen <miaohong.chen@amlogic.com>
drivers/frame_provider/decoder/h264/vh264_mvc.c
drivers/frame_provider/decoder/utils/vdec.c
drivers/frame_provider/decoder/utils/vdec.h
drivers/frame_provider/decoder/vc1/vvc1.c
drivers/stream_input/amports/amstream.c
drivers/stream_input/amports/stream_buffer_interface.c

index 821b3c11061d3af569da30cdcad0fd65cfa29316..7dff6f4783678db813e2c14c1173b41406d0218a 100644 (file)
@@ -104,6 +104,7 @@ static const struct vframe_operations_s vh264mvc_vf_provider = {
 
 static struct vframe_provider_s vh264mvc_vf_prov;
 
+static struct vdec_s *vdec = NULL;
 static u32 frame_width, frame_height, frame_dur;
 static u32 saved_resolution;
 static struct timer_list recycle_timer;
@@ -900,6 +901,11 @@ static void vh264mvc_isr(void)
        u64 pts_us64;
        u32 frame_size;
        int ret = READ_VREG(MAILBOX_COMMAND);
+
+       if (is_support_no_parser()) {
+               STBUF_WRITE(&vdec->vbuf, set_rp,
+                       READ_VREG(VLD_MEM_VIFIFO_RP));
+       }
        /* pr_info("vh264mvc_isr, cmd =%x\n", ret); */
        switch (ret & 0xff) {
        case CMD_ALLOC_VIEW_0:
@@ -1640,6 +1646,8 @@ static int amvdec_h264mvc_probe(struct platform_device *pdev)
        INIT_WORK(&error_wd_work, error_do_work);
        INIT_WORK(&set_clk_work, vh264_mvc_set_clk);
 
+       vdec = pdata;
+
        atomic_set(&vh264mvc_active, 1);
 
        mutex_unlock(&vh264_mvc_mutex);
index 72cfe0d158db6f667921cdd2b33ec5d58e14dffb..9646f7da4baf7b00b5221a19d01922892127311a 100644 (file)
@@ -5656,6 +5656,53 @@ u32  vdec_get_frame_vdec(struct vdec_s *vdec,  struct vframe_counter_s *tmpbuf)
 }
 EXPORT_SYMBOL(vdec_get_frame_vdec);
 
+void vdec_set_vld_wp(struct vdec_s *vdec, u32 wp)
+{
+       if (vdec_single(vdec)) {
+               WRITE_VREG(VLD_MEM_VIFIFO_WP, wp);
+       }
+}
+EXPORT_SYMBOL(vdec_set_vld_wp);
+
+void vdec_config_vld_reg(struct vdec_s *vdec, u32 addr, u32 size)
+{
+       if (vdec_single(vdec)) {
+               WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0);
+               /* reset VLD before setting all pointers */
+               WRITE_VREG(VLD_MEM_VIFIFO_WRAP_COUNT, 0);
+               /*TODO: only > m6*/
+               WRITE_VREG(DOS_SW_RESET0, (1 << 4));
+               WRITE_VREG(DOS_SW_RESET0, 0);
+
+
+               WRITE_VREG(POWER_CTL_VLD, 1 << 4);
+
+               WRITE_VREG(VLD_MEM_VIFIFO_START_PTR,
+                      addr);
+               WRITE_VREG(VLD_MEM_VIFIFO_END_PTR,
+                      addr + size - 8);
+               WRITE_VREG(VLD_MEM_VIFIFO_CURR_PTR,
+                      addr);
+
+               WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 1);
+               WRITE_VREG(VLD_MEM_VIFIFO_CONTROL, 0);
+
+               /* set to manual mode */
+               WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 2);
+               WRITE_VREG(VLD_MEM_VIFIFO_WP, addr);
+
+               WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 3);
+               WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, 2);
+
+               /* enable */
+               WRITE_VREG(VLD_MEM_VIFIFO_CONTROL,
+                       (0x11 << 16) | (1<<10) | (1 << 1) | (1 << 2));
+               SET_VREG_MASK(VLD_MEM_VIFIFO_CONTROL,
+                       7 << 3);
+       }
+}
+EXPORT_SYMBOL(vdec_config_vld_reg);
+
 RESERVEDMEM_OF_DECLARE(vdec, "amlogic, vdec-memory", vdec_mem_setup);
 /*
 uint force_hevc_clock_cntl;
index 63b786c42180c8b92c0ea47d0407642411096ced..c02faf849d413875d62a00b230073d41551a4f00 100644 (file)
@@ -488,5 +488,7 @@ int vdec_resource_checking(struct vdec_s *vdec);
 void vdec_set_profile_level(struct vdec_s *vdec, u32 profile_idc, u32 level_idc);
 
 extern void vdec_stream_skip_data(struct vdec_s *vdec, int skip_size);
+void vdec_set_vld_wp(struct vdec_s *vdec, u32 wp);
+void vdec_config_vld_reg(struct vdec_s *vdec, u32 addr, u32 size);
 
 #endif                         /* VDEC_H */
index 2921218a853e2392aaffd884b143d4d0494f5b69..681de1340ccbf40e22dd50bfe0e30d3efe102274 100644 (file)
@@ -291,6 +291,11 @@ static irqreturn_t vvc1_isr(int irq, void *dev_id)
                v_width = READ_VREG(AV_SCRATCH_J);
                v_height = READ_VREG(AV_SCRATCH_K);
 
+               if (is_support_no_parser()) {
+                       STBUF_WRITE(&vdec->vbuf, set_rp,
+                               READ_VREG(VLD_MEM_VIFIFO_RP));
+               }
+
                if (v_width && v_width <= 4096
                        && (v_width != vvc1_amstream_dec_info.width)) {
                        pr_info("frame width changed %d to %d\n",
index 63b085044ce9cc7e06fd0e5f6518ecb281b54fab..d48a24a5946633699501bfb9ba1d4e98fb7d75b8 100644 (file)
@@ -983,6 +983,9 @@ static int amstream_port_init(struct port_priv_s *priv)
                                /* def used stbuf with parser if the feature disable. */
                                if (!is_support_no_parser())
                                        ops = get_esparser_stbuf_ops();
+                               else if (vdec->format == VFORMAT_H264MVC ||
+                                       vdec->format == VFORMAT_VC1)
+                                       ops = get_stbuf_ops();
                        }
 
                        r = stream_buffer_base_init(&vdec->vbuf, ops, &pars);
index 6e0988d873cbe688e73976c03091ef73bbf665cb..f5827c671e01647726ca089598611e602321d456 100644 (file)
@@ -97,6 +97,8 @@ static int stream_buffer_init(struct stream_buf_s *stbuf, struct vdec_s *vdec)
                }
                stbuf->use_ptsserv = 1;
        }
+       vdec_config_vld_reg(vdec, addr, size);
+
        ret = vdec_set_input_buffer(vdec, addr, size);
        if (ret) {
                pr_err("[%d]: set input buffer err.\n", stbuf->id);
@@ -284,6 +286,8 @@ static void stream_buffer_set_wp(struct stream_buf_s *stbuf, u32 val)
                ((stbuf->buf_start + stbuf->buf_size) - stbuf->buf_wp);
 
        stbuf->buf_wp = val;
+       vdec_set_vld_wp(container_of(stbuf, struct vdec_s, vbuf), stbuf->buf_wp);
+
        atomic_add(len, &stbuf->payload);
 }