media: merged code from 43177e6a on the amlogic-3.14-dev
authorNanxin Qin <nanxin.qin@amlogic.com>
Mon, 19 Jun 2017 07:34:01 +0000 (15:34 +0800)
committerNanxin Qin <nanxin.qin@amlogic.com>
Mon, 21 Aug 2017 12:30:19 +0000 (20:30 +0800)
PD#146152: merged code from 43177e6a on the amlogic-3.14-dev

1. support for multi-instance features
2. fixed in multi-instance codec_mm memory bugs and added some
debugging information
3. optimization of vfm problems

Change-Id: I43ba9d4894ae71d53c158df667490030735b9e1e
Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
Signed-off-by: KeLe Bai <kele.bai@amlogic.com>
78 files changed:
MAINTAINERS
arch/arm64/configs/meson64_defconfig
drivers/amlogic/media/Kconfig
drivers/amlogic/media/Makefile
drivers/amlogic/media/common/arch/registers/register_map.c
drivers/amlogic/media/common/arch/registers/register_ops.c
drivers/amlogic/media/common/arch/registers/register_ops_m8.c
drivers/amlogic/media/common/canvas/canvas.c
drivers/amlogic/media/common/canvas/canvas_mgr.c
drivers/amlogic/media/common/codec_mm/Makefile
drivers/amlogic/media/common/codec_mm/codec_mm.c
drivers/amlogic/media/common/codec_mm/codec_mm_priv.h
drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c
drivers/amlogic/media/common/codec_mm/codec_mm_scatter_priv.h
drivers/amlogic/media/common/codec_mm/configs/Makefile [new file with mode: 0644]
drivers/amlogic/media/common/codec_mm/configs/configs.c [new file with mode: 0644]
drivers/amlogic/media/common/codec_mm/configs/configs_module.c [new file with mode: 0644]
drivers/amlogic/media/common/codec_mm/configs/configs_priv.h [new file with mode: 0644]
drivers/amlogic/media/common/codec_mm/configs/configs_test.c [new file with mode: 0644]
drivers/amlogic/media/common/ge2d/ge2d_hw.c
drivers/amlogic/media/common/rdma/Makefile
drivers/amlogic/media/common/rdma/rdma.c
drivers/amlogic/media/common/rdma/rdma_mgr.c
drivers/amlogic/media/common/vfm/vfm.c
drivers/amlogic/media/common/vfm/vfm.h
drivers/amlogic/media/common/vfm/vframe_provider.c
drivers/amlogic/media/common/vfm/vframe_receiver.c
drivers/amlogic/media/common/vfm/vftrace.c
drivers/amlogic/media/deinterlace/deinterlace.c
drivers/amlogic/media/deinterlace/deinterlace.h
drivers/amlogic/media/frame_sync/ptsserv.c
drivers/amlogic/media/frame_sync/timestamp.c
drivers/amlogic/media/frame_sync/tsync.c
drivers/amlogic/media/frame_sync/tsync_pcr.c
drivers/amlogic/media/video_processor/ionvideo/ionvideo.c
drivers/amlogic/media/video_processor/video_dev/amlvideo.c
drivers/amlogic/media/video_processor/video_dev/amlvideo.h
drivers/amlogic/media/video_processor/video_dev/amlvideo2.c
drivers/amlogic/media/video_sink/Kconfig
drivers/amlogic/media/video_sink/amvideocap_priv.h [new file with mode: 0644]
drivers/amlogic/media/video_sink/video.c
drivers/amlogic/media/video_sink/video_keeper.c
drivers/amlogic/media/video_sink/video_priv.h
drivers/amlogic/media/video_sink/vpp.c
drivers/amlogic/wifi/wifi_dt.c
include/linux/amlogic/cpu_version.h
include/linux/amlogic/major.h
include/linux/amlogic/media/canvas/canvas.h
include/linux/amlogic/media/canvas/canvas_mgr.h
include/linux/amlogic/media/codec_mm/codec_mm.h
include/linux/amlogic/media/codec_mm/codec_mm_scatter.h
include/linux/amlogic/media/codec_mm/configs.h [new file with mode: 0644]
include/linux/amlogic/media/codec_mm/configs_api.h [new file with mode: 0644]
include/linux/amlogic/media/frame_sync/ptsserv.h
include/linux/amlogic/media/frame_sync/tsync.h
include/linux/amlogic/media/registers/register_map.h
include/linux/amlogic/media/registers/register_ops.h
include/linux/amlogic/media/registers/regs/aiu_regs.h
include/linux/amlogic/media/registers/regs/demux_regs.h
include/linux/amlogic/media/registers/regs/dos_regs.h
include/linux/amlogic/media/registers/regs/hevc_regs.h
include/linux/amlogic/media/registers/regs/parser_regs.h
include/linux/amlogic/media/registers/regs/sys_regs.h
include/linux/amlogic/media/registers/regs/vdin_regs.h
include/linux/amlogic/media/registers/regs/viu_regs.h
include/linux/amlogic/media/registers/regs/vpp_regs.h
include/linux/amlogic/media/tvin/tvin.h [new file with mode: 0644]
include/linux/amlogic/media/tvin/tvin_v4l2.h [new file with mode: 0644]
include/linux/amlogic/media/utils/aformat.h
include/linux/amlogic/media/utils/amports_config.h
include/linux/amlogic/media/utils/amstream.h
include/linux/amlogic/media/utils/vdec_reg.h
include/linux/amlogic/media/vfm/vframe.h
include/linux/amlogic/media/vfm/vframe_provider.h
include/linux/amlogic/media/video_sink/amvideocap.h [new file with mode: 0644]
include/linux/amlogic/media/video_sink/ionvideo_ext.h
include/linux/amlogic/media/video_sink/video.h
include/linux/amlogic/media/video_sink/vpp.h

index e257c81..ced5dc8 100644 (file)
@@ -14047,3 +14047,8 @@ F: drivers/amlogic/media/vout/backlight/bl_extern/pmu_aml1218.c
 AMLOGIC MESONGXL ADD A113X 128m DTS
 M:     Yuegui He <yuegui.he@amlogic.com>
 F:     arch/arm64/boot/dts/amlogic/axg_s420_128m.dts
+
+AMLOGIC multimedia
+M:  Nanxin Qin <nanxin.qin@amlogic.com>
+F: drivers/amlogic/media/common/codec_mm/configs/*
+
index 3e5caa7..4357d9c 100644 (file)
@@ -221,15 +221,18 @@ CONFIG_AMLOGIC_PWM=y
 CONFIG_AMLOGIC_MEDIA_ENABLE=y
 CONFIG_AMLOGIC_MEDIA_COMMON=y
 CONFIG_AMLOGIC_MEDIA_DRIVERS=y
+CONFIG_AMLOGIC_MEDIA_MULTI_DEC=y
 CONFIG_AMLOGIC_MEDIA_CODEC_MM=y
 CONFIG_AMLOGIC_MEDIA_CANVAS=y
 CONFIG_AMLOGIC_MEDIA_GE2D=y
 CONFIG_AMLOGIC_ION=y
 CONFIG_AMLOGIC_MEDIA_RDMA=y
+CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA=y
 CONFIG_AMLOGIC_MEDIA_VFM=y
 CONFIG_AMLOGIC_VPU=y
 CONFIG_AMLOGIC_VIDEOBUF_RESOURCE=y
 CONFIG_AMLOGIC_MEDIA_VIDEO=y
+CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE=y
 CONFIG_AMLOGIC_VOUT=y
 CONFIG_AMLOGIC_CVBS_OUTPUT=y
 CONFIG_AMLOGIC_WSS=y
index e04b50f..009b3bb 100644 (file)
@@ -35,6 +35,10 @@ config AMLOGIC_MEDIA_DRIVERS
                module, video decoder management module and post
                processing of the frame.
 
+config AMLOGIC_MEDIA_MULTI_DEC
+       bool "Support multi-instance decoding"
+       default n
+
 if AMLOGIC_MEDIA_COMMON
 source "drivers/amlogic/media/common/Kconfig"
 endif
index e1ef9d6..d33bc71 100644 (file)
@@ -7,4 +7,4 @@ obj-$(CONFIG_AMLOGIC_MEDIA_FB_EXT)      +=      osd_ext/
 obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE)        +=      deinterlace/
 obj-$(CONFIG_AMLOGIC_MEDIA_VIN)                +=      vin/
 obj-$(CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR)    +=      video_processor/
-obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT) += enhancement/
\ No newline at end of file
+obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT) += enhancement/
index ad62a0b..87f98cf 100644 (file)
@@ -223,6 +223,94 @@ void codecio_write_dmcbus(unsigned int reg, unsigned int val)
                return;
 }
 
+int codecio_read_parsbus(unsigned int reg)
+{
+       int ret, val;
+
+       ret = codecio_reg_read(CODECIO_CBUS_BASE, reg << 2, &val);
+       if (ret) {
+               pr_err("read parser reg %x error %d\n", reg, ret);
+               return -1;
+       }
+
+       return val;
+}
+
+void codecio_write_parsbus(unsigned int reg, unsigned int val)
+{
+       int ret;
+
+       ret = codecio_reg_write(CODECIO_CBUS_BASE, reg << 2, val);
+       if (ret)
+               pr_err("write parser reg %x error %d\n", reg, ret);
+}
+
+int codecio_read_aiubus(unsigned int reg)
+{
+       int ret, val;
+
+       ret = codecio_reg_read(CODECIO_CBUS_BASE, reg << 2, &val);
+       if (ret) {
+               pr_err("read aiu reg %x error %d\n", reg, ret);
+               return -1;
+       }
+
+       return val;
+}
+
+void codecio_write_aiubus(unsigned int reg, unsigned int val)
+{
+       int ret;
+
+       ret = codecio_reg_write(CODECIO_CBUS_BASE, reg << 2, val);
+       if (ret)
+               pr_err("write aiu reg %x error %d\n", reg, ret);
+}
+
+int codecio_read_demuxbus(unsigned int reg)
+{
+       int ret, val;
+
+       ret = codecio_reg_read(CODECIO_CBUS_BASE, reg << 2, &val);
+       if (ret) {
+               pr_err("read demux reg %x error %d\n", reg, ret);
+               return -1;
+       }
+
+       return val;
+}
+
+void codecio_write_demuxbus(unsigned int reg, unsigned int val)
+{
+       int ret;
+
+       ret = codecio_reg_write(CODECIO_CBUS_BASE, reg << 2, val);
+       if (ret)
+               pr_err("write demux reg %x error %d\n", reg, ret);
+}
+
+int codecio_read_resetbus(unsigned int reg)
+{
+       int ret, val;
+
+       ret = codecio_reg_read(CODECIO_CBUS_BASE, reg << 2, &val);
+       if (ret) {
+               pr_err("read reset reg %x error %d\n", reg, ret);
+               return -1;
+       }
+
+       return val;
+}
+
+void codecio_write_resetbus(unsigned int reg, unsigned int val)
+{
+       int ret;
+
+       ret = codecio_reg_write(CODECIO_CBUS_BASE, reg << 2, val);
+       if (ret)
+               pr_err("write reset reg %x error %d\n", reg, ret);
+}
+
 static int codec_io_probe(struct platform_device *pdev)
 {
        int i = 0;
index 2768d77..3711d44 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
-#include <linux/amlogic/media/old_cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
 #include <linux/amlogic/media/utils/log.h>
 
 #include <linux/amlogic/media/registers/register_ops.h>
index c643b2a..5ec36c7 100644 (file)
@@ -27,6 +27,7 @@
        MESON_CPU_MAJOR_ID_GXL, \
        MESON_CPU_MAJOR_ID_GXM, \
        MESON_CPU_MAJOR_ID_TXL, \
+       MESON_CPU_MAJOR_ID_TXLX, \
                        0}
 #define REGISTER_FOR_GXCPU {\
        MESON_CPU_MAJOR_ID_GXBB, \
@@ -34,6 +35,7 @@
        MESON_CPU_MAJOR_ID_GXL, \
        MESON_CPU_MAJOR_ID_GXM, \
        MESON_CPU_MAJOR_ID_TXL, \
+       MESON_CPU_MAJOR_ID_TXLX, \
                        0}
 int codec_apb_read(unsigned int reg)
 {
@@ -57,6 +59,10 @@ static struct chip_register_ops m8_ops[] __initdata = {
        {IO_HHI_BUS, 0, codecio_read_cbus, codecio_write_cbus},
        {IO_AO_BUS, 0, codecio_read_aobus, codecio_write_aobus},
        {IO_VPP_BUS, 0, codecio_read_vcbus, codecio_write_vcbus},
+       {IO_PARSER_BUS, 0, codecio_read_parsbus, codecio_write_parsbus},
+       {IO_AIU_BUS, 0, codecio_read_aiubus, codecio_write_aiubus},
+       {IO_DEMUX_BUS, 0, codecio_read_demuxbus, codecio_write_demuxbus},
+       {IO_RESET_BUS, 0, codecio_read_resetbus, codecio_write_resetbus},
 };
 
 static struct chip_register_ops ex_gx_ops[] __initdata = {
@@ -75,6 +81,48 @@ static int __init vdec_reg_ops_init(void)
 {
        int cpus[] = REGISTER_FOR_CPU;
        int gxcpus[] = REGISTER_FOR_GXCPU;
+       int  i = 0;
+
+       /*
+        * because of register range of the parser ,demux
+        * reset and aiu has be changed in the txlx platform,
+        * so we have must be offset the old range of regs.
+        *
+        * the new 0x3860 of the reg base minus the old 0x2900
+        * equal to the 0xf00 of the delta value
+        * #define PARSER_CONTROL 0x3860
+        * 0xf00 == (0x3800 - 0x2900)
+        *
+        * #define AIU_958_BPF 0x1400
+        * -0x100 == (0x1400 - 0x1500)
+        *
+        * #define FEC_INPUT_CONTROL 0x1802
+        * 0x200 == (0x1802 - 0x1602)
+        *
+        * #define RESET0_REGISTER 0x0401
+        * -0xd00 == (0x0401 - 0x1101)
+        */
+       if (get_cpu_type() > MESON_CPU_MAJOR_ID_TXL) {
+               for (i = 0; i < ARRAY_SIZE(m8_ops); i++) {
+                       switch (m8_ops[i].bus_type) {
+                       case IO_PARSER_BUS:
+                               m8_ops[i].ext_offset = 0xf00;
+                               break;
+
+                       case IO_AIU_BUS:
+                               m8_ops[i].ext_offset = -0x100;
+                               break;
+
+                       case IO_DEMUX_BUS:
+                               m8_ops[i].ext_offset = 0x200;
+                               break;
+
+                       case IO_RESET_BUS:
+                               m8_ops[i].ext_offset = -0xd00;
+                               break;
+                       }
+               }
+       }
 
        register_reg_ops_mgr(cpus, m8_ops,
                sizeof(m8_ops) / sizeof(struct chip_register_ops));
index 6781193..d81a7fd 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/spinlock.h>
 #include <linux/major.h>
 #include <linux/io.h>
+#include <linux/amlogic/cpu_version.h>
 #include <linux/amlogic/media/old_cpu_version.h>
 #include <linux/kernel.h>
 
@@ -158,8 +159,11 @@ static void canvas_config_locked(u32 index, struct canvas_s *p)
        u32 reg_add = 0;
 
        canvas_lut_data_build(p->addr,
-               p->width,
-               p->height, p->wrap, p->blkmode, p->endian, &datal, &datah);
+                       p->width,
+                       p->height,
+                       p->wrap,
+                       p->blkmode,
+                       p->endian, &datal, &datah);
 
        if ((get_cpu_type() == MESON_CPU_MAJOR_ID_M8M2) ||
                (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB))
@@ -202,29 +206,25 @@ int canvas_read_hw(u32 index, struct canvas_s *canvas)
 }
 EXPORT_SYMBOL(canvas_read_hw);
 
-static inline void canvas_lock(void)
-{
-       struct canvas_device_info *info = &canvas_info;
+#define canvas_lock(info, f, f2) do {\
+               spin_lock_irqsave(&info->lock, f);\
+               raw_local_save_flags(f2);\
+               local_fiq_disable();\
+       } while (0)
 
-       raw_local_save_flags(info->fiq_flag);
-       local_fiq_disable();
-       spin_lock_irqsave(&info->lock, info->flags);
-}
+#define canvas_unlock(info, f, f2) do {\
+               raw_local_irq_restore(f2);\
+               spin_unlock_irqrestore(&info->lock, f);\
+       } while (0)
 
-static inline void canvas_unlock(void)
-{
-       struct canvas_device_info *info = &canvas_info;
 
-       spin_unlock_irqrestore(&info->lock, info->flags);
-       raw_local_irq_restore(info->fiq_flag);
-}
 
 void canvas_config_ex(u32 index, ulong addr, u32 width, u32 height, u32 wrap,
        u32 blkmode, u32 endian)
 {
        struct canvas_device_info *info = &canvas_info;
        struct canvas_s *canvas;
-
+       unsigned long flags, fiqflags;
        if (!CANVAS_VALID(index))
                return;
 
@@ -233,7 +233,7 @@ void canvas_config_ex(u32 index, ulong addr, u32 width, u32 height, u32 wrap,
                dump_stack();
                return;
        }
-       canvas_lock();
+       canvas_lock(info, flags, fiqflags);
        canvas = &info->canvasPool[index];
        canvas->addr = addr;
        canvas->width = width;
@@ -242,7 +242,7 @@ void canvas_config_ex(u32 index, ulong addr, u32 width, u32 height, u32 wrap,
        canvas->blkmode = blkmode;
        canvas->endian = endian;
        canvas_config_locked(index, canvas);
-       canvas_unlock();
+       canvas_unlock(info, flags, fiqflags);
 }
 EXPORT_SYMBOL(canvas_config_ex);
 
@@ -275,6 +275,7 @@ void canvas_copy(u32 src, u32 dst)
        struct canvas_device_info *info = &canvas_info;
        struct canvas_s *canvas_src = &info->canvasPool[src];
        struct canvas_s *canvas_dst = &info->canvasPool[dst];
+       unsigned long flags, fiqflags;
 
        if (!CANVAS_VALID(src) || !CANVAS_VALID(dst))
                return;
@@ -287,7 +288,7 @@ void canvas_copy(u32 src, u32 dst)
                return;
        }
 
-       canvas_lock();
+       canvas_lock(info, flags, fiqflags);
        canvas_dst->addr = canvas_src->addr;
        canvas_dst->width = canvas_src->width;
        canvas_dst->height = canvas_src->height;
@@ -297,7 +298,7 @@ void canvas_copy(u32 src, u32 dst)
        canvas_dst->dataH = canvas_src->dataH;
        canvas_dst->dataL = canvas_src->dataL;
        canvas_config_locked(dst, canvas_dst);
-       canvas_unlock();
+       canvas_unlock(info, flags, fiqflags);
 }
 EXPORT_SYMBOL(canvas_copy);
 
@@ -305,6 +306,7 @@ void canvas_update_addr(u32 index, u32 addr)
 {
        struct canvas_device_info *info = &canvas_info;
        struct canvas_s *canvas;
+       unsigned long flags, fiqflags;
 
        if (!CANVAS_VALID(index))
                return;
@@ -315,11 +317,12 @@ void canvas_update_addr(u32 index, u32 addr)
                dump_stack();
                return;
        }
-       canvas_lock();
+       canvas_lock(info, flags, fiqflags);
        canvas->addr = addr;
        canvas_config_locked(index, canvas);
-       canvas_unlock();
+       canvas_unlock(info, flags, fiqflags);
 
+       return;
 }
 EXPORT_SYMBOL(canvas_update_addr);
 
@@ -495,7 +498,8 @@ static int canvas_probe(struct platform_device *pdev)
        }
        info->res = *res;
        size = (int)resource_size(res);
-       pr_info("canvas_probe reg=%p,size=%x\n", (void *)res->start, size);
+       pr_info("canvas_probe reg=%p,size=%x\n",
+                       (void *)res->start, size);
        if (!devm_request_mem_region(&pdev->dev,
                res->start, size, pdev->name)) {
                dev_err(&pdev->dev, "Memory region busy\n");
@@ -514,7 +518,8 @@ static int canvas_probe(struct platform_device *pdev)
        for (i = 0; i < info->max_canvas_num; i++) {
                info->canvasPool[i].index = i;
                r = kobject_init_and_add(&info->canvasPool[i].kobj,
-                       &canvas_attr_type, &pdev->dev.kobj, "%d", i);
+                               &canvas_attr_type,
+                               &pdev->dev.kobj, "%d", i);
                if (r) {
                        pr_error("Unable to create canvas objects %d\n", i);
                        goto err2;
@@ -545,7 +550,8 @@ static int canvas_remove(struct platform_device *pdev)
        amcanvas_manager_exit();
        devm_iounmap(&pdev->dev, info->reg_base);
        devm_release_mem_region(&pdev->dev,
-               info->res.start, resource_size(&info->res));
+                               info->res.start,
+                               resource_size(&info->res));
        pr_error("Canvas driver removed.\n");
 
        return 0;
index cfe6837..d564e64 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/amlogic/media/canvas/canvas.h>
 #include <linux/amlogic/media/canvas/canvas_mgr.h>
+#include <linux/amlogic/cpu_version.h>
 #include <linux/amlogic/media/old_cpu_version.h>
 
 /*ignore canvas 0,
@@ -63,11 +64,13 @@ canvas_pool_map_alloc_canvas_in(struct canvas_pool *pool, const char *owner)
 
        do {
                i = find_next_zero_bit(pool->canvas_map,
-                       sizeof(pool->canvas_map), start_index);
+                       pool->canvas_max,
+                       start_index);
                if (!VALID_CANVAS(i)) {
                        if (!looped) {
                                start_index = 1;
                                looped = 1;
+                               continue;
                        } else
                                return -1;
                }
@@ -105,7 +108,8 @@ int canvas_pool_map_alloc_canvas(const char *owner)
  */
 static int
 canvas_pool_map_alloc_canvas_continue_set(struct canvas_pool *pool,
-       const char *owner, u32 *canvas, enum canvas_map_type_e type)
+                                         const char *owner, u32 *canvas,
+                                         enum canvas_map_type_e type)
 {
        int found_retry = 0;
        int found = 0;
@@ -395,11 +399,12 @@ canvas_pool_map_show(struct class *class,
                        test_bit(i, pool->canvas_map),
                        info.fixed_onwer, o1, o2, info.alloc_time);
                size += snprintf(buf + size, PAGE_SIZE - size,
-                       "\taddr=%08x,\ts=%d X %d,\trap=%d,\tmod=%d\n",
-                       (unsigned int)canvas.addr,
-                       (int)canvas.width,
-                       (int)canvas.height,
-                       (int)canvas.wrap, (int)canvas.blkmode);
+                               "\taddr=%08x,\ts=%d X %d,\trap=%d,\tmod=%d\n",
+                               (unsigned int)canvas.addr,
+                               (int)canvas.width,
+                               (int)canvas.height,
+                               (int)canvas.wrap,
+                               (int)canvas.blkmode);
        }
        pool->next_dump_index = i;
        if (pool->next_dump_index >= pool->canvas_max)
@@ -415,18 +420,23 @@ canvas_pool_states_show(struct class *class,
        ssize_t size = 0;
        int i;
        struct canvas_pool *pool = get_canvas_pool();
-
-       size += snprintf(buf + size, PAGE_SIZE - size, "canvas tatol num: %d\n",
-               pool->canvas_max);
-       size += snprintf(buf + size, PAGE_SIZE - size,
-               "canvas next_dump_index: %d\n", pool->next_dump_index);
-       size += snprintf(buf + size, PAGE_SIZE - size,
-               "canvas next_alloced_index: %d\n", pool->next_alloced_index);
+       size += snprintf(buf + size, PAGE_SIZE - size, "canvas total num: %d\n",
+                        pool->canvas_max);
+       size +=
+           snprintf(buf + size, PAGE_SIZE - size,
+                    "canvas next_dump_index: %d\n", pool->next_dump_index);
+       size +=
+           snprintf(buf + size, PAGE_SIZE - size,
+                    "canvas next_alloced_index: %d\n",
+                    pool->next_alloced_index);
        size += snprintf(buf + size, PAGE_SIZE - size, "canvas map:\n");
-       for (i = 0; i < sizeof(pool->canvas_map) / (8 * sizeof(u32)); i++)
-               size += snprintf(buf + size, PAGE_SIZE - size,
-                       "% 3d - % 3d : %08x\n", i * 32, (i + 1) * 32 - 1,
-                       (u32) pool->canvas_map[i]);
+       for (i = 0; i < CANVAS_MAX_NUM / BITS_PER_LONG; i++)
+               size +=
+                   snprintf(buf + size, PAGE_SIZE - size,
+                            "% 3d - % 3d : %0lx\n",
+                            i * BITS_PER_LONG,
+                            (i + 1) * BITS_PER_LONG - 1,
+                            (ulong) pool->canvas_map[i]);
        return size;
 }
 
@@ -439,14 +449,15 @@ canvas_pool_debug_show(struct class *class,
        size += snprintf(buf + size, PAGE_SIZE - size,
                "help: echo n > canvas_pool_debug\n");
        size += snprintf(buf + size, PAGE_SIZE - size, "1:next_dump_index=0\n");
-       size += snprintf(buf + size, PAGE_SIZE - size,
-               "2:next_alloced_index=0\n");
+       size +=
+           snprintf(buf + size, PAGE_SIZE - size, "2:next_alloced_index=0\n");
        return size;
 }
 
 static ssize_t
 canvas_pool_debug_store(struct class *class,
-       struct class_attribute *attr, const char *buf, size_t size)
+                       struct class_attribute *attr, const char *buf,
+                       size_t size)
 {
        unsigned int val;
        ssize_t ret = 0;
@@ -507,10 +518,13 @@ static void canvas_pool_config(void)
        canvas_pool_register_const_canvas(0x26, 0x39, "vdin");
        canvas_pool_register_const_canvas(0x78, 0xbf, "amvdec");
        canvas_pool_register_const_canvas(0x60, 0x65, "display");
+       canvas_pool_register_const_canvas(0x66, 0x6b, "display2");
        canvas_pool_register_const_canvas(0x70, 0x77, "ppmgr");
        canvas_pool_register_const_canvas(0xe4, 0xef, "encoder");
        canvas_pool_register_const_canvas(0x40, 0x48, "osd");
+#ifdef CONFIG_AMLOGIC_VIDEOIN_MANAGER
        canvas_pool_register_const_canvas(0x4e, 0x5f, "vm");
+#endif
        canvas_pool_register_const_canvas(0xc0, 0xd7, "amlvideo2");
        /*please add static canvas later. */
 }
index 0260ebf..5c3293e 100644 (file)
@@ -10,3 +10,4 @@
 obj-$(CONFIG_AMLOGIC_MEDIA_CODEC_MM)   +=      codec_mm.o
 obj-$(CONFIG_AMLOGIC_MEDIA_CODEC_MM)   +=      codec_mm_scatter.o
 obj-$(CONFIG_AMLOGIC_MEDIA_CODEC_MM)   +=      codec_mm_keeper.o
+obj-$(CONFIG_AMLOGIC_MEDIA_CODEC_MM)   +=      configs/
index 1690238..7307227 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <linux/amlogic/media/codec_mm/codec_mm.h>
 #include <linux/amlogic/media/codec_mm/codec_mm_scatter.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
 
 #include "codec_mm_priv.h"
 #include "codec_mm_scatter_priv.h"
 #define TVP_POOL_NAME "TVP_POOL"
 #define CMA_RES_POOL_NAME "CMA_RES"
 
+#define CONFIG_PATH "media.codec_mm"
+#define CONFIG_PREFIX "media"
+
+
+
 #define RES_IS_MAPED
+#define DEFAULT_TVP_SIZE_FOR_4K (256 * SZ_1M)
+#define DEFAULT_TVP_SIZE_FOR_NO4K (160 * SZ_1M)
 
 #define ALLOC_MAX_RETRY 1
 
@@ -90,16 +98,18 @@ u32 codec_mm_get_keep_debug_mode(void)
 }
 EXPORT_SYMBOL(codec_mm_get_keep_debug_mode);
 
+static int default_tvp_size;
+static int default_tvp_4k_size;
+static int default_cma_res_size;
+
 #define TVP_MAX_SLOT 8
 struct extpool_mgt_s {
        struct gen_pool *gen_pool[TVP_MAX_SLOT];
        struct codec_mm_s *mm[TVP_MAX_SLOT];
        int slot_num;
-       int default_size;
-       int default_4k_size;
        int alloced_size;
        int total_size;
-       spinlock_t lock;
+       struct mutex pool_lock;
 };
 
 struct codec_mm_mgt_s {
@@ -259,6 +269,7 @@ static int codec_mm_alloc_in(
        int try_cma_first = mem->flags & CODEC_MM_FLAGS_CMA_FIRST;
        int max_retry = ALLOC_MAX_RETRY;
        int have_space;
+       int alloc_trace_mask = 0;
 
        int can_from_res = ((mgt->res_pool != NULL) &&  /*have res */
                !(mem->flags & CODEC_MM_FLAGS_CMA)) ||  /*must not CMA */
@@ -302,9 +313,11 @@ static int codec_mm_alloc_in(
                if ((mem->flags & CODEC_MM_FLAGS_DMA_CPU) &&
                        mem->page_count <= mgt->alloc_from_sys_pages_max &&
                        align_2n <= PAGE_SHIFT) {
+                       alloc_trace_mask |= 1 << 0;
                        mem->mem_handle = (void *)__get_free_pages(GFP_KERNEL,
                                get_order(mem->buffer_size));
-                       mem->from_flags = AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES;
+                       mem->from_flags =
+                               AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES;
                        if (mem->mem_handle) {
                                mem->vbuffer = mem->mem_handle;
                                mem->phy_addr = virt_to_phys(mem->mem_handle);
@@ -317,6 +330,7 @@ static int codec_mm_alloc_in(
                        /*
                         *normal cma.
                         */
+                       alloc_trace_mask |= 1 << 1;
                        mem->mem_handle = dma_alloc_from_contiguous(mgt->dev,
                                        mem->page_count,
                                        align_2n - PAGE_SHIFT);
@@ -324,8 +338,7 @@ static int codec_mm_alloc_in(
                        if (mem->mem_handle) {
                                mem->vbuffer = mem->mem_handle;
                                mem->phy_addr =
-                                       page_to_phys((struct page *)
-                                       mem->mem_handle);
+                                page_to_phys((struct page *)mem->mem_handle);
 #ifdef CONFIG_ARM64
                                if (mem->flags & CODEC_MM_FLAGS_CMA_CLEAR) {
                                        /*dma_clear_buffer((struct page *)*/
@@ -335,13 +348,14 @@ static int codec_mm_alloc_in(
                                break;
                        }
                }
-               /*reserved alloc.. */
-               if (can_from_res && (align_2n <= RESERVE_MM_ALIGNED_2N)) {
+               /*reserved alloc..*/
+               if (can_from_res &&
+                       (align_2n <= RESERVE_MM_ALIGNED_2N)) {
                        int aligned_buffer_size = ALIGN(mem->buffer_size,
                                (1 << RESERVE_MM_ALIGNED_2N));
-                       mem->mem_handle =
-                               (void *)gen_pool_alloc(mgt->res_pool,
-                               aligned_buffer_size);
+                       alloc_trace_mask |= 1 << 2;
+                       mem->mem_handle = (void *)gen_pool_alloc(mgt->res_pool,
+                                                       aligned_buffer_size);
                        mem->from_flags =
                                AMPORTS_MEM_FLAGS_FROM_GET_FROM_REVERSED;
                        if (mem->mem_handle) {
@@ -364,7 +378,8 @@ static int codec_mm_alloc_in(
                                 */
                                int aligned_buffer_size =
                                        ALIGN(mem->buffer_size,
-                                       (1 << RESERVE_MM_ALIGNED_2N));
+                                               (1 << RESERVE_MM_ALIGNED_2N));
+                               alloc_trace_mask |= 1 << 3;
                                mem->mem_handle =
                                        (void *)codec_mm_extpool_alloc(
                                                &mgt->cma_res_pool,
@@ -387,14 +402,15 @@ static int codec_mm_alloc_in(
                        /*
                         *normal cma.
                         */
+                       alloc_trace_mask |= 1 << 4;
                        mem->mem_handle = dma_alloc_from_contiguous(mgt->dev,
-                               mem->page_count, align_2n - PAGE_SHIFT);
+                                       mem->page_count,
+                                       align_2n - PAGE_SHIFT);
                        mem->from_flags = AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA;
                        if (mem->mem_handle) {
                                mem->vbuffer = mem->mem_handle;
                                mem->phy_addr =
-                                       page_to_phys((struct page *)
-                                       mem->mem_handle);
+                                page_to_phys((struct page *)mem->mem_handle);
 #ifdef CONFIG_ARM64
                                if (mem->flags & CODEC_MM_FLAGS_CMA_CLEAR) {
                                        /*dma_clear_buffer((struct page *)*/
@@ -404,14 +420,18 @@ static int codec_mm_alloc_in(
                                break;
                        }
                }
-               if (can_from_tvp && align_2n <= RESERVE_MM_ALIGNED_2N) {
+               if (can_from_tvp &&
+                               align_2n <= RESERVE_MM_ALIGNED_2N) {
                        /* 64k,aligend */
                        int aligned_buffer_size = ALIGN(mem->buffer_size,
-                               (1 << RESERVE_MM_ALIGNED_2N));
-                       mem->mem_handle =
-                               (void *)codec_mm_extpool_alloc(&mgt->tvp_pool,
-                               &mem->from_ext, aligned_buffer_size);
-                       mem->from_flags = AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP;
+                                       (1 << RESERVE_MM_ALIGNED_2N));
+                       alloc_trace_mask |= 1 << 5;
+                       mem->mem_handle = (void *)codec_mm_extpool_alloc(
+                                       &mgt->tvp_pool,
+                                       &mem->from_ext,
+                                       aligned_buffer_size);
+                       mem->from_flags =
+                               AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP;
                        if (mem->mem_handle) {
                                /*no vaddr for TVP MEMORY */
                                mem->vbuffer = NULL;
@@ -422,10 +442,13 @@ static int codec_mm_alloc_in(
                }
 
                if ((mem->flags & CODEC_MM_FLAGS_DMA_CPU) &&
-                       mgt->enable_kmalloc_on_nomem && !try_alloced_from_sys) {
+                       mgt->enable_kmalloc_on_nomem &&
+                       !try_alloced_from_sys) {
+                       alloc_trace_mask |= 1 << 6;
                        mem->mem_handle = (void *)__get_free_pages(GFP_KERNEL,
                                get_order(mem->buffer_size));
-                       mem->from_flags = AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES;
+                       mem->from_flags =
+                               AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES;
                        if (mem->mem_handle) {
                                mem->vbuffer = mem->mem_handle;
                                mem->phy_addr =
@@ -436,11 +459,30 @@ static int codec_mm_alloc_in(
        } while (--max_retry > 0);
        if (mem->mem_handle)
                return 0;
-       else
+       else {
+               if (debug_mode & 0x10) {
+                       pr_info("codec mm have space:%x\n",
+                               have_space);
+                       pr_info("canfrom: %d,%d,%d,%d\n",
+                               can_from_tvp,
+                               can_from_sys,
+                               can_from_res,
+                               can_from_cma);
+                       pr_info("alloc flags:%d,align=%d,%d,pages:%d,s:%d\n",
+                               mem->flags,
+                               mem->align2n,
+                               align_2n,
+                               mem->page_count,
+                               mem->buffer_size);
+                       pr_info("try alloc mask:%x\n",
+                               alloc_trace_mask);
+               }
                return -10003;
+       }
 }
 
-static void codec_mm_free_in(struct codec_mm_mgt_s *mgt, struct codec_mm_s *mem)
+static void codec_mm_free_in(struct codec_mm_mgt_s *mgt,
+               struct codec_mm_s *mem)
 {
        if (!(mem->flags & CODEC_MM_FLAGS_FOR_LOCAL_MGR))
                mgt->total_alloced_size -= mem->buffer_size;
@@ -459,16 +501,20 @@ static void codec_mm_free_in(struct codec_mm_mgt_s *mgt, struct codec_mm_s *mem)
                        (unsigned long)mem->mem_handle, mem->buffer_size);
                mgt->alloced_res_size -= mem->buffer_size;
        } else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP) {
-               codec_mm_extpool_free((struct gen_pool *)mem->from_ext,
-                       mem->mem_handle, mem->buffer_size);
+               codec_mm_extpool_free(
+                       (struct gen_pool *)mem->from_ext,
+                       mem->mem_handle,
+                       mem->buffer_size);
                mgt->tvp_pool.alloced_size -= mem->buffer_size;
        } else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_PAGES) {
                free_pages((unsigned long)mem->mem_handle,
                        get_order(mem->buffer_size));
                mgt->alloced_sys_size -= mem->buffer_size;
        } else if (mem->from_flags == AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA_RES) {
-               codec_mm_extpool_free((struct gen_pool *)mem->from_ext,
-                       mem->mem_handle, mem->buffer_size);
+               codec_mm_extpool_free(
+                       (struct gen_pool *)mem->from_ext,
+                       mem->mem_handle,
+                       mem->buffer_size);
                mgt->cma_res_pool.alloced_size -= mem->buffer_size;
        }
 
@@ -489,13 +535,19 @@ struct codec_mm_s *codec_mm_alloc(const char *owner, int size,
                return NULL;
        }
 
-       if ((mgt->tvp_enable & 3) && (memflags & CODEC_MM_FLAGS_FOR_VDECODER)) {
-               /*
-                *if tvp & video decoder used tvp memory.
-                *Audio don't protect for default now.
-                */
-               memflags = memflags & (~CODEC_MM_FLAGS_FROM_MASK);
-               memflags |= CODEC_MM_FLAGS_TVP;
+       if (mgt->tvp_enable & 3) {
+               /*if tvp & video decoder used tvp memory.*/
+                  /*Audio don't protect for default now.*/
+               if (memflags & CODEC_MM_FLAGS_TVP) {
+                       /*clear other flags, when tvp mode.*/
+                       memflags = memflags & (~CODEC_MM_FLAGS_FROM_MASK);
+                       memflags |= CODEC_MM_FLAGS_TVP;
+               }
+       } else { /*tvp not enabled*/
+               if (memflags & CODEC_MM_FLAGS_TVP) {
+                       pr_err("TVP not enabled, when alloc from tvp %s need %d\n",
+                               owner, size);
+               }
        }
        if ((memflags & CODEC_MM_FLAGS_FROM_MASK) == 0)
                memflags |= CODEC_MM_FLAGS_DMA;
@@ -512,12 +564,16 @@ struct codec_mm_s *codec_mm_alloc(const char *owner, int size,
                !(memflags & CODEC_MM_FLAGS_FOR_SCATTER)) {
                /*if not scatter, free scatter caches. */
                pr_err(" No mem ret=%d, clear scatter cache!!\n", ret);
-               codec_mm_scatter_free_all_ignorecache();
+               codec_mm_scatter_free_all_ignorecache(1);
                ret = codec_mm_alloc_in(mgt, mem);
        }
        if (ret < 0) {
                pr_err("not enough mem for %s size %d, ret=%d\n",
-                       owner, size, ret);
+                               owner, size, ret);
+               pr_err("mem flags %d %d, %d\n",
+                               memflags,
+                               mem->flags,
+                               align2n);
                kfree(mem);
                if (debug_mode & 0x10)
                        dump_mem_infos(NULL, 0);
@@ -559,10 +615,12 @@ struct codec_mm_s *codec_mm_alloc(const char *owner, int size,
                mgt->alloced_for_sc_cnt++;
        }
        spin_unlock_irqrestore(&mgt->lock, flags);
+       mem->alloced_jiffies = get_jiffies_64();
        if (debug_mode & 0x20)
-               pr_err("%s alloc mem size %d at %lx from %d\n",
+               pr_err("%s alloc mem size %d at %lx from %d,flags:%d\n",
                        owner, size, mem->phy_addr,
-                       mem->from_flags);
+                       mem->from_flags,
+                       memflags);
        return mem;
 }
 EXPORT_SYMBOL(codec_mm_alloc);
@@ -624,12 +682,12 @@ EXPORT_SYMBOL(codec_mm_dma_free_coherent);
 
 void codec_mm_release_with_check(struct codec_mm_s *mem, const char *owner)
 {
+       struct codec_mm_mgt_s *mgt = get_mem_mgt();
        unsigned long flags;
        int ret;
-
-       spin_lock_irqsave(&mem->lock, flags);
+       spin_lock_irqsave(&mgt->lock, flags);
        ret = codec_mm_valid_mm_locked(mem);
-       spin_unlock_irqrestore(&mem->lock, flags);
+       spin_unlock_irqrestore(&mgt->lock, flags);
        if (ret) {
                /*for check,*/
                return codec_mm_release(mem, owner);
@@ -637,7 +695,9 @@ void codec_mm_release_with_check(struct codec_mm_s *mem, const char *owner)
 }
 EXPORT_SYMBOL(codec_mm_release_with_check);
 
-void codec_mm_dma_flush(void *vaddr, int size, enum dma_data_direction dir)
+void codec_mm_dma_flush(void *vaddr,
+       int size,
+       enum dma_data_direction dir)
 {
        struct codec_mm_mgt_s *mgt = get_mem_mgt();
        dma_addr_t dma_addr;
@@ -697,13 +757,37 @@ unsigned long codec_mm_alloc_for_dma(const char *owner, int page_cnt,
        struct codec_mm_s *mem;
 
        mem = codec_mm_alloc(owner, page_cnt << PAGE_SHIFT, align2n, memflags);
-
        if (!mem)
                return 0;
        return mem->phy_addr;
 }
 EXPORT_SYMBOL(codec_mm_alloc_for_dma);
 
+unsigned long codec_mm_alloc_for_dma_ex(
+               const char *owner,
+               int page_cnt,
+               int align2n,
+               int memflags,
+               int ins_id,
+               int buffer_id)
+{
+       struct codec_mm_s *mem;
+
+       mem = codec_mm_alloc(owner, page_cnt << PAGE_SHIFT, align2n, memflags);
+       if (!mem)
+               return 0;
+       mem->ins_id = ins_id;
+       mem->ins_buffer_id = buffer_id;
+       if (debug_mode & 0x20) {
+               pr_err("%s, for ins %d, buffer id:%d\n",
+                       mem->owner[0] ? mem->owner[0] : "no",
+                       mem->ins_id,
+                       buffer_id);
+       }
+       return mem->phy_addr;
+}
+EXPORT_SYMBOL(codec_mm_alloc_for_dma_ex);
+
 int codec_mm_free_for_dma(const char *owner, unsigned long phy_addr)
 {
        struct codec_mm_s *mem;
@@ -718,8 +802,9 @@ int codec_mm_free_for_dma(const char *owner, unsigned long phy_addr)
 }
 EXPORT_SYMBOL(codec_mm_free_for_dma);
 
-static int codec_mm_init_tvp_pool(struct extpool_mgt_s *tvp_pool,
-       struct codec_mm_s *mm)
+static int codec_mm_init_tvp_pool(
+                       struct extpool_mgt_s *tvp_pool,
+                       struct codec_mm_s *mm)
 {
        struct gen_pool *pool;
        int ret;
@@ -737,27 +822,32 @@ static int codec_mm_init_tvp_pool(struct extpool_mgt_s *tvp_pool,
        return 0;
 }
 
-int codec_mm_extpool_pool_alloc(struct extpool_mgt_s *tvp_pool,
+int codec_mm_extpool_pool_alloc(
+       struct extpool_mgt_s *tvp_pool,
        int size, int memflags, int for_tvp)
 {
        struct codec_mm_mgt_s *mgt = get_mem_mgt();
        struct codec_mm_s *mem;
-       int alloced_size = tvp_pool->alloced_size;
+       int alloced_size = tvp_pool->total_size;
        int try_alloced_size = size;
        int ret;
 
 /*alloced from reserved*/
+       mutex_lock(&tvp_pool->pool_lock);
        try_alloced_size = mgt->total_reserved_size - mgt->alloced_res_size;
        if (try_alloced_size > 0 && for_tvp) {
                try_alloced_size = min_t(int,
                        size - alloced_size, try_alloced_size);
                mem = codec_mm_alloc(TVP_POOL_NAME,
-                       try_alloced_size,
-                       0,
-                       CODEC_MM_FLAGS_FOR_LOCAL_MGR | CODEC_MM_FLAGS_RESERVED);
+                                       try_alloced_size,
+                                       0,
+                                       CODEC_MM_FLAGS_FOR_LOCAL_MGR |
+                                       CODEC_MM_FLAGS_RESERVED);
 
                if (mem) {
-                       ret = codec_mm_init_tvp_pool(tvp_pool, mem);
+                       ret = codec_mm_init_tvp_pool(
+                               tvp_pool,
+                               mem);
                        if (ret < 0) {
                                codec_mm_release(mem, TVP_POOL_NAME);
                        } else {
@@ -787,7 +877,9 @@ int codec_mm_extpool_pool_alloc(struct extpool_mgt_s *tvp_pool,
                                        CODEC_MM_FLAGS_CMA);
 
                if (mem) {
-                       ret = codec_mm_init_tvp_pool(tvp_pool, mem);
+                       ret = codec_mm_init_tvp_pool(
+                               tvp_pool,
+                               mem);
                        if (ret < 0) {
                                codec_mm_release(mem, TVP_POOL_NAME);
                        } else {
@@ -798,11 +890,10 @@ int codec_mm_extpool_pool_alloc(struct extpool_mgt_s *tvp_pool,
        }
 
 alloced_finished:
-       if (alloced_size > 0) {
+       if (alloced_size > 0)
                tvp_pool->total_size = alloced_size;
-               return alloced_size;
-       }
-       return -1;
+       mutex_unlock(&tvp_pool->pool_lock);
+       return alloced_size;
 }
 EXPORT_SYMBOL(codec_mm_extpool_pool_alloc);
 
@@ -817,7 +908,7 @@ static int codec_mm_extpool_pool_release(struct extpool_mgt_s *tvp_pool)
        struct codec_mm_mgt_s *mgt = get_mem_mgt();
        int i;
        int ignored = 0;
-
+       mutex_lock(&tvp_pool->pool_lock);
        for (i = 0; i < tvp_pool->slot_num; i++) {
                struct gen_pool *gpool = tvp_pool->gen_pool[i];
                int slot_mem_size = 0;
@@ -860,6 +951,7 @@ static int codec_mm_extpool_pool_release(struct extpool_mgt_s *tvp_pool)
 
        }
        tvp_pool->slot_num = ignored;
+       mutex_unlock(&tvp_pool->pool_lock);
        return ignored;
 }
 
@@ -968,20 +1060,25 @@ static int dump_mem_infos(void *buf, int size)
        int tsize = 0;
        int s;
 
-       if (!pbuf)
+       if (!pbuf) {
                pbuf = sbuf;
-       s = sprintf(pbuf, "codec mem info:\n\ttotal codec mem size:%d MB\n",
+               size = 512;
+       }
+       s = snprintf(pbuf, size - tsize,
+               "codec mem info:\n\ttotal codec mem size:%d MB\n",
                mgt->total_codec_mem_size / SZ_1M);
        tsize += s;
        pbuf += s;
 
-       s = sprintf(pbuf, "\talloced size= %d MB\n\tmax alloced: %d MB\n",
+       s = snprintf(pbuf, size - tsize,
+               "\talloced size= %d MB\n\tmax alloced: %d MB\n",
                mgt->total_alloced_size / SZ_1M,
                mgt->max_used_mem_size / SZ_1M);
        tsize += s;
        pbuf += s;
 
-       s = sprintf(pbuf, "\tCMA:%d,RES:%d,TVP:%d,SYS:%d MB\n",
+       s = snprintf(pbuf, size - tsize,
+               "\tCMA:%d,RES:%d,TVP:%d,SYS:%d MB\n",
                mgt->alloced_cma_size / SZ_1M,
                mgt->alloced_res_size / SZ_1M,
                mgt->tvp_pool.alloced_size / SZ_1M,
@@ -990,7 +1087,7 @@ static int dump_mem_infos(void *buf, int size)
        pbuf += s;
 
        if (mgt->res_pool) {
-               s = sprintf(pbuf,
+               s = snprintf(pbuf, size - tsize,
                        "\t[%d]RES size:%d MB,alloced:%d MB free:%d MB\n",
                        AMPORTS_MEM_FLAGS_FROM_GET_FROM_REVERSED,
                        (int)(gen_pool_size(mgt->res_pool) / SZ_1M),
@@ -1000,17 +1097,18 @@ static int dump_mem_infos(void *buf, int size)
                pbuf += s;
        }
 
-       s = sprintf(pbuf, "\t[%d]CMA size:%d MB:alloced: %d MB,free:%d MB\n",
-               AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA,
-               (int)(dma_get_cma_size_int_byte(mgt->dev) / SZ_1M),
-               (int)(mgt->alloced_cma_size / SZ_1M),
-               (int)((dma_get_cma_size_int_byte(mgt->dev) -
-                               mgt->alloced_cma_size) / SZ_1M));
+       s = snprintf(pbuf, size - tsize,
+                       "\t[%d]CMA size:%d MB:alloced: %d MB,free:%d MB\n",
+                       AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA,
+                       (int)(dma_get_cma_size_int_byte(mgt->dev) / SZ_1M),
+                       (int)(mgt->alloced_cma_size / SZ_1M),
+                       (int)((dma_get_cma_size_int_byte(mgt->dev) -
+                       mgt->alloced_cma_size) / SZ_1M));
        tsize += s;
        pbuf += s;
 
        if (mgt->tvp_pool.slot_num > 0) {
-               s = sprintf(pbuf,
+               s = snprintf(pbuf, size - tsize,
                        "\t[%d]TVP size:%d MB,alloced:%d MB free:%d MB\n",
                        AMPORTS_MEM_FLAGS_FROM_GET_FROM_TVP,
                        (int)(mgt->tvp_pool.total_size / SZ_1M),
@@ -1021,14 +1119,13 @@ static int dump_mem_infos(void *buf, int size)
                pbuf += s;
        }
        if (mgt->cma_res_pool.slot_num > 0) {
-               s = sprintf(pbuf,
+               s = snprintf(pbuf, size - tsize,
                        "\t[%d]CMA_RES size:%d MB,alloced:%d MB free:%d MB\n",
-                       AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA_RES,
-                       (int)(mgt->cma_res_pool.total_size / SZ_1M),
-                       (int)(mgt->cma_res_pool.alloced_size / SZ_1M),
-                       (int)((mgt->cma_res_pool.total_size -
-                                       mgt->cma_res_pool.alloced_size) /
-                               SZ_1M));
+                               AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA_RES,
+                               (int)(mgt->cma_res_pool.total_size / SZ_1M),
+                               (int)(mgt->cma_res_pool.alloced_size / SZ_1M),
+                               (int)((mgt->cma_res_pool.total_size -
+                               mgt->cma_res_pool.alloced_size) / SZ_1M));
                tsize += s;
                pbuf += s;
        }
@@ -1045,23 +1142,35 @@ static int dump_mem_infos(void *buf, int size)
                return tsize;
        }
        list_for_each_entry(mem, &mgt->mem_list, list) {
-               s = sprintf(pbuf,
-               "\towner:[%d] %s:%s,addr=%p,s=%d,from=%d,cnt=%d\n",
-               mem->mem_id,
-               mem->owner[0] ? mem->owner[0] : "no",
-               mem->owner[1] ? mem->owner[1] : "no",
-               (void *)mem->phy_addr,
-               mem->buffer_size, mem->from_flags,
-               atomic_read(&mem->use_cnt));
+               s = snprintf(pbuf, size - tsize,
+                       "\t[%d].%d:%s.%d,addr=%p,size=%d,from=%d,cnt=%d,",
+                       mem->mem_id,
+                       mem->ins_id,
+                       mem->owner[0] ? mem->owner[0] : "no",
+                       mem->ins_buffer_id,
+                       (void *)mem->phy_addr,
+                       mem->buffer_size,
+                       mem->from_flags,
+                       atomic_read(&mem->use_cnt)
+                       );
+               s += snprintf(pbuf + s, size - tsize,
+                       "flags=%d,used:%lld ms\n",
+                       mem->flags,
+                       (get_jiffies_64() - mem->alloced_jiffies) * 100/HZ);
 
+               tsize += s;
                if (buf) {
                        pbuf += s;
-                       if (tsize + s > size - 128)
-                               break;  /*no memory for dump now. */
+                       if (tsize > size - 256) {
+                               s += snprintf(pbuf + s, size - tsize,
+                                       "\n\t\t**NOT END**\n");
+                               tsize += s;
+                               break;/*no memory for dump now.*/
+                       }
                } else {
                        pr_info("%s", sbuf);
+                       tsize = 0;
                }
-               tsize += s;
        }
        spin_unlock_irqrestore(&mgt->lock, flags);
 
@@ -1107,8 +1216,8 @@ EXPORT_SYMBOL(codec_mm_get_total_size);
 int codec_mm_get_free_size(void)
 {
        struct codec_mm_mgt_s *mgt = get_mem_mgt();
-
-       return codec_mm_get_total_size() - mgt->total_alloced_size;
+       return codec_mm_get_total_size() -
+               mgt->total_alloced_size;
 }
 EXPORT_SYMBOL(codec_mm_get_free_size);
 
@@ -1132,7 +1241,7 @@ int codec_mm_enough_for_size(int size, int with_wait)
 
        if (!have_mem && with_wait && mgt->alloced_for_sc_cnt > 0) {
                pr_err(" No mem, clear scatter cache!!\n");
-               codec_mm_scatter_free_all_ignorecache();
+               codec_mm_scatter_free_all_ignorecache(1);
                have_mem = codec_mm_alloc_pre_check_in(mgt, size, 0);
                if (have_mem)
                        return 1;
@@ -1164,7 +1273,8 @@ int codec_mm_mgt_init(struct device *dev)
                        (~((1 << RESERVE_MM_ALIGNED_2N) - 1));
                aligned_size = mgt->rmem.size -
                        (int)(aligned_addr - (unsigned long)mgt->rmem.base);
-               gen_pool_add(mgt->res_pool, aligned_addr, aligned_size, -1);
+               gen_pool_add(mgt->res_pool,
+                       aligned_addr, aligned_size, -1);
                pr_debug("add reserve memory %p(aligned %p) size=%x(aligned %x)\n",
                        (void *)mgt->rmem.base, (void *)aligned_addr,
                        (int)mgt->rmem.size, (int)aligned_size);
@@ -1177,14 +1287,19 @@ int codec_mm_mgt_init(struct device *dev)
        mgt->total_cma_size = dma_get_cma_size_int_byte(mgt->dev);
        mgt->total_codec_mem_size += mgt->total_cma_size;
        /*2M for audio not protect.*/
-       mgt->tvp_pool.default_4k_size = mgt->total_codec_mem_size - SZ_1M * 2;
+       default_tvp_4k_size = mgt->total_codec_mem_size - SZ_1M * 2;
+       if (default_tvp_4k_size > DEFAULT_TVP_SIZE_FOR_4K)
+               default_tvp_4k_size = DEFAULT_TVP_SIZE_FOR_4K;
        /*97MB -> 160MB, may not enough for h265*/
-       mgt->tvp_pool.default_size = mgt->total_codec_mem_size > SZ_1M * 160 ?
-                       SZ_1M * 160 : mgt->tvp_pool.default_4k_size;
+       default_tvp_size = (mgt->total_codec_mem_size - (SZ_1M * 2)) >
+                       DEFAULT_TVP_SIZE_FOR_NO4K ?
+                               DEFAULT_TVP_SIZE_FOR_NO4K :
+                               default_tvp_4k_size;
 
-       mgt->cma_res_pool.default_size = mgt->total_cma_size;
-       mgt->cma_res_pool.default_4k_size = mgt->total_cma_size;
+       default_cma_res_size = mgt->total_cma_size;
        mgt->global_memid = 0;
+       mutex_init(&mgt->tvp_pool.pool_lock);
+       mutex_init(&mgt->cma_res_pool.pool_lock);
        spin_lock_init(&mgt->lock);
        return 0;
 }
@@ -1273,7 +1388,8 @@ static ssize_t codec_mm_keeper_dump_show(struct class *class,
 }
 
 static ssize_t tvp_enable_help_show(struct class *class,
-       struct class_attribute *attr, char *buf)
+               struct class_attribute *attr,
+               char *buf)
 {
        ssize_t size = 0;
 
@@ -1288,7 +1404,8 @@ static ssize_t tvp_enable_help_show(struct class *class,
 }
 
 static ssize_t tvp_enable_store(struct class *class,
-       struct class_attribute *attr, const char *buf, size_t size)
+               struct class_attribute *attr,
+               const char *buf, size_t size)
 {
        struct codec_mm_mgt_s *mgt = get_mem_mgt();
        unsigned int val;
@@ -1304,7 +1421,7 @@ static ssize_t tvp_enable_store(struct class *class,
        tvp changes.
        */
        codec_mm_keeper_free_all_keep(2);
-       codec_mm_scatter_free_all_ignorecache();
+       codec_mm_scatter_free_all_ignorecache(3);
        switch (val) {
        case 0:
                ret = codec_mm_extpool_pool_release(&mgt->tvp_pool);
@@ -1312,14 +1429,16 @@ static ssize_t tvp_enable_store(struct class *class,
                pr_info("disalbe tvp\n");
                break;
        case 1:
-               codec_mm_extpool_pool_alloc(&mgt->tvp_pool,
-                       mgt->tvp_pool.default_size, 0, 1);
+               codec_mm_extpool_pool_alloc(
+                       &mgt->tvp_pool,
+                       default_tvp_size, 0, 1);
                mgt->tvp_enable = 1;
                pr_info("enable tvp for 1080p\n");
                break;
        case 2:
-               codec_mm_extpool_pool_alloc(&mgt->tvp_pool,
-                       mgt->tvp_pool.default_4k_size, 0, 1);
+               codec_mm_extpool_pool_alloc(
+                       &mgt->tvp_pool,
+                       default_tvp_4k_size, 0, 1);
                mgt->tvp_enable = 2;
                pr_info("enable tvp for 4k\n");
                break;
@@ -1330,7 +1449,8 @@ static ssize_t tvp_enable_store(struct class *class,
 }
 
 static ssize_t fastplay_enable_help_show(struct class *class,
-       struct class_attribute *attr, char *buf)
+               struct class_attribute *attr,
+               char *buf)
 {
        ssize_t size = 0;
 
@@ -1343,7 +1463,8 @@ static ssize_t fastplay_enable_help_show(struct class *class,
 }
 
 static ssize_t fastplay_enable_store(struct class *class,
-       struct class_attribute *attr, const char *buf, size_t size)
+               struct class_attribute *attr,
+               const char *buf, size_t size)
 {
        struct codec_mm_mgt_s *mgt = get_mem_mgt();
        unsigned int val;
@@ -1361,8 +1482,9 @@ static ssize_t fastplay_enable_store(struct class *class,
                pr_err("disalbe fastplay\n");
                break;
        case 1:
-               codec_mm_extpool_pool_alloc(&mgt->cma_res_pool,
-                       mgt->cma_res_pool.default_4k_size, 0, 0);
+               codec_mm_extpool_pool_alloc(
+                       &mgt->cma_res_pool,
+                       default_cma_res_size, 0, 0);
                mgt->fastplay_enable = 1;
                pr_err("enable fastplay\n");
                break;
@@ -1375,38 +1497,23 @@ static ssize_t fastplay_enable_store(struct class *class,
 static ssize_t codec_mm_config_show(struct class *class,
        struct class_attribute *attr, char *buf)
 {
-       struct codec_mm_mgt_s *mgt = get_mem_mgt();
-       size_t ret;
+       ssize_t ret;
 
-       ret = sprintf(buf,
-               "default_tvp_size:0x%x(%d MB)\n",
-               mgt->tvp_pool.default_size, mgt->tvp_pool.default_size / SZ_1M);
-       ret += sprintf(buf + ret,
-               "default_tvp_4k_size:0x%x(%d MB)\n",
-               mgt->tvp_pool.default_4k_size,
-               mgt->tvp_pool.default_4k_size / SZ_1M);
-       ret += codec_mm_scatter_mgt_get_config(buf + ret);
+       ret = configs_list_path_nodes(CONFIG_PATH, buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
        return ret;
 }
 
 static ssize_t codec_mm_config_store(struct class *class,
-       struct class_attribute *attr, const char *buf, size_t size)
+                       struct class_attribute *attr,
+                       const char *buf, size_t size)
 {
-       struct codec_mm_mgt_s *mgt = get_mem_mgt();
-       unsigned int val;
-       ssize_t ret;
+       int ret;
 
-       ret = sscanf(buf, "default_tvp_size:0x%x", &val);
-       if (ret == 1) {
-               mgt->tvp_pool.default_size = val;
-               return size;
-       }
-       ret = sscanf(buf, "default_tvp_4k_size:0x%x", &val);
-       if (ret == 1) {
-               mgt->tvp_pool.default_4k_size = val;
-               return size;
-       }
-       return codec_mm_scatter_mgt_set_config(buf, size);
+       ret = configs_set_prefix_path_valonpath(CONFIG_PREFIX, buf);
+       if (ret < 0)
+               pr_err("set config failed %s\n", buf);
+       return size;
 }
 
 static ssize_t tvp_region_show(struct class *class,
@@ -1542,6 +1649,9 @@ static ssize_t codec_mm_debug_store(struct class *class,
        case 10:
                codec_mm_keeper_free_all_keep(1);
                break;
+       case 11:
+               dump_mem_infos(NULL, 0);
+               break;
        case 20: {
                int cmd, len;
                unsigned int addr;
@@ -1585,10 +1695,80 @@ static struct class_attribute codec_mm_class_attrs[] = {
 };
 
 static struct class codec_mm_class = {
-       .name = "codec_mm",
-       .class_attrs = codec_mm_class_attrs,
+               .name = "codec_mm",
+               .class_attrs = codec_mm_class_attrs,
+       };
+
+static struct mconfig codec_mm_configs[] = {
+       MC_PI32("default_tvp_size", &default_tvp_size),
+       MC_PI32("default_tvp_4k_size", &default_tvp_4k_size),
+       MC_PI32("default_cma_res_size", &default_cma_res_size),
+};
+static struct mconfig_node codec_mm_trigger_node;
+int codec_mm_trigger_fun(const char *trigger, int id, const char *buf, int size)
+{
+       int ret = size;
+
+       switch (trigger[0]) {
+       case 't':
+               tvp_enable_store(NULL, NULL, buf, size);
+               break;
+       case 'f':
+               fastplay_enable_store(NULL, NULL, buf, size);
+               break;
+       case 'd':
+               codec_mm_debug_store(NULL, NULL, buf, size);
+               break;
+       default:
+               ret = -1;
+       }
+       return size;
+}
+int codec_mm_trigger_help_fun(const char *trigger, int id, char *sbuf, int size)
+{
+       int ret = -1;
+       void *buf, *getbuf = NULL;
+
+       if (size < PAGE_SIZE) {
+               void *getbuf = (void *)__get_free_page(GFP_KERNEL);
+
+               if (!getbuf)
+                       return -ENOMEM;
+               buf = getbuf;
+       } else {
+               buf = sbuf;
+       }
+       switch (trigger[0]) {
+       case 't':
+               ret = tvp_enable_help_show(NULL, NULL, buf);
+               break;
+       case 'f':
+               ret = fastplay_enable_help_show(NULL, NULL, buf);
+               break;
+       case 'd':
+               ret = codec_mm_debug_show(NULL, NULL, buf);
+               break;
+       default:
+               pr_err("unknown trigger:[%s]\n", trigger);
+               ret = -1;
+       }
+       if (ret > 0 && getbuf != NULL) {
+               int ret = min_t(int, ret, size);
+
+               strncpy(sbuf, buf, ret);
+       }
+       if (getbuf != NULL)
+               free_page((unsigned long)getbuf);
+       return ret;
+}
+
+static struct mconfig codec_mm_trigger[] = {
+       MC_FUN("tvp_enable", codec_mm_trigger_help_fun, codec_mm_trigger_fun),
+       MC_FUN("fastplay", codec_mm_trigger_help_fun, codec_mm_trigger_fun),
+       MC_FUN("debug", codec_mm_trigger_help_fun, codec_mm_trigger_fun),
 };
 
+
 static int codec_mm_probe(struct platform_device *pdev)
 {
 
@@ -1615,6 +1795,9 @@ static int codec_mm_probe(struct platform_device *pdev)
        codec_mm_keeper_mgr_init();
        amstream_test_init();
        codec_mm_scatter_mgt_test();
+       REG_PATH_CONFIGS(CONFIG_PATH, codec_mm_configs);
+       INIT_REG_NODE_CONFIGS(CONFIG_PATH, &codec_mm_trigger_node,
+               "trigger", codec_mm_trigger, CONFIG_FOR_RW | CONFIG_FOR_T);
        return 0;
 }
 
index 2bd7ca6..32cc094 100644 (file)
 
 
 extern void dma_clear_buffer(struct page *page, size_t size);
-struct codec_mm_s *codec_mm_alloc(const char *owner, int size,
-       int align2n, int memflags);
-void codec_mm_release(struct codec_mm_s *mem, const char *owner);
-u32 get_codec_mm_profiles(void);
 
 u32 codec_mm_get_sc_debug_mode(void);
 u32 codec_mm_get_keep_debug_mode(void);
index ed539cf..1505625 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
 
 #include "codec_mm_priv.h"
 #include "codec_mm_scatter_priv.h"
 
 #endif
 #define MAX_SC_LIST 64
+#define MK_TAG(a, b, c, d) (((a) << 24) | ((b) << 16) |\
+                                       ((c) << 8) | d)
+#define SMGT_IDENTIFY_TAG MK_TAG('Z', 'S', 'C', 'Z')
+
+struct codec_mm_scatter_s {
+       u32 keep_size_PAGE;
+       u32 reserved_block_mm_M;
+       u32 try_alloc_in_cma_page_cnt;
+       u32 try_alloc_in_sys_page_cnt_max;
+       u32 try_alloc_in_sys_page_cnt_min;
+       u32 enable_slot_from_sys;
+       u32 no_cache_size_M;
+       u32 support_from_slot_sys;
+};
+
 struct codec_mm_scatter_mgt {
+       unsigned int tag;/*=*/
        struct codec_mm_slot *slot_list_map[MAX_SID];
+       int tvp_mode;
        int codec_mm_num;
        int total_page_num;
        int alloced_page_num;
        int max_alloced;
-       int try_alloc_in_cma_page_cnt;
-       int try_alloc_in_sys_page_cnt;
-       int try_alloc_in_sys_page_cnt_max;
-       int try_alloc_in_sys_page_cnt_min;
+       u32 try_alloc_in_cma_page_cnt;
+       u32 try_alloc_in_sys_page_cnt;
+       u32 try_alloc_in_sys_page_cnt_max;
+       u32 try_alloc_in_sys_page_cnt_min;
        int alloc_from_cma_first;
-       int enable_slot_from_sys;
-       int no_cache_size_M;
-       int support_from_slot_sys;
+       u32 enable_slot_from_sys;
+       u32 no_cache_size_M;
+       u32 support_from_slot_sys;
        int one_page_cnt;
        int scatters_cnt;
        int slot_cnt;
-       int reserved_block_mm_M;
-       int keep_size_PAGE;
+       u32 reserved_block_mm_M;
+       u32 keep_size_PAGE;
+       int mem_flags;
 
        int alloc_from_sys_sc_cnt;
        int alloc_from_sys_page_cnt;
@@ -165,12 +184,19 @@ struct codec_mm_scatter_mgt {
        struct codec_mm_scatter *scmap[MAX_SC_LIST];/*used for valid check. */
 };
 
+static struct codec_mm_scatter_s g_scatter;
 static struct codec_mm_scatter_mgt *scatter_mgt;
-
-static struct codec_mm_scatter_mgt *codec_mm_get_scatter_mgt(void)
+static struct codec_mm_scatter_mgt *scatter_tvp_mgt;
+static struct codec_mm_scatter_mgt *codec_mm_get_scatter_mgt(
+       int is_tvp)
 {
+       if (is_tvp)
+               return scatter_tvp_mgt;
        return scatter_mgt;
 }
+static int codec_mm_scatter_valid_locked(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_scatter *mms);
 
 /*#define MY_MUTEX_DEBUG*/
 #ifdef MY_MUTEX_DEBUG
@@ -261,22 +287,25 @@ static inline void codec_mm_list_unlock(
 }
 
 static int codec_mm_scatter_alloc_want_pages_in(
+               struct codec_mm_scatter_mgt *smgt,
                struct codec_mm_scatter *mms,
                int want_pages);
 
 static struct workqueue_struct *codec_mm_scatter_wq_get(void)
 {
-       static struct workqueue_struct *codec_mm_scatter;
+       static struct workqueue_struct *codec_mm_scatter_wq;
 
-       if (!codec_mm_scatter)
-               codec_mm_scatter = create_singlethread_workqueue("codec_mm_sc");
-       return codec_mm_scatter;
+       if (!codec_mm_scatter_wq) {
+               codec_mm_scatter_wq =
+                       create_singlethread_workqueue("codec_mm_sc");
+       }
+       return codec_mm_scatter_wq;
 }
 
 
-static int codec_mm_schedule_delay_work(int delay_ms, int for_update)
+static int codec_mm_schedule_delay_work(struct codec_mm_scatter_mgt *smgt,
+       int delay_ms, int for_update)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        bool ret;
        if (!for_update && delayed_work_pending(&smgt->dealy_work))
                return 0;
@@ -299,9 +328,9 @@ static inline u64 codec_mm_get_current_us(void)
        return div64_u64(timeval_to_ns(&tv), 1000);
 }
 
-static void codec_mm_update_alloc_time(u64 startus)
+static void codec_mm_update_alloc_time(
+       struct codec_mm_scatter_mgt *smgt, u64 startus)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int spend_time_us;
 
        spend_time_us = (int)(codec_mm_get_current_us() - startus);
@@ -332,10 +361,9 @@ static void codec_mm_update_alloc_time(u64 startus)
        }
 }
 
-void codec_mm_clear_alloc_infos(void)
+static void codec_mm_clear_alloc_infos_in(
+       struct codec_mm_scatter_mgt *smgt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
-
        smgt->alloc_cnt = 0;
        smgt->alloc_10us_less_cnt = 0;
        smgt->alloc_10_50us_cnt = 0;
@@ -347,11 +375,17 @@ void codec_mm_clear_alloc_infos(void)
        smgt->alloc_total_us = 0;
        smgt->alloc_max_us = 0;
 }
+void codec_mm_clear_alloc_infos(void)
+{
+       codec_mm_clear_alloc_infos_in(codec_mm_get_scatter_mgt(0));
+       codec_mm_clear_alloc_infos_in(codec_mm_get_scatter_mgt(1));
+}
 
 
-static int codec_mm_set_slot_in_hash(struct codec_mm_slot *slot)
+static int codec_mm_set_slot_in_hash(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_slot *slot)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
 
        page_sid_type sid = SLOT_TO_SID(slot);
 
@@ -388,9 +422,9 @@ static int codec_mm_set_slot_in_hash(struct codec_mm_slot *slot)
 }
 
 static struct codec_mm_slot *codec_mm_find_slot_in_hash(
+       struct codec_mm_scatter_mgt *smgt,
        page_sid_type sid, ulong addr)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_slot *fslot, *slot;
 
        if (!VALID_SID(sid))
@@ -430,9 +464,10 @@ err:
        return NULL;
 }
 
-static int codec_mm_slot_free(struct codec_mm_slot *slot)
+static int codec_mm_slot_free(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_slot *slot)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int ret = 0;
 
        codec_mm_list_lock(smgt);
@@ -487,11 +522,10 @@ static int codec_mm_slot_free(struct codec_mm_slot *slot)
        kfree(slot);
        return 0;
 }
-
-static int codec_mm_slot_try_free(struct codec_mm_slot *slot)
+static int codec_mm_slot_try_free(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_slot *slot)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
-
        if (smgt->keep_size_PAGE > 0) {
                /*delay free, when size < delay_free_M MB */
                int free_pages = smgt->total_page_num - smgt->alloced_page_num;
@@ -499,7 +533,7 @@ static int codec_mm_slot_try_free(struct codec_mm_slot *slot)
                if (free_pages < smgt->keep_size_PAGE)
                        return -1;
        }
-       return codec_mm_slot_free(slot);
+       return codec_mm_slot_free(smgt, slot);
 }
 
 static inline int codec_mm_slot_init_bitmap(struct codec_mm_slot *slot)
@@ -523,9 +557,10 @@ static inline int codec_mm_slot_init_bitmap(struct codec_mm_slot *slot)
 /*
 *flags : 1. don't used codecmm.
 */
-static struct codec_mm_slot *codec_mm_slot_alloc(int size, int flags)
+static struct codec_mm_slot *codec_mm_slot_alloc(
+       struct codec_mm_scatter_mgt *smgt,
+       int size, int flags)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_slot *slot;
        struct codec_mm_s *mm;
        int try_alloc_size = size;
@@ -553,9 +588,12 @@ static struct codec_mm_slot *codec_mm_slot_alloc(int size, int flags)
                        if (codec_mm_get_free_size() < try_alloc_size)
                                try_alloc_size = codec_mm_get_free_size();
                        mm = codec_mm_alloc(SCATTER_MEM, try_alloc_size, 0,
-                               CODEC_MM_FLAGS_CMA_FIRST |
-                               CODEC_MM_FLAGS_FOR_VDECODER |
-                               CODEC_MM_FLAGS_FOR_SCATTER);
+                                       CODEC_MM_FLAGS_CMA_FIRST |
+                                       CODEC_MM_FLAGS_FOR_VDECODER |
+                                       CODEC_MM_FLAGS_FOR_SCATTER |
+                                       (smgt->tvp_mode ?
+                                               CODEC_MM_FLAGS_TVP : 0)
+                                       );
                        if (mm != NULL) {
                                slot->from_type = SLOT_FROM_CODEC_MM;
                                slot->mm = mm;
@@ -588,8 +626,8 @@ static struct codec_mm_slot *codec_mm_slot_alloc(int size, int flags)
                        goto error;     /*don't alloc 1 page with slot. */
                }
        }
-       if (!have_alloced && codec_mm_video_tvp_enabled()) {
-               /*tvp not support alloc from sys. */
+       if (!have_alloced && smgt->tvp_mode) {
+               /*tvp not support alloc from sys.*/
                goto error;
        }
        while (!have_alloced) {
@@ -629,7 +667,7 @@ static struct codec_mm_slot *codec_mm_slot_alloc(int size, int flags)
                have_alloced = 1;
                break;
        }
-       codec_mm_set_slot_in_hash(slot);
+       codec_mm_set_slot_in_hash(smgt, slot);
 
        return slot;
 error:
@@ -637,9 +675,10 @@ error:
        return NULL;
 }
 
-static int codec_mm_slot_free_page(struct codec_mm_slot *slot, ulong phy_addr)
+static int codec_mm_slot_free_page(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_slot *slot, ulong phy_addr)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int bit;
 
        if (!slot || !slot->pagemap || slot->page_num <= 0)
@@ -663,10 +702,11 @@ static int codec_mm_slot_free_page(struct codec_mm_slot *slot, ulong phy_addr)
        return 0;
 }
 
-static int codec_mm_slot_alloc_pages(struct codec_mm_slot *slot,
-       phy_addr_type *pages, int num)
+static int codec_mm_slot_alloc_pages(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_slot *slot,
+       phy_addr_type  *pages, int num)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int alloced = 0;
        int need = num;
        int can_alloced;
@@ -740,23 +780,24 @@ static inline page_sid_type codec_mm_get_page_sid(
        return PAGE_SID(page);
 }
 
-static int codec_mm_page_free_to_slot(page_sid_type sid, ulong addr)
+static int codec_mm_page_free_to_slot(
+       struct codec_mm_scatter_mgt *smgt,
+       page_sid_type sid, ulong addr)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_slot *slot;
        int ret;
        int slot_free = 0;
 
-       slot = codec_mm_find_slot_in_hash(sid, addr);
+       slot = codec_mm_find_slot_in_hash(smgt, sid, addr);
        if (!slot)
                return -1;
-       ret = codec_mm_slot_free_page(slot, addr);
+       ret = codec_mm_slot_free_page(smgt, slot, addr);
        if (ret != 0)
                ERR_LOG("free slot addr error =%p ret=%d\n",
                        (void *)addr, ret);
 
        if (slot->alloced_page_num == 0)
-               slot_free = (codec_mm_slot_try_free(slot) == 0);
+               slot_free = (codec_mm_slot_try_free(smgt, slot) == 0);
 
        if (!slot_free) {       /*move to have free list. */
                codec_mm_list_lock(smgt);
@@ -773,9 +814,10 @@ static int codec_mm_page_free_to_slot(page_sid_type sid, ulong addr)
        return 0;
 }
 
-static int codec_mm_page_alloc_from_one_pages(phy_addr_type *pages, int num)
+static int codec_mm_page_alloc_from_one_pages(
+       struct codec_mm_scatter_mgt *smgt,
+       phy_addr_type *pages, int num)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int neednum = num;
        int alloced = 0;
 
@@ -805,9 +847,10 @@ static int codec_mm_page_alloc_from_one_pages(phy_addr_type *pages, int num)
        return alloced;
 }
 
-static int codec_mm_page_alloc_from_slot(phy_addr_type *pages, int num)
+static int codec_mm_page_alloc_from_slot(
+       struct codec_mm_scatter_mgt *smgt,
+       phy_addr_type *pages, int num)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_slot *slot = NULL;
        int alloced = 0;
        int neednum = num;
@@ -828,8 +871,8 @@ static int codec_mm_page_alloc_from_slot(phy_addr_type *pages, int num)
                if (smgt->total_page_num <= 0 ||        /*no codec mm. */
                        smgt->alloced_page_num == smgt->total_page_num ||
                        list_empty(&smgt->free_list)) {
-                       /*codec_mm_scatter_info_dump(NULL, 0); */
-                       slot = codec_mm_slot_alloc(0, 0);
+                       /*codec_mm_scatter_info_dump(NULL, 0);*/
+                       slot = codec_mm_slot_alloc(smgt, 0, 0);
                        if (!slot) {
                                /*
                                   *ERR_LOG("can't alloc slot from system\n");
@@ -862,7 +905,8 @@ static int codec_mm_page_alloc_from_slot(phy_addr_type *pages, int num)
                }
                codec_mm_list_unlock(smgt);
                if (slot) {
-                       n = codec_mm_slot_alloc_pages(slot,
+                       n = codec_mm_slot_alloc_pages(smgt,
+                               slot,
                                &pages[alloced], neednum);
                        codec_mm_list_lock(smgt);
                        slot->on_alloc_free--;  /*alloc use end */
@@ -918,9 +962,9 @@ static int codec_mm_page_alloc_from_slot(phy_addr_type *pages, int num)
 
 
 static int codec_mm_page_alloc_from_free_scatter(
+       struct codec_mm_scatter_mgt *smgt,
        phy_addr_type *pages, int num)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_scatter *mms;
        int need = num;
        int alloced = 0;
@@ -955,6 +999,7 @@ static int codec_mm_page_alloc_from_free_scatter(
 }
 
 static int codec_mm_page_alloc_all_locked(
+               struct codec_mm_scatter_mgt *smgt,
                phy_addr_type *pages, int num, int iscache)
 {
        int alloced = 0;
@@ -966,18 +1011,21 @@ static int codec_mm_page_alloc_all_locked(
                new_alloc = 0;
                if (can_from_scatter) {
                        new_alloc = codec_mm_page_alloc_from_free_scatter(
+                               smgt,
                                pages + alloced,
                                num - alloced);
                        if (new_alloc <= 0)
                                can_from_scatter = 0;
                } else if (can_from_slot) {
                        new_alloc = codec_mm_page_alloc_from_slot(
+                               smgt,
                                pages + alloced,
                                num - alloced);
                        if (new_alloc <= 0)
                                can_from_slot = 0;
-               } else if (!codec_mm_video_tvp_enabled()) {
+               } else if (!smgt->tvp_mode) {
                        new_alloc = codec_mm_page_alloc_from_one_pages(
+                               smgt,
                                pages + alloced,
                                num - alloced);
                        if (new_alloc <= 0)
@@ -991,9 +1039,9 @@ static int codec_mm_page_alloc_all_locked(
 }
 
 static int codec_mm_pages_free_to_scatter(
+       struct codec_mm_scatter_mgt *smgt,
        struct codec_mm_scatter *src_mms)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_scatter *dst_mms;
        int moved = 0;
        int left;
@@ -1025,40 +1073,15 @@ static int codec_mm_pages_free_to_scatter(
        return moved;
 }
 
-#if 0
-
-/*
-*return:
-*1:for valid;
-*0:no valid mms.
-*must check in
-*codec_mm_list_lock
-*/
-static int codec_mm_scatter_valid_check_inlock(struct codec_mm_scatter *mms)
-{
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
-       struct list_head *pos, *to_check_list;
 
-       if (!mms)
-               return 0;
-       to_check_list = &mms->list;
-       if (list_empty(&smgt->scatter_list))
-               return 0;
-       list_for_each(pos, &smgt->scatter_list) {
-               if (pos == to_check_list)
-                       return 1;
-       }
-       return 0;
-}
-#endif
 
 /*
 *free one page in mms;
 */
 static int codec_mm_scatter_free_page_id_locked(
+       struct codec_mm_scatter_mgt *smgt,
        struct codec_mm_scatter *mms, int id)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        page_sid_type sid;
        int ret;
 
@@ -1078,7 +1101,7 @@ static int codec_mm_scatter_free_page_id_locked(
                mms->page_cnt--;
                return 0;
        }
-       ret = codec_mm_page_free_to_slot(sid, PAGE_ADDR_OF_MMS(mms, id));
+       ret = codec_mm_page_free_to_slot(smgt, sid, PAGE_ADDR_OF_MMS(mms, id));
        if (!ret) {
                mms->page_cnt--;
                mms->page_tail--;
@@ -1089,10 +1112,12 @@ static int codec_mm_scatter_free_page_id_locked(
 /*
 *free one page in mms;
 */
-static int codec_mm_scatter_free_pages_in_locked(struct codec_mm_scatter *mms,
+static int codec_mm_scatter_free_pages_in_locked(
+       struct codec_mm_scatter *mms,
        int start_id)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
+       struct codec_mm_scatter_mgt *smgt =
+               (struct codec_mm_scatter_mgt *)mms->manager;
        int i;
        int ret;
        int id = start_id;
@@ -1100,7 +1125,7 @@ static int codec_mm_scatter_free_pages_in_locked(struct codec_mm_scatter *mms,
        int not_continue_print = 1;
 
        for (i = mms->page_tail; i >= id; i--) {
-               ret = codec_mm_scatter_free_page_id_locked(mms, i);
+               ret = codec_mm_scatter_free_page_id_locked(smgt, mms, i);
                if (ret < 0) {
                        if (not_continue_print) {
                                ERR_LOG("page free error.%d,id=%d, addr:%d\n",
@@ -1130,13 +1155,14 @@ static int codec_mm_scatter_free_tail_pages_in(
        int fast)
 {
        int id = start_free_id;
-
+       struct codec_mm_scatter_mgt *smgt;
        if (!mms || id < 0 || id >= mms->page_cnt || mms->page_tail < 0) {
                if (mms)
                        ERR_LOG("free mm scatters error id %d,page_cnt=%d\n",
                                id, mms->page_cnt);
                return -1;
        }
+       smgt = (struct codec_mm_scatter_mgt *)mms->manager;
        codec_mm_scatter_lock(mms);
        mms->page_used = start_free_id;
 
@@ -1145,7 +1171,7 @@ static int codec_mm_scatter_free_tail_pages_in(
                return 0;
        }
        if (fast == 2 || fast == 3) {
-               codec_mm_pages_free_to_scatter(mms);
+               codec_mm_pages_free_to_scatter(smgt, mms);
                if (fast == 2 || mms->page_used == mms->page_cnt) {
                        codec_mm_scatter_unlock(mms);
                        return 0;
@@ -1156,27 +1182,34 @@ static int codec_mm_scatter_free_tail_pages_in(
        return 0;
 }
 
-int codec_mm_scatter_free_tail_pages(struct codec_mm_scatter *mms,
-       int start_free_id)
+int codec_mm_scatter_free_tail_pages(
+               struct codec_mm_scatter *mms,
+               int start_free_id)
 {
        int ret = 0;
 
        if (start_free_id < mms->page_cnt)
-               ret = codec_mm_scatter_free_tail_pages_in(mms,
+               ret = codec_mm_scatter_free_tail_pages_in(
+                       mms,
                        start_free_id, 0);
        return ret;
 }
 EXPORT_SYMBOL(codec_mm_scatter_free_tail_pages);
 
-int codec_mm_scatter_free_tail_pages_fast(struct codec_mm_scatter *mms,
+int codec_mm_scatter_free_tail_pages_fast(
+       struct codec_mm_scatter *mms,
        int start_free_id)
 {
        int ret = 0;
-
+       if (!mms)
+               return -1;
        if (start_free_id < mms->page_cnt)
-               ret = codec_mm_scatter_free_tail_pages_in(mms,
-                       start_free_id, 2);
-       codec_mm_schedule_delay_work(100, 0);
+               ret = codec_mm_scatter_free_tail_pages_in(
+                               mms,
+                               start_free_id, 2);
+       codec_mm_schedule_delay_work(
+               (struct codec_mm_scatter_mgt *)mms->manager,
+               100, 0);
        return ret;
 }
 EXPORT_SYMBOL(codec_mm_scatter_free_tail_pages_fast);
@@ -1205,9 +1238,9 @@ int codec_mm_scatter_free_all_pages(struct codec_mm_scatter *mms)
 EXPORT_SYMBOL(codec_mm_scatter_free_all_pages);
 
 static inline int codec_mm_scatter_map_add_locked(
+       struct codec_mm_scatter_mgt *smgt,
        struct codec_mm_scatter *mms)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int i;
 
        for (i = 0; i < MAX_SC_LIST; i++) {
@@ -1220,9 +1253,9 @@ static inline int codec_mm_scatter_map_add_locked(
 }
 
 static inline int codec_mm_scatter_map_del_locked(
+       struct codec_mm_scatter_mgt *smgt,
        struct codec_mm_scatter *mms)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int i;
 
        for (i = 0; i < MAX_SC_LIST; i++) {
@@ -1234,9 +1267,10 @@ static inline int codec_mm_scatter_map_del_locked(
        return 0;
 }
 
-int codec_mm_scatter_valid_locked(struct codec_mm_scatter *mms)
+int codec_mm_scatter_valid_locked(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_scatter *mms)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int i;
        int valid = 0;
 
@@ -1251,9 +1285,11 @@ int codec_mm_scatter_valid_locked(struct codec_mm_scatter *mms)
 EXPORT_SYMBOL(codec_mm_scatter_valid_locked);
 
 /*free scatter's all */
-static int codec_mm_scatter_free_on_nouser(struct codec_mm_scatter *mms)
+static int codec_mm_scatter_free_on_nouser_ext(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_scatter *mms,
+       int not_in_mgt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int ret = 0;
        int free;
 
@@ -1271,8 +1307,11 @@ static int codec_mm_scatter_free_on_nouser(struct codec_mm_scatter *mms)
        free = mms->page_cnt;
        if (!list_empty(&mms->list))
                list_del(&mms->list);
-       smgt->scatters_cnt--;
-       codec_mm_scatter_map_del_locked(mms);
+       if (!not_in_mgt) {
+               smgt->scatters_cnt--;
+       codec_mm_scatter_map_del_locked(smgt, mms);
+       }
+
        codec_mm_list_unlock(smgt);
        codec_mm_scatter_unlock(mms);
        if (mms->page_cnt > 0)
@@ -1291,6 +1330,14 @@ static int codec_mm_scatter_free_on_nouser(struct codec_mm_scatter *mms)
        SC_FREE(mms);
        return ret;
 }
+/*free scatter's all */
+static int codec_mm_scatter_free_on_nouser(
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_scatter *mms)
+{
+       return codec_mm_scatter_free_on_nouser_ext(
+               smgt, mms, 0);
+}
 
 /*
 *mask for other use it.
@@ -1298,14 +1345,17 @@ static int codec_mm_scatter_free_on_nouser(struct codec_mm_scatter *mms)
 static int codec_mm_scatter_inc_user_in(struct codec_mm_scatter *mms,
        int cnt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
+       struct codec_mm_scatter_mgt *smgt;
        int ret = -1;
        int old_user;
 
        if (!mms)
                return -1;
+       smgt = (struct codec_mm_scatter_mgt *)mms->manager;
+       if (smgt->tag != SMGT_IDENTIFY_TAG)
+               return -2;/*not valid tag*/
        codec_mm_list_lock(smgt);
-       if (!codec_mm_scatter_valid_locked(mms)) {
+       if (!codec_mm_scatter_valid_locked(smgt, mms)) {
                codec_mm_list_unlock(smgt);
                return -1;
        }
@@ -1320,16 +1370,20 @@ static int codec_mm_scatter_inc_user_in(struct codec_mm_scatter *mms,
 }
 
 /*mask scatter's to free.*/
-static int codec_mm_scatter_dec_user_in(struct codec_mm_scatter *mms,
-       int delay_free_ms, int cnt)
+static int codec_mm_scatter_dec_user_in(
+               struct codec_mm_scatter *mms,
+               int delay_free_ms, int cnt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
+       struct codec_mm_scatter_mgt *smgt;
        int after_users = 1;
 
        if (!mms)
                return -1;
+       smgt = (struct codec_mm_scatter_mgt *)mms->manager;
+       if (smgt->tag != SMGT_IDENTIFY_TAG)
+               return -2;/*not valid tag*/
        codec_mm_list_lock(smgt);
-       if (!codec_mm_scatter_valid_locked(mms)) {
+       if (!codec_mm_scatter_valid_locked(smgt, mms)) {
                codec_mm_list_unlock(smgt);
                return -1;
        }
@@ -1348,7 +1402,7 @@ static int codec_mm_scatter_dec_user_in(struct codec_mm_scatter *mms,
        }
        codec_mm_list_unlock(smgt);
        if (after_users == 0)
-               codec_mm_schedule_delay_work(0, 1);
+               codec_mm_schedule_delay_work(smgt, 0, 1);
        return 0;
 }
 
@@ -1392,9 +1446,11 @@ EXPORT_SYMBOL(codec_mm_scatter_dec_owner_user);
 *      max pages == support 4k,need pages;
 *      page num = current size need pages;
 */
-struct codec_mm_scatter *codec_mm_scatter_alloc_new(int max_page, int page_num)
+struct codec_mm_scatter *codec_mm_scatter_alloc_new(
+       struct codec_mm_scatter_mgt *smgt,
+       int max_page,
+       int page_num)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_scatter *mms;
        int ret;
 
@@ -1414,11 +1470,13 @@ struct codec_mm_scatter *codec_mm_scatter_alloc_new(int max_page, int page_num)
        memset(mms->pages_list, 0, sizeof(phy_addr_type) * max_page);
        mms->page_cnt = 0;
        mms->page_tail = -1;
+       mms->manager = (void *)smgt;
        atomic_set(&mms->user_cnt, 0);
        mutex_init(&mms->mutex);
        if (page_num > 0) {
-               ret = codec_mm_page_alloc_all_locked(mms->pages_list, page_num,
-                       mms == smgt->cache_sc);
+               ret = codec_mm_page_alloc_all_locked(smgt,
+                               mms->pages_list, page_num,
+                               mms == smgt->cache_sc);
                if (ret <= 0)
                        goto error;
                mms->page_cnt = ret;
@@ -1429,11 +1487,11 @@ struct codec_mm_scatter *codec_mm_scatter_alloc_new(int max_page, int page_num)
        mms->page_used = mms->page_cnt;
        list_add_tail(&mms->list, &smgt->scatter_list);
        smgt->scatters_cnt++;
-       codec_mm_scatter_map_add_locked(mms);
+       codec_mm_scatter_map_add_locked(smgt, mms);
        codec_mm_list_unlock(smgt);
        return mms;
 error:
-       codec_mm_scatter_free_on_nouser(mms);
+       codec_mm_scatter_free_on_nouser_ext(smgt, mms, 1);
        return NULL;
 }
 EXPORT_SYMBOL(codec_mm_scatter_alloc_new);
@@ -1445,14 +1503,17 @@ EXPORT_SYMBOL(codec_mm_scatter_alloc_new);
 *      max pages == support 4k,need pages;
 *      page num = current size need pages;
 */
-struct codec_mm_scatter *codec_mm_scatter_alloc(int max_page, int page_num)
+struct codec_mm_scatter *codec_mm_scatter_alloc(
+       int max_page, int page_num,
+       int istvp)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
+       struct codec_mm_scatter_mgt *smgt;
        struct codec_mm_scatter *mms, *alloced_mms;
        struct list_head *pos, *next;
        int ret;
        u64 startus;
 
+       smgt = codec_mm_get_scatter_mgt(istvp);
        startus = codec_mm_get_current_us();
        alloced_mms = NULL;
        codec_mm_list_lock(smgt);
@@ -1480,17 +1541,17 @@ struct codec_mm_scatter *codec_mm_scatter_alloc(int max_page, int page_num)
                *just alloc mms first,
                *alloc pages later.
                */
-               alloced_mms = codec_mm_scatter_alloc_new(max_page, 0);
+               alloced_mms = codec_mm_scatter_alloc_new(smgt, max_page, 0);
        }
        if (alloced_mms) {
-               ret = codec_mm_scatter_alloc_want_pages_in(alloced_mms,
+               ret = codec_mm_scatter_alloc_want_pages_in(smgt, alloced_mms,
                        page_num);
                if (ret < 0) {
                        atomic_sub(1000, &alloced_mms->user_cnt);
                        return NULL;
                }
                /*pr_info("reused old mms! %p\n", alloced_mms);*/
-               codec_mm_update_alloc_time(startus);
+               codec_mm_update_alloc_time(smgt, startus);
                return alloced_mms;
        }
        return NULL;
@@ -1498,10 +1559,10 @@ struct codec_mm_scatter *codec_mm_scatter_alloc(int max_page, int page_num)
 EXPORT_SYMBOL(codec_mm_scatter_alloc);
 
 static int codec_mm_scatter_alloc_want_pages_in(
-               struct codec_mm_scatter *mms,
-               int want_pages)
+       struct codec_mm_scatter_mgt *smgt,
+       struct codec_mm_scatter *mms,
+       int want_pages)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int ret;
 
        if (want_pages > mms->page_max_cnt)
@@ -1510,6 +1571,7 @@ static int codec_mm_scatter_alloc_want_pages_in(
        mms->page_used = want_pages;
        if (want_pages > mms->page_cnt) {
                ret = codec_mm_page_alloc_all_locked(
+                               smgt,
                                &mms->pages_list[mms->page_tail + 1],
                                        want_pages - mms->page_cnt,
                                mms == smgt->cache_sc);
@@ -1530,7 +1592,7 @@ static int codec_mm_scatter_alloc_want_pages_in(
        codec_mm_scatter_unlock(mms);
        if (smgt->cached_pages < smgt->keep_size_PAGE / 2) {
                /*try alloc more cache.*/
-               codec_mm_schedule_delay_work(0, 1);
+               codec_mm_schedule_delay_work(smgt, 0, 1);
        }
        return 0;
 }
@@ -1539,19 +1601,22 @@ int codec_mm_scatter_alloc_want_pages(
                struct codec_mm_scatter *mms,
                int want_pages)
 {
+       struct codec_mm_scatter_mgt *smgt;
        int ret;
        u64 startus;
-
+       if (!mms)
+               return -1;
+       smgt = (struct codec_mm_scatter_mgt *)mms->manager;
        startus = codec_mm_get_current_us();
-       ret = codec_mm_scatter_alloc_want_pages_in(mms, want_pages);
-       codec_mm_update_alloc_time(startus);
+       ret = codec_mm_scatter_alloc_want_pages_in(
+               smgt, mms, want_pages);
+       codec_mm_update_alloc_time(smgt, startus);
        return ret;
 }
 EXPORT_SYMBOL(codec_mm_scatter_alloc_want_pages);
 
-int codec_mm_free_all_free_slots(void)
+int codec_mm_free_all_free_slots_in(struct codec_mm_scatter_mgt *smgt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_slot *slot, *to_free;
 
        do {
@@ -1576,15 +1641,23 @@ int codec_mm_free_all_free_slots(void)
                codec_mm_list_unlock(smgt);
                if (!to_free)
                        break;
-               codec_mm_slot_free(to_free);
+               codec_mm_slot_free(smgt, to_free);
        } while (1);
        return 0;
 }
 EXPORT_SYMBOL(codec_mm_free_all_free_slots);
 
-int codec_mm_scatter_info_dump(void *buf, int size)
+int codec_mm_free_all_free_slots(void)
+{
+       codec_mm_free_all_free_slots_in(codec_mm_get_scatter_mgt(0));
+       codec_mm_free_all_free_slots_in(codec_mm_get_scatter_mgt(1));
+       return 0;
+}
+
+static int codec_mm_scatter_info_dump_in(
+       struct codec_mm_scatter_mgt *smgt,
+       void *buf, int size)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        char *pbuf = buf;
        char sbuf[512];
        int tsize = 0;
@@ -1601,7 +1674,8 @@ int codec_mm_scatter_info_dump(void *buf, int size)
                        pbuf += s; \
                } while (0)
 
-       BUFPRINT("codec scattered memory info:\n");
+       BUFPRINT("codec %sscattered memory info:\n",
+               smgt->tvp_mode ? "TVP " : "");
        BUFPRINT("\ttotal size:%dM, %d Bytes,pages:%d\n",
                         (smgt->total_page_num << PAGE_SHIFT) / SZ_1M,
                         smgt->total_page_num << PAGE_SHIFT,
@@ -1670,6 +1744,28 @@ int codec_mm_scatter_info_dump(void *buf, int size)
 }
 EXPORT_SYMBOL(codec_mm_scatter_info_dump);
 
+int codec_mm_scatter_info_dump(
+       void *buf, int size)
+{
+       char *pbuf = buf;
+       int esize = size;
+       int ret;
+
+       ret = codec_mm_scatter_info_dump_in(
+               codec_mm_get_scatter_mgt(0),
+               pbuf,
+               esize);
+       if (buf != NULL && ret > 0) {
+               pbuf += ret;
+               esize -= ret;
+       }
+       ret += codec_mm_scatter_info_dump_in(
+               codec_mm_get_scatter_mgt(1),
+               pbuf,
+               esize);
+       return ret;
+}
+
 int codec_mm_dump_slot(struct codec_mm_slot *slot, void *buf, int size)
 {
        char *pbuf = buf;
@@ -1726,9 +1822,8 @@ int codec_mm_dump_slot(struct codec_mm_slot *slot, void *buf, int size)
 }
 EXPORT_SYMBOL(codec_mm_dump_slot);
 
-int codec_mm_dump_all_slots(void)
+int codec_mm_dump_all_slots_in(struct codec_mm_scatter_mgt *smgt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_slot *slot, *fslot;
        int total_pages = 0;
        int alloced_pages = 0;
@@ -1768,9 +1863,17 @@ int codec_mm_dump_all_slots(void)
 }
 EXPORT_SYMBOL(codec_mm_dump_all_slots);
 
-int codec_mm_dump_all_hash_table(void)
+int codec_mm_dump_all_slots(void)
+{
+       codec_mm_dump_all_slots_in(codec_mm_get_scatter_mgt(0));
+       codec_mm_dump_all_slots_in(codec_mm_get_scatter_mgt(1));
+       return 0;
+}
+
+
+int codec_mm_dump_all_hash_table_in(
+       struct codec_mm_scatter_mgt *smgt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_slot *slot, *fslot;
        int i;
        int total_pages = 0;
@@ -1815,9 +1918,16 @@ int codec_mm_dump_all_hash_table(void)
 }
 EXPORT_SYMBOL(codec_mm_dump_all_hash_table);
 
-int codec_mm_dump_free_slots(void)
+int codec_mm_dump_all_hash_table(void)
+{
+       codec_mm_dump_all_hash_table_in(codec_mm_get_scatter_mgt(0));
+       codec_mm_dump_all_hash_table_in(codec_mm_get_scatter_mgt(1));
+       return 0;
+}
+
+
+static int codec_mm_dump_free_slots_in(struct codec_mm_scatter_mgt *smgt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_slot *slot;
        int total_pages = 0;
        int alloced_pages = 0;
@@ -1846,7 +1956,16 @@ int codec_mm_dump_free_slots(void)
 }
 EXPORT_SYMBOL(codec_mm_dump_free_slots);
 
-int codec_mm_dump_scatter(struct codec_mm_scatter *mms, void *buf, int size)
+int codec_mm_dump_free_slots(void)
+{
+       codec_mm_dump_free_slots_in(codec_mm_get_scatter_mgt(0));
+       codec_mm_dump_free_slots_in(codec_mm_get_scatter_mgt(1));
+       return 0;
+}
+
+int codec_mm_dump_scatter(
+       struct codec_mm_scatter *mms,
+       void *buf, int size)
 {
        char *pbuf = buf;
        char sbuf[512];
@@ -1886,9 +2005,8 @@ int codec_mm_dump_scatter(struct codec_mm_scatter *mms, void *buf, int size)
 }
 EXPORT_SYMBOL(codec_mm_dump_scatter);
 
-int codec_mm_dump_all_scatters(void)
+static  int codec_mm_dump_all_scatters_in(struct codec_mm_scatter_mgt *smgt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        struct codec_mm_scatter *mms;
        struct list_head *pos, *tmp;
 
@@ -1911,137 +2029,39 @@ int codec_mm_dump_all_scatters(void)
 }
 EXPORT_SYMBOL(codec_mm_dump_all_scatters);
 
-struct sc_configs {
-       int id;
-       const char *name;
-};
-
-enum config_id {
-       ID0_KEEP_SIZE,
-       ID1_RES_BLK_SIZEM,
-       ID2_ONCE_CMA_SIZEM,
-       ID3_MAX_SYS_PAGES,
-       ID4_MIN_SYS_PAGES,
-       ID5_SLOT_FROM_SYS,
-       ID6_NO_CACHE_SIZE,
-       IDX_MAX,
-};
-struct sc_configs sc_global_config[] = {
-       {ID0_KEEP_SIZE, "keep_size"},
-       {ID1_RES_BLK_SIZEM, "res_blk_size"},
-       {ID2_ONCE_CMA_SIZEM, "once_cma_size"},
-       {ID3_MAX_SYS_PAGES, "max_sys_pages"},
-       {ID4_MIN_SYS_PAGES, "min_sys_pages"},
-       {ID5_SLOT_FROM_SYS, "enable_slot_from_sys"},
-       {ID6_NO_CACHE_SIZE, "no_cache_size_M"},
-};
-
-static int codec_mm_scatter_mgt_get_config_in(int id)
-{
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
-
-       switch (id) {
-       case ID0_KEEP_SIZE:
-               return (smgt->keep_size_PAGE << PAGE_SHIFT) / SZ_1M;
-       case ID1_RES_BLK_SIZEM:
-               return smgt->reserved_block_mm_M;
-       case ID2_ONCE_CMA_SIZEM:
-               return smgt->try_alloc_in_cma_page_cnt;
-       case ID3_MAX_SYS_PAGES:
-               return smgt->try_alloc_in_sys_page_cnt_max;
-       case ID4_MIN_SYS_PAGES:
-               return smgt->try_alloc_in_sys_page_cnt_min;
-       case ID5_SLOT_FROM_SYS:
-               return smgt->enable_slot_from_sys;
-       case ID6_NO_CACHE_SIZE:
-               return smgt->no_cache_size_M;
-       default:
-               return 0;
-       }
-       return -1;
-}
-
-static int codec_mm_scatter_mgt_set_config_in(int id, int newset)
+int codec_mm_dump_all_scatters(void)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
-       int val;
-
-       switch (id) {
-       case ID0_KEEP_SIZE:
-               val = newset * (SZ_1M >> PAGE_SHIFT);
-               smgt->keep_size_PAGE = val;
-               break;
-       case ID1_RES_BLK_SIZEM:
-               smgt->reserved_block_mm_M = newset;
-               break;
-       case ID2_ONCE_CMA_SIZEM:
-               smgt->try_alloc_in_cma_page_cnt = newset;
-               break;
-       case ID3_MAX_SYS_PAGES:
-               smgt->try_alloc_in_sys_page_cnt_max = newset;
-               break;
-       case ID4_MIN_SYS_PAGES:
-               smgt->try_alloc_in_sys_page_cnt_min = newset;
-               break;
-       case ID5_SLOT_FROM_SYS:
-               smgt->enable_slot_from_sys = newset;
-               smgt->support_from_slot_sys = newset;
-               break;
-       case ID6_NO_CACHE_SIZE:
-               smgt->no_cache_size_M = newset;
-               break;
-       default:
-               return -1;
-       }
+       codec_mm_dump_all_scatters_in(codec_mm_get_scatter_mgt(0));
+       codec_mm_dump_all_scatters_in(codec_mm_get_scatter_mgt(1));
        return 0;
 }
 
-int codec_mm_scatter_mgt_get_config(char *buf)
-{
-       size_t ret = 0;
-       int i;
 
-       for (i = 0; i < IDX_MAX; i++) {
-               ret += sprintf(buf + ret,
-                       "scatter:%s:%d\n",
-                       sc_global_config[i].name,
-                       codec_mm_scatter_mgt_get_config_in(i));
-       }
-       return ret;
-}
-EXPORT_SYMBOL(codec_mm_scatter_mgt_get_config);
 
-int codec_mm_scatter_mgt_set_config(const char *buf, size_t size)
+int codec_mm_scatter_update_config(struct codec_mm_scatter_mgt *smgt)
 {
-       size_t ret = 0;
-       char *str;
-       int i;
-       int val;
-
-       for (i = 0; i < IDX_MAX; i++) {
-               str = strstr(buf, sc_global_config[i].name);
-               if (!str)
-                       continue;       /*to next. */
-               str += strlen(sc_global_config[i].name);
-               if (str[0] != ':' || str[1] == '\0')
-                       continue;       /*to next. */
-               ret = sscanf(str, ":%d", &val);
-               if (ret == 1) {
-                       codec_mm_scatter_mgt_set_config_in(i, val);
-                       return size;
-               }
-       }
-       pr_info("unknown cmd %s\n", buf);
-       return -1;
+       smgt->keep_size_PAGE = g_scatter.keep_size_PAGE;
+       smgt->reserved_block_mm_M = g_scatter.reserved_block_mm_M;
+       smgt->try_alloc_in_cma_page_cnt = g_scatter.try_alloc_in_cma_page_cnt;
+       smgt->try_alloc_in_sys_page_cnt_max
+               = g_scatter.try_alloc_in_sys_page_cnt_max;
+       smgt->try_alloc_in_sys_page_cnt_min
+               = g_scatter.try_alloc_in_sys_page_cnt_min;
+       smgt->enable_slot_from_sys = g_scatter.enable_slot_from_sys;
+       smgt->support_from_slot_sys = g_scatter.support_from_slot_sys;
+       smgt->no_cache_size_M = g_scatter.no_cache_size_M;
+       return 0;
 }
-EXPORT_SYMBOL(codec_mm_scatter_mgt_set_config);
 
-int codec_mm_scatter_mgt_delay_free_swith(int on,
+int codec_mm_scatter_mgt_delay_free_swith(
+       int on,
        int delay_ms,
-       int wait_size_M)
+       int wait_size_M,
+       int is_tvp)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
+       struct codec_mm_scatter_mgt *smgt;
 
+       smgt = codec_mm_get_scatter_mgt(is_tvp);
        codec_mm_list_lock(smgt);
        if (on) {
                smgt->delay_free_on++;
@@ -2064,7 +2084,7 @@ int codec_mm_scatter_mgt_delay_free_swith(int on,
                smgt->force_cache_page_cnt = wait_size_M >> PAGE_SHIFT;
                smgt->delay_free_timeout_jiffies64 =
                        get_jiffies_64() + 10000 * HZ/1000;
-               codec_mm_schedule_delay_work(0, 1);/*start cache*/
+               codec_mm_schedule_delay_work(smgt, 0, 1);/*start cache*/
                while (smgt->cached_pages < smgt->force_cache_page_cnt) {
                        if (smgt->cache_sc &&
                                (smgt->cached_pages >=
@@ -2085,15 +2105,16 @@ int codec_mm_scatter_mgt_delay_free_swith(int on,
                smgt->delay_free_timeout_jiffies64 =
                        get_jiffies_64() + delay_ms * HZ/1000;
        } else if (on) {
-               codec_mm_schedule_delay_work(0, 1);
+               codec_mm_schedule_delay_work(smgt, 0, 1);
        } else {
-               codec_mm_schedule_delay_work(delay_ms, 0);
+               codec_mm_schedule_delay_work(smgt, delay_ms, 0);
        }
        return 0;
 }
 EXPORT_SYMBOL(codec_mm_scatter_mgt_delay_free_swith);
 
-static void codec_mm_scatter_cache_manage(struct codec_mm_scatter_mgt *smgt)
+static void codec_mm_scatter_cache_manage(
+       struct codec_mm_scatter_mgt *smgt)
 {
        struct codec_mm_scatter *mms;
        int alloced = 0;
@@ -2137,6 +2158,7 @@ static void codec_mm_scatter_cache_manage(struct codec_mm_scatter_mgt *smgt)
                                if (need > mms->page_cnt) {
                                        alloced =
                                        !codec_mm_scatter_alloc_want_pages_in(
+                                               smgt,
                                                mms,
                                                need);
                                } else {
@@ -2145,8 +2167,6 @@ static void codec_mm_scatter_cache_manage(struct codec_mm_scatter_mgt *smgt)
                        } else {
                                alloced = 0;
                        }
-               /*int from_sys = codec_mm_get_free_size() < 16 * SZ_1M;*/
-               /*alloced = !!codec_mm_slot_alloc(0, (from_sys ? 1 : 0));*/
                } else if ((smgt->cached_pages >
                        (smgt->keep_size_PAGE + 1000)) &&
                        time_after64(get_jiffies_64(),
@@ -2161,33 +2181,35 @@ static void codec_mm_scatter_cache_manage(struct codec_mm_scatter_mgt *smgt)
                                codec_mm_scatter_free_tail_pages(mms,
                                        free_start);
                        }
-                       codec_mm_free_all_free_slots();
-                       /*free some slots. */
+                       codec_mm_free_all_free_slots_in(smgt);
+                       /*free some slots.*/
                }
        } else if (smgt->delay_free_on <= 0 &&
                        time_after64(get_jiffies_64(),
                        smgt->delay_free_timeout_jiffies64)) {
                /*free all free pages, no delay needed.*/
-               codec_mm_free_all_free_slots();
+               codec_mm_free_all_free_slots_in(smgt);
        }
        if (smgt->keep_size_PAGE > 0 && smgt->delay_free_on) {
                if (((smgt->force_cache_on ||
                          (total_free_page < smgt->keep_size_PAGE)) &&
-                       !codec_mm_video_tvp_enabled()) &&
+                       !smgt->tvp_mode) &&
                        alloced) {/*if failed may deadlock...*/
                        /*ignore keep on tvp mode.*/
                        if (smgt->force_cache_on)
-                               codec_mm_schedule_delay_work(0, 1);
+                               codec_mm_schedule_delay_work(smgt, 0, 1);
                        else
-                               codec_mm_schedule_delay_work(10, 0);
+                               codec_mm_schedule_delay_work(smgt, 10, 0);
                } else
-                       codec_mm_schedule_delay_work(100, 0);
+                       codec_mm_schedule_delay_work(smgt, 100, 0);
        } else if (!smgt->delay_free_on && smgt->total_page_num > 0) {
-               codec_mm_schedule_delay_work(100, 0);
+               codec_mm_schedule_delay_work(smgt, 100, 0);
        }
 }
 
-static int codec_mm_scatter_scatter_arrange(struct codec_mm_scatter_mgt *smgt)
+
+static int codec_mm_scatter_scatter_arrange(
+       struct codec_mm_scatter_mgt *smgt)
 {
        struct codec_mm_scatter *mms;
        struct codec_mm_scatter *first_free_mms = NULL;
@@ -2195,8 +2217,8 @@ static int codec_mm_scatter_scatter_arrange(struct codec_mm_scatter_mgt *smgt)
        int n = 0;
 
        if (smgt->delay_free_on > 0 && !smgt->cache_sc) {
-               /*no free scatter. */
-               mms = codec_mm_scatter_alloc_new(16384, 0);
+               /*no free scatter.*/
+               mms = codec_mm_scatter_alloc_new(smgt, 16384, 0);
                if (mms) {
                        codec_mm_list_lock(smgt);
                        list_del_init(&mms->list);
@@ -2213,7 +2235,7 @@ static int codec_mm_scatter_scatter_arrange(struct codec_mm_scatter_mgt *smgt)
                smgt->cached_pages = 0;
                codec_mm_list_unlock(smgt);
                codec_mm_scatter_dec_owner_user(mms, 0);
-               codec_mm_scatter_free_on_nouser(mms);
+               codec_mm_scatter_free_on_nouser(smgt, mms);
        }
 
        codec_mm_list_lock(smgt);
@@ -2282,7 +2304,7 @@ static int codec_mm_scatter_scatter_clear(
        }
        codec_mm_list_unlock(smgt);
        if (to_free_mms != NULL)
-               codec_mm_scatter_free_on_nouser(to_free_mms);
+               codec_mm_scatter_free_on_nouser(smgt, to_free_mms);
        if (less_page_mms && (less_page_mms != to_free_mms))
                codec_mm_scatter_free_unused_pages(less_page_mms);
        return (to_free_mms != NULL) || (less_page_mms != NULL);
@@ -2295,11 +2317,12 @@ static int codec_mm_scatter_scatter_clear(
 *0 is all freeed.
 *N is have some pages not alloced.
 */
-int codec_mm_scatter_free_all_ignorecache(void)
+static int codec_mm_scatter_free_all_ignorecache_in(
+       struct codec_mm_scatter_mgt *smgt)
 {
-       struct codec_mm_scatter_mgt *smgt = codec_mm_get_scatter_mgt();
        int need_retry = 1;
        int retry_num = 0;
+
        mutex_lock(&smgt->monitor_lock);
        pr_info("force free all scatter ignorecache!\n");
        do {
@@ -2314,7 +2337,7 @@ int codec_mm_scatter_free_all_ignorecache(void)
                codec_mm_list_unlock(smgt);
                if (mms) {
                        codec_mm_scatter_dec_owner_user(mms, 0);
-                       codec_mm_scatter_free_on_nouser(mms);
+                       codec_mm_scatter_free_on_nouser(smgt, mms);
                }
                /*alloced again on timer?*/
                  /* check again. */
@@ -2326,7 +2349,7 @@ int codec_mm_scatter_free_all_ignorecache(void)
                pr_info("can't free all scatter, because some have used!!\n");
                codec_mm_dump_all_scatters();
        }
-       codec_mm_free_all_free_slots();
+       codec_mm_free_all_free_slots_in(smgt);
        if (smgt->total_page_num > 0) {
                /*have some not free,dump tables for debug */
                pr_info("Some slots have not free!!\n\n");
@@ -2337,12 +2360,25 @@ int codec_mm_scatter_free_all_ignorecache(void)
 }
 EXPORT_SYMBOL(codec_mm_scatter_free_all_ignorecache);
 
+int codec_mm_scatter_free_all_ignorecache(int flags)
+{
+       if (flags & 1)
+               codec_mm_scatter_free_all_ignorecache_in(
+                       codec_mm_get_scatter_mgt(0));
+       if (flags & 2)
+               codec_mm_scatter_free_all_ignorecache_in(
+                       codec_mm_get_scatter_mgt(1));
+       return 0;
+}
+
 static void codec_mm_scatter_monitor(struct work_struct *work)
 {
        struct codec_mm_scatter_mgt *smgt = container_of(work,
                                        struct codec_mm_scatter_mgt,
                                        dealy_work.work);
        int needretry = 0;
+
+       codec_mm_scatter_update_config(smgt);
        mutex_lock(&smgt->monitor_lock);
        smgt->scatter_task_run_num++;
 
@@ -2350,49 +2386,97 @@ static void codec_mm_scatter_monitor(struct work_struct *work)
        needretry = codec_mm_scatter_scatter_clear(smgt, 0);
 
        if (needretry)
-               codec_mm_schedule_delay_work(10, 0);
+               codec_mm_schedule_delay_work(smgt, 10, 0);
        else if (smgt->scatters_cnt > 0)
-               codec_mm_schedule_delay_work(100, 0);
+               codec_mm_schedule_delay_work(smgt, 100, 0);
        codec_mm_scatter_cache_manage(smgt);
        mutex_unlock(&smgt->monitor_lock);
 }
 
-int codec_mm_scatter_mgt_init(void)
+static int codec_mm_scatter_mgt_alloc_in(struct codec_mm_scatter_mgt **psmgt)
 {
-       scatter_mgt = kmalloc(sizeof(struct codec_mm_scatter_mgt), GFP_KERNEL);
-       if (!scatter_mgt) {
+       struct codec_mm_scatter_mgt *smgt;
+
+       smgt = kmalloc(sizeof(struct codec_mm_scatter_mgt), GFP_KERNEL);
+       if (!smgt) {
                ERR_LOG("ERR:codec mm mpt init ERROR\n");
                return -1;
        }
-       memset(scatter_mgt, 0, sizeof(struct codec_mm_scatter_mgt));
-       spin_lock_init(&scatter_mgt->list_lock);
-       scatter_mgt->alloced_page_num = 0;
-       scatter_mgt->try_alloc_in_cma_page_cnt = (4 * 1024 * 1024) / PAGE_SIZE;
-       scatter_mgt->try_alloc_in_sys_page_cnt_max = MAX_SYS_BLOCK_PAGE;
-       scatter_mgt->try_alloc_in_sys_page_cnt = MAX_SYS_BLOCK_PAGE;
-       scatter_mgt->try_alloc_in_sys_page_cnt_min = MIN_SYS_BLOCK_PAGE;
-       scatter_mgt->reserved_block_mm_M = 64;
-       scatter_mgt->keep_size_PAGE = 20 * SZ_1M >> PAGE_SHIFT;
-       scatter_mgt->alloc_from_cma_first = 1;
-       scatter_mgt->enable_slot_from_sys = 1;
-       scatter_mgt->support_from_slot_sys =
-               scatter_mgt->enable_slot_from_sys;
+       memset(smgt, 0, sizeof(struct codec_mm_scatter_mgt));
+       spin_lock_init(&smgt->list_lock);
+       smgt->tag = SMGT_IDENTIFY_TAG;
+       smgt->alloced_page_num = 0;
+       smgt->try_alloc_in_cma_page_cnt = (4 * 1024 * 1024) / PAGE_SIZE;
+       smgt->try_alloc_in_sys_page_cnt_max = MAX_SYS_BLOCK_PAGE;
+       smgt->try_alloc_in_sys_page_cnt = MAX_SYS_BLOCK_PAGE;
+       smgt->try_alloc_in_sys_page_cnt_min = MIN_SYS_BLOCK_PAGE;
+       smgt->reserved_block_mm_M = 64;
+       smgt->keep_size_PAGE = 20 * SZ_1M >> PAGE_SHIFT;
+       smgt->alloc_from_cma_first = 1;
+       smgt->enable_slot_from_sys = 1;
+       smgt->support_from_slot_sys =
+               smgt->enable_slot_from_sys;
+       smgt->mem_flags = CODEC_MM_FLAGS_CMA_FIRST |
+                                       CODEC_MM_FLAGS_FOR_VDECODER |
+                                       CODEC_MM_FLAGS_FOR_SCATTER;
        if ((totalram_pages << PAGE_SHIFT) < 800 * SZ_1M) {
                /*less memory boards don't cache more,*/
                /*after alloced many pages.*/
-               scatter_mgt->no_cache_size_M = 100;
+               smgt->no_cache_size_M = 100;
        } else
-               scatter_mgt->no_cache_size_M = 0;
-       INIT_LIST_HEAD(&scatter_mgt->free_list);
-       INIT_LIST_HEAD(&scatter_mgt->scatter_list);
-       mutex_init(&scatter_mgt->monitor_lock);
+               smgt->no_cache_size_M = 0;
+       INIT_LIST_HEAD(&smgt->free_list);
+       INIT_LIST_HEAD(&smgt->scatter_list);
+       mutex_init(&smgt->monitor_lock);
 
-       INIT_DELAYED_WORK(&scatter_mgt->dealy_work,
+       INIT_DELAYED_WORK(&smgt->dealy_work,
                                codec_mm_scatter_monitor);
+       *psmgt = smgt;
+       return 0;
+}
 
+static struct mconfig codec_mm_sc_configs[] = {
+       MC_PU32("keep_size_PAGE", &g_scatter.keep_size_PAGE),
+       MC_PU32("reserved_block_mm_M", &g_scatter.reserved_block_mm_M),
+       MC_PU32("try_alloc_in_cma_page_cnt",
+               &g_scatter.try_alloc_in_cma_page_cnt),
+       MC_PU32("try_alloc_in_sys_page_cnt_max",
+               &g_scatter.try_alloc_in_sys_page_cnt_max),
+       MC_PU32("try_alloc_in_sys_page_cnt_min",
+               &g_scatter.try_alloc_in_sys_page_cnt_min),
+       MC_PU32("enable_slot_from_sys",
+               &g_scatter.enable_slot_from_sys),
+       MC_PU32("no_cache_size_M", &g_scatter.no_cache_size_M),
+};
+
+static struct mconfig_node codec_mm_sc;
+
+int codec_mm_scatter_mgt_init(void)
+{
+       struct codec_mm_scatter_mgt *smgt;
+
+       codec_mm_scatter_mgt_alloc_in(&scatter_mgt);
+       codec_mm_scatter_mgt_alloc_in(&scatter_tvp_mgt);
+       scatter_tvp_mgt->tvp_mode = 1;
+       scatter_tvp_mgt->mem_flags |= CODEC_MM_FLAGS_TVP;
+       smgt = scatter_mgt;
+       g_scatter.keep_size_PAGE = smgt->keep_size_PAGE;
+       g_scatter.reserved_block_mm_M = smgt->reserved_block_mm_M;
+       g_scatter.try_alloc_in_cma_page_cnt = smgt->try_alloc_in_cma_page_cnt;
+       g_scatter.try_alloc_in_sys_page_cnt_max
+               = smgt->try_alloc_in_sys_page_cnt_max;
+       g_scatter.try_alloc_in_sys_page_cnt_min
+               = smgt->try_alloc_in_sys_page_cnt_min;
+       g_scatter.enable_slot_from_sys = smgt->enable_slot_from_sys;
+       g_scatter.support_from_slot_sys = smgt->support_from_slot_sys;
+       g_scatter.no_cache_size_M = smgt->no_cache_size_M;
+
+       INIT_REG_NODE_CONFIGS("media.codec_mm",
+               &codec_mm_sc, "scatter",
+               codec_mm_sc_configs,
+               CONFIG_FOR_RW);
        return 0;
 }
-EXPORT_SYMBOL(codec_mm_scatter_mgt_init);
 
 int codec_mm_scatter_mgt_test(void)
 {
@@ -2489,8 +2573,10 @@ int codec_mm_scatter_test(int mode, int p1, int p2)
                INFO_LOG(" alloc sc[%d] num %d:\n", p1, p2);
                if (p1 > 0 && p1 < 64) {
                        if (sc[p1])
-                               codec_mm_scatter_free_on_nouser(sc[p1]);
-                       sc[p1] = codec_mm_scatter_alloc(p2 * 2, p2);
+                               codec_mm_scatter_free_on_nouser(
+                               (struct codec_mm_scatter_mgt *)sc[p1]->manager,
+                               sc[p1]);
+                       sc[p1] = codec_mm_scatter_alloc(p2 * 2, p2, 0);
                }
                break;
        case 2:         /*alloc more */
@@ -2506,7 +2592,9 @@ int codec_mm_scatter_test(int mode, int p1, int p2)
        case 4:
                INFO_LOG(" free sc[%d] all\n", p1);
                if (p1 > 0 && p1 < 64 && sc[p1]) {
-                       codec_mm_scatter_free_on_nouser(sc[p1]);
+                       codec_mm_scatter_free_on_nouser(
+                       (struct codec_mm_scatter_mgt *)sc[p1]->manager,
+                       sc[p1]);
                        sc[p1] = NULL;
                }
                break;
index 0d636ec..5695af4 100644 (file)
@@ -64,8 +64,8 @@ int codec_mm_scatter_dec_keeper_user(void *sc_mm, int delay_ms);
 int codec_mm_scatter_mgt_get_config(char *buf);
 int codec_mm_scatter_mgt_set_config(const char *buf, size_t size);
 
-int codec_mm_scatter_free_all_ignorecache(void);
-int codec_mm_scatter_valid_locked(struct codec_mm_scatter *mms);
+int codec_mm_scatter_free_all_ignorecache(int flags);
+
 
 void codec_mm_clear_alloc_infos(void);
 
diff --git a/drivers/amlogic/media/common/codec_mm/configs/Makefile b/drivers/amlogic/media/common/codec_mm/configs/Makefile
new file mode 100644 (file)
index 0000000..c95b63b
--- /dev/null
@@ -0,0 +1,14 @@
+##########################################
+########## Amlogic codec memory manager ###############
+##########################################
+
+##########################################
+## The order of directories matter.
+## Do not change.
+##########################################
+
+
+obj-$(CONFIG_AMLOGIC_MEDIA_CODEC_MM)   += configs.o configs_module.o
+obj-$(CONFIG_AMLOGIC_MEDIA_CODEC_MM)   += configs_test.o
+
+
diff --git a/drivers/amlogic/media/common/codec_mm/configs/configs.c b/drivers/amlogic/media/common/codec_mm/configs/configs.c
new file mode 100644 (file)
index 0000000..87fbb8c
--- /dev/null
@@ -0,0 +1,1094 @@
+/*
+ * drivers/amlogic/media/common/codec_mm/configs/configs.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/amlogic/media/codec_mm/configs.h>
+#include "configs_priv.h"
+static struct mconfig_node root_node;
+static struct mconfig_node *configs_get_root_node(void)
+{
+       return &root_node;
+}
+
+#ifdef DEBUG_CONFIG
+#define config_debug(args...) pr_info(args)
+#else
+#define config_debug(args...)
+#endif
+int configs_inc_node_ref(
+       struct mconfig_node *node)
+{
+       return atomic_inc_return(&node->ref_cnt);
+}
+
+int configs_dec_node_ref(
+       struct mconfig_node *node)
+{
+       return atomic_dec_return(&node->ref_cnt);
+}
+
+static int configs_put_node(struct mconfig_node *node,
+       int del_parent_ref, struct mconfig_node *root_node)
+{
+       struct mconfig_node *pnode;
+
+       if (!node)
+               return 0;
+       configs_dec_node_ref(node);
+       pnode = node->parent_node;
+       if (!del_parent_ref)
+               return 0;
+       while ((pnode != NULL) && (pnode != root_node)) {
+               configs_dec_node_ref(pnode);
+               pnode = pnode->parent_node;
+       }
+       return 0;
+}
+
+
+static int configs_parser_first_node(
+       const char *root_str,
+       char *sub_str,
+       int sub_size,
+       int *is_end_node)
+{
+       int node_size;
+       char *str;
+       char *pstr;
+
+       if (strlen(root_str) <= 0)
+               return 0;
+       str = strchr(root_str, '.');
+       if (str != NULL) {
+               node_size = str - root_str;
+               *is_end_node = 0;
+       } else {
+               str = strchr(root_str, '=');
+               if (str != NULL)
+                       node_size = str - root_str;
+               else
+                       node_size = strlen(root_str);
+               *is_end_node = 1;
+       }
+       if (node_size >= MAX_ITEM_NAME - 1)
+               node_size = MAX_ITEM_NAME - 1;
+       if (node_size > 0) {
+               strncpy(sub_str, root_str, node_size);
+               sub_str[node_size] = '\0';
+               pstr = sub_str;
+               while (pstr[0] != '\0' &&
+                       pstr[0] != ' ' &&
+                       pstr[0] != '\r' &&
+                       pstr[0] != '\n') {
+                       /*not space. */
+                       pstr++;
+               }
+               pstr[0] = '\0';
+       } else
+               sub_str[0] = '\0';
+       return node_size;
+}
+
+static inline const char *configs_parser_str_valstr(
+       const char *root_str)
+{
+       char *str;
+
+       if (strlen(root_str) <= 0)
+               return NULL;
+       str = strchr(root_str, '=');
+       if (str)
+               str = str + 1;  /*del = */
+       return str;
+}
+
+static int configs_parser_value_u32(const char *str, u32 *val)
+{
+       int ret = 0;
+       const char *pstr;
+
+       if (!str || strlen(str) <= 0)
+               return 0;
+       pstr = str;
+       while (pstr[0] == ' ')
+               pstr++;
+       if (pstr[0] == '-') {
+               ret = sscanf(pstr, "-%d", val);
+               *val = -((int)*val);
+       } else if (strstr(pstr, "0x"))
+               ret = sscanf(pstr, "0x%x", val);
+       else if (strstr(pstr, "0x"))
+               ret = sscanf(pstr, "0x%x", val);
+       else {
+               ret = kstrtou32(pstr, 0, val);
+               if (ret == 0)
+                       ret = 1;
+       }
+       return ret;
+}
+
+static int configs_parser_value_u64(const char *str, u64 *val)
+{
+       int ret = 0;
+       const char *pstr;
+
+       if (!str || strlen(str) <= 0)
+               return 0;
+       pstr = str;
+       while (pstr[0] == ' ')
+               pstr++;
+       if (pstr[0] == '-') {
+               ret = sscanf(pstr, "-%lld", val);
+               *val = -((int)*val);
+       } else if (strstr(pstr, "0x"))
+               ret = sscanf(pstr, "0x%llx", val);
+       else if (strstr(pstr, "0x"))
+               ret = sscanf(pstr, "0x%llx", val);
+       else {
+               ret = kstrtou64(pstr, 0, val);
+               if (ret == 0)
+                       ret = 1;
+       }
+       return ret;
+}
+
+static int configs_parser_value_bool(const char *str, bool *pbool)
+{
+       const char *pstr;
+
+       if (!str || strlen(str) <= 0)
+               return 0;
+       pstr = str;
+       while (pstr[0] == ' ')
+               pstr++;
+       if (str[0] == '1') {
+               *pbool = true;
+       } else if (str[0] == '0') {
+               *pbool = false;
+       } else if (!strcmp(str, "true") ||
+                       !strcmp(str, "TRUE") ||
+                       !strcmp(str, "true")) {
+               *pbool = true;
+       } else if (strcmp(str, "false") ||
+                       !strcmp(str, "FALSE") ||
+                       !strcmp(str, "False")) {
+               *pbool = false;
+       } else {
+               return 0;
+       }
+       return 1;
+}
+
+
+static struct mconfig_node *configs_get_node_with_name(
+       struct mconfig_node
+       *rootnode, const char *node_name)
+{
+       struct mconfig_node *snode, *need;
+       struct list_head *node_list, *next;
+
+       need = NULL;
+       if (!rootnode)
+               rootnode = configs_get_root_node();
+       mutex_lock(&rootnode->lock);
+       if (list_empty(&rootnode->son_node_list)) {
+               mutex_unlock(&rootnode->lock);
+               return NULL;
+       }
+       list_for_each_safe(node_list, next, &rootnode->son_node_list) {
+               snode = list_entry(node_list, struct mconfig_node, list);
+               if (!strcmp(snode->name, node_name)) {
+                       need = snode;
+                       if (snode->active <= 0 ||
+                               configs_inc_node_ref(need) < 0)
+                               need = NULL;
+                       break;
+               }
+       }
+       mutex_unlock(&rootnode->lock);
+       return need;
+}
+
+int configs_init_new_node(struct mconfig_node *node,
+       const char *name, int rw_flags)
+{
+       node->configs = NULL;
+       node->configs_num = 0;
+       node->son_node_num = 0;
+       node->name = name;
+       node->rw_flags = rw_flags;
+       node->depth = 0;
+       node->active = 1;
+       node->prefix[0] = '\0';
+       atomic_set(&node->ref_cnt, 0);
+       mutex_init(&node->lock);
+       INIT_LIST_HEAD(&node->list);
+       INIT_LIST_HEAD(&node->son_node_list);
+       return 0;
+}
+EXPORT_SYMBOL(configs_init_new_node);
+
+int configs_register_node(struct mconfig_node *parent,
+       struct mconfig_node *new_node)
+{
+       if (!parent)
+               parent = configs_get_root_node();
+       if (!parent || new_node == parent)
+               return 0;       /*top node add. */
+       if (parent->depth >= MAX_DEPTH)
+               return -1;      /*too deep path */
+       if (strlen(parent->prefix) + strlen(parent->name) >=
+                       MAX_PREFIX_NAME - 2) {
+               pr_err("unsupport deep path %s.%s,len=%d > %d\n",
+                      parent->prefix, parent->name,
+                      (int)(strlen(parent->prefix) + strlen(parent->name) + 1),
+                      MAX_PREFIX_NAME - 1);
+               return -2;      /*unsuport deep path */
+       }
+       if (configs_get_node_with_name(parent, new_node->name) != NULL) {
+               pr_err("have register same node[%s] on %s before\n",
+                       new_node->name, parent->name);
+               return -3;
+       }
+       /*
+        *root.name.bb
+        *depth:0.1.2
+        *depth 0 &1 don't sed prefix.
+        *for ignore "root."
+        */
+       new_node->depth = parent->depth + 1;
+       if (new_node->depth >= 2) {
+               if (parent->prefix[0]) {
+                       strcpy(new_node->prefix, parent->prefix);
+                       strcat(new_node->prefix, ".");
+               }
+               strcat(new_node->prefix, parent->name);
+       }
+       mutex_lock(&parent->lock);
+       new_node->parent_node = parent;
+       list_add_tail(&new_node->list, &parent->son_node_list);
+       /*
+        *node parent not have write permissions,
+        *del the the node write permissions;
+        *same as read.
+        */
+       new_node->rw_flags = parent->rw_flags & new_node->rw_flags;
+       parent->son_node_num++;
+       new_node->active = 1;
+       mutex_unlock(&parent->lock);
+       return 0;
+}
+EXPORT_SYMBOL(configs_register_node);
+
+static struct mconfig_node *configs_get_node_path_end_node(
+       struct mconfig_node *root_node, const char *path)
+{
+       char sub_node_name[128];
+       struct mconfig_node *node, *start_node, *parent_node;
+       int i, end;
+       const char *next_path = path;
+
+       if (!path)
+               return NULL;
+       end = 0;
+       start_node = root_node;
+       if (!root_node)
+               start_node = configs_get_root_node();
+       node = start_node;
+       while (!end) {
+               parent_node = node;
+               i = configs_parser_first_node(next_path,
+                       sub_node_name, 128, &end);
+               if (i <= 0 || sub_node_name[0] == '\0') {
+                       pr_err("can't find [%s] 's node!!\n", path);
+                       return NULL;
+               }
+               /*only no top node. */
+               if (end && !root_node && node == start_node) {
+                       if (!strcmp(node->name, sub_node_name)) {
+                               /*need node is top node */
+                               break;
+                       }
+               }
+               config_debug("configs_parser_first_node{%s} end%d\n",
+                       sub_node_name, end);
+               node = configs_get_node_with_name(parent_node,
+                       sub_node_name);
+               if (node == NULL) {
+                       pr_err("can't find node:[%s], from:[%s], path=%s\n",
+                               sub_node_name, parent_node->name, path);
+                       return NULL;
+               }
+               next_path = next_path + i + 1;  /*media.vdec --> vdec */
+               config_debug("get snode[%s] from node[%s], end=%d\n",
+                       node->name, parent_node->name, end);
+       }
+       return node;
+}
+EXPORT_SYMBOL(configs_get_node_path_end_node);
+
+int configs_register_path_node(const char *path,
+       struct mconfig_node *new_node)
+{
+       struct mconfig_node *parent = NULL;
+       int ret;
+
+       if (path && strlen(path) > 0) {
+               parent = configs_get_node_path_end_node(NULL, path);
+               if (!parent)
+                       return -1;
+       }
+       ret = configs_register_node(parent, new_node);
+       configs_put_node(parent, 1, NULL);
+       return ret;
+}
+EXPORT_SYMBOL(configs_register_path_node);
+
+int configs_register_configs(struct mconfig_node *node,
+       struct mconfig *configs, int num)
+{
+       if (!node)
+               return -1;
+       if (node->configs != NULL || node->configs_num > 0) {
+               pr_err("node[%s] register config before!.\n", node->name);
+               return -2;
+       }
+       if (0) {
+               int i;
+
+               for (i = 0; i < num; i++) {
+                       pr_info("init node:%s, config[i].data %lx-%lx\n",
+                               node->name,
+                               configs[i].ldata[0],
+                               configs[i].ldata[1]);
+               }
+       }
+       mutex_lock(&node->lock);
+       node->configs = configs;
+       node->configs_num = num;
+       mutex_unlock(&node->lock);
+       return 0;
+}
+EXPORT_SYMBOL(configs_register_configs);
+
+int configs_register_path_configs(const char *path,
+       struct mconfig *configs, int num)
+{
+       struct mconfig_node *parent = NULL;
+       int ret;
+
+       if (path && strlen(path) > 0) {
+               parent = configs_get_node_path_end_node(NULL, path);
+               if (!parent)
+                       return -1;
+               ret = configs_register_configs(parent, configs, num);
+               configs_put_node(parent, 1, NULL);
+               return ret;
+       }
+       return -1;
+}
+EXPORT_SYMBOL(configs_register_path_configs);
+
+int configs_del_endnode(struct mconfig_node *parent,
+       struct mconfig_node *node)
+{
+       struct mconfig_node *parent_node;
+
+       parent_node = node->parent_node;
+       node->active = 0;
+       /*always set it to no active */
+       if (atomic_read(&node->ref_cnt) != 0)
+               return -1;
+       /*always del configs. */
+       node->configs = NULL;
+       node->configs_num = 0;
+       /*do't del node when have son node. */
+       if (node->son_node_num > 0)
+               return -2;
+       if (parent) {
+               mutex_lock(&parent->lock);
+               list_del(&node->list);
+               parent->son_node_num--;
+               mutex_unlock(&parent->lock);
+       }
+       return 0;
+}
+
+static struct mconfig *configs_get_node_config(
+       struct mconfig_node *node, char *name)
+{
+       int i;
+       struct mconfig *config = NULL;
+
+       mutex_lock(&node->lock);
+       for (i = 0; i < node->configs_num; i++) {
+               struct mconfig *val = &node->configs[i];
+
+               if (val && !strcmp(val->item_name, name)) {
+                       configs_inc_node_ref(node);
+                       config = val;
+                       break;
+               }
+       }
+       mutex_unlock(&node->lock);
+       config_debug("get config[%s] from %s-end-%p\n",
+               name, node->name, (void *)config);
+       return config;
+}
+
+static int configs_config2str(struct mconfig *config,
+       char *buf, int size)
+{
+       int ret = 0;
+
+       if (size < 1)
+               return 0;
+       switch (config->type) {
+       case CONFIG_TYPE_PBOOL:
+               ret = snprintf(buf, size, "%s",
+                       config->pboolval[0] ? "true" : "false");
+               break;
+       case CONFIG_TYPE_PI32:
+               ret = snprintf(buf, size, "%u", config->pival[0]);
+               break;
+       case CONFIG_TYPE_PU32:
+               ret = snprintf(buf, size, "%d", config->pu32val[0]);
+               break;
+       case CONFIG_TYPE_PU64:
+               ret = snprintf(buf, size, "%llx", config->pu64val[0]);
+               break;
+       case CONFIG_TYPE_PSTR:
+       case CONFIG_TYPE_PCSTR:
+               ret = snprintf(buf, size, "%s", config->str);
+               break;
+       case CONFIG_TYPE_BOOL:
+               ret = snprintf(buf, size, "%s",
+                       config->pboolval ? "true" : "false");
+       case CONFIG_TYPE_I32:
+               ret = snprintf(buf, size, "%d", config->ival);
+               break;
+       case CONFIG_TYPE_U32:
+               ret = snprintf(buf, size, "%u", config->u32val);
+               break;
+       case CONFIG_TYPE_U64:
+               ret = snprintf(buf, size, "0x%llx", config->u64val);
+               break;
+       case CONFIG_TYPE_FUN:
+               if (!config->f_get)
+                       ret = 0;
+               else
+                       ret = config->f_get(config->item_name,
+                               config->id, buf, size);
+               break;
+       default:
+               ret = -4;
+       }
+       if (ret <= 0) {
+               pr_err("config2str error %s-type:%d,%lx-%lx,ret=%d\n",
+                      config->item_name, config->type,
+                      config->ldata[0], config->ldata[1], ret);
+       } else if (ret >= size) {
+               buf[size - 1] = '\0';
+               ret = size - 1;
+       }
+       return ret;
+}
+
+static int configs_str2config(struct mconfig *config,
+       const char *str)
+{
+       int ret = 0;
+       u32 val;
+       u64 val64;
+       bool bval;
+
+       if (!str || strlen(str) <= 0)
+               return 0;
+       switch (config->type) {
+       case CONFIG_TYPE_PBOOL:
+       case CONFIG_TYPE_BOOL:
+               ret = configs_parser_value_bool(str, &bval);
+               if (ret <= 0)
+                       break;
+               if (config->type == CONFIG_TYPE_PBOOL)
+                       config->pboolval[0] = bval;
+               else
+                       config->boolval = bval;
+               break;
+       case CONFIG_TYPE_PI32:
+       case CONFIG_TYPE_PU32:
+               ret = configs_parser_value_u32(str, (u32 *) &val);
+               if (ret > 0)
+                       config->pu32val[0] = val;
+               break;
+       case CONFIG_TYPE_PU64:
+               ret = configs_parser_value_u64(str, (u64 *) &val64);
+               if (ret > 0)
+                       config->pu64val[0] = val64;
+               break;
+       case CONFIG_TYPE_PSTR:
+               strncpy(config->str, str, config->size);
+               ret = strlen(config->str);
+               break;
+       case CONFIG_TYPE_I32:
+       case CONFIG_TYPE_U32:
+               ret = configs_parser_value_u32(str, (u32 *) &val);
+               if (ret > 0)
+                       config->u32val = val;
+               break;
+       case CONFIG_TYPE_U64:
+               ret = configs_parser_value_u64(str, (u64 *) &val64);
+               if (ret > 0)
+                       config->u64val = val64;
+               break;
+       case CONFIG_TYPE_FUN:
+               if (!config->f_set)
+                       ret = -1;
+               else
+                       ret = config->f_set(config->item_name,
+                                       config->id,
+                                       str, strlen(str));
+               break;
+       case CONFIG_TYPE_PCSTR: /*can't set. */
+       default:
+               ret = -4;
+       }
+       return ret;
+}
+
+static char *configs_build_prefix(
+               struct mconfig_node *node,
+               const char *prefix,
+               int mode,
+               char *buf,
+               int size)
+{
+       if (!buf)
+               return "";
+       buf[0] = '\0';
+       if (mode & LIST_MODE_PATH_FULLPREFIX) {
+               if (node->prefix[0]) {
+                       snprintf(buf, size, "%s",
+                               node->prefix);
+               }
+       } else if (mode & LIST_MODE_PATH_PREFIX) {
+               if (prefix && prefix[0]) {
+                       snprintf(buf, size, "%s",
+                               prefix);
+               }
+       }
+       if (buf[0] && buf[strlen(buf) - 1] != '.')
+               strncat(buf, ".", size);
+       return buf;
+}
+
+static int configs_list_node_configs_locked(
+       struct mconfig_node *node,
+       char *buf, int size, const char *prefix,
+       int mode)
+{
+       int i;
+       int ret;
+       int pn_size = 0;
+       struct mconfig *config = NULL;
+       const char *cprefix = prefix;
+
+       if (!buf || size < 8 || !node->configs)
+               return 0;
+       if (!cprefix)
+               cprefix = "";
+       for (i = 0; i < node->configs_num && (size - pn_size) > 8; i++) {
+               config = &node->configs[i];
+               ret = snprintf(buf + pn_size,
+                               size - pn_size,
+                               " %s%s.%s%s",
+                            cprefix,
+                            node->name,
+                            config->item_name,
+                            (node->rw_flags & CONFIG_FOR_R) ? "=" : "");
+               if (ret > 0)
+                       pn_size += ret;
+               if ((mode & LIST_MODE_VAL) &&
+                       ((mode & CONFIG_FOR_T) ||
+                       !(CONFIG_FOR_T & node->rw_flags)) &&
+                       (node->rw_flags & CONFIG_FOR_R)) {
+                       ret = configs_config2str(config,
+                               buf + pn_size, size - pn_size);
+                       if (ret > 0) {
+                               if ((pn_size + ret) < size) {
+                                       strcat(buf, "\n");
+                                       ret++;
+                               }
+                               pn_size += ret;
+                       } else {
+                               if (ret == 0 && (pn_size + ret) < size) {
+                                       strcat(buf, "\n");
+                                       ret++;
+                                       continue;
+                               }
+                               break;
+                       }
+               } else {
+                       ret = snprintf(buf + pn_size, size - pn_size, "\n");
+                       if (ret > 0)
+                               pn_size += ret;
+               }
+       }
+       return pn_size;
+}
+
+int configs_list_node_configs(struct mconfig_node *node,
+       char *buf, int size,
+       int mode)
+{
+       int ret;
+
+       mutex_lock(&node->lock);
+       ret = configs_list_node_configs_locked(node, buf,
+               size, NULL, mode);
+       mutex_unlock(&node->lock);
+       return ret;
+}
+
+static int configs_list_nodes_in(struct mconfig_node *node,
+       char *buf, int size, const char *prefix,
+       int mode)
+{
+       int ret;
+       int pn_size = 0;
+       char cprefix[MAX_PREFIX_NAME + MAX_ITEM_NAME];
+       char *c_prefix;
+       char rw[4][4] = { "N", "r", "w", "rw" };
+
+       if (!node || !buf || size <= 0)
+               return 0;
+       if (!(node->rw_flags & mode))
+               return 0;/*LIST_MODE_LIST_RD/WD flags*/
+       config_debug("start dump node %s...\n", node->name);
+       c_prefix = configs_build_prefix(node,
+                               prefix,
+                               mode,
+                               cprefix,
+                               MAX_PREFIX_NAME + MAX_ITEM_NAME);
+       mutex_lock(&node->lock);
+       if (mode & LIST_MODE_NODE_INFO) {
+               ret = snprintf(buf + pn_size, size - pn_size,
+                               "[NODE]%s%s:[%s/%d/%d/%d]\n",
+                            c_prefix,
+                            node->name,
+                            rw[(node->rw_flags & 3)],
+                            atomic_read(&node->ref_cnt),
+                            node->configs_num,
+                            node->depth);
+               if (ret > 0)
+                       pn_size += ret;
+       }
+       if (mode & LIST_MODE_CONFIGS_VAL) {
+               ret = configs_list_node_configs_locked(node, buf + pn_size,
+                       size - pn_size, c_prefix, mode);
+               if (ret > 0)
+                       pn_size += ret;
+       }
+       if ((mode & LIST_MODE_SUB_NODES) && node->son_node_num > 0) {
+               struct mconfig_node *snode;
+               struct list_head *node_list, *next;
+
+               if (mode & LIST_MODE_PATH_PREFIX) {
+                       if (node->depth > 0)/*not root.*/
+                               strncat(cprefix, node->name,
+                                       MAX_PREFIX_NAME + MAX_ITEM_NAME);
+               }
+               list_for_each_safe(node_list, next, &node->son_node_list) {
+                       snode = list_entry(node_list,
+                                       struct mconfig_node, list);
+                       if (snode) {
+                               ret = configs_list_nodes_in(snode,
+                                       buf + pn_size, size - pn_size,
+                                       cprefix, mode);
+                               if (ret > 0)
+                                       pn_size += ret;
+                       }
+               }
+       }
+       mutex_unlock(&node->lock);
+       return pn_size;
+}
+
+int configs_list_nodes(struct mconfig_node *node,
+       char *buf, int size, int mode)
+{
+       if (!node)
+               node = configs_get_root_node();
+       return configs_list_nodes_in(node, buf, size,
+                       NULL,
+                       mode);
+}
+
+int configs_list_path_nodes(const char *prefix,
+       char *buf, int size, int mode)
+{
+       struct mconfig_node *node;
+       int ret = 0;
+
+       node = configs_get_node_path_end_node(NULL, prefix);
+       if (node != NULL) {
+               ret = configs_list_nodes(node, buf, size, mode);
+               configs_put_node(node, 1, NULL);
+       }
+       return ret;
+}
+
+static int configs_get_node_path_config(
+       struct mconfig_node *root_node,
+       struct mconfig **config_ret,
+       const char *path,
+       struct mconfig_node **hold_node, int set)
+{
+       char sub_node_name[128];
+       struct mconfig_node *node, *parent_node;
+       struct mconfig *config = NULL;
+       int i, end;
+       const char *next_path = path;
+       int err = 0;
+
+       if (!path)
+               return -EIO;
+       end = 0;
+       if (!root_node)
+               root_node = configs_get_root_node();
+       node = root_node;
+       while (!end) {
+               parent_node = node;
+               i = configs_parser_first_node(next_path,
+                       sub_node_name, 128, &end);
+               if (i <= 0 || sub_node_name[0] == '\0') {
+                       pr_err("can't find [%s] 's node!!\n", path);
+                       return -1;
+               }
+               config_debug("configs_parser_first_node{%s} end%d\n",
+                       sub_node_name, end);
+               if (!end) {
+                       node = configs_get_node_with_name(parent_node,
+                               sub_node_name);
+                       if (node == NULL) {
+                               if (parent_node != root_node) {
+                                       node = parent_node;
+                                       goto out;
+                               }
+                               /*for reset refs. */
+                               pr_err("can't find node:[%s], from:[%s], path=%s\n",
+                                      sub_node_name, parent_node->name, path);
+                               err = -ENOENT;
+                               goto out;
+                       }
+                       next_path = next_path + i + 1;  /*media.vdec --> vdec */
+                       config_debug("get snode[%s] from node[%s], end=%d\n",
+                               node->name, parent_node->name, end);
+               }
+       }
+       if (set && !(node->rw_flags & CONFIG_FOR_W)) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (!set && !(node->rw_flags & CONFIG_FOR_R)) {
+               err = -EPERM;
+               goto out;
+       }
+       config = configs_get_node_config(node, sub_node_name);
+       if (!config) {
+               /*release node refs. */
+               err = -EPERM;
+       } else
+               *hold_node = node;
+ out:
+       if (config == NULL) {
+               if (node) {
+                       configs_put_node(node, 1, root_node);
+                       pr_err("can't find node %s's  config:%s\n",
+                               node->name, sub_node_name);
+               } else
+                       pr_err("can't find node %s from %s\n",
+                       sub_node_name, root_node->name);
+       } else {
+               *config_ret = config;
+               err = 0;
+       }
+       return err;
+}
+
+static int configs_setget_config_value(struct mconfig *config,
+       const void *val_set, void *val_get, int size, int set)
+{
+       int s;
+       int ret;
+       void *dst;
+       const void *src;
+
+       if (set) {
+               dst = config->buf_ptr;
+               src = val_set;
+       } else {
+               dst = val_get;
+               src = config->buf_ptr;
+       }
+       if (!dst || !src)
+               return -1;
+       switch (config->type) {
+       case CONFIG_TYPE_PU32:
+       case CONFIG_TYPE_PI32:
+               if (size < sizeof(u32))
+                       return -2;
+               ((u32 *) dst)[0] = ((const u32 *)src)[0];
+               ret = sizeof(u32);
+               break;
+       case CONFIG_TYPE_PU64:
+               if (size < sizeof(u64))
+                       return -2;
+               ((u64 *) dst)[0] = ((const u64 *)src)[0];
+               ret = sizeof(u64);
+               break;
+       case CONFIG_TYPE_PCSTR:
+               if (set) {
+                       ret = -3;
+                       break;
+               }
+               /*rd same as CONFIG_TYPE_PSTR */
+       case CONFIG_TYPE_PSTR:
+               s = min_t(int, size - 1, config->size - 1);
+               if (s > 0)
+                       strncpy(dst, src, s);
+               else
+                       ret = -3;
+               ret = s;
+               break;
+       case CONFIG_TYPE_U32:
+       case CONFIG_TYPE_I32:
+               if (size < sizeof(u32))
+                       return -2;
+               if (set)
+                       config->u32val = ((const u32 *)src)[0];
+               else
+                       ((u32 *) dst)[0] = config->u32val;
+               ret = sizeof(u32);
+               break;
+       case CONFIG_TYPE_U64:
+               if (size < sizeof(u64))
+                       return -2;
+               if (set)
+                       config->u64val = ((const u64 *)src)[0];
+               else
+                       ((u64 *) dst)[0] = config->u64val;
+               ret = sizeof(u64);
+               break;
+       default:
+               ret = -4;
+       }
+       return ret;
+}
+
+static int configs_setget_node_path_value(
+       struct mconfig_node *topnode,
+       const char *path,
+       const void *val_set, void *val_get,
+       int size, int set)
+{
+       struct mconfig_node *node;
+       struct mconfig *config;
+       int ret;
+
+       ret = configs_get_node_path_config(topnode, &config, path, &node, set);
+       if (ret != 0)
+               return ret;
+       if (set)
+               pr_err("start set config val config=%s, val=%x\n",
+               config->item_name, *(int *)val_set);
+       ret = configs_setget_config_value(config, val_set,
+               val_get, size, set);
+       config_debug("setget config val config=%s, ret=%x end\n",
+               config->item_name, ret);
+       configs_put_node(node, 0, topnode);
+       configs_put_node(node, 1, topnode);
+       return ret;
+}
+
+int configs_set_node_path_str(struct mconfig_node *topnode,
+       const char *path, const char *val)
+{
+       struct mconfig_node *node;
+       struct mconfig *config;
+       int ret = -1;
+
+       if (!val || !path || strlen(path) <= 0 || strlen(val) <= 0)
+               return -1;
+       ret = configs_get_node_path_config(topnode, &config, path, &node, 1);
+       if (ret != 0)
+               return ret;
+       config_debug("start set config val config=%s, %s\n",
+               config->item_name, val);
+       mutex_lock(&node->lock);
+       ret = configs_str2config(config, val);
+       mutex_unlock(&node->lock);
+       configs_put_node(node, 0, topnode);
+       configs_put_node(node, 1, topnode);
+       if (ret > 0)
+               ret = 0;/*set ok*/
+       else if (ret == 0)
+               ret = -1;/*val not changed.*/
+       return ret;
+}
+int configs_set_node_nodepath_str(struct mconfig_node *topnode,
+       const char *path, const char *val)
+{
+       if (topnode == NULL) {
+               return configs_set_node_path_str(topnode,
+                       path, val);
+       }
+       if (strncmp(topnode->name, path, strlen(topnode->name))) {
+               pr_err("nodepath(%s) must start from node=%s\n",
+                       path, topnode->name);
+               return -1;
+       }
+       return configs_set_node_path_str(topnode,
+                       path + strlen(topnode->name) + 1, val);
+}
+
+int configs_set_prefix_path_str(const char *prefix,
+       const char *path, const char *str)
+{
+       struct mconfig_node *topnode = NULL;
+       int ret;
+
+       if (prefix && strlen(prefix) > 0) {
+               topnode = configs_get_node_path_end_node(NULL, prefix);
+               if (!topnode) {
+                       pr_err("[0]can't get node from %s\n", prefix);
+                       return -1;
+               }
+       }
+       ret = configs_set_node_path_str(topnode, path, str);
+       configs_put_node(topnode, 1, NULL);
+       return ret;
+}
+
+int configs_set_node_path_valonpath(
+       struct mconfig_node *topnode,
+       const char *path)
+{
+       return configs_set_node_path_str(topnode, path,
+               configs_parser_str_valstr(path));
+}
+
+int configs_set_prefix_path_valonpath(const char *prefix,
+       const char *path)
+{
+       struct mconfig_node *topnode = NULL;
+       int ret;
+
+       if (prefix && strlen(prefix) > 0) {
+               topnode = configs_get_node_path_end_node(NULL, prefix);
+               if (!topnode) {
+                       pr_err("can't get node from %s\n", prefix);
+                       return -1;
+               }
+       }
+       ret = configs_set_node_path_str(topnode, path,
+               configs_parser_str_valstr(path));
+       configs_put_node(topnode, 1, NULL);
+       return ret;
+}
+
+int configs_get_node_path_str(struct mconfig_node *topnode,
+       const char *path, char *buf, int size)
+{
+       struct mconfig_node *node;
+       struct mconfig *config;
+       int ret = -1;
+
+       if (!path || strlen(path) <= 0)
+               return -1;
+       ret = configs_get_node_path_config(topnode,
+               &config, path, &node, 0);
+       if (ret != 0)
+               return ret;
+       config_debug("startget config val config=%s\n",
+               config->item_name);
+       ret = configs_config2str(config, buf, size);
+       configs_put_node(node, 0, topnode);
+       configs_put_node(node, 1, topnode);
+       return ret;
+}
+int configs_get_node_nodepath_str(struct mconfig_node *topnode,
+       const char *path, char *buf, int size)
+{
+       if (topnode == NULL)
+               return configs_get_node_path_str(topnode, path, buf, size);
+       if (strncmp(topnode->name, path, strlen(topnode->name))) {
+               pr_err("nodepath(%s) must start from node=%s\n",
+                       path, topnode->name);
+               return -1;
+       }
+       return configs_get_node_path_str(topnode,
+               path + strlen(topnode->name) + 1,
+               buf, size);
+
+}
+
+static inline int configs_set_node_path_value(
+       struct mconfig_node *topnode,
+       const char *path, const void *val, int size)
+{
+       return configs_setget_node_path_value(topnode,
+               path, val, NULL, size, 1);
+}
+
+static int configs_get_node_path_value(struct mconfig_node *topnode,
+       const char *path, void *val, int size)
+{
+       return configs_setget_node_path_value(topnode,
+               path, NULL, val, size, 0);
+}
+
+int configs_get_node_path_u32(struct mconfig_node *topnode,
+       const char *path, u32 *val)
+{
+       return configs_get_node_path_value(topnode, path, val, sizeof(u32));
+}
+
+int configs_get_node_path_u64(struct mconfig_node *topnode,
+       const char *path, u64 *val)
+{
+       return configs_get_node_path_value(topnode, path, val, sizeof(u64));
+}
+
+int configs_set_node_path_u32(struct mconfig_node *topnode,
+       const char *path, u32 val)
+{
+       return configs_set_node_path_value(topnode, path, &val, sizeof(u32));
+}
+
+int configs_set_node_path_u64(struct mconfig_node *topnode,
+       const char *path, u64 val)
+{
+       return configs_set_node_path_value(topnode, path, &val,
+               sizeof(u64));
+}
+
+int configs_config_system_init(void)
+{
+       configs_init_new_node(&root_node, "root", CONFIG_FOR_RW);
+       configs_register_node(NULL, &root_node);
+       return 0;
+}
diff --git a/drivers/amlogic/media/common/codec_mm/configs/configs_module.c b/drivers/amlogic/media/common/codec_mm/configs/configs_module.c
new file mode 100644 (file)
index 0000000..0087625
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * drivers/amlogic/media/common/codec_mm/configs/configs_module.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
+#include <linux/amlogic/media/codec_mm/configs_api.h>
+#define MAX_OPENED_CNT 65536
+#include "configs_priv.h"
+#define MODULE_NAME "media-configs-dev"
+
+static struct class *config_dev_class;
+static unsigned int config_major;
+struct mediaconfig_node {
+       const char *parent;
+       const char *name;
+       const char *dev_name;
+       int rw_flags;
+       atomic_t opened_cnt;
+       struct device *class_dev;
+       struct mconfig_node node;
+
+};
+
+static ssize_t all_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_nodes(NULL, buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+
+static ssize_t media_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+
+static ssize_t video_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media.video", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+static ssize_t decoder_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media.decoder", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+static ssize_t vdec_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media.vdec", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+static ssize_t tsync_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media.tsync", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+
+
+static ssize_t amports_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media.amports", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+static ssize_t parser_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media.parser", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+
+
+
+static ssize_t show_config(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_nodes(NULL, buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+
+static ssize_t store_config(struct class *class,
+                       struct class_attribute *attr,
+                       const char *buf, size_t size)
+{
+       ssize_t ret;
+
+       ret = configs_set_path_valonpath(buf);
+       if (ret >= 0)
+               return size;
+       return ret;
+}
+
+static ssize_t show_config_debug(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       return config_dump(buf, PAGE_SIZE);
+}
+
+static ssize_t store_config_debug(struct class *class,
+                       struct class_attribute *attr,
+                       const char *buf, size_t size)
+{
+       configs_config_setstr(buf);
+       return size;
+}
+
+static ssize_t audio_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media.audio", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+static ssize_t vfm_show(struct class *class,
+                       struct class_attribute *attr, char *buf)
+{
+       ssize_t s;
+
+       s = configs_list_path_nodes("media.vfm", buf, PAGE_SIZE,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (s > 0)
+               return s;
+       return -EPERM;
+}
+
+static struct class_attribute configs_class_attrs[] = {
+       __ATTR_RO(all),
+       __ATTR_RO(media),
+       __ATTR_RO(video),
+       __ATTR_RO(decoder),
+       __ATTR_RO(amports),
+       __ATTR_RO(tsync),
+       __ATTR_RO(parser),
+       __ATTR_RO(vdec),
+       __ATTR_RO(audio),
+       __ATTR_RO(vfm),
+       __ATTR(config, 0664,
+       show_config, store_config),
+       __ATTR(debug, 0664,
+       show_config_debug, store_config_debug),
+       __ATTR_NULL
+};
+
+static struct class media_configs_class = {
+               .name = "media-configs",
+               .class_attrs = configs_class_attrs,
+};
+
+static struct mediaconfig_node mediaconfig_nodes[] = {
+       {"", "media", "media", CONFIG_FOR_RW},
+       {"media", "decoder", "media.decoder", CONFIG_FOR_RW},
+       {"media", "parser", "media.parser", CONFIG_FOR_RW},
+       {"media", "video", "media.video", CONFIG_FOR_RW},
+       {"media", "amports", "media.amports", CONFIG_FOR_RW},
+       {"media", "tsync", "media.tsync", CONFIG_FOR_RW},
+       {"media", "codec_mm", "media.codec_mm", CONFIG_FOR_RW},
+       {"media", "audio", "media.audio", CONFIG_FOR_RW},
+       {"media", "vfm", "media.vfm", CONFIG_FOR_RW},
+};
+
+struct config_file_private {
+       struct mediaconfig_node *node;
+       char common[128];
+       pid_t pid;
+       pid_t tgid;
+       long opened_jiffies;
+       long last_access_jiffies;
+       long access_get_cnt;
+       long access_set_cnt;
+       long access_dump_cnt;
+       long error_cnt;
+       int enable_trace_get;
+       int enable_trace_set;
+       int last_read_end;
+};
+
+static int configs_open(struct inode *inode, struct file *file)
+{
+       struct mediaconfig_node *node = &mediaconfig_nodes[iminor(inode)];
+       struct config_file_private *priv;
+
+       if (atomic_read(&node->opened_cnt) > MAX_OPENED_CNT) {
+               pr_err("too many files opened.!!\n");
+               return -EMFILE;
+       }
+       priv = kzalloc(sizeof(struct config_file_private), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       file->private_data = priv;
+       priv->pid = current->pid;
+       priv->tgid = current->tgid;
+       priv->opened_jiffies = jiffies;
+       priv->node = node;
+       atomic_inc(&node->opened_cnt);
+       configs_inc_node_ref(&node->node);
+       return 0;
+}
+static ssize_t configs_read(struct file *file, char __user *buf,
+                       size_t count, loff_t *ppos)
+{
+       struct config_file_private *priv = file->private_data;
+       struct mediaconfig_node *node = priv->node;
+       int ret;
+
+       if (*ppos > 0)
+               return 0;/*don't support seek read. read end.*/
+       if (!access_ok(VERIFY_WRITE, buf, count))
+               return -EIO;
+       ret = configs_list_nodes(&node->node, buf, count,
+               LIST_MODE_NODE_CMDVAL_ALL);
+       if (ret > 0)
+               *ppos = ret;
+       return ret;
+}
+
+static int configs_close(struct inode *inode, struct file *file)
+{
+       struct config_file_private *priv = file->private_data;
+       struct mediaconfig_node *node = priv->node;
+
+       configs_dec_node_ref(&node->node);
+       atomic_dec(&node->opened_cnt);
+
+       kfree(priv);
+
+       return 0;
+}
+static long configs_ioctl(struct file *file, unsigned int cmd, ulong arg)
+{
+       struct config_file_private *priv = file->private_data;
+       struct mediaconfig_node *node = priv->node;
+       struct media_config_io_str io;
+       struct media_config_io_str *user_io = (void *)arg;
+       int r = -1;
+
+       priv->last_access_jiffies = jiffies;
+       switch (cmd) {
+       case MEDIA_CONFIG_SET_CMD_STR:
+               priv->access_set_cnt++;
+               r = copy_from_user(io.cmd_path,
+                       user_io->cmd_path, sizeof(io.cmd_path));
+               r |= copy_from_user(io.val, user_io->val, sizeof(io.val));
+               /*pr_info("set%s:%s dev=%s\n", io.cmd_path,*/
+               /*io.val, node->dev_name);*/
+               if (r) {
+                       r = -EIO;
+                       break;
+               }
+               if (!strncmp(io.cmd_path, node->dev_name,
+               strlen(node->dev_name)))
+                       r = configs_set_node_nodepath_str(NULL,
+                               io.cmd_path,
+                               io.val);
+               else
+                   pr_info("set %s %s  not match devname=%s\n",
+               io.cmd_path, io.val, node->dev_name);
+               break;
+       case MEDIA_CONFIG_GET_CMD_STR:
+               r = -1;
+               priv->access_get_cnt++;
+               r = copy_from_user(&io.cmd_path,
+                               user_io->cmd_path, sizeof(io.cmd_path));
+               if (r) {
+                       r = -EIO;
+                       break;
+               }
+               io.val[0] = '\0';
+               if (!strncmp(io.cmd_path, node->dev_name,
+               strlen(node->dev_name))) {
+                       r = configs_get_node_nodepath_str(NULL,
+                               io.cmd_path,
+                               io.val,
+                               sizeof(io.val));
+
+               /*pr_info("configs_get_node_nodepath_str*/
+               /*ret %x [%s]\n", r, io.val);*/
+               if (r > 0 && r <= sizeof(io.val) - 1) {
+                       /*+1 for end str.*/
+                       if (copy_to_user(user_io->val, io.val, r + 1) != 0) {
+                               r = -EIO;
+                               break;
+                               }
+                               put_user(r, &user_io->ret);
+                               r = 0;
+                       } else {
+                                put_user(-1, &user_io->ret);
+                       }
+               } else
+                       pr_info("set %s %s  not match devname=%s\n",
+                       io.cmd_path, io.val, node->dev_name);
+               break;
+       default:
+               r = -EINVAL;
+               pr_err("unsupport cmd %x\n", cmd);
+       }
+       if (r < 0)
+               priv->error_cnt++;
+       return r;
+}
+
+
+
+#ifdef CONFIG_COMPAT
+static long configs_compat_ioctl(struct file *file,
+               unsigned int cmd, ulong arg)
+{
+       return configs_ioctl(file, cmd, (ulong)compat_ptr(arg));
+}
+#endif
+static const struct file_operations configs_fops = {
+       .owner = THIS_MODULE,
+       .open = configs_open,
+       .read = configs_read,
+       .release = configs_close,
+       .unlocked_ioctl = configs_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = configs_compat_ioctl,
+#endif
+};
+
+
+static int __init configs_init_devices(void)
+{
+       int i;
+       int num = sizeof(mediaconfig_nodes)/sizeof(struct mediaconfig_node);
+
+       int r;
+
+       r = class_register(&media_configs_class);
+       if (r) {
+               pr_err("configs class create fail.\n");
+               goto error1;
+       }
+
+       r = register_chrdev(0, MODULE_NAME, &configs_fops);
+       if (r < 0) {
+               pr_err("Can't allocate major for config device\n");
+               goto error1;
+       }
+       config_major = r;
+
+       config_dev_class = class_create(THIS_MODULE, MODULE_NAME);
+       num = sizeof(mediaconfig_nodes)/sizeof(struct mediaconfig_node);
+       for (i = 0; i < num; i++) {
+               struct mediaconfig_node *mnode = &mediaconfig_nodes[i];
+
+               mnode->class_dev = device_create(config_dev_class, NULL,
+                               MKDEV(config_major, i), NULL,
+                               mnode->dev_name);
+               if (mnode->class_dev == NULL) {
+                       pr_err("device_create %s failed\n", mnode->dev_name);
+                       r = -1;
+                       goto error2;
+               }
+       }
+       return 0;
+#if 0
+error3:
+       for (mnode = &mediaconfig_nodes[0], i = 0; i < num; i++, mnode++)
+               device_destroy(config_dev_class, MKDEV(config_major, i));
+       class_destroy(config_dev_class);
+#endif
+error2:
+       unregister_chrdev(config_major, MODULE_NAME);
+error1:
+       class_destroy(&media_configs_class);
+       return r;
+}
+module_init(configs_init_devices);
+
+static int __init media_configs_system_init(void)
+{
+       int i;
+       int num = sizeof(mediaconfig_nodes)/sizeof(struct mediaconfig_node);
+       struct mediaconfig_node *mnode;
+       int r;
+
+       pr_info("media_configs_system_init\n");
+       configs_config_system_init();
+       for (i = 0; i < num; i++) {
+               mnode = &mediaconfig_nodes[i];
+               configs_init_new_node(&mnode->node, mnode->name,
+                               mnode->rw_flags);
+               r = configs_register_path_node(mnode->parent,
+                                       &mnode->node);
+               if (r < 0) {
+                       pr_err("ERR!!!.register node[%s] to [%s] failed!\n",
+                               mnode->name, mnode->parent);
+                       return r;
+               }
+       }
+
+       return 0;
+}
+
+arch_initcall(media_configs_system_init);
+MODULE_DESCRIPTION("AMLOGIC config modules driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/amlogic/media/common/codec_mm/configs/configs_priv.h b/drivers/amlogic/media/common/codec_mm/configs/configs_priv.h
new file mode 100644 (file)
index 0000000..82c6025
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * drivers/amlogic/media/common/codec_mm/configs/configs_priv.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef AMLOGIC_MEDIA_CONFIG_HEADER_PRIV__
+#define AMLOGIC_MEDIA_CONFIG_HEADER_PRIV__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+int configs_config_system_init(void);
+int configs_inc_node_ref_locked(
+       struct mconfig_node *node);
+int configs_dec_node_ref_locked(
+       struct mconfig_node *node);
+int config_dump(void *buf, int size);
+int configs_config_setstr(const char *buf);
+
+#endif
+
diff --git a/drivers/amlogic/media/common/codec_mm/configs/configs_test.c b/drivers/amlogic/media/common/codec_mm/configs/configs_test.c
new file mode 100644 (file)
index 0000000..c0f4eb8
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * drivers/amlogic/media/common/codec_mm/configs/configs_test.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/amlogic/media/codec_mm/configs.h>
+
+static struct mconfig_node media;
+static struct mconfig_node vdec;
+static struct mconfig_node decoder;
+static struct mconfig_node parser;
+static struct mconfig_node codec;
+static struct mconfig_node fast;
+static struct mconfig_node fast2;
+
+
+static  struct mconfig vdec_configs[] = {
+       MC_I32("vdec", 1),
+       MC_I32("vdec1", 1),
+       MC_I32("vdec2", 2),
+       MC_I32("vdec3", 3),
+       MC_I32("vdec4", 4),
+
+};
+
+static struct mconfig decoder_configs[] = {
+       MC_I32("264", 1),
+       MC_I32("265", 1),
+       MC_U32("vp9", 2),
+       MC_U32("vc1", 3),
+       MC_U32("rmvb", 4),
+};
+
+
+
+static struct mconfig parser_configs[] = {
+       MC_I32("ts", 1),
+       MC_I32("es", 1),
+       MC_I32("demux", 2),
+       MC_U32("rm", 3),
+       MC_U32("ps", 4),
+};
+
+static struct mconfig vdec_profile[] = {
+       MC_CSTR("265", "compress,di,c,mmu"),
+       MC_CSTR("264",  "compress,di,c,4k"),
+       MC_CSTR("263",  "compress,di,c"),
+       MC_CSTR("vc1",  "compress,di,c"),
+       MC_CSTR("rm",  "compress,di,di,ps"),
+};
+static int a, b, c, d, e;
+struct mconfig fast_profile[] = {
+       MC_PI32("265", &a),
+       MC_PI32("264",  &b),
+       MC_PI32("263",  &c),
+       MC_PI32("vc1",  &d),
+       MC_PI32("rm",  &e),
+};
+
+int dump_set(const char *trigger, int id, const char *buf, int size)
+{
+       pr_err("trigger-->[%s]\n", buf);
+       return size;
+}
+
+
+struct mconfig fast2_profile[] = {
+       MC_FUN("trigger", NULL, &dump_set),
+};
+
+
+
+
+
+
+static int config_test(void)
+{
+       static int init;
+
+       if (init > 0)
+               return 0;
+       init++;
+       configs_init_new_node(&media, "debug", CONFIG_FOR_RW);
+       configs_register_node(NULL, &media);
+
+       configs_init_new_node(&vdec, "vdec", CONFIG_FOR_RW);
+       configs_register_node(&media, &vdec);
+       REG_CONFIGS(&vdec, vdec_configs);
+
+       configs_init_new_node(&decoder, "decoder", CONFIG_FOR_RW);
+       REG_CONFIGS(&decoder, decoder_configs);
+       configs_register_node(&media, &decoder);
+
+       configs_init_new_node(&parser, "parser", CONFIG_FOR_W);
+       REG_CONFIGS(&parser, parser_configs);
+       configs_register_node(&media, &parser);
+
+       configs_init_new_node(&codec, "codec", CONFIG_FOR_R);
+       REG_CONFIGS(&codec, vdec_profile);
+       configs_register_node(&media, &codec);
+
+       configs_init_new_node(&fast, "fast", CONFIG_FOR_RW);
+       REG_CONFIGS(&fast, fast_profile);
+       configs_register_node(&media, &fast);
+
+       configs_init_new_node(&fast2, "trigger", CONFIG_FOR_W);
+       REG_CONFIGS(&fast2, fast2_profile);
+       configs_register_node(&media, &fast2);
+
+       /* configs_register_configs(); */
+       return 0;
+}
+int config_dump(void *buf, int size)
+{
+       config_test();
+       b++;
+       c = b+3;
+       a++;
+       d += 2;
+       return configs_list_nodes(NULL, buf, size,
+               LIST_MODE_FULL_CMDVAL_ALL);
+}
+int configs_config_setstr(const char *buf)
+{
+       int ret;
+
+       config_test();
+       pr_info("-----------start configs_config_setstr\n\n");
+       ret = configs_set_path_valonpath(buf);
+       pr_info("-----------end configs_config_setstr\n\n");
+       return ret;
+}
+
index 9766edb..8d88c99 100644 (file)
@@ -933,7 +933,7 @@ void ge2d_set_cmd(struct ge2d_cmd_s *cfg)
         * scale_out_done(test1823) hang issue when
         * scaling down ratio is high.
         */
-       if (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX)
+       if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX)
                ge2d_reg_set_bits(GE2D_GEN_CTRL4, cfg->hang_flag, 0, 1);
        ge2d_reg_write(GE2D_CMD_CTRL,
                        (cfg->src2_fill_color_en << 9) |
@@ -980,7 +980,7 @@ void ge2d_set_gen(struct ge2d_gen_s *cfg)
                        (cfg->vfmt_onoff_en << 15) |
                        (cfg->dp_off_cnt << 0)
                       );
-       if (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX) {
+       if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX) {
                ge2d_reg_set_bits(GE2D_GEN_CTRL4,
                        (cfg->fifo_size << 26) |
                        (cfg->fifo_size << 24) |
index d519938..4d61427 100644 (file)
@@ -1,5 +1,5 @@
-obj-$(CONFIG_AMLOGIC_MEDIA_RDMA)       +=      rdma_module.o
-rdma_module-objs       +=      rdma_mgr.o
+obj-$(CONFIG_AMLOGIC_MEDIA_RDMA)       +=      rdma_mgr.o
+
 ifeq ($(CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA),y)
-rdma_module-objs       +=      rdma.o
+obj-$(CONFIG_AMLOGIC_MEDIA_RDMA)       +=      rdma.o
 endif
index deaca89..f31374d 100644 (file)
 #define Wr_reg_bits(adr, val, start, len) \
                        WRITE_VCBUS_REG_BITS(adr, val, start, len)
 
-
-/*#define CONFIG_RDMA_IN_RDMAIRQ*/
-/*#define CONFIG_RDMA_IN_TASK*/
-
 #define RDMA_TABLE_SIZE                    (8 * (PAGE_SIZE))
-
 static int vsync_rdma_handle;
-
 static int irq_count;
-
 static int enable;
-
-static int enable_mask = 0x400ff;
-
+static int cur_enable;
 static int pre_enable_;
-
 static int debug_flag;
-
 static int vsync_cfg_count;
-
-#define RDMA_VSYNC_INPUT_TRIG          0x1
-static bool vsync_rdma_config_delay_flag;
+static u32 force_rdma_config;
+static bool first_config;
+static bool rdma_done;
 
 static void vsync_rdma_irq(void *arg);
 
@@ -77,99 +66,80 @@ struct rdma_op_s vsync_rdma_op = {
        NULL
 };
 
-static struct semaphore  rdma_sema;
-struct task_struct *rdma_task;
-static unsigned int rdma_config_flag;
-
-static unsigned char rdma_start_flag;
-
-
-static int rdma_task_handle(void *data)
-{
-       int ret = 0;
-
-       while (1) {
-               ret = down_interruptible(&rdma_sema);
-               if (debug_flag & 2)
-                       pr_info("%s: %x\r\n", __func__, rdma_config_flag);
-               if (rdma_config_flag == 1) {
-                       rdma_config_flag = 0;
-                       if (rdma_config(vsync_rdma_handle,
-                               RDMA_VSYNC_INPUT_TRIG) != 1){
-                               rdma_config_flag = 2;
-                               /*
-                                *fail or rdma table empty,
-                                *there is no rdma irq
-                                */
-                       }
-               }
-               if (rdma_start_flag) {
-                       if (vsync_rdma_handle <= 0)
-                               vsync_rdma_handle =
-                               rdma_register(&vsync_rdma_op,
-                               NULL, RDMA_TABLE_SIZE);
-                       rdma_start_flag = 0;
-               }
-       }
-       return 0;
-}
-
-
 void vsync_rdma_config(void)
 {
-       int enable_ = ((enable & enable_mask) | (enable_mask >> 8)) & 0xff;
+       int iret = 0;
+       int enable_ = cur_enable & 0xf;
 
-       if (vsync_rdma_handle == 0)
+       if (vsync_rdma_handle <= 0)
                return;
 
+       /* first frame not use rdma */
+       if (!first_config) {
+               cur_enable = enable;
+               pre_enable_ = enable_;
+               first_config = true;
+               rdma_done = false;
+               return;
+       }
+
+       /* if rdma mode changed, reset rdma */
        if (pre_enable_ != enable_) {
-               if (((enable_mask >> 17) & 0x1) == 0)
-                       rdma_clear(vsync_rdma_handle);
-               vsync_rdma_config_delay_flag = false;
+               rdma_clear(vsync_rdma_handle);
+               force_rdma_config = 1;
        }
-       if (enable == 1)
-               rdma_watchdog_setting(1);
-       else
-               rdma_watchdog_setting(0);
-       if (enable_ == 1) {
-#ifdef CONFIG_RDMA_IN_TASK
-               if (debug_flag & 2) {
-                       pr_info("%s: %d : %d :\r\n", __func__,
-                       rdma_config_flag, pre_enable_);
-               }
-               if ((rdma_config_flag == 2) || (pre_enable_ != enable)) {
-                       rdma_config_flag = 1;
-                       up(&rdma_sema);
-               }
-
-#elif (defined CONFIG_RDMA_IN_RDMAIRQ)
-               if (pre_enable_ != enable_)
-                       rdma_config(vsync_rdma_handle, RDMA_VSYNC_INPUT_TRIG);
-#else
-               rdma_config(vsync_rdma_handle, RDMA_VSYNC_INPUT_TRIG);
-               vsync_cfg_count++;
-#endif
-       } else if (enable_ == 2)
-               rdma_config(vsync_rdma_handle,
-                       RDMA_TRIGGER_MANUAL); /*manually in cur vsync*/
-       else if (enable_ == 3)
-               ;
-       else if (enable_ == 4)
-               rdma_config(vsync_rdma_handle,
-                       RDMA_TRIGGER_DEBUG1); /*for debug*/
-       else if (enable_ == 5)
-               rdma_config(vsync_rdma_handle,
-                       RDMA_TRIGGER_DEBUG2); /*for debug*/
-       else if (enable_ == 6)
-               ;
 
+       if (force_rdma_config)
+               rdma_done = true;
+
+       if (enable_ == 1) {
+               if (rdma_done)
+                       iret = rdma_watchdog_setting(0);
+               else
+                       iret = rdma_watchdog_setting(1);
+       } else {
+               /* not vsync mode */
+               iret = rdma_watchdog_setting(0);
+               force_rdma_config = 1;
+       }
+       rdma_done = false;
+       if (iret)
+               force_rdma_config = 1;
+
+       iret = 0;
+       if (force_rdma_config) {
+               if (enable_ == 1) {
+                       iret = rdma_config(vsync_rdma_handle,
+                               RDMA_TRIGGER_VSYNC_INPUT);
+                       if (iret)
+                               vsync_cfg_count++;
+               } else if (enable_ == 2)
+                       /*manually in cur vsync*/
+                       rdma_config(vsync_rdma_handle,
+                               RDMA_TRIGGER_MANUAL);
+               else if (enable_ == 3)
+                       ;
+               else if (enable_ == 4)
+                       rdma_config(vsync_rdma_handle,
+                               RDMA_TRIGGER_DEBUG1); /*for debug*/
+               else if (enable_ == 5)
+                       rdma_config(vsync_rdma_handle,
+                               RDMA_TRIGGER_DEBUG2); /*for debug*/
+               else if (enable_ == 6)
+                       ;
+               if (!iret)
+                       force_rdma_config = 1;
+               else
+                       force_rdma_config = 0;
+       }
        pre_enable_ = enable_;
+       cur_enable = enable;
 }
 EXPORT_SYMBOL(vsync_rdma_config);
 
 void vsync_rdma_config_pre(void)
 {
-       int enable_ = ((enable&enable_mask)|(enable_mask>>8))&0xff;
+       int enable_ = cur_enable & 0xf;
 
        if (vsync_rdma_handle == 0)
                return;
@@ -182,48 +152,32 @@ EXPORT_SYMBOL(vsync_rdma_config_pre);
 
 static void vsync_rdma_irq(void *arg)
 {
-#ifdef CONFIG_RDMA_IN_TASK
-       int enable_ = ((enable&enable_mask) | (enable_mask >> 8)) & 0xff;
+       int iret;
+       int enable_ = cur_enable & 0xf;
 
        if (enable_ == 1) {
-               rdma_config_flag = 1;
-               up(&rdma_sema);
+               /*triggered by next vsync*/
+               iret = rdma_config(vsync_rdma_handle,
+                       RDMA_TRIGGER_VSYNC_INPUT);
+               if (iret)
+                       vsync_cfg_count++;
        } else
-               rdma_config(vsync_rdma_handle, 0);
-
-#elif (defined CONFIG_RDMA_IN_RDMAIRQ)
-       int enable_ = ((enable&enable_mask) | (enable_mask >> 8)) & 0xff;
+               iret = rdma_config(vsync_rdma_handle, 0);
+       pre_enable_ = enable_;
 
-       if (enable_ == 1)
-               rdma_config(vsync_rdma_handle,
-               RDMA_VSYNC_INPUT_TRIG); /*triggered by next vsync*/
+       if ((!iret) || (enable_ != 1))
+               force_rdma_config = 1;
        else
-               rdma_config(vsync_rdma_handle, 0);
-#endif
+               force_rdma_config = 0;
+       rdma_done = true;
        irq_count++;
+       return;
 }
 
-MODULE_PARM_DESC(enable, "\n enable\n");
-module_param(enable, uint, 0664);
-
-MODULE_PARM_DESC(enable_mask, "\n enable_mask\n");
-module_param(enable_mask, uint, 0664);
-
-MODULE_PARM_DESC(irq_count, "\n irq_count\n");
-module_param(irq_count, uint, 0664);
-
-
-
-MODULE_PARM_DESC(debug_flag, "\n debug_flag\n");
-module_param(debug_flag, uint, 0664);
-
-
-MODULE_PARM_DESC(vsync_cfg_count, "\n vsync_cfg_count\n");
-module_param(vsync_cfg_count, uint, 0664);
-
 u32 VSYNC_RD_MPEG_REG(u32 adr)
 {
-       int enable_ = ((enable&enable_mask) | (enable_mask >> 8)) & 0xff;
+       int enable_ = cur_enable & 0xf;
+
        u32 read_val = Rd(adr);
 
        if ((enable_ != 0) && (vsync_rdma_handle > 0))
@@ -235,7 +189,7 @@ EXPORT_SYMBOL(VSYNC_RD_MPEG_REG);
 
 int VSYNC_WR_MPEG_REG(u32 adr, u32 val)
 {
-       int enable_ = ((enable & enable_mask) | (enable_mask >> 8)) & 0xff;
+       int enable_ = cur_enable & 0xf;
 
        if ((enable_ != 0) && (vsync_rdma_handle > 0)) {
                rdma_write_reg(vsync_rdma_handle, adr, val);
@@ -250,11 +204,11 @@ EXPORT_SYMBOL(VSYNC_WR_MPEG_REG);
 
 int VSYNC_WR_MPEG_REG_BITS(u32 adr, u32 val, u32 start, u32 len)
 {
-       int enable_ = ((enable & enable_mask) | (enable_mask >> 8)) & 0xff;
+       int enable_ = cur_enable & 0xf;
 
        if ((enable_ != 0) && (vsync_rdma_handle > 0)) {
                rdma_write_reg_bits(vsync_rdma_handle, adr, val, start, len);
-       }       else {
+       } else {
                u32 read_val = Rd(adr);
                u32 write_val = (read_val & ~(((1L<<(len))-1)<<(start)))
                        |((unsigned int)(val) << (start));
@@ -269,21 +223,14 @@ EXPORT_SYMBOL(VSYNC_WR_MPEG_REG_BITS);
 
 bool is_vsync_rdma_enable(void)
 {
-       int enable_ = ((enable & enable_mask) | (enable_mask >> 8)) & 0xff;
+       bool ret;
+       int enable_ = cur_enable & 0xf;
 
-               return (enable_ != 0) && (((enable_mask >> 19) & 0x1) == 0);
+       ret = (enable_ != 0);
+       return ret;
 }
 EXPORT_SYMBOL(is_vsync_rdma_enable);
 
-void start_rdma(void)
-{
-       if (vsync_rdma_handle <= 0) {
-               rdma_start_flag = 1;
-               up(&rdma_sema);
-       }
-}
-EXPORT_SYMBOL(start_rdma);
-
 void enable_rdma_log(int flag)
 {
        if (flag)
@@ -302,14 +249,30 @@ EXPORT_SYMBOL(enable_rdma);
 static int  __init rdma_init(void)
 
 {
-       WRITE_VCBUS_REG(VPU_VDISP_ASYNC_HOLD_CTRL, 0x18101810);
-       WRITE_VCBUS_REG(VPU_VPUARB2_ASYNC_HOLD_CTRL, 0x18101810);
-
+       vsync_rdma_handle =
+               rdma_register(&vsync_rdma_op,
+               NULL, RDMA_TABLE_SIZE);
+       pr_info("%s video rdma handle = %d.\n", __func__,
+               vsync_rdma_handle);
+       cur_enable = 0;
        enable = 1;
-
-       sema_init(&rdma_sema, 1);
-       kthread_run(rdma_task_handle, NULL, "kthread_h265");
+       force_rdma_config = 1;
        return 0;
 }
 
 module_init(rdma_init);
+
+MODULE_PARM_DESC(enable, "\n enable\n");
+module_param(enable, uint, 0664);
+
+MODULE_PARM_DESC(irq_count, "\n irq_count\n");
+module_param(irq_count, uint, 0664);
+
+MODULE_PARM_DESC(debug_flag, "\n debug_flag\n");
+module_param(debug_flag, uint, 0664);
+
+MODULE_PARM_DESC(vsync_cfg_count, "\n vsync_cfg_count\n");
+module_param(vsync_cfg_count, uint, 0664);
+
+MODULE_PARM_DESC(force_rdma_config, "\n force_rdma_config\n");
+module_param(force_rdma_config, uint, 0664);
index 03dc8d6..3b626e5 100644 (file)
 #define rdma_io_read(addr) readl(addr)
 #define rdma_io_write(addr, val) writel((val), addr)
 
-#define RDMA_VSYNC_INPUT_TRIG          0x1
-#define SKIP_OSD_CHANNEL
+/* #define SKIP_OSD_CHANNEL */
 
 int rdma_mgr_irq_request;
+int rdma_reset_tigger_flag;
 
-static int debug_flag_mgr;
-
+static int debug_flag;
 /* burst size 0=16; 1=24; 2=32; 3=48.*/
 static int ctrl_ahb_rd_burst_size = 3;
 static int ctrl_ahb_wr_burst_size = 3;
-static int rdma_watchdog = 4;
+static int rdma_watchdog = 10;
 static int reset_count;
 static int rdma_watchdog_count;
-static int rdma_vsync_isr_done;
-static int rdma_monitor_reg;
 static int rdma_force_reset = -1;
+static u16 trace_reg;
+
 #define RDMA_NUM 8
 struct rdma_regadr_s {
        u32 rdma_ahb_start_addr;
@@ -92,6 +91,7 @@ struct rdma_instance_s {
        u32 *rdma_table_addr;
        u32 rdma_table_phy_addr;
        int rdma_item_count;
+       int rdma_write_count;
        unsigned char keep_buf;
        unsigned char used;
        int prev_trigger_type;
@@ -109,93 +109,121 @@ static struct rdma_device_info rdma_info;
 
 static struct rdma_regadr_s rdma_regadr[RDMA_NUM] = {
        {RDMA_AHB_START_ADDR_MAN,
-                       RDMA_AHB_END_ADDR_MAN,
-                       0, 0,
-                       RDMA_ACCESS_MAN, 1,
-                       RDMA_ACCESS_MAN, 2,
-               24, 24},
+               RDMA_AHB_END_ADDR_MAN,
+               0, 0,
+               RDMA_ACCESS_MAN, 1,
+               RDMA_ACCESS_MAN, 2,
+               24, 24
+       },
        {RDMA_AHB_START_ADDR_1,
-                       RDMA_AHB_END_ADDR_1,
-                       RDMA_ACCESS_AUTO, 8,
-                       RDMA_ACCESS_AUTO, 1,
-                       RDMA_ACCESS_AUTO, 5,
-               25, 25},
+               RDMA_AHB_END_ADDR_1,
+               RDMA_ACCESS_AUTO,  8,
+               RDMA_ACCESS_AUTO,  1,
+               RDMA_ACCESS_AUTO,  5,
+               25, 25
+       },
        {RDMA_AHB_START_ADDR_2,
                        RDMA_AHB_END_ADDR_2,
-                       RDMA_ACCESS_AUTO, 16,
-                       RDMA_ACCESS_AUTO, 2,
-                       RDMA_ACCESS_AUTO, 6,
-               26, 26},
+                       RDMA_ACCESS_AUTO,  16,
+                       RDMA_ACCESS_AUTO,  2,
+                       RDMA_ACCESS_AUTO,  6,
+                       26, 26
+       },
        {RDMA_AHB_START_ADDR_3,
-                       RDMA_AHB_END_ADDR_3,
-                       RDMA_ACCESS_AUTO, 24,
-                       RDMA_ACCESS_AUTO, 3,
-                       RDMA_ACCESS_AUTO, 7,
-               27, 27},
+               RDMA_AHB_END_ADDR_3,
+               RDMA_ACCESS_AUTO,  24,
+               RDMA_ACCESS_AUTO,  3,
+               RDMA_ACCESS_AUTO,  7,
+               27, 27
+       },
        {RDMA_AHB_START_ADDR_4,
                        RDMA_AHB_END_ADDR_4,
                        RDMA_ACCESS_AUTO3, 0,
                        RDMA_ACCESS_AUTO2, 0,
                        RDMA_ACCESS_AUTO2, 4,
-               28, 28},
+                       28, 28
+       },
        {RDMA_AHB_START_ADDR_5,
-                       RDMA_AHB_END_ADDR_5,
-                       RDMA_ACCESS_AUTO3, 8,
-                       RDMA_ACCESS_AUTO2, 1,
-                       RDMA_ACCESS_AUTO2, 5,
-               29, 29},
+               RDMA_AHB_END_ADDR_5,
+               RDMA_ACCESS_AUTO3, 8,
+               RDMA_ACCESS_AUTO2, 1,
+               RDMA_ACCESS_AUTO2, 5,
+               29, 29
+       },
        {RDMA_AHB_START_ADDR_6,
-                       RDMA_AHB_END_ADDR_6,
-                       RDMA_ACCESS_AUTO3, 16,
-                       RDMA_ACCESS_AUTO2, 2,
-                       RDMA_ACCESS_AUTO2, 6,
-               30, 30},
+               RDMA_AHB_END_ADDR_6,
+               RDMA_ACCESS_AUTO3, 16,
+               RDMA_ACCESS_AUTO2, 2,
+               RDMA_ACCESS_AUTO2, 6,
+               30, 30
+       },
        {RDMA_AHB_START_ADDR_7,
-                       RDMA_AHB_END_ADDR_7,
-                       RDMA_ACCESS_AUTO3, 24,
-                       RDMA_ACCESS_AUTO2, 3,
-                       RDMA_ACCESS_AUTO2, 7,
-               31, 31}
+               RDMA_AHB_END_ADDR_7,
+               RDMA_ACCESS_AUTO3, 24,
+               RDMA_ACCESS_AUTO2, 3,
+               RDMA_ACCESS_AUTO2, 7,
+               31, 31
+       }
 };
 
 int rdma_register(struct rdma_op_s *rdma_op, void *op_arg, int table_size)
 {
        int i;
+       unsigned long flags;
        struct rdma_device_info *info = &rdma_info;
        dma_addr_t dma_handle;
-
+       spin_lock_irqsave(&rdma_lock, flags);
        for (i = 1; i < RDMA_NUM; i++) {
                /* 0 is reserved for RDMA MANUAL */
                if (info->rdma_ins[i].op == NULL &&
-                       info->rdma_ins[i].used == 0) {
-                       info->rdma_ins[i].not_process = 0;
-                       info->rdma_ins[i].op_arg = op_arg;
-
-                       if (info->rdma_ins[i].rdma_table_size == 0) {
-                               info->rdma_ins[i].rdma_table_addr =
-                                       dma_alloc_coherent(&info->rdma_dev->dev,
-                                       table_size, &dma_handle, GFP_KERNEL);
-                               info->rdma_ins[i].rdma_table_phy_addr =
-                                       (u32) (dma_handle);
-
-                               info->rdma_ins[i].reg_buf =
-                                       kmalloc(table_size, GFP_KERNEL);
-                               pr_info("%s, rdma_table_addr %p rdma_table_addr_phy %x reg_buf %p\n",
-                               __func__, info->rdma_ins[i].rdma_table_addr,
-                               info->rdma_ins[i].rdma_table_phy_addr,
-                               info->rdma_ins[i].reg_buf);
-                               info->rdma_ins[i].rdma_table_size = table_size;
-                       }
+                               info->rdma_ins[i].used == 0) {
                        info->rdma_ins[i].op = rdma_op;
                        break;
                }
        }
+       spin_unlock_irqrestore(&rdma_lock, flags);
        if (i < RDMA_NUM) {
+               info->rdma_ins[i].not_process = 0;
+               info->rdma_ins[i].op_arg = op_arg;
+               info->rdma_ins[i].rdma_item_count = 0;
+               info->rdma_ins[i].rdma_write_count = 0;
+               if (info->rdma_ins[i].rdma_table_size == 0) {
+                       info->rdma_ins[i].rdma_table_addr =
+                               dma_alloc_coherent(
+                               &info->rdma_dev->dev, table_size,
+                               &dma_handle, GFP_KERNEL);
+                       info->rdma_ins[i].rdma_table_phy_addr
+                               = (u32)(dma_handle);
+                       info->rdma_ins[i].reg_buf =
+                               kmalloc(table_size, GFP_KERNEL);
+                       pr_info("%s, rdma_table_addr %p rdma_table_addr_phy %x reg_buf %p\n",
+                               __func__,
+                               info->rdma_ins[i].rdma_table_addr,
+                               info->rdma_ins[i].rdma_table_phy_addr,
+                               info->rdma_ins[i].reg_buf);
+                       info->rdma_ins[i].rdma_table_size = table_size;
+               }
+
                if (info->rdma_ins[i].rdma_table_addr == NULL ||
                        info->rdma_ins[i].reg_buf == NULL) {
+                       if (!info->rdma_ins[i].keep_buf) {
+                               kfree(info->rdma_ins[i].reg_buf);
+                               info->rdma_ins[i].reg_buf = NULL;
+                       }
+                       if (info->rdma_ins[i].rdma_table_addr) {
+                               dma_free_coherent(
+                               &info->rdma_dev->dev,
+                               table_size,
+                               info->rdma_ins[i].rdma_table_addr,
+                               (dma_addr_t)
+                               info->rdma_ins[i].rdma_table_phy_addr);
+                               info->rdma_ins[i].rdma_table_addr = NULL;
+                       }
+                       info->rdma_ins[i].rdma_table_size  = 0;
                        info->rdma_ins[i].op = NULL;
                        i = -1;
-                       pr_info("%s: memory allocate fail\n", __func__);
+                       pr_info("%s: memory allocate fail\n",
+                               __func__);
                } else
                        pr_info("%s success, handle %d table_size %d\n",
                                __func__, i, table_size);
@@ -212,43 +240,44 @@ void rdma_unregister(int i)
 
        pr_info("%s(%d)\r\n", __func__, i);
        if (i > 0 && i < RDMA_NUM && info->rdma_ins[i].op) {
-               int table_size;
-
-               /*rdma_clear(i); */
-               spin_lock_irqsave(&rdma_lock, flags);
-               table_size = info->rdma_ins[i].rdma_table_size;
-               info->rdma_ins[i].op = NULL;
-               if (!info->rdma_ins[i].keep_buf)
-                       info->rdma_ins[i].rdma_table_size = 0;
-               spin_unlock_irqrestore(&rdma_lock, flags);
-
+               /*rdma_clear(i);*/
                info->rdma_ins[i].op_arg = NULL;
                if (!info->rdma_ins[i].keep_buf) {
                        kfree(info->rdma_ins[i].reg_buf);
                        info->rdma_ins[i].reg_buf = NULL;
-                       if (info->rdma_ins[i].rdma_table_addr) {
-                               dma_free_coherent(&info->rdma_dev->dev,
-                                       table_size,
-                                       info->rdma_ins[i].rdma_table_addr,
-                                       (dma_addr_t)
-                                       info->rdma_ins[i].rdma_table_phy_addr);
-                       }
                }
+               if (info->rdma_ins[i].rdma_table_addr) {
+                       dma_free_coherent(&info->rdma_dev->dev,
+                       info->rdma_ins[i].rdma_table_size,
+                       info->rdma_ins[i].rdma_table_addr,
+                       (dma_addr_t)
+                       info->rdma_ins[i].rdma_table_phy_addr);
+                       info->rdma_ins[i].rdma_table_addr = NULL;
+               }
+               info->rdma_ins[i].rdma_table_size = 0;
+               spin_lock_irqsave(&rdma_lock, flags);
+               info->rdma_ins[i].op = NULL;
+               spin_unlock_irqrestore(&rdma_lock, flags);
        }
 }
 EXPORT_SYMBOL(rdma_unregister);
 static void rdma_reset(unsigned char external_reset)
 {
-       if (debug_flag_mgr & 4)
-               pr_info("%s(%d)\n", __func__, external_reset);
+       if (debug_flag & 4)
+               pr_info("%s(%d)\n",
+                       __func__, external_reset);
 
        if (external_reset) {
-               WRITE_MPEG_REG(RESET4_REGISTER, (1 << 5));
+               WRITE_MPEG_REG(
+                       RESET4_REGISTER,
+                       (1 << 5));
        } else {
                WRITE_VCBUS_REG(RDMA_CTRL, (0x1 << 1));
                WRITE_VCBUS_REG(RDMA_CTRL, (0x1 << 1));
-               WRITE_VCBUS_REG(RDMA_CTRL, (ctrl_ahb_wr_burst_size << 4) |
-                       (ctrl_ahb_rd_burst_size << 2) | (0x0 << 1));
+               WRITE_VCBUS_REG(RDMA_CTRL,
+                       (ctrl_ahb_wr_burst_size << 4) |
+                       (ctrl_ahb_rd_burst_size << 2) |
+                       (0x0 << 1));
        }
        reset_count++;
 }
@@ -260,14 +289,13 @@ irqreturn_t rdma_mgr_isr(int irq, void *dev_id)
        int retry_count = 0;
        u32 rdma_status;
        int i;
-
-       if (debug_flag_mgr & 0x10)
+       if (debug_flag & 0x10)
                return IRQ_HANDLED;
        rdma_isr_count++;
 QUERY:
        retry_count++;
        rdma_status = READ_VCBUS_REG(RDMA_STATUS);
-       if ((debug_flag_mgr & 4) && ((rdma_isr_count % 30) == 0))
+       if ((debug_flag & 4) && ((rdma_isr_count % 30) == 0))
                pr_info("%s: %x\r\n", __func__, rdma_status);
        for (i = 0; i < RDMA_NUM; i++) {
                struct rdma_instance_s *ins = &info->rdma_ins[i];
@@ -281,19 +309,15 @@ QUERY:
                if (i == 3)
                        continue;
 #endif
-               if (ins->prev_trigger_type == RDMA_VSYNC_INPUT_TRIG) {
-                       rdma_vsync_isr_done = 1;
-                       ;
-               }
                if (rdma_status & (1 << ins->rdma_regadr->irq_status_bitpos)) {
-                       if (debug_flag_mgr & 2)
+                       if (debug_flag & 2)
                                pr_info("%s: process %d\r\n", __func__, i);
 
-                       WRITE_VCBUS_REG(RDMA_CTRL,
-                               (1 << ins->rdma_regadr->clear_irq_bitpos));
-
                        if (ins->op && ins->op->irq_cb)
                                ins->op->irq_cb(ins->op->arg);
+
+                       WRITE_VCBUS_REG(RDMA_CTRL,
+                               (1 << ins->rdma_regadr->clear_irq_bitpos));
                }
        }
        rdma_status = READ_VCBUS_REG(RDMA_STATUS);
@@ -328,15 +352,19 @@ int rdma_config(int handle, int trigger_type)
        struct rdma_instance_s *ins = &info->rdma_ins[handle];
        bool auto_start = false;
 
-       if (handle == 0)
-               pr_info("%s error, rdma_config(handle == 0) not allowed\n",
-                       __func__);
+       if (handle == 0 || handle >= RDMA_NUM) {
+               pr_info(
+                       "%s error, rdma_config(handle == %d) not allowed\n",
+                       __func__, handle);
+               return -1;
+       }
 
        spin_lock_irqsave(&rdma_lock, flags);
        if (ins->op == NULL) {
                spin_unlock_irqrestore(&rdma_lock, flags);
 
-               pr_info("%s: handle (%d) not register\n", __func__, handle);
+               pr_info("%s: handle (%d) not register\n",
+                       __func__, handle);
                return -1;
        }
 
@@ -367,87 +395,92 @@ int rdma_config(int handle, int trigger_type)
                        ins->rdma_regadr->trigger_mask_reg_bitpos,
                        8);
                ret = 1;
+               ins->rdma_write_count = 0;
        } else if (ins->rdma_item_count <= 0 || trigger_type == 0) {
                if (trigger_type == RDMA_TRIGGER_MANUAL)
                        WRITE_VCBUS_REG(RDMA_ACCESS_MAN,
                                READ_VCBUS_REG(RDMA_ACCESS_MAN) & (~1));
-               if (debug_flag_mgr & 2) {
-                       pr_info("%s: trigger_type %d : %d\r\n",
+                       if (debug_flag & 2) {
+                               pr_info("%s: trigger_type %d : %d\r\n",
                                __func__, trigger_type, ins->rdma_item_count);
-               }
-               WRITE_VCBUS_REG_BITS(ins->rdma_regadr->trigger_mask_reg,
+                       }
+               WRITE_VCBUS_REG_BITS(
+                       ins->rdma_regadr->trigger_mask_reg,
                        0, ins->rdma_regadr->trigger_mask_reg_bitpos, 8);
-               rdma_vsync_isr_done = 1;
+               ins->rdma_write_count = 0;
                ret = 0;
        } else {
                memcpy(ins->rdma_table_addr, ins->reg_buf,
                        ins->rdma_item_count * 2 * sizeof(u32));
 
                if (trigger_type > 0 && trigger_type <= RDMA_TRIGGER_MANUAL) {
+                       ins->rdma_write_count = ins->rdma_item_count;
                        ins->prev_trigger_type = trigger_type;
                        if (trigger_type == RDMA_TRIGGER_MANUAL) {
                                /*manual RDMA */
                                struct rdma_instance_s *man_ins =
                                        &info->rdma_ins[0];
                                WRITE_VCBUS_REG(RDMA_ACCESS_MAN,
-                                       READ_VCBUS_REG(RDMA_ACCESS_MAN)
-                                       & (~1));
-                               WRITE_VCBUS_REG(man_ins->
-                                       rdma_regadr->rdma_ahb_start_addr,
-                                       ins->rdma_table_phy_addr);
-                               WRITE_VCBUS_REG(man_ins->
-                                       rdma_regadr->rdma_ahb_end_addr,
-                                       ins->rdma_table_phy_addr +
-                                       ins->rdma_item_count * 8 - 1);
-
-                               WRITE_VCBUS_REG_BITS(man_ins->
-                                       rdma_regadr->addr_inc_reg, 0,
-                                       man_ins->
-                                       rdma_regadr->addr_inc_reg_bitpos, 1);
-                               WRITE_VCBUS_REG_BITS(man_ins->
-                                       rdma_regadr->rw_flag_reg, 1,
-                                       man_ins->
-                                       rdma_regadr->rw_flag_reg_bitpos, 1);
-                               /* Manual-start RDMA */
+                               READ_VCBUS_REG(RDMA_ACCESS_MAN) & (~1));
+                               WRITE_VCBUS_REG(
+                               man_ins->rdma_regadr->rdma_ahb_start_addr,
+                               ins->rdma_table_phy_addr);
+                               WRITE_VCBUS_REG(
+                               man_ins->rdma_regadr->rdma_ahb_end_addr,
+                               ins->rdma_table_phy_addr
+                               + ins->rdma_item_count * 8 - 1);
+
+                               WRITE_VCBUS_REG_BITS(
+                               man_ins->rdma_regadr->addr_inc_reg,
+                               0,
+                               man_ins->rdma_regadr->addr_inc_reg_bitpos,
+                               1);
+                               WRITE_VCBUS_REG_BITS(
+                               man_ins->rdma_regadr->rw_flag_reg,
+                               1,
+                               man_ins->rdma_regadr->rw_flag_reg_bitpos,
+                               1);
+                               /* Manual-start RDMA*/
                                WRITE_VCBUS_REG(RDMA_ACCESS_MAN,
-                                       READ_VCBUS_REG(RDMA_ACCESS_MAN)
-                                       | 1);
+                                       READ_VCBUS_REG(RDMA_ACCESS_MAN) | 1);
 
-                               if (debug_flag_mgr & 2)
+                               if (debug_flag & 2)
                                        pr_info("%s: manual config %d:\r\n",
-                                               __func__, ins->rdma_item_count);
-                       } else {        /* interrupt input trigger RDMA */
-                               if (debug_flag_mgr & 2)
+                                       __func__, ins->rdma_item_count);
+                       } else {
+                               /* interrupt input trigger RDMA */
+                               if (debug_flag & 2)
                                        pr_info("%s: case 3 : %d:\r\n",
-                                               __func__, ins->rdma_item_count);
-                               WRITE_VCBUS_REG_BITS(ins->
-                                       rdma_regadr->trigger_mask_reg, 0,
-                                       ins->
-                                       rdma_regadr->trigger_mask_reg_bitpos,
-                                       8);
-
-                               WRITE_VCBUS_REG(ins->
-                                       rdma_regadr->rdma_ahb_start_addr,
+                                       __func__, ins->rdma_item_count);
+                               WRITE_VCBUS_REG_BITS(
+                               ins->rdma_regadr->trigger_mask_reg,
+                               0,
+                               ins->rdma_regadr->trigger_mask_reg_bitpos,
+                               8);
+
+                               WRITE_VCBUS_REG(
+                                       ins->rdma_regadr->rdma_ahb_start_addr,
                                        ins->rdma_table_phy_addr);
-                               WRITE_VCBUS_REG(ins->
-                                       rdma_regadr->rdma_ahb_end_addr,
-                                       ins->rdma_table_phy_addr +
-                                       ins->rdma_item_count * 8 - 1);
-
-                               WRITE_VCBUS_REG_BITS(ins->
-                                       rdma_regadr->addr_inc_reg, 0,
+                               WRITE_VCBUS_REG(
+                                       ins->rdma_regadr->rdma_ahb_end_addr,
+                                       ins->rdma_table_phy_addr
+                                       + ins->rdma_item_count * 8 - 1);
+
+                               WRITE_VCBUS_REG_BITS(
+                                       ins->rdma_regadr->addr_inc_reg,
+                                       0,
                                        ins->rdma_regadr->addr_inc_reg_bitpos,
                                        1);
-                               WRITE_VCBUS_REG_BITS(ins->
-                                       rdma_regadr->rw_flag_reg, 1,
+                               WRITE_VCBUS_REG_BITS(
+                                       ins->rdma_regadr->rw_flag_reg,
+                                       1,
                                        ins->rdma_regadr->rw_flag_reg_bitpos,
                                        1);
-                               WRITE_VCBUS_REG_BITS(ins->
-                                       rdma_regadr->trigger_mask_reg,
-                                       trigger_type,
-                                       ins->
-                                       rdma_regadr->trigger_mask_reg_bitpos,
-                                       8);
+                               WRITE_VCBUS_REG_BITS(
+                               ins->rdma_regadr->trigger_mask_reg,
+                               trigger_type,
+                               ins->rdma_regadr->trigger_mask_reg_bitpos,
+                               8);
                        }
                } else if (trigger_type == 0x101) {     /* debug mode */
                        int i;
@@ -455,30 +488,31 @@ int rdma_config(int handle, int trigger_type)
                        for (i = 0; i < ins->rdma_item_count; i++) {
                                WRITE_VCBUS_REG(ins->rdma_table_addr[i << 1],
                                        ins->rdma_table_addr[(i << 1) + 1]);
-                               if (debug_flag_mgr & 1)
+                               if (debug_flag & 1)
                                        pr_info("WR(%x)<=%x\n",
-                                               ins->rdma_table_addr[i << 1],
-                                               ins->rdma_table_addr[(i << 1) +
-                                                       1]);
+                                       ins->rdma_table_addr[i << 1],
+                                       ins->rdma_table_addr[(i << 1) + 1]);
                        }
-               } else if (trigger_type == 0x102) {     /* debug mode */
+                       ins->rdma_write_count = 0;
+               } else if (trigger_type == 0x102) { /* debug mode */
                        int i;
 
                        for (i = 0; i < ins->rdma_item_count; i++) {
                                WRITE_VCBUS_REG(ins->reg_buf[i << 1],
                                        ins->reg_buf[(i << 1) + 1]);
-                               if (debug_flag_mgr & 1)
+                               if (debug_flag & 1)
                                        pr_info("WR(%x)<=%x\n",
                                                ins->reg_buf[i << 1],
                                                ins->reg_buf[(i << 1) + 1]);
                        }
+                       ins->rdma_write_count = 0;
                }
                ret = 1;
        }
        ins->rdma_item_count = 0;
        spin_unlock_irqrestore(&rdma_lock, flags);
 
-       if (debug_flag_mgr & 2)
+       if (debug_flag & 2)
                pr_info("%s: (%d 0x%x) ret %d\r\n",
                        __func__, handle, trigger_type, ret);
 
@@ -489,18 +523,23 @@ EXPORT_SYMBOL(rdma_config);
 int rdma_clear(int handle)
 {
        int ret = 0;
+       unsigned long flags;
        struct rdma_device_info *info = &rdma_info;
        struct rdma_instance_s *ins = &info->rdma_ins[handle];
-
-       if (handle == 0 || ins->op == NULL) {
+       spin_lock_irqsave(&rdma_lock, flags);
+       if (handle <= 0 ||
+               handle >= RDMA_NUM ||
+               ins->op == NULL) {
+               spin_unlock_irqrestore(&rdma_lock, flags);
                pr_info("%s error, handle (%d) not register\n",
                        __func__, handle);
                return -1;
        }
-
-       WRITE_VCBUS_REG_BITS(ins->rdma_regadr->trigger_mask_reg,
+       WRITE_VCBUS_REG_BITS(
+               ins->rdma_regadr->trigger_mask_reg,
                0, ins->rdma_regadr->trigger_mask_reg_bitpos, 8);
-
+       ins->rdma_write_count = 0;
+       spin_unlock_irqrestore(&rdma_lock, flags);
        return ret;
 }
 EXPORT_SYMBOL(rdma_clear);
@@ -508,6 +547,9 @@ EXPORT_SYMBOL(rdma_clear);
 u32 rdma_read_reg(int handle, u32 adr)
 {
        int i;
+       u32 *write_table;
+       int match = 0;
+       int read_from = 0;
        struct rdma_device_info *info = &rdma_info;
        struct rdma_instance_s *ins = &info->rdma_ins[handle];
        u32 read_val = READ_VCBUS_REG(adr);
@@ -515,29 +557,72 @@ u32 rdma_read_reg(int handle, u32 adr)
        for (i = (ins->rdma_item_count - 1); i >= 0; i--) {
                if (ins->reg_buf[i << 1] == adr) {
                        read_val = ins->reg_buf[(i << 1) + 1];
+                       match = 1;
+                       read_from = 1;
                        break;
                }
        }
+       if (!match) {
+               write_table = ins->rdma_table_addr;
+               for (i = (ins->rdma_write_count - 1);
+                       i >= 0; i--) {
+                       if (write_table[i << 1] == adr) {
+                               read_val =
+                                       write_table[(i << 1) + 1];
+                               read_from = 2;
+                               break;
+                       }
+               }
+       }
+       if (adr == trace_reg) {
+               if (read_from == 2)
+                       pr_info("(%s) handle %d, %04x=0x%08x from write table(%d)\n",
+                               __func__,
+                               handle, adr,
+                               read_val,
+                               ins->rdma_write_count);
+               else if (read_from == 1)
+                       pr_info("(%s) handle %d, %04x=0x%08x from item table(%d)\n",
+                               __func__,
+                               handle, adr,
+                               read_val,
+                               ins->rdma_item_count);
+               else
+                       pr_info("(%s) handle %d, %04x=0x%08x from real reg\n",
+                               __func__,
+                               handle, adr,
+                               read_val);
+       }
        return read_val;
 }
 EXPORT_SYMBOL(rdma_read_reg);
 
-int rdma_reset_tigger_flag;
 int rdma_watchdog_setting(int flag)
 {
-       if (rdma_vsync_isr_done) {
-               rdma_watchdog_count = 0;
-               rdma_vsync_isr_done = 0;
-       }
+       int ret = 0;
        if (flag == 0)
                rdma_watchdog_count = 0;
        else
                rdma_watchdog_count++;
-       if (debug_flag_mgr & 8) {
+
+       if (debug_flag & 8) {
                rdma_force_reset = 1;
-               debug_flag_mgr = 0;
+               debug_flag = 0;
        }
-       return 0;
+       if (((rdma_watchdog > 0) &&
+               (rdma_watchdog_count > rdma_watchdog))
+               || (rdma_force_reset > 0)) {
+               pr_info("%s rdma reset: %d, force flag:%d\n",
+                       __func__,
+                       rdma_watchdog_count,
+                       rdma_force_reset);
+               rdma_watchdog_count = 0;
+               rdma_force_reset = 0;
+               rdma_reset(1);
+               rdma_reset_tigger_flag = 1;
+               ret = 1;
+       }
+       return ret;
 }
 EXPORT_SYMBOL(rdma_watchdog_setting);
 
@@ -549,7 +634,7 @@ int rdma_write_reg(int handle, u32 adr, u32 val)
        if (ins->rdma_table_size == 0)
                return -1;
 
-       if (debug_flag_mgr & 1)
+       if (debug_flag & 1)
                pr_info("rdma_write(%d) %d(%x)<=%x\n",
                        handle, ins->rdma_item_count, adr, val);
        if (((ins->rdma_item_count << 1) + 1) <
@@ -559,34 +644,24 @@ int rdma_write_reg(int handle, u32 adr, u32 val)
                ins->rdma_item_count++;
        } else {
                int i;
-
-               if (debug_flag_mgr & 4)
+               if (debug_flag & 4)
                        pr_info("%s(%d, %x, %x ,%d) buf overflow\n",
-                               __func__, rdma_watchdog_count, handle, adr,
-                               val);
+               __func__, rdma_watchdog_count, handle, adr, val);
                for (i = 0; i < ins->rdma_item_count; i++)
                        WRITE_VCBUS_REG(ins->reg_buf[i << 1],
                                ins->reg_buf[(i << 1) + 1]);
                ins->rdma_item_count = 0;
+               ins->rdma_write_count = 0;
                ins->reg_buf[ins->rdma_item_count << 1] = adr;
                ins->reg_buf[(ins->rdma_item_count << 1) + 1] = val;
                ins->rdma_item_count++;
        }
-       if ((rdma_watchdog > 0) && (rdma_watchdog_count > rdma_watchdog)) {
-               pr_info("%s rdma reset :%d\n", __func__, rdma_watchdog_count);
-               rdma_watchdog_count = 0;
-               rdma_reset(1);
-               rdma_config(handle, ins->prev_trigger_type);
-               rdma_reset_tigger_flag = 1;
-       }
-       if (rdma_force_reset == 1) {
-               rdma_force_reset = 0;
-               rdma_reset_tigger_flag = 1;
-               rdma_watchdog_count = 0;
-               rdma_reset(1);
-               rdma_config(handle, ins->prev_trigger_type);
-               pr_info("%s rdma force reset\n", __func__);
-       }
+       if (adr == trace_reg)
+               pr_info("(%s) handle %d, %04x=0x%08x (%d)\n",
+                       __func__,
+                       handle, adr,
+                       val,
+                       ins->rdma_item_count);
        return 0;
 }
 EXPORT_SYMBOL(rdma_write_reg);
@@ -594,7 +669,9 @@ EXPORT_SYMBOL(rdma_write_reg);
 int rdma_write_reg_bits(int handle, u32 adr, u32 val, u32 start, u32 len)
 {
        int i;
+       u32 *write_table;
        int match = 0;
+       int read_from = 0;
        struct rdma_device_info *info = &rdma_info;
        struct rdma_instance_s *ins = &info->rdma_ins[handle];
        u32 read_val = READ_VCBUS_REG(adr);
@@ -607,16 +684,52 @@ int rdma_write_reg_bits(int handle, u32 adr, u32 val, u32 start, u32 len)
                if (ins->reg_buf[i << 1] == adr) {
                        read_val = ins->reg_buf[(i << 1) + 1];
                        match = 1;
+                       read_from = 1;
                        break;
                }
        }
-       write_val = (read_val & ~(((1L << (len)) - 1) << (start)))
-               | ((unsigned int)(val) << (start));
+       if (!match) {
+               write_table = ins->rdma_table_addr;
+               for (i = (ins->rdma_write_count - 1);
+                       i >= 0; i--) {
+                       if (write_table[i << 1] == adr) {
+                               read_val =
+                                       write_table[(i << 1) + 1];
+                               read_from = 2;
+                               break;
+                       }
+               }
+       }
+       write_val = (read_val & ~(((1L<<(len))-1)<<(start)))
+               |((unsigned int)(val) << (start));
+
+       if (adr == trace_reg) {
+               if (read_from == 2)
+                       pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from write table(%d)\n",
+                               __func__,
+                               handle, adr,
+                               read_val,
+                               write_val,
+                               ins->rdma_write_count);
+               else if (read_from == 1)
+                       pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from item table(%d)\n",
+                               __func__,
+                               handle, adr,
+                               read_val,
+                               write_val,
+                               ins->rdma_item_count);
+               else
+                       pr_info("(%s) handle %d, %04x=0x%08x->0x%08x from real reg\n",
+                               __func__,
+                               handle, adr,
+                               read_val,
+                               write_val);
+       }
        if (match) {
                ins->reg_buf[(i << 1) + 1] = write_val;
                return 0;
        }
-       if (debug_flag_mgr & 1)
+       if (debug_flag & 1)
                pr_info("rdma_write(%d) %d(%x)<=%x\n",
                        handle, ins->rdma_item_count, adr, write_val);
 
@@ -625,8 +738,8 @@ int rdma_write_reg_bits(int handle, u32 adr, u32 val, u32 start, u32 len)
 }
 EXPORT_SYMBOL(rdma_write_reg_bits);
 
-MODULE_PARM_DESC(debug_flag_mgr, "\n debug_flag_mgr\n");
-module_param(debug_flag_mgr, uint, 0664);
+MODULE_PARM_DESC(debug_flag, "\n debug_flag\n");
+module_param(debug_flag, uint, 0664);
 
 MODULE_PARM_DESC(rdma_watchdog, "\n rdma_watchdog\n");
 module_param(rdma_watchdog, uint, 0664);
@@ -634,15 +747,15 @@ module_param(rdma_watchdog, uint, 0664);
 MODULE_PARM_DESC(reset_count, "\n reset_count\n");
 module_param(reset_count, uint, 0664);
 
-MODULE_PARM_DESC(rdma_monitor_reg, "\n rdma_monitor_reg\n");
-module_param(rdma_monitor_reg, uint, 0664);
-
 MODULE_PARM_DESC(ctrl_ahb_rd_burst_size, "\n ctrl_ahb_rd_burst_size\n");
 module_param(ctrl_ahb_rd_burst_size, uint, 0664);
 
 MODULE_PARM_DESC(ctrl_ahb_wr_burst_size, "\n ctrl_ahb_wr_burst_size\n");
 module_param(ctrl_ahb_wr_burst_size, uint, 0664);
 
+MODULE_PARM_DESC(trace_reg, "\n trace_addr\n");
+module_param(trace_reg, ushort, 0664);
+
 /* static int __devinit rdma_probe(struct platform_device *pdev) */
 static int rdma_probe(struct platform_device *pdev)
 {
@@ -654,17 +767,26 @@ static int rdma_probe(struct platform_device *pdev)
        int_rdma = platform_get_irq_byname(pdev, "rdma");
 
        pr_info("%s\n", __func__);
+
+       WRITE_VCBUS_REG(VPU_VDISP_ASYNC_HOLD_CTRL, 0x18101810);
+       WRITE_VCBUS_REG(VPU_VPUARB2_ASYNC_HOLD_CTRL, 0x18101810);
+
        rdma_mgr_irq_request = 0;
+       trace_reg = 0;
+
        for (i = 0; i < RDMA_NUM; i++) {
                info->rdma_ins[i].rdma_table_size = 0;
                info->rdma_ins[i].rdma_regadr = &rdma_regadr[i];
                info->rdma_ins[i].keep_buf = 1;
                /*do not change it in normal case */
                info->rdma_ins[i].used = 0;
+               info->rdma_ins[i].prev_trigger_type = 0;
+               info->rdma_ins[i].rdma_write_count = 0;
        }
-       WRITE_MPEG_REG(RESET4_REGISTER, (1 << 5));
-#if 1
-       info->rdma_ins[3].used = 1;     /* OSD driver uses this channel */
+       WRITE_MPEG_REG(RESET4_REGISTER,
+                                  (1 << 5));
+#ifdef SKIP_OSD_CHANNEL
+       info->rdma_ins[3].used = 1; /* OSD driver uses this channel */
 #endif
        if (int_rdma == -ENXIO) {
                dev_err(&pdev->dev, "cannot get rdma irq resource\n");
@@ -677,8 +799,9 @@ static int rdma_probe(struct platform_device *pdev)
        }
 
        rdma_mgr_irq_request = 1;
-       data32 = 0;
-       data32 |= 0 << 6;
+       data32  = 0;
+       data32 |= 1 << 7; /* wrtie ddr urgent */
+       data32 |= 1 << 6; /* read ddr urgent */
        data32 |= ctrl_ahb_wr_burst_size << 4;
        data32 |= ctrl_ahb_rd_burst_size << 2;
        data32 |= 0 << 1;
index 25f0520..ab0001a 100644 (file)
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/list.h>
-
+#include <linux/io.h>
+#include <linux/uaccess.h>
 /* Amlogic headers */
 #include <linux/amlogic/media/vfm/vframe.h>
 #include <linux/amlogic/media/vfm/vframe_provider.h>
 #include <linux/amlogic/media/vfm/vframe_receiver.h>
 
+#include <linux/amlogic/major.h>
 /*for dumpinfos*/
 #include <linux/amlogic/media/canvas/canvas_mgr.h>
 #include <linux/amlogic/media/canvas/canvas.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
 
 /* Local headers */
 #include "vftrace.h"
@@ -47,7 +50,7 @@ static DEFINE_SPINLOCK(lock);
 #define VFM_NAME_LEN    100
 #define VFM_MAP_SIZE    10
 #define VFM_MAP_COUNT   20
-
+static struct device *vfm_dev;
 struct vfm_map_s {
        char id[VFM_NAME_LEN];
        char name[VFM_MAP_SIZE][VFM_NAME_LEN];
@@ -154,52 +157,94 @@ int vfm_map_add(char *id, char *name_chain)
 {
        int i, j;
        int ret = -1;
-       char *ptr, *token;
+       char *ptr, *token = NULL;
        struct vfm_map_s *p;
+       int old_num = vfm_map_num;
+       unsigned long flags;
+       int add_ok = 0;
+       int cnt = 10;
 
        p = kmalloc(sizeof(struct vfm_map_s), GFP_KERNEL);
-       if (p) {
-               memset(p, 0, sizeof(struct vfm_map_s));
-               memcpy(p->id, id, strlen(id));
-               p->valid = 1;
-               ptr = name_chain;
-               while (1) {
-                       token = strsep(&ptr, "\n ");
-                       if (token == NULL)
-                               break;
-                       if (*token == '\0')
-                               continue;
-                       memcpy(p->name[p->vfm_map_size], token, strlen(token));
-                       p->vfm_map_size++;
-               }
-               for (i = 0; i < vfm_map_num; i++) {
-                       if (vfm_map[i] && (vfm_map[i]->vfm_map_size ==
-                                       p->vfm_map_size) &&
-                               (!strcmp(vfm_map[i]->id, p->id))) {
-                               for (j = 0; j < p->vfm_map_size; j++) {
-                                       if (strcmp(vfm_map[i]->name[j],
-                                                       p->name[j])) {
-                                               break;
-                                       }
-                               }
-                               if (j == p->vfm_map_size) {
-                                       vfm_map[i]->valid = 1;
-                                       kfree(p);
+       if (!p) {
+               pr_err("%s: Error, map no mem!!\n", __func__);
+               return -ENOMEM;
+       }
+       memset(p, 0, sizeof(struct vfm_map_s));
+       memcpy(p->id, id, strlen(id));
+       p->valid = 1;
+       ptr = name_chain;
+
+       do {
+               token = strsep(&ptr, "\n ");
+               if (token == NULL)
+                       break;
+               if (*token == '\0')
+                       continue;
+               memcpy(p->name[p->vfm_map_size], token, strlen(token));
+               p->vfm_map_size++;
+       } while (token && cnt--);
+
+       cnt = 10; /*limit the cnt of retry to avoid the infinite loop*/
+
+retry:
+       for (i = 0; i < vfm_map_num; i++) {
+               struct vfm_map_s *pi = vfm_map[i];
+
+               if (!pi || (strcmp(pi->id, p->id))) {
+                       /*not same id to next one*/
+                       continue;
+               } else if (pi->valid) {
+                       for (j = 0; j < p->vfm_map_size; j++) {
+                               if (strcmp(pi->name[j],
+                                       p->name[j])){
                                        break;
                                }
                        }
+                       if (j == p->vfm_map_size) {
+                               pi->valid = 1;
+                               kfree(p);
+                               add_ok = 1;
+                               break;
+                       }
+               } else if (!pi->valid) {
+                       /*
+                        *over write old setting.
+                        *  don't free old one,
+                        * because it may on used.
+                        */
+                       for (j = 0; j < p->vfm_map_size; j++) {
+                               /*over write node.*/
+                               strcpy(pi->name[j], p->name[j]);
+                       }
+                       pi->vfm_map_size = p->vfm_map_size;
+                       pi->valid = 1;
+                       kfree(p);
+                       add_ok = 1;
+                       break;
+               }
+       }
+       if (!add_ok) {
+               spin_lock_irqsave(&lock, flags);
+               if (i == old_num && old_num != vfm_map_num && cnt--) {
+                       spin_unlock_irqrestore(&lock, flags);
+                       pr_err("%s: vfm_map changed on add, need retry!\n",
+                               __func__);
+                       goto retry;
                }
                if (i == vfm_map_num) {
                        if (i < VFM_MAP_COUNT) {
                                vfm_map[i] = p;
                                vfm_map_num++;
-                       } else {
+                               add_ok = 1;
+                       } else{
                                pr_err("%s: Error, map full\n", __func__);
                                ret = -1;
                        }
                }
-               ret = 0;
+               spin_unlock_irqrestore(&lock, flags);
        }
+       if (add_ok)
+               ret = 0;
        return ret;
 }
 EXPORT_SYMBOL(vfm_map_add);
@@ -214,7 +259,6 @@ static char *vf_get_provider_name_inmap(int i, const char *receiver_name)
                        if ((j > 0) &&
                                ((vfm_map[i]->active >> (j - 1)) & 0x1)) {
                                provider_name = vfm_map[i]->name[j - 1];
-                               ;
                        }
                        break;
                }
@@ -254,7 +298,6 @@ static char *vf_get_receiver_name_inmap(int i, const char *provider_name)
                }
                if ((!strncmp(vfm_map[i]->name[j], provider_name, namelen)) &&
                        ((j + 1) < vfm_map[i]->vfm_map_size)) {
-                       receiver_name = vfm_map[i]->name[j + 1];
 
                        if (namelen == provide_namelen) {
                                /* exact match */
@@ -295,13 +338,17 @@ char *vf_get_receiver_name(const char *provider_name)
 static void vfm_init(void)
 {
 #if ((defined CONFIG_AMLOGIC_POST_PROCESS_MANAGER) && \
-       (defined CONFIG_DEINTERLACE))
+       (defined CONFIG_AMLOGIC_MEDIA_DEINTERLACE))
        char def_id[] = "default";
+#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
        char def_name_chain[] = "decoder ppmgr deinterlace amvideo";
+#else
+       char def_name_chain[] = "decoder amvideo";
+#endif
 #elif (defined CONFIG_AMLOGIC_POST_PROCESS_MANAGER)
        char def_id[] = "default";
        char def_name_chain[] = "decoder ppmgr amvideo";
-#elif (defined CONFIG_DEINTERLACE)
+#elif (defined CONFIG_AMLOGIC_MEDIA_DEINTERLACE)
        char def_id[] = "default";
        char def_name_chain[] = "decoder deinterlace amvideo";
 #else /**/
@@ -323,9 +370,6 @@ static void vfm_init(void)
 #endif /**/
 #endif /**/
 #endif /**/
-       char def_osd_id[] = "default_osd";
-       char def_osd_name_chain[] = "osd amvideo4osd";
-       /* char def_osd_name_chain[] = "osd amvideo"; */
 #ifdef CONFIG_VDIN_MIPI
        char def_mipi_id[] = "default_mipi";
        char def_mipi_name_chain[] = "vdin mipi";
@@ -343,11 +387,22 @@ static void vfm_init(void)
        char tvpath_chain[] = "vdin0 deinterlace amvideo";
 #endif
 #endif /**/
+#ifdef CONFIG_AM_VDEC_DV
+       char def_dvbl_id[] = "dvblpath";
+/*     char def_dvbl_chain[] = "dvbldec dvbl amvideo";*/
+       char def_dvbl_chain[] = "dvbldec amvideo";
+
+       char def_dvel_id[] = "dvelpath";
+       char def_dvel_chain[] = "dveldec dvel";
+#endif
+#if 1/*def CONFIG_AM_HDMIIN_DV*/
+       char def_dvhdmiin_id[] = "dvhdmiin";
+       char def_dvhdmiin_chain[] = "dv_vdin amvideo";
+#endif
        int i;
 
        for (i = 0; i < VFM_MAP_COUNT; i++)
                vfm_map[i] = NULL;
-       vfm_map_add(def_osd_id, def_osd_name_chain);
        vfm_map_add(def_id, def_name_chain);
 #ifdef CONFIG_VDIN_MIPI
        vfm_map_add(def_mipi_id, def_mipi_name_chain);
@@ -362,6 +417,13 @@ static void vfm_init(void)
 #ifdef CONFIG_AMLOGIC_V4L_VIDEO2
        vfm_map_add(def_amlvideo2_id, def_amlvideo2_chain);
 #endif /**/
+#ifdef CONFIG_AM_VDEC_DV
+       vfm_map_add(def_dvbl_id, def_dvbl_chain);
+       vfm_map_add(def_dvel_id, def_dvel_chain);
+#endif
+#if 1/*def CONFIG_AM_HDMIIN_DV*/
+       vfm_map_add(def_dvhdmiin_id, def_dvhdmiin_chain);
+#endif
 }
 
 /*
@@ -375,14 +437,15 @@ static ssize_t vfm_map_show(struct class *class,
 
        for (i = 0; i < vfm_map_num; i++) {
                if (vfm_map[i] && vfm_map[i]->valid) {
-                       len += sprintf(buf + len, "%s { ", vfm_map[i]->id);
+                       len += sprintf(buf + len, "[%02d]  %s { ",
+                               i,/*in slot num.*/
+                               vfm_map[i]->id);
                        for (j = 0; j < vfm_map[i]->vfm_map_size; j++) {
                                if (j < (vfm_map[i]->vfm_map_size - 1)) {
                                        len += sprintf(buf + len, "%s(%d) ",
-                                               vfm_map[i]->name[j],
-                                               (vfm_map[i]->active >> j) &
-                                               0x1);
-                               } else {
+                                          vfm_map[i]->name[j],
+                                          (vfm_map[i]->active >> j) & 0x1);
+                               } else{
                                        len += sprintf(buf + len, "%s",
                                                vfm_map[i]->name[j]);
                                }
@@ -395,20 +458,20 @@ static ssize_t vfm_map_show(struct class *class,
        return len;
 }
 
-static int vf_get_states(struct vframe_provider_s *vfp,
+static int vfm_vf_get_states(struct vframe_provider_s *vfp,
        struct vframe_states *states)
 {
        int ret = -1;
        unsigned long flags;
 
        spin_lock_irqsave(&lock, flags);
-       if (vfp && vfp->ops && vfp->ops->vf_states)
-               ret = vfp->ops->vf_states(states, vfp->op_arg);
+       ret = vf_get_states(vfp, states);
        spin_unlock_irqrestore(&lock, flags);
        return ret;
 }
 
-static inline struct vframe_s *vmf_vf_peek(struct vframe_provider_s *vfp)
+static inline struct vframe_s *vfm_vf_peek(
+       struct vframe_provider_s *vfp)
 {
        if (!(vfp && vfp->ops && vfp->ops->peek))
                return NULL;
@@ -421,53 +484,144 @@ static void vfm_dump_provider(const char *name)
        struct vframe_states states;
        unsigned long flags;
        struct vframe_s *vf;
+       char *buf, *pbuf;
 
        if (!prov)
                return;
-       if (!vf_get_states(prov, &states)) {
-               pr_info("vframe_pool_size=%d\n", states.vf_pool_size);
-               pr_info("vframe buf_free_num=%d\n", states.buf_free_num);
-               pr_info("vframe buf_recycle_num=%d\n", states.buf_recycle_num);
-               pr_info("vframe buf_avail_num=%d\n", states.buf_avail_num);
+
+       buf = kzalloc(0x400, GFP_KERNEL);
+       if (IS_ERR_OR_NULL(buf))
+               return;
+
+       pbuf = buf;
+
+       if (!vfm_vf_get_states(prov, &states)) {
+               pr_info("vframe_pool_size=%d\n",
+                       states.vf_pool_size);
+               pr_info("vframe buf_free_num=%d\n",
+                       states.buf_free_num);
+               pr_info("vframe buf_recycle_num=%d\n",
+                       states.buf_recycle_num);
+               pr_info("vframe buf_avail_num=%d\n",
+                       states.buf_avail_num);
 
                spin_lock_irqsave(&lock, flags);
 
-               vf = vmf_vf_peek(prov);
+               vf = vfm_vf_peek(prov);
                if (vf) {
-                       pr_info("vframe ready frame delayed =%dms\n",
+                       pbuf += sprintf(pbuf,
+                               "vframe ready frame delayed =%dms\n",
                                (int)(jiffies_64 -
-                                       vf->ready_jiffies64) * 1000 / HZ);
-                       pr_info("vf index=%d\n", vf->index);
-                       pr_info("vf->pts=%d\n", vf->pts);
-                       pr_info("vf canvas0Addr=%x\n", vf->canvas0Addr);
-                       pr_info("vf canvas1Addr=%x\n", vf->canvas1Addr);
-                       pr_info("vf canvas0Addr.y.addr=%x(%d)\n",
-                               canvas_get_addr(canvasY(vf->canvas0Addr)),
-                               canvas_get_addr(canvasY(vf->canvas0Addr)));
-                       pr_info("vf canvas0Adr.uv.adr=%x(%d)\n",
-                               canvas_get_addr(canvasUV(vf->canvas0Addr)),
-                               canvas_get_addr(canvasUV(vf->canvas0Addr)));
+                               vf->ready_jiffies64) * 1000 /
+                               HZ);
+                       pbuf += sprintf(pbuf, "vf index=%d\n", vf->index);
+                       pbuf += sprintf(pbuf, "vf->pts=%d\n", vf->pts);
+                       pbuf += sprintf(pbuf, "vf->type=%d\n", vf->type);
+                       if (vf->type & VIDTYPE_COMPRESS) {
+                               pbuf += sprintf(pbuf, "vf compHeadAddr=%x\n",
+                                               vf->compHeadAddr);
+                               pbuf += sprintf(pbuf, "vf compBodyAddr =%x\n",
+                                               vf->compBodyAddr);
+                       } else {
+                               pbuf += sprintf(pbuf, "vf canvas0Addr=%x\n",
+                                       vf->canvas0Addr);
+                               pbuf += sprintf(pbuf, "vf canvas1Addr=%x\n",
+                                       vf->canvas1Addr);
+                               pbuf += sprintf(pbuf,
+                                       "vf canvas0Addr.y.addr=%x(%d)\n",
+                                       canvas_get_addr(
+                                       canvasY(vf->canvas0Addr)),
+                                       canvas_get_addr(
+                                       canvasY(vf->canvas0Addr)));
+                               pbuf += sprintf(pbuf,
+                                       "vf canvas0Adr.uv.adr=%x(%d)\n",
+                                       canvas_get_addr(
+                                       canvasUV(vf->canvas0Addr)),
+                                       canvas_get_addr(
+                                       canvasUV(vf->canvas0Addr)));
+                       }
                }
                spin_unlock_irqrestore(&lock, flags);
+
+               pr_info("%s\n", buf);
        }
        vftrace_dump_trace_infos(prov->traceget);
        vftrace_dump_trace_infos(prov->traceput);
+
+       kfree(buf);
 }
 
 #define VFM_CMD_ADD 1
 #define VFM_CMD_RM  2
 #define VFM_CMD_DUMP  3
+#define VFM_CMD_ADDDUMMY 4
+
+/*dummy receiver*/
+
+static int dummy_receiver_event_fun(int type, void *data, void *arg)
+{
+       struct vframe_receiver_s *dummy_vf_recv
+               = (struct vframe_receiver_s *)arg;
+       if (type == VFRAME_EVENT_PROVIDER_UNREG) {
+               char *provider_name = (char *)data;
+
+               pr_info("%s, provider %s unregistered\n",
+                       __func__, provider_name);
+       } else if (type ==
+               VFRAME_EVENT_PROVIDER_VFRAME_READY) {
+               struct vframe_s *vframe_tmp = vf_get(dummy_vf_recv->name);
+
+               while (vframe_tmp) {
+                       vf_put(vframe_tmp, dummy_vf_recv->name);
+                       vf_notify_provider(dummy_vf_recv->name,
+                               VFRAME_EVENT_RECEIVER_PUT, NULL);
+                       vframe_tmp = vf_get(dummy_vf_recv->name);
+               }
+       } else if (type == VFRAME_EVENT_PROVIDER_QUREY_STATE) {
+               return RECEIVER_ACTIVE;
+       } else if (type == VFRAME_EVENT_PROVIDER_REG) {
+               char *provider_name = (char *)data;
+
+               pr_info("%s, provider %s registered\n",
+                       __func__, provider_name);
+       }
+       return 0;
+}
+
+static const struct vframe_receiver_op_s dummy_vf_receiver = {
+       .event_cb = dummy_receiver_event_fun
+};
+
+static void add_dummy_receiver(char *vfm_name_)
+{
+       struct vframe_receiver_s *dummy_vf_recv =
+        kmalloc(sizeof(struct vframe_receiver_s), GFP_KERNEL);
+       pr_info("%s(%s)\n", __func__, vfm_name_);
+       if (dummy_vf_recv) {
+               char *vfm_name = kmalloc(16, GFP_KERNEL);
+
+               snprintf(vfm_name, 16, "%s", vfm_name_);
+               vf_receiver_init(dummy_vf_recv, vfm_name,
+                       &dummy_vf_receiver, dummy_vf_recv);
+               vf_reg_receiver(dummy_vf_recv);
+               pr_info("%s: %s\n", __func__, dummy_vf_recv->name);
+       }
+}
+
+/**/
 
 /*
  * echo add <name> <node1 node2 ...> > /sys/class/vfm/map
  * echo rm <name>                    > /sys/class/vfm/map
  * echo rm all                       > /sys/class/vfm/map
  * echo dump providername                      > /sys/class/vfm/map
+ * echo dummy name > /sys/class/vfm/map
  * <name> the name of the path.
  * <node1 node2 ...> the name of the nodes in the path.
  */
 static ssize_t vfm_map_store(struct class *class,
-       struct class_attribute *attr, const char *buf, size_t count)
+                struct class_attribute *attr,
+                const char *buf, size_t count)
 {
        char *buf_orig, *ps, *token;
        int i = 0;
@@ -492,6 +646,8 @@ static ssize_t vfm_map_store(struct class *class,
                                cmd = VFM_CMD_RM;
                        else if (!strcmp(token, "dump"))
                                cmd = VFM_CMD_DUMP;
+                       else if (!strcmp(token, "dummy"))
+                               cmd = VFM_CMD_ADDDUMMY;
                        else
                                break;
                } else if (i == 1) {
@@ -505,6 +661,8 @@ static ssize_t vfm_map_store(struct class *class,
                                        count = 0;
                        } else if (cmd == VFM_CMD_DUMP) {
                                vfm_dump_provider(token);
+                       } else if (cmd == VFM_CMD_ADDDUMMY) {
+                               add_dummy_receiver(token);
                        }
                        break;
                }
@@ -517,6 +675,159 @@ static ssize_t vfm_map_store(struct class *class,
 static CLASS_ATTR(map, 0664, vfm_map_show, vfm_map_store);
 static struct class vfm_class = {
        .name = CLS_NAME,
+       };
+int vfm_map_store_fun(const char *trigger, int id, const char *buf, int size)
+{
+       int ret = size;
+
+       switch (id) {
+       case 0: return vfm_map_store(NULL, NULL, buf, size);
+       default:
+               ret = -1;
+       }
+       return size;
+}
+int vfm_map_show_fun(const char *trigger, int id, char *sbuf, int size)
+{
+       int ret = -1;
+
+       void *buf, *getbuf = NULL;
+
+       if (size < PAGE_SIZE) {
+               getbuf = (void *)__get_free_page(GFP_KERNEL);
+               if (!getbuf)
+                       return -ENOMEM;
+               buf = getbuf;
+       } else {
+               buf = sbuf;
+       }
+
+       switch (id) {
+       case 0:
+               ret = vfm_map_show(NULL, NULL, buf);
+               break;
+       default:
+               ret = -1;
+       }
+       if (ret > 0 && getbuf != NULL) {
+               ret = min_t(int, ret, size);
+               strncpy(sbuf, buf, ret);
+       }
+       if (getbuf != NULL)
+               free_page((unsigned long)getbuf);
+       return ret;
+}
+
+static struct mconfig vfm_configs[] = {
+       MC_FUN_ID("map", vfm_map_show_fun, vfm_map_store_fun, 0),
+};
+
+/*********************************************************
+ * /dev/vfm APIs
+ *********************************************************/
+static int vfm_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static int vfm_release(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static long vfm_ioctl(struct file *file, unsigned int cmd, ulong arg)
+{
+       long ret = 0;
+
+       struct vfmctl *user_argp = (void __user *)arg;
+       struct vfmctl argp;
+
+       switch (cmd) {
+       case VFM_IOCTL_CMD_SET:{
+               ret =
+               copy_from_user(argp.name, user_argp->name, sizeof(argp.name));
+               ret |=
+               copy_from_user(argp.val, user_argp->val, sizeof(argp.val));
+               if (ret)
+                       ret = -EINVAL;
+               else
+               ret =
+               vfm_map_store(NULL, NULL, argp.val, sizeof(argp.val));
+               }
+               break;
+       case VFM_IOCTL_CMD_GET:{
+       /*
+        *overflow bug, need fixed.
+        *vfm_map_show(NULL, NULL, argp.val);
+        *ret = copy_to_user(user_argp->val, argp.val, sizeof(argp.val));
+        *if (ret != 0)
+        *      return -EIO;
+        *}
+        */
+               return -EIO;
+               }
+               break;
+       case VFM_IOCTL_CMD_ADD:{
+               ret =
+               copy_from_user(argp.name, user_argp->name, sizeof(argp.name));
+               ret |=
+               copy_from_user(argp.val, user_argp->val, sizeof(argp.val));
+               if (ret)
+                       ret = -EINVAL;
+               else
+               ret = vfm_map_add(argp.name, argp.val);
+               }
+               break;
+       case VFM_IOCTL_CMD_RM:{
+               ret =
+               copy_from_user(argp.val, user_argp->val, sizeof(argp.val));
+               if (ret)
+                       ret = -EINVAL;
+               else
+               ret = vfm_map_remove(argp.val);
+               }
+               break;
+       case VFM_IOCTL_CMD_DUMP:{
+               ret =
+               copy_from_user(argp.val, user_argp->val, sizeof(argp.val));
+               if (ret)
+                       ret = -EINVAL;
+               vfm_dump_provider(argp.val);
+               }
+               break;
+       case VFM_IOCTL_CMD_ADDDUMMY:{
+               ret =
+               copy_from_user(argp.val, user_argp->val, sizeof(argp.val));
+               if (ret)
+                       ret = -EINVAL;
+               add_dummy_receiver(argp.val);
+               }
+
+               break;
+       default:
+               return -EINVAL;
+       }
+       return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static long vfm_compat_ioctl(struct file *file, unsigned int cmd, ulong arg)
+{
+       long ret = 0;
+
+       ret = vfm_ioctl(file, cmd, (ulong)compat_ptr(arg));
+       return ret;
+}
+#endif
+static const struct file_operations vfm_fops = {
+       .owner = THIS_MODULE,
+       .open = vfm_open,
+       .release = vfm_release,
+       .unlocked_ioctl = vfm_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = vfm_compat_ioctl,
+#endif
+       .poll = NULL,
 };
 
 static int __init vfm_class_init(void)
@@ -534,12 +845,24 @@ static int __init vfm_class_init(void)
                pr_err("%s: class_create_file failed\n", __func__);
                class_unregister(&vfm_class);
        }
+       REG_PATH_CONFIGS("media.vfm", vfm_configs);
+
+
+       /* create vfm device */
+       error = register_chrdev(VFM_MAJOR, "vfm", &vfm_fops);
+       if (error < 0) {
+               pr_err("Can't register major for vfm device\n");
+               return error;
+       }
+       vfm_dev = device_create(&vfm_class, NULL,
+               MKDEV(VFM_MAJOR, 0), NULL, DEV_NAME);
        return error;
 }
 
 static void __exit vfm_class_exit(void)
 {
        class_unregister(&vfm_class);
+       unregister_chrdev(VFM_MAJOR, DEV_NAME);
 }
 
 fs_initcall(vfm_class_init);
index e0320eb..f0dcfa8 100644 (file)
@@ -40,4 +40,17 @@ extern int vfm_debug_flag;
 extern int vfm_trace_enable;   /* 1; */
 extern int vfm_trace_num;      /*  */
 
+struct vfmctl {
+       char name[10];
+       char val[300];
+};
+
+#define VFM_IOC_MAGIC  'V'
+#define VFM_IOCTL_CMD_ADD   _IOW(VFM_IOC_MAGIC, 0x00, struct vfmctl)
+#define VFM_IOCTL_CMD_RM    _IOW(VFM_IOC_MAGIC, 0x01, struct vfmctl)
+#define VFM_IOCTL_CMD_DUMP   _IOW(VFM_IOC_MAGIC, 0x02, struct vfmctl)
+#define VFM_IOCTL_CMD_ADDDUMMY    _IOW(VFM_IOC_MAGIC, 0x03, struct vfmctl)
+#define VFM_IOCTL_CMD_SET   _IOW(VFM_IOC_MAGIC, 0x04, struct vfmctl)
+#define VFM_IOCTL_CMD_GET   _IOWR(VFM_IOC_MAGIC, 0x05, struct vfmctl)
+
 #endif
index 54f34aa..3a60462 100644 (file)
@@ -86,17 +86,68 @@ struct vframe_provider_s *vf_get_provider(const char *receiver_name)
 }
 EXPORT_SYMBOL(vf_get_provider);
 
+/*#define NO_CHEKC_PROVIDER_USE*/
+#ifdef NO_CHEKC_PROVIDER_USE
+static inline int use_provider(struct vframe_provider_s *prov)
+{
+       return prov != NULL;
+}
+static inline void unuse_provider(struct vframe_provider_s *prov)
+{
+}
+static int vf_provider_close(struct vframe_provider_s *prov)
+{
+       return 1;
+}
+#else
+static inline int use_provider(struct vframe_provider_s *prov)
+{
+       int ret = 0;
+
+       if (prov) {
+               ret = atomic_inc_return(&prov->use_cnt);
+               if (ret <= 0)
+                       atomic_dec_return(&prov->use_cnt);
+       }
+       return ret > 0;
+}
+static inline void unuse_provider(struct vframe_provider_s *prov)
+{
+       if (prov)
+               atomic_dec_return(&prov->use_cnt);
+}
+#define CLOSED_CNT -100000
+static int vf_provider_close(struct vframe_provider_s *prov)
+{
+       int ret;
+       int wait_max = 10000;
+
+       if (!prov)
+               return -1;
+       ret = atomic_add_return(CLOSED_CNT, &prov->use_cnt);
+       while (ret > CLOSED_CNT && wait_max-- > 0) {
+               schedule();/*shecule and  wait for complete.*/
+               ret = atomic_read(&prov->use_cnt);
+       };
+       if (ret > CLOSED_CNT) {
+               pr_err("**ERR***,release, provider %s not finised,%d, wait=%d\n",
+                       prov->name, ret, wait_max);
+       }
+       return 0;
+}
+#endif
 int vf_notify_provider(const char *receiver_name, int event_type, void *data)
 {
        int ret = -1;
        struct vframe_provider_s *provider = vf_get_provider(receiver_name);
 
-       if (provider) {
+       if (use_provider(provider)) {
                if (provider->ops && provider->ops->event_cb) {
                        provider->ops->event_cb(event_type, data,
                                provider->op_arg);
                        ret = 0;
                }
+               unuse_provider(provider);
        } else {
                /* pr_err("Error: %s, fail to get provider of receiver %s\n",*/
                   /*__func__, receiver_name); */
@@ -111,12 +162,13 @@ int vf_notify_provider_by_name(const char *provider_name, int event_type,
        int ret = -1;
        struct vframe_provider_s *provider =
                vf_get_provider_by_name(provider_name);
-       if (provider) {
+       if (use_provider(provider)) {
                if (provider->ops && provider->ops->event_cb) {
                        provider->ops->event_cb(event_type, data,
                                provider->op_arg);
                        ret = 0;
                }
+               unuse_provider(provider);
        } else{
                /* pr_err("Error: %s, fail to get provider of receiver %s\n",*/
                                /*__func__, receiver_name); */
@@ -126,7 +178,8 @@ int vf_notify_provider_by_name(const char *provider_name, int event_type,
 EXPORT_SYMBOL(vf_notify_provider_by_name);
 
 void vf_provider_init(struct vframe_provider_s *prov,
-       const char *name, const struct vframe_operations_s *ops, void *op_arg)
+               const char *name,
+               const struct vframe_operations_s *ops, void *op_arg)
 {
        if (!prov)
                return;
@@ -134,6 +187,9 @@ void vf_provider_init(struct vframe_provider_s *prov,
        prov->name = name;
        prov->ops = ops;
        prov->op_arg = op_arg;
+       prov->traceget = NULL;
+       prov->traceput = NULL;
+       atomic_set(&prov->use_cnt, 0);
        INIT_LIST_HEAD(&prov->list);
 }
 EXPORT_SYMBOL(vf_provider_init);
@@ -146,6 +202,8 @@ int vf_reg_provider(struct vframe_provider_s *prov)
 
        if (!prov || !prov->name)
                return -1;
+       prov->traceget = NULL;
+       prov->traceput = NULL;
        for (i = 0; i < MAX_PROVIDER_NUM; i++) {
                p = provider_table[i];
                if (p) {
@@ -164,8 +222,9 @@ int vf_reg_provider(struct vframe_provider_s *prov)
                receiver = vf_get_receiver(prov->name);
                if (receiver && receiver->ops && receiver->ops->event_cb) {
                        receiver->ops->event_cb(VFRAME_EVENT_PROVIDER_REG,
-                               (void *)prov->name, receiver->op_arg);
-               } else {
+                               (void *)prov->name,
+                               receiver->op_arg);
+               } else{
                        pr_err("%s Error to notify receiver\n", __func__);
                }
                if (vfm_debug_flag & 1)
@@ -173,11 +232,10 @@ int vf_reg_provider(struct vframe_provider_s *prov)
        } else {
                pr_err("%s: Error, provider_table full\n", __func__);
        }
-       prov->traceget = NULL;
+       atomic_set(&prov->use_cnt, 0);/*set it ready for use.*/
        if (vfm_trace_enable & 1)
                prov->traceget = vftrace_alloc_trace(prov->name, 1,
-                       vfm_trace_num);
-       prov->traceput = NULL;
+                               vfm_trace_num);
        if (vfm_trace_enable & 2)
                prov->traceput = vftrace_alloc_trace(prov->name, 0,
                        vfm_trace_num);
@@ -202,15 +260,16 @@ void vf_unreg_provider(struct vframe_provider_s *prov)
                                vftrace_free_trace(p->traceput);
                                p->traceput = NULL;
                        }
+                       vf_provider_close(prov);
                        provider_table[i] = NULL;
                        if (vfm_debug_flag & 1)
                                pr_err("%s:%s\n", __func__, prov->name);
                        receiver = vf_get_receiver(prov->name);
                        if (receiver && receiver->ops
                                && receiver->ops->event_cb) {
-                               receiver->
-                                       ops->event_cb
-                                       (VFRAME_EVENT_PROVIDER_UNREG, NULL,
+                               receiver->ops->event_cb(
+                                       VFRAME_EVENT_PROVIDER_UNREG,
+                                       NULL,
                                        receiver->op_arg);
                        } else {
                                pr_err("%s Error to notify receiver\n",
@@ -237,9 +296,8 @@ void vf_light_unreg_provider(struct vframe_provider_s *prov)
                        receiver = vf_get_receiver(p->name);
                        if (receiver && receiver->ops
                                && receiver->ops->event_cb) {
-                               receiver->
-                                       ops->event_cb
-                                       (VFRAME_EVENT_PROVIDER_LIGHT_UNREG,
+                               receiver->ops->event_cb(
+                                       VFRAME_EVENT_PROVIDER_LIGHT_UNREG,
                                        NULL, receiver->op_arg);
                        }
                        break;
@@ -264,10 +322,9 @@ void vf_ext_light_unreg_provider(struct vframe_provider_s *prov)
                        receiver = vf_get_receiver(prov->name);
                        if (receiver && receiver->ops
                                && receiver->ops->event_cb) {
-                               receiver->
-                                       ops->event_cb
-                                       (VFRAME_EVENT_PROVIDER_LIGHT_UNREG,
-                                       NULL, receiver->op_arg);
+                               receiver->ops->event_cb(
+                                       VFRAME_EVENT_PROVIDER_LIGHT_UNREG,
+                                        NULL, receiver->op_arg);
                        }
                        vf_update_active_map();
                        break;
@@ -279,11 +336,14 @@ EXPORT_SYMBOL(vf_ext_light_unreg_provider);
 struct vframe_s *vf_peek(const char *receiver)
 {
        struct vframe_provider_s *vfp;
-
+       struct vframe_s *vf = NULL;
        vfp = vf_get_provider(receiver);
-       if (!(vfp && vfp->ops && vfp->ops->peek))
-               return NULL;
-       return vfp->ops->peek(vfp->op_arg);
+       if (use_provider(vfp)) {
+               if (vfp->ops && vfp->ops->peek)
+                       vf = vfp->ops->peek(vfp->op_arg);
+               unuse_provider(vfp);
+       }
+       return vf;
 }
 EXPORT_SYMBOL(vf_peek);
 
@@ -291,14 +351,15 @@ struct vframe_s *vf_get(const char *receiver)
 {
 
        struct vframe_provider_s *vfp;
-       struct vframe_s *vf;
-
+       struct vframe_s *vf = NULL;
        vfp = vf_get_provider(receiver);
-       if (!(vfp && vfp->ops && vfp->ops->get))
-               return NULL;
-       vf = vfp->ops->get(vfp->op_arg);
-       if (vf)
-               vftrace_info_in(vfp->traceget, vf);
+       if (use_provider(vfp)) {
+               if (vfp->ops && vfp->ops->get)
+                       vf = vfp->ops->get(vfp->op_arg);
+               if (vf)
+                       vftrace_info_in(vfp->traceget, vf);
+               unuse_provider(vfp);
+       }
        return vf;
 }
 EXPORT_SYMBOL(vf_get);
@@ -308,10 +369,37 @@ void vf_put(struct vframe_s *vf, const char *receiver)
        struct vframe_provider_s *vfp;
 
        vfp = vf_get_provider(receiver);
-       if (!(vfp && vfp->ops && vfp->ops->put))
-               return;
-       if (vf)
-               vftrace_info_in(vfp->traceput, vf);
-       vfp->ops->put(vf, vfp->op_arg);
+       if (use_provider(vfp)) {
+               if (vfp->ops && vfp->ops->put)
+                       vfp->ops->put(vf, vfp->op_arg);
+               if (vf)
+                       vftrace_info_in(vfp->traceput, vf);
+               unuse_provider(vfp);
+       }
 }
 EXPORT_SYMBOL(vf_put);
+
+int vf_get_states(struct vframe_provider_s *vfp,
+       struct vframe_states *states)
+{
+       int ret = -1;
+
+       if (use_provider(vfp)) {
+               if (vfp->ops && vfp->ops->vf_states)
+                       ret = vfp->ops->vf_states(states, vfp->op_arg);
+               unuse_provider(vfp);
+       }
+       return ret;
+}
+EXPORT_SYMBOL(vf_get_states);
+int vf_get_states_by_name(const char *receiver_name,
+       struct vframe_states *states)
+{
+       struct vframe_provider_s *vfp;
+
+       vfp = vf_get_provider(receiver_name);
+       return vf_get_states(vfp, states);
+}
+EXPORT_SYMBOL(vf_get_states_by_name);
+
+
index 7761907..f25b39f 100644 (file)
@@ -139,7 +139,8 @@ int vf_notify_receiver_by_name(const char *receiver_name, int event_type,
 EXPORT_SYMBOL(vf_notify_receiver_by_name);
 
 void vf_receiver_init(struct vframe_receiver_s *recv,
-       const char *name, const struct vframe_receiver_op_s *ops, void *op_arg)
+               const char *name,
+               const struct vframe_receiver_op_s *ops, void *op_arg)
 {
        if (!recv)
                return;
index c7ded87..7ec062d 100644 (file)
@@ -111,7 +111,10 @@ static void vftrace_dump_trace_info(struct trace_info *info, int i)
                i,
                info->vf,
                info->index,
-               info->type, info->pts, info->duration, info->in_time_us);
+               info->type,
+               info->pts,
+               info->duration,
+               info->in_time_us);
 }
 
 void vftrace_dump_trace_infos(void *vhandle)
index 90ee85a..f788666 100644 (file)
@@ -65,9 +65,6 @@
 #include "deinterlace_mtn.h"
 #include "deinterlace_dbg.h"
 #include <linux/amlogic/media/video_sink/video.h>
-#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
-#include "rdma.h"
-#endif
 #if defined(NEW_DI_TV)
 #define ENABLE_SPIN_LOCK_ALWAYS
 #endif
index d06a4b0..b209bf4 100644 (file)
 #define        DET3D
 #undef SUPPORT_MPEG_TO_VDIN /* for all ic after m6c@20140731 */
 
-#ifndef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
-#ifndef VSYNC_WR_MPEG_REG
-#define VSYNC_WR_MPEG_REG(adr, val) aml_write_vcbus(adr, val)
-#define VSYNC_WR_MPEG_REG_BITS(adr, val, start, len)  \
-               aml_vcbus_update_bits(adr, ((1<<len)-1)<<start, val<<start)
-#define VSYNC_RD_MPEG_REG(adr) aml_read_vcbus(adr)
-#endif
-#endif
-
 /************************************
  *      di hardware level interface
  *************************************/
@@ -421,6 +412,21 @@ void DI_Wr_reg_bits(unsigned int adr, unsigned int val,
 void DI_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val);
 void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, unsigned int val,
        unsigned int start, unsigned int len);
+#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
+extern void enable_rdma(int enable_flag);
+extern int VSYNC_WR_MPEG_REG(u32 adr, u32 val);
+extern int VSYNC_WR_MPEG_REG_BITS(u32 adr, u32 val, u32 start, u32 len);
+extern u32 VSYNC_RD_MPEG_REG(u32 adr);
+extern bool is_vsync_rdma_enable(void);
+#else
+#ifndef VSYNC_WR_MPEG_REG
+#define VSYNC_WR_MPEG_REG(adr, val) aml_write_vcbus(adr, val)
+#define VSYNC_WR_MPEG_REG_BITS(adr, val, start, len)  \
+               aml_vcbus_update_bits(adr, ((1<<len)-1)<<start, val<<start)
+#define VSYNC_RD_MPEG_REG(adr) aml_read_vcbus(adr)
+#endif
+#endif
+
 
 #define DI_COUNT   1
 #define DI_MAP_FLAG    0x1
index 0c8b724..30fc69c 100644 (file)
@@ -115,9 +115,9 @@ static inline void get_wrpage_offset(u8 type, u32 *page, u32 *page_offset)
                do {
                        local_irq_save(flags);
 
-                       page1 = READ_MPEG_REG(PARSER_AV_WRAP_COUNT) & 0xffff;
-                       offset = READ_MPEG_REG(PARSER_VIDEO_WP);
-                       page2 = READ_MPEG_REG(PARSER_AV_WRAP_COUNT) & 0xffff;
+                       page1 = READ_PARSER_REG(PARSER_AV_WRAP_COUNT) & 0xffff;
+                       offset = READ_PARSER_REG(PARSER_VIDEO_WP);
+                       page2 = READ_PARSER_REG(PARSER_AV_WRAP_COUNT) & 0xffff;
 
                        local_irq_restore(flags);
                } while (page1 != page2);
@@ -128,9 +128,9 @@ static inline void get_wrpage_offset(u8 type, u32 *page, u32 *page_offset)
                do {
                        local_irq_save(flags);
 
-                       page1 = READ_MPEG_REG(PARSER_AV_WRAP_COUNT) >> 16;
-                       offset = READ_MPEG_REG(PARSER_AUDIO_WP);
-                       page2 = READ_MPEG_REG(PARSER_AV_WRAP_COUNT) >> 16;
+                       page1 = READ_PARSER_REG(PARSER_AV_WRAP_COUNT) >> 16;
+                       offset = READ_PARSER_REG(PARSER_AUDIO_WP);
+                       page2 = READ_PARSER_REG(PARSER_AV_WRAP_COUNT) >> 16;
 
                        local_irq_restore(flags);
                } while (page1 != page2);
@@ -163,11 +163,11 @@ static inline void get_rdpage_offset(u8 type, u32 *page, u32 *page_offset)
                        local_irq_save(flags);
 
                        page1 =
-                               READ_MPEG_REG(AIU_MEM_AIFIFO_BUF_WRAP_COUNT) &
+                               READ_AIU_REG(AIU_MEM_AIFIFO_BUF_WRAP_COUNT) &
                                0xffff;
-                       offset = READ_MPEG_REG(AIU_MEM_AIFIFO_MAN_RP);
+                       offset = READ_AIU_REG(AIU_MEM_AIFIFO_MAN_RP);
                        page2 =
-                               READ_MPEG_REG(AIU_MEM_AIFIFO_BUF_WRAP_COUNT) &
+                               READ_AIU_REG(AIU_MEM_AIFIFO_BUF_WRAP_COUNT) &
                                0xffff;
 
                        local_irq_restore(flags);
@@ -500,9 +500,9 @@ static int pts_checkin_offset_inline(u8 type, u32 offset, u32 val, u64 uS64)
                                pr_info("init apts[%d] at 0x%x\n", type, val);
 
                        if (type == PTS_TYPE_VIDEO)
-                               WRITE_MPEG_REG(VIDEO_PTS, val);
+                               WRITE_PARSER_REG(VIDEO_PTS, val);
                        else if (type == PTS_TYPE_AUDIO)
-                               WRITE_MPEG_REG(AUDIO_PTS, val);
+                               WRITE_PARSER_REG(AUDIO_PTS, val);
 
                        pTable->status = PTS_RUNNING;
                }
@@ -1042,6 +1042,53 @@ int pts_set_rec_size(u8 type, u32 val)
        }
 }
 EXPORT_SYMBOL(pts_set_rec_size);
+
+/**
+ * return number of recs if the offset is bigger
+ */
+int pts_get_rec_num(u8 type, u32 val)
+{
+       ulong flags;
+       struct pts_table_s *pTable;
+       struct pts_rec_s *p;
+       int r = 0;
+
+       if (type >= PTS_TYPE_MAX)
+               return 0;
+
+       pTable = &pts_table[type];
+
+       if (list_empty(&pTable->valid_list))
+               return 0;
+
+       spin_lock_irqsave(&lock, flags);
+
+       if (pTable->pts_search == &pTable->valid_list) {
+               p = list_entry(pTable->valid_list.next,
+                       struct pts_rec_s, list);
+       } else {
+               p = list_entry(pTable->pts_search, struct pts_rec_s,
+                       list);
+       }
+
+       if (OFFSET_LATER(val, p->offset)) {
+               list_for_each_entry_continue(p, &pTable->valid_list,
+                                       list) {
+                       if (OFFSET_LATER(p->offset, val))
+                               break;
+               }
+       }
+
+       list_for_each_entry_continue(p, &pTable->valid_list, list) {
+               r++;
+       }
+
+       spin_unlock_irqrestore(&lock, flags);
+
+       return r;
+}
+EXPORT_SYMBOL(pts_get_rec_num);
+
 /* #define SIMPLE_ALLOC_LIST */
 static void free_pts_list(struct pts_table_s *pTable)
 {
@@ -1151,16 +1198,21 @@ int pts_start(u8 type)
                        return -ENOMEM;
                /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
                if (has_hevc_vdec() && (type == PTS_TYPE_HEVC)) {
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+                       pTable->buf_start = READ_PARSER_REG(
+                                       PARSER_VIDEO_START_PTR);
+                       pTable->buf_size = READ_PARSER_REG(PARSER_VIDEO_END_PTR)
+                                                       - pTable->buf_start + 8;
+#else
                        pTable->buf_start = READ_VREG(HEVC_STREAM_START_ADDR);
                        pTable->buf_size = READ_VREG(HEVC_STREAM_END_ADDR)
-                                                          - pTable->buf_start;
-                       WRITE_MPEG_REG(VIDEO_PTS, 0);
+                                                       - pTable->buf_start;
+#endif
+                       WRITE_PARSER_REG(VIDEO_PTS, 0);
                        timestamp_pcrscr_set(0);
-                       /*
-                        *video always need
-                        * the pcrscr,Clear
-                        *it to use later
-                        */
+                       /* video always need the pcrscr,*/
+                       /*Clear it to use later */
+
                        timestamp_firstvpts_set(0);
                        pTable->first_checkin_pts = -1;
                        pTable->first_lookup_ok = 0;
@@ -1168,14 +1220,20 @@ int pts_start(u8 type)
                } else
                        /* #endif */
                        if (type == PTS_TYPE_VIDEO) {
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+                               pTable->buf_start = READ_PARSER_REG(
+                                               PARSER_VIDEO_START_PTR);
+                               pTable->buf_size = READ_PARSER_REG(
+                                               PARSER_VIDEO_END_PTR)
+                                       - pTable->buf_start + 8;
+#else
                                pTable->buf_start = READ_VREG(
                                                VLD_MEM_VIFIFO_START_PTR);
                                pTable->buf_size = READ_VREG(
                                                VLD_MEM_VIFIFO_END_PTR)
                                        - pTable->buf_start + 8;
-
-                               /*
-                                *since the HW buffer wrap counter only have
+#endif
+                               /* since the HW buffer wrap counter only have
                                 * 16 bits, a too small buf_size will make pts i
                                 * lookup fail with streaming offset wrapped
                                 * before 32 bits boundary.
@@ -1184,29 +1242,25 @@ int pts_start(u8 type)
                                 */
                                /* BUG_ON(pTable->buf_size <= 0x10000); */
 
-                               WRITE_MPEG_REG(VIDEO_PTS, 0);
+                               WRITE_PARSER_REG(VIDEO_PTS, 0);
                                timestamp_pcrscr_set(0);
-                               /*
-                                *video always
-                                *need the
-                                *pcrscr,
-                                *Clear it
-                                *to use later
-                                */
+                               /* video always need the pcrscr, */
+                               /*Clear it to use later*/
+
                                timestamp_firstvpts_set(0);
                                pTable->first_checkin_pts = -1;
                                pTable->first_lookup_ok = 0;
                                pTable->first_lookup_is_fail = 0;
                        } else if (type == PTS_TYPE_AUDIO) {
                                pTable->buf_start =
-                                       READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR);
-                               pTable->buf_size = READ_MPEG_REG(
+                                       READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR);
+                               pTable->buf_size = READ_AIU_REG(
                                                AIU_MEM_AIFIFO_END_PTR)
                                        - pTable->buf_start + 8;
 
                                /* BUG_ON(pTable->buf_size <= 0x10000); */
 
-                               WRITE_MPEG_REG(AUDIO_PTS, 0);
+                               WRITE_PARSER_REG(AUDIO_PTS, 0);
                                timestamp_firstapts_set(0);
                                pTable->first_checkin_pts = -1;
                                pTable->first_lookup_ok = 0;
index c226325..f85f8e7 100644 (file)
@@ -49,31 +49,31 @@ void set_timestamp_inc_factor(u32 factor)
 
 u32 timestamp_vpts_get(void)
 {
-       return (u32) READ_MPEG_REG(VIDEO_PTS);
+       return (u32) READ_PARSER_REG(VIDEO_PTS);
 }
 EXPORT_SYMBOL(timestamp_vpts_get);
 
 void timestamp_vpts_set(u32 pts)
 {
-       WRITE_MPEG_REG(VIDEO_PTS, pts);
+       WRITE_PARSER_REG(VIDEO_PTS, pts);
 }
 EXPORT_SYMBOL(timestamp_vpts_set);
 
 void timestamp_vpts_inc(s32 val)
 {
-       WRITE_MPEG_REG(VIDEO_PTS, READ_MPEG_REG(VIDEO_PTS) + val);
+       WRITE_PARSER_REG(VIDEO_PTS, READ_PARSER_REG(VIDEO_PTS) + val);
 }
 EXPORT_SYMBOL(timestamp_vpts_inc);
 
 u32 timestamp_apts_get(void)
 {
-       return (u32) READ_MPEG_REG(AUDIO_PTS);
+       return (u32) READ_PARSER_REG(AUDIO_PTS);
 }
 EXPORT_SYMBOL(timestamp_apts_get);
 
 void timestamp_apts_set(u32 pts)
 {
-       WRITE_MPEG_REG(AUDIO_PTS, pts);
+       WRITE_PARSER_REG(AUDIO_PTS, pts);
 }
 EXPORT_SYMBOL(timestamp_apts_set);
 
@@ -83,7 +83,7 @@ void timestamp_apts_inc(s32 inc)
 #ifdef MODIFY_TIMESTAMP_INC_WITH_PLL
                inc = inc * timestamp_inc_factor / PLL_FACTOR;
 #endif
-               WRITE_MPEG_REG(AUDIO_PTS, READ_MPEG_REG(AUDIO_PTS) + inc);
+               WRITE_PARSER_REG(AUDIO_PTS, READ_PARSER_REG(AUDIO_PTS) + inc);
        }
 }
 EXPORT_SYMBOL(timestamp_apts_inc);
index a132df3..7498ba7 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/amlogic/media/utils/vdec_reg.h>
 #include <linux/amlogic/media/frame_sync/tsync_pcr.h>
 #include <linux/amlogic/media/registers/register.h>
-
+#include <linux/amlogic/media/codec_mm/configs.h>
 
 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
 /* TODO: for stream buffer register bit define only */
@@ -125,7 +125,9 @@ static const struct {
                AVEVENT_FLAG_PARAM
        }, {
                "AUDIO_PRE_START", 15, AUDIO_PRE_START, 0
-       },
+       }, {
+           "AUDIO_WAIT", 10, AUDIO_WAIT, 0
+       }
 };
 
 static const char * const tsync_mode_str[] = {
@@ -216,9 +218,9 @@ static void tsync_pcr_recover_with_audio(void)
 #if 0                          /* MESON_CPU_TYPE < MESON_CPU_TYPE_MESON6 */
 
        if (get_cpu_type() < MESON_CPU_MAJOR_ID_M6) {
-               u32 ab_level = READ_MPEG_REG(AIU_MEM_AIFIFO_LEVEL);
-               u32 ab_size = READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR)
-                       - READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR) + 8;
+               u32 ab_level = READ_AIU_REG(AIU_MEM_AIFIFO_LEVEL);
+               u32 ab_size = READ_AIU_REG(AIU_MEM_AIFIFO_END_PTR)
+                       - READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR) + 8;
                u32 vb_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL);
                u32 vb_size = READ_VREG(VLD_MEM_VIFIFO_END_PTR)
                        - READ_VREG(VLD_MEM_VIFIFO_START_PTR) + 8;
@@ -228,7 +230,7 @@ static void tsync_pcr_recover_with_audio(void)
                bool lower_than_high = false;
                bool higher_than_low = false;
 
-               if ((READ_MPEG_REG(AIU_MEM_I2S_CONTROL) &
+               if ((READ_AIU_REG(AIU_MEM_I2S_CONTROL) &
                         (MEM_CTRL_EMPTY_EN | MEM_CTRL_EMPTY_EN)) == 0)
                        return;
                /*
@@ -471,7 +473,7 @@ static bool tsync_pcr_recover_use_video(void)
         *mixer so audio playback has no direct relationship with
         *applications. TODO.
         */
-       return ((READ_MPEG_REG(AIU_MEM_I2S_CONTROL) &
+       return ((READ_AIU_REG(AIU_MEM_I2S_CONTROL) &
                         (MEM_CTRL_EMPTY_EN | MEM_CTRL_EMPTY_EN)) == 0) ?
                true : false;
 }
@@ -811,6 +813,9 @@ void tsync_avevent_locked(enum avevent_e event, u32 param)
                timestamp_apts_start(0);
                break;
 
+       case AUDIO_WAIT:
+               timestamp_pcrscr_set(timestamp_vpts_get());
+               break;
        case AUDIO_START:
                /* reset discontinue var */
                tsync_set_sync_adiscont(0);
@@ -917,12 +922,12 @@ void tsync_avevent_locked(enum avevent_e event, u32 param)
        case VIDEO_START:
        case AUDIO_START:
        case AUDIO_RESUME:
-               /*amvdev_resume();*///DEBUG_TMP
+               /*amvdev_resume();*//*DEBUG_TMP*/
                break;
        case VIDEO_STOP:
        case AUDIO_STOP:
        case AUDIO_PAUSE:
-               /*amvdev_pause();*///DEBUG_TMP
+               /*amvdev_pause();*//*DEBUG_TMP*/
                break;
        case VIDEO_PAUSE:
                /*
@@ -1075,7 +1080,7 @@ int tsync_set_apts(unsigned int pts)
        timestamp_apts_set(pts);
 
        /*if (get_vsync_pts_inc_mode() && (tsync_mode != TSYNC_MODE_VMASTER))*/
-               /*tsync_mode = TSYNC_MODE_VMASTER;*///DEBUG_TMP
+               /*tsync_mode = TSYNC_MODE_VMASTER;*//*DEBUG_TMP*/
 
        if (tsync_mode == TSYNC_MODE_AMASTER)
                t = timestamp_pcrscr_get();
@@ -1916,6 +1921,159 @@ static struct class tsync_class = {
                .class_attrs = tsync_class_attrs,
        };
 
+
+int tsync_store_fun(const char *trigger, int id, const char *buf, int size)
+{
+       int ret = size;
+
+       switch (id) {
+       case 0: return store_vpts(NULL, NULL, buf, size);
+       case 1: return store_apts(NULL, NULL, buf, size);
+       case 2: return dobly_store_sync(NULL, NULL, buf, size);
+       case 3: return store_pcrscr(NULL, NULL, buf, size);
+       case 4: return store_event(NULL, NULL, buf, size);
+       case 5: return store_mode(NULL, NULL, buf, size);
+       case 6: return store_enable(NULL, NULL, buf, size);
+       case 7: return store_pcr_recover(NULL, NULL, buf, size);
+       case 8: return store_discontinue(NULL, NULL, buf, size);
+       case 9: return store_debug_pts_checkin(NULL, NULL, buf, size);
+       case 10:return store_debug_pts_checkout(NULL, NULL, buf, size);
+       case 11:return store_debug_vpts(NULL, NULL, buf, size);
+       case 12:return store_debug_apts(NULL, NULL, buf, size);
+       case 13:return store_av_threshold_min(NULL, NULL, buf, size);
+       case 14:return store_av_threshold_max(NULL, NULL, buf, size);
+       /*case 15:return -1;*/
+       /*case 16:return -1;*/
+       case 17:return store_vpause_flag(NULL, NULL, buf, size);
+       case 18:return store_slowsync_enable(NULL, NULL, buf, size);
+       case 19:return store_startsync_mode(NULL, NULL, buf, size);
+       case 20:return store_firstapts(NULL, NULL, buf, size);
+       case 21:return -1;
+       default:
+               ret = -1;
+       }
+       return size;
+}
+int tsync_show_fun(const char *trigger, int id, char *sbuf, int size)
+{
+       int ret = -1;
+       void *buf, *getbuf = NULL;
+
+       if (size < PAGE_SIZE) {
+               getbuf = (void *)__get_free_page(GFP_KERNEL);
+               if (!getbuf)
+                       return -ENOMEM;
+               buf = getbuf;
+       } else {
+               buf = sbuf;
+       }
+
+       switch (id) {
+       case 0:
+               ret = show_vpts(NULL, NULL, buf);
+               break;
+       case 1:
+               ret = show_apts(NULL, NULL, buf);
+               break;
+       case 2:
+               ret =  dobly_show_sync(NULL, NULL, buf);
+               break;
+       case 3:
+               ret = show_pcrscr(NULL, NULL, buf);
+               break;
+       case 4:
+               ret = -1;
+               break;
+       case 5:
+               ret = show_mode(NULL, NULL, buf);
+               break;
+       case 6:
+               ret = show_enable(NULL, NULL, buf);
+               break;
+       case 7:
+               ret = show_pcr_recover(NULL, NULL, buf);
+               break;
+       case 8:
+               ret = show_discontinue(NULL, NULL, buf);
+               break;
+       case 9:
+               ret = show_debug_pts_checkin(NULL, NULL, buf);
+               break;
+       case 10:
+               ret = show_debug_pts_checkout(NULL, NULL, buf);
+               break;
+       case 11:
+               ret = show_debug_vpts(NULL, NULL, buf);
+               break;
+       case 12:
+               ret = show_debug_apts(NULL, NULL, buf);
+               break;
+       case 13:
+               ret = show_av_threshold_min(NULL, NULL, buf);
+               break;
+       case 14:
+               ret = show_av_threshold_max(NULL, NULL, buf);
+               break;
+       case 15:
+               ret = show_last_checkin_apts(NULL, NULL, buf);
+               break;
+       case 16:
+               ret = show_firstvpts(NULL, NULL, buf);
+               break;
+       case 17:
+               ret = show_vpause_flag(NULL, NULL, buf);
+               break;
+       case 18:
+               ret = show_slowsync_enable(NULL, NULL, buf);
+               break;
+       case 19:
+               ret = show_startsync_mode(NULL, NULL, buf);
+               break;
+       case 20:
+               ret = show_firstapts(NULL, NULL, buf);
+               break;
+       case 21:
+               ret = show_checkin_firstvpts(NULL, NULL, buf);
+               break;
+       default:
+               ret = -1;
+       }
+       if (ret > 0 && getbuf != NULL) {
+               ret = min_t(int, ret, size);
+               strncpy(sbuf, buf, ret);
+       }
+       if (getbuf != NULL)
+               free_page((unsigned long)getbuf);
+       return ret;
+}
+
+
+static struct mconfig tsync_configs[] = {
+       MC_FUN_ID("pts_video", tsync_show_fun, tsync_store_fun, 0),
+       MC_FUN_ID("pts_audio", tsync_show_fun, tsync_store_fun, 1),
+       MC_FUN_ID("dobly_av_sync", tsync_show_fun, tsync_store_fun, 2),
+       MC_FUN_ID("pts_pcrscr", tsync_show_fun, tsync_store_fun, 3),
+       MC_FUN_ID("event", tsync_show_fun, tsync_store_fun, 4),
+       MC_FUN_ID("mode", tsync_show_fun, tsync_store_fun, 5),
+       MC_FUN_ID("enable", tsync_show_fun, tsync_store_fun, 6),
+       MC_FUN_ID("pcr_recover", tsync_show_fun, tsync_store_fun, 7),
+       MC_FUN_ID("discontinue", tsync_show_fun, tsync_store_fun, 8),
+       MC_FUN_ID("debug_pts_checkin", tsync_show_fun, tsync_store_fun, 9),
+       MC_FUN_ID("debug_pts_checkout", tsync_show_fun, tsync_store_fun, 10),
+       MC_FUN_ID("debug_video_pts", tsync_show_fun, tsync_store_fun, 11),
+       MC_FUN_ID("debug_audio_pts", tsync_show_fun, tsync_store_fun, 12),
+       MC_FUN_ID("av_threshold_min", tsync_show_fun, tsync_store_fun, 13),
+       MC_FUN_ID("av_threshold_max", tsync_show_fun, tsync_store_fun, 14),
+       MC_FUN_ID("last_checkin_apts", tsync_show_fun, NULL, 15),
+       MC_FUN_ID("firstvpts", tsync_show_fun, NULL, 16),
+       MC_FUN_ID("vpause_flag", tsync_show_fun, tsync_store_fun, 17),
+       MC_FUN_ID("slowsync_enable", tsync_show_fun, tsync_store_fun, 18),
+       MC_FUN_ID("startsync_mode", tsync_show_fun, tsync_store_fun, 19),
+       MC_FUN_ID("firstapts", tsync_show_fun, tsync_store_fun, 20),
+       MC_FUN_ID("checkin_firstvpts", tsync_show_fun, NULL, 21),
+};
+
+
 static int __init tsync_module_init(void)
 {
        int r;
@@ -1929,6 +2087,8 @@ static int __init tsync_module_init(void)
 
        tsync_pcr_init();
 
+       REG_PATH_CONFIGS("media.tsync", tsync_configs);
+
        return 0;
 }
 
index 9af1ab3..4868932 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/amlogic/media/frame_sync/ptsserv.h>
 
 #include <linux/amlogic/media/frame_sync/tsync_pcr.h>
-#include <linux/amlogic/media/old_cpu_version.h>
+#include <linux/amlogic/cpu_version.h>
 
 #ifdef CONFIG_AM_PCRSYNC_LOG
 #define AMLOG
@@ -120,8 +120,8 @@ static u32 tsync_pcr_discontinue_threshold = (TIME_UNIT90K * 1.5);
 static u32 tsync_pcr_ref_latency = (TIME_UNIT90K * 0.3);
 
 /* use for pcr valid mode */
-static u32 tsync_pcr_max_cache_time = TIME_UNIT90K * 1.5;
-static u32 tsync_pcr_up_cache_time = TIME_UNIT90K * 1.2;
+static u32 tsync_pcr_max_cache_time = TIME_UNIT90K * 2.4;
+static u32 tsync_pcr_up_cache_time = TIME_UNIT90K * 2.2;
 /* modify it by dolby av sync */
 static u32 tsync_pcr_down_cache_time = TIME_UNIT90K * 0.8;   /* 0.6 */
 static u32 tsync_pcr_min_cache_time = TIME_UNIT90K * 0.4;    /* 0.2 */
@@ -193,6 +193,18 @@ static DEFINE_SPINLOCK(tsync_pcr_lock);
 
 #define LTRACE() pr_info("[%s:%d]\n", __func__, __LINE__)
 
+module_param(tsync_pcr_max_cache_time, uint, 0664);
+MODULE_PARM_DESC(tsync_pcr_max_cache_time, "\n tsync pcr max cache time\n");
+
+module_param(tsync_pcr_up_cache_time, uint, 0664);
+MODULE_PARM_DESC(tsync_pcr_up_cache_time, "\n tsync pcr up cache time\n");
+
+module_param(tsync_pcr_down_cache_time, uint, 0664);
+MODULE_PARM_DESC(tsync_pcr_down_cache_time, "\n tsync pcr down cache time\n");
+
+module_param(tsync_pcr_min_cache_time, uint, 0664);
+MODULE_PARM_DESC(tsync_pcr_min_cache_time, "\n tsync pcr min cache time\n");
+
 u32 get_stbuf_rp(int type)
 {
 #if 0//DEBUG_TMP
@@ -211,7 +223,7 @@ u32 get_stbuf_rp(int type)
 
                pbuf = get_buf_by_type(PTS_TYPE_VIDEO);
                if (pbuf != NULL && pbuf->flag & BUF_FLAG_IN_USE)
-                       return stbuf_rp(pbuf)
+                       return stbuf_rp(pbuf);
        } else {
                /* audio */
                pbuf = get_buf_by_type(PTS_TYPE_AUDIO);
@@ -517,7 +529,7 @@ void tsync_pcr_avevent_locked(enum avevent_e event, u32 param)
 
        case VIDEO_TSTAMP_DISCONTINUITY: {
                /* unsigned oldpts=timestamp_vpts_get(); */
-               /*u32 tsdemux_pcr = 0;*//*tsdemux_pcrscr_get();*///DEBUG_TMP
+               /*u32 tsdemux_pcr = 0;*//*tsdemux_pcrscr_get();*//*DEBUG_TMP*/
                /* if((abs(param-oldpts)>AV_DISCONTINUE_THREDHOLD_MIN) &&
                 *(!get_vsync_pts_inc_mode())){
                 */
@@ -695,18 +707,18 @@ void tsync_pcr_avevent_locked(enum avevent_e event, u32 param)
        case VIDEO_START:
        case AUDIO_START:
        case AUDIO_RESUME:
-               /*amvdev_resume();*///DEBUG_TMP
+               /*amvdev_resume();*//*DEBUG_TMP*/
                break;
        case VIDEO_STOP:
        case AUDIO_STOP:
        case AUDIO_PAUSE:
-               /*amvdev_pause();*///DEBUG_TMP
+               /*amvdev_pause();*//*DEBUG_TMP*/
                break;
        case VIDEO_PAUSE:
                /*if (tsync_pcr_vpause_flag)*/
-                       /*amvdev_pause();*///DEBUG_TMP
+                       /*amvdev_pause();*//*DEBUG_TMP*/
                /*else*/
-                       /*amvdev_resume();*///DEBUG_TMP
+                       /*amvdev_resume();*//*DEBUG_TMP*/
                break;
        default:
                break;
@@ -734,7 +746,7 @@ static unsigned long tsync_pcr_check(void)
                || tsync_pcr_freerun_mode == 1)
                return res;
 
-       tsdemux_pcr = 0;/*tsdemux_pcrscr_get();*///DEBUG_TMP
+       tsdemux_pcr = 0;/*tsdemux_pcrscr_get();*//*DEBUG_TMP*/
        if (tsync_pcr_usepcr == 1) {
                /* To monitor the pcr discontinue */
                tsdemux_pcr_diff = abs(tsdemux_pcr - tsync_pcr_last_tsdemuxpcr);
@@ -755,12 +767,17 @@ static unsigned long tsync_pcr_check(void)
                                tsync_pcr_discontinue_waited = TIME_UNIT90K * 5;
 
                        pr_info
-                       ("[tsync_pcr_check] refpcr_discontinue. ");
+                       ("[tsync_pcr_check] refpcr_discontinue.\n");
                        pr_info
-                       ("tsdemux_pcr_diff=%x, last refpcr=%x, ",
+                       ("tsdemux_pcr_diff=%x, last refpcr=%x,\n",
                         tsdemux_pcr_diff, tsync_pcr_last_tsdemuxpcr);
                        pr_info("repcr=%x,waited=%x\n",
                         tsdemux_pcr, tsync_pcr_discontinue_waited);
+                       pr_info("last checkin vpts:%d\n",
+                        (u32)get_last_checkin_pts(PTS_TYPE_VIDEO));
+                       pr_info("last checkin apts:%d\n",
+                        (u32)get_last_checkin_pts(PTS_TYPE_AUDIO));
+
                        tsync_pcr_discontinue_local_point =
                                timestamp_pcrscr_get();
                        tsync_pcr_discontinue_point =
@@ -777,6 +794,12 @@ static unsigned long tsync_pcr_check(void)
                                pr_info
                                (" discontinue didn't happen, waited=%x\n",
                                 tsync_pcr_discontinue_waited);
+                               pr_info
+                               (" timestamp_pcrscr_get() =%x\n",
+                                timestamp_pcrscr_get());
+                               pr_info
+                               (" tsync_pcr_discontinue_local_point =%x\n",
+                                tsync_pcr_discontinue_local_point);
                                /* the v-discontinue did'n happen */
                                tsync_pcr_tsdemuxpcr_discontinue = 0;
                                tsync_pcr_discontinue_point = 0;
@@ -858,17 +881,18 @@ static unsigned long tsync_pcr_check(void)
        cur_vpts = timestamp_vpts_get();
 
        /*set pcr after discontinue according to apts and vpts*/
-       if (tsync_pcr_tsdemuxpcr_discontinue &
+       if ((tsync_pcr_tsdemuxpcr_discontinue &
+               (AUDIO_DISCONTINUE | VIDEO_DISCONTINUE)) ==
                (AUDIO_DISCONTINUE | VIDEO_DISCONTINUE)) {
                if (cur_apts < cur_vpts && cur_vpts - cur_apts < 3 * 90000
                        && last_checkin_minpts - cur_apts > 54000)
                        timestamp_pcrscr_set(cur_apts + 6300);
                else
                        timestamp_pcrscr_set(cur_apts);
-/*
*             pr_info("after discontinue, pcr = 0x%x,apts=0x%x,vpts=0x%x\n",
*                     timestamp_pcrscr_get(), cur_apts, cur_vpts);
- */
+
              pr_info("after discontinue, pcr = 0x%x,apts=0x%x,vpts=0x%x\n",
                      timestamp_pcrscr_get(), cur_apts, cur_vpts);
+
        }
 
        if (tsync_pcr_reset_flag == 0) {
@@ -1064,7 +1088,8 @@ static unsigned long tsync_pcr_check(void)
                u64 ref_pcr = (u64)  tsdemux_pcr;
                u64 cur_pcr = (u64) timestamp_pcrscr_get();
                int64_t cur_delta = (int64_t) ref_pcr - (int64_t) cur_pcr;
-               int64_t diff = (cur_delta - tsync_pcr_stream_delta);
+               /* int64_t diff = (cur_delta - tsync_pcr_stream_delta); */
+               int64_t diff = cur_delta;
 
                /* if(diff > OPEN_RECOVERY_THRESHOLD && cur_pcr<ref_pcr
                 *   && play_mode!=PLAY_MODE_SPEED && need_recovery){
@@ -1244,7 +1269,7 @@ int tsync_pcr_start(void)
 
                first_time_record = (jiffies * TIME_UNIT90K) / HZ;
                tsync_pcr_started = 1;
-               /*if (tsdemux_pcrscr_valid() == 0) {*///DEBUG_TMP
+               /*if (tsdemux_pcrscr_valid() == 0) {*//*DEBUG_TMP*/
                if (0) {
                        tsync_pcr_usepcr = 0;
                        tsync_pcr_inited_mode = INIT_PRIORITY_AUDIO;
index cca5600..8fd9f57 100644 (file)
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(video_nr_base, "videoX start number, 13 is the base nr");
 static int scaling_rate = 100;
 static int ionvideo_seek_flag;
 
-#ifdef CONFIG_MULTI_DEC
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
 static unsigned int n_devs = 9;
 #else
 static unsigned int n_devs = 1;
index 88202ab..c3e41c5 100644 (file)
@@ -85,7 +85,7 @@ static unsigned int video_nr_base = 10;
 /* module_param(video_nr_base, uint, 0644); */
 /* MODULE_PARM_DESC(video_nr_base, "videoX start number, 10 is defaut"); */
 
-#ifdef CONFIG_MULTI_DEC
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
 static unsigned int n_devs = 1;
 #else
 static unsigned int n_devs = 1;
@@ -226,6 +226,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
        struct vivi_dev *dev = (struct vivi_dev *)private_data;
 
        if (type == VFRAME_EVENT_PROVIDER_UNREG) {
+               if (dev->index != 8)
+                       mutex_lock(&dev->vfpMutex);
                AMLVIDEO_DBG("AML:VFRAME_EVENT_PROVIDER_UNREG\n");
                if (vf_get_receiver(dev->vf_provider_name)) {
                        AMLVIDEO_DBG("unreg:amlvideo\n");
@@ -241,17 +243,20 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
 
                dev->vf = NULL;
                dev->first_frame = 0;
+               mutex_unlock(&dev->vfpMutex);
        } else if (type == VFRAME_EVENT_PROVIDER_QUREY_STATE) {
                amlvideo_vf_states(&states, dev);
-               if (states.buf_avail_num > 0)
+               if (states.buf_avail_num > 0) {
                        return RECEIVER_ACTIVE;
-               if (vf_notify_receiver(
-                       dev->vf_provider_name,
-                       VFRAME_EVENT_PROVIDER_QUREY_STATE,
-                       NULL) == RECEIVER_ACTIVE)
-                       return RECEIVER_ACTIVE;
-               return RECEIVER_INACTIVE;
-
+               } else {
+                       if (vf_notify_receiver(
+                               dev->vf_provider_name,
+                               VFRAME_EVENT_PROVIDER_QUREY_STATE,
+                               NULL)
+                       == RECEIVER_ACTIVE)
+                               return RECEIVER_ACTIVE;
+                       return RECEIVER_INACTIVE;
+               }
                /*break;*/
        } else if (type == VFRAME_EVENT_PROVIDER_START) {
                AMLVIDEO_DBG("AML:VFRAME_EVENT_PROVIDER_START\n");
@@ -270,6 +275,12 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                                                VFRAME_EVENT_PROVIDER_START,
                                                NULL);
                }
+       } else if (type == VFRAME_EVENT_PROVIDER_FR_HINT) {
+               vf_notify_receiver(dev->vf_provider_name,
+                       VFRAME_EVENT_PROVIDER_FR_HINT, data);
+       } else if (type == VFRAME_EVENT_PROVIDER_FR_END_HINT) {
+               vf_notify_receiver(dev->vf_provider_name,
+               VFRAME_EVENT_PROVIDER_FR_END_HINT, data);
        }
        return 0;
 }
@@ -507,6 +518,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
        dev->vf = vf_get(dev->vf_receiver_name);
        if (!dev->vf) {
                /* printk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__); */
+               mutex_unlock(&dev->vfpMutex);
                return -EAGAIN;
        }
 
@@ -593,6 +605,7 @@ static int amlvideo_open(struct file *file)
 
        dev->vf = NULL;
        dev->index = 0;
+       mutex_unlock(&dev->vfpMutex);
        mutex_lock(&dev->mutex);
        dev->users++;
        if (dev->users > 1) {
@@ -605,15 +618,15 @@ static int amlvideo_open(struct file *file)
                dev->users--;
                mutex_unlock(&dev->mutex);
                return -ENOMEM;
+       } else {
+               fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+               if (fh == NULL) {
+                       kfree(res);
+                       dev->users--;
+                       mutex_unlock(&dev->mutex);
+                       retval = -ENOMEM;
+               }
        }
-       fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-       if (fh == NULL) {
-               kfree(res);
-               dev->users--;
-               mutex_unlock(&dev->mutex);
-               retval = -ENOMEM;
-       }
-
        mutex_unlock(&dev->mutex);
 
        file->private_data = fh;
@@ -677,6 +690,7 @@ static int amlvideo_close(struct file *file)
        videobuf_mmap_free(&fh->vb_vidq);
        kfree(fh);
        dev->index = 8;
+       mutex_unlock(&dev->vfpMutex);
 /* if (dev->res) { */
        kfree(dev->res);
        dev->res = NULL;
@@ -802,6 +816,7 @@ static int __init amlvideo_create_instance(int inst)
        /* initialize locks */
        spin_lock_init(&dev->slock);
        mutex_init(&dev->mutex);
+       mutex_init(&dev->vfpMutex);
 
        ret = -ENOMEM;
        vfd = video_device_alloc();
@@ -862,7 +877,16 @@ free_dev: kfree(dev);
        return ret;
 }
 
-static int amlvideo_driver_probe(struct platform_device *pdev)
+#undef NORM_MAXW
+#undef NORM_MAXH
+/* #define __init */
+/* This routine allocates from 1 to n_devs virtual drivers.*/
+/*
+ *The real maximum number of virtual drivers will depend on how many drivers
+ *will succeed. This is limited to the maximum number of devices that
+ *videodev supports, which is equal to VIDEO_NUM_DEVICES.
+ */
+static int __init amlvideo_init(void)
 {
        int ret = 0, i;
 
@@ -899,51 +923,10 @@ static int amlvideo_driver_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int amlvideo_drv_remove(struct platform_device *pdev)
+static void __exit amlvideo_exit(void)
 {
        /*vf_unreg_receiver(&video_vf_recv);*/
        amlvideo_release();
-       return 0;
-}
-
-static const struct of_device_id amlvideo_dt_match[] = {
-       {
-               .compatible = "amlogic, amlvideo",
-       },
-};
-
-/* general interface for a linux driver .*/
-static struct platform_driver amlvideo_drv = {
-.probe = amlvideo_driver_probe,
-.remove = amlvideo_drv_remove,
-.driver = {
-               .name = "amlvideo",
-               .owner = THIS_MODULE,
-               .of_match_table = amlvideo_dt_match,
-       }
-};
-
-#undef NORM_MAXW
-#undef NORM_MAXH
-/* #define __init */
-/* This routine allocates from 1 to n_devs virtual drivers.
- * The real maximum number of virtual drivers will depend on how many drivers
- * will succeed. This is limited to the maximum number of devices that
- * videodev supports, which is equal to VIDEO_NUM_DEVICES.
- */
-static int __init amlvideo_init(void)
-{
-       if (platform_driver_register(&amlvideo_drv)) {
-               pr_err("Failed to register amlvideo driver\n");
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
-static void __exit amlvideo_exit(void)
-{
-       platform_driver_unregister(&amlvideo_drv);
 }
 
 module_init(amlvideo_init);
index 5ad5aea..7f0bf72 100644 (file)
@@ -72,6 +72,7 @@ struct vivi_dev {
        struct vframe_s *vf;
        struct vframe_s *amlvideo_pool_ready[AMLVIDEO_POOL_SIZE + 1];
        int index;
+       struct mutex vfpMutex;
        int amlvideo_v4l_num;
        char vf_receiver_name[AMLVIDEO_VF_NAME_SIZE];
        char vf_provider_name[AMLVIDEO_VF_NAME_SIZE];
index 9ab3761..3494e3d 100644 (file)
@@ -4680,17 +4680,52 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
        return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
 }
 #endif
-
-static enum tvin_scan_mode_e vmode2scan_mode(const struct vinfo_s *vinfo)
+static enum tvin_scan_mode_e vmode2scan_mode(enum vmode_e mode)
 {
        enum tvin_scan_mode_e scan_mode =
                TVIN_SCAN_MODE_NULL;/* 1: progressive 2:interlaced */
 
-       if (vinfo->height == vinfo->field_height)
-               scan_mode = TVIN_SCAN_MODE_PROGRESSIVE;
-       else
+#if 0 //DEBUG_TMP
+       switch (mode) {
+       case VMODE_480I:
+       case VMODE_480CVBS:
+       case VMODE_NTSC_M:
+       case VMODE_576I:
+       case VMODE_576CVBS:
+       case VMODE_PAL_M:
+       case VMODE_PAL_N:
+       case VMODE_1080I:
+       case VMODE_1080I_50HZ:
                scan_mode = TVIN_SCAN_MODE_INTERLACED;
-
+               break;
+       case VMODE_480P:
+       case VMODE_576P:
+       case VMODE_720P:
+       case VMODE_1080P:
+       case VMODE_720P_50HZ:
+       case VMODE_1080P_50HZ:
+       case VMODE_1080P_24HZ:
+       case VMODE_4K2K_30HZ:
+       case VMODE_4K2K_25HZ:
+       case VMODE_4K2K_24HZ:
+       case VMODE_4K2K_SMPTE:
+       case VMODE_VGA:
+       case VMODE_SVGA:
+       case VMODE_XGA:
+       case VMODE_SXGA:
+       case VMODE_LCD:
+       case VMODE_4K2K_50HZ:
+       case VMODE_4K2K_50HZ_Y420:
+       case VMODE_4K2K_60HZ:
+       case VMODE_4K2K_60HZ_Y420:
+               scan_mode = TVIN_SCAN_MODE_PROGRESSIVE;
+               break;
+       default:
+               pr_err("unknown mode=%d\n", mode);
+               break;
+       }
+       /* pr_err("mode=%d, scan_mode=%d\n", mode, scan_mode); */
+#endif
        return scan_mode;
 }
 
@@ -4751,7 +4786,7 @@ static int amlvideo2_start_tvin_service(struct amlvideo2_node *node)
        para.vs_bp = 0;
        para.dfmt = TVIN_NV21;/* TVIN_YUV422; */
        para.scan_mode = vmode2scan_mode(
-               vinfo);/* TVIN_SCAN_MODE_PROGRESSIVE; */
+               vinfo->mode);/* TVIN_SCAN_MODE_PROGRESSIVE; */
        if (para.scan_mode == TVIN_SCAN_MODE_INTERLACED)
                para.v_active = para.v_active / 2;
 
@@ -4868,8 +4903,7 @@ int amlvideo2_notify_callback(struct notifier_block *block, unsigned long cmd,
                }
                /*debug provider vf state*/
                if (amlvideo2_dbg_en) {
-                       if (vfp && vfp->ops && vfp->ops->vf_states)
-                               ret = vfp->ops->vf_states(&states, vfp->op_arg);
+                       ret = vf_get_states(vfp, &states);
                        if (ret == 0) {
                                pr_info("vf_pool_size = %d, buf_free_num = %d .\n",
                                states.vf_pool_size, states.buf_free_num);
@@ -4992,7 +5026,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
        para.vs_bp = 0;
        para.dfmt = TVIN_NV21;/* TVIN_YUV422; */
        para.scan_mode = vmode2scan_mode(
-               vinfo);/* TVIN_SCAN_MODE_PROGRESSIVE; */
+               vinfo->mode);/* TVIN_SCAN_MODE_PROGRESSIVE; */
        if (para.scan_mode == TVIN_SCAN_MODE_INTERLACED)
                para.v_active = para.v_active / 2;
 
@@ -5453,6 +5487,7 @@ static int amlvideo2_open(struct file *file)
                        pr_err("alloc amlvideo2.0 cma buffer failed.\n");
                else
                        pr_err("alloc amlvideo2.1 cma buffer failed.\n");
+               node->users--;
                mutex_unlock(&node->mutex);
                return -ENOMEM;
        }
@@ -5461,6 +5496,7 @@ static int amlvideo2_open(struct file *file)
        if (fh == NULL) {
                node->users--;
                /* node->provider  = NULL; */
+               amlvideo2_cma_buf_uninit(node->vid_dev, node->vid);
                mutex_unlock(&node->mutex);
                return -ENOMEM;
        }
@@ -5469,6 +5505,8 @@ static int amlvideo2_open(struct file *file)
                reserve = &node->vid_dev->memobj;
                if (!reserve) {
                        pr_err("alloc reserve buffer failed !\n");
+                       node->users--;
+                       amlvideo2_cma_buf_uninit(node->vid_dev, node->vid);
                        mutex_unlock(&node->mutex);
                        return -ENOMEM;
                }
@@ -5631,15 +5669,11 @@ static struct video_device amlvideo2_template = {
 /* .current_norm = V4L2_STD_NTSC_M, */
 };
 
-static int vf_get_states(struct vframe_states *states, int node_index)
+static int amlvideo2_vf_get_states(struct vframe_states *states, int node_index)
 {
        int ret = -1;
-       struct vframe_provider_s *vfp;
        const char *name = (node_index == 0) ? DEVICE_NAME0 : DEVICE_NAME1;
-
-       vfp = vf_get_provider(name);
-       if (vfp && vfp->ops && vfp->ops->vf_states)
-               ret = vfp->ops->vf_states(states, vfp->op_arg);
+       ret = vf_get_states_by_name(name, states);
        return ret;
 }
 
@@ -5720,7 +5754,7 @@ static int amlvideo2_receiver_event_fun(int type, void *data,
                node->amlvideo2_pool_ready = NULL;
                node->amlvideo2_pool_size = 0;
                node->video_blocking = false;
-               if (vf_get_states(&frame_states, node->vid) == 0)
+               if (amlvideo2_vf_get_states(&frame_states, node->vid) == 0)
                        node->amlvideo2_pool_size = frame_states.vf_pool_size;
                else
                        node->amlvideo2_pool_size = 4;
index 908c859..68c8f4b 100644 (file)
@@ -23,4 +23,10 @@ config  AMLOGIC_MEDIA_VSYNC_RDMA
 
 endif
 
+config AMLOGIC_MEDIA_VIDEOCAPTURE
+    bool "Amlogic Video Capture support"
+    default n
+    help
+               Internal Video Capture driver
+
 endmenu
diff --git a/drivers/amlogic/media/video_sink/amvideocap_priv.h b/drivers/amlogic/media/video_sink/amvideocap_priv.h
new file mode 100644 (file)
index 0000000..40b2fb2
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * drivers/amlogic/media/video_sink/amvideocap_priv.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef AMVIDEOCAP_PRIV_HHH
+#define AMVIDEOCAP_PRIV_HHH
+#include <linux/amlogic/media/video_sink/amvideocap.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+
+struct video_frame_info {
+       int at_flags;
+       int width;
+       int height;
+       int fmt;
+       int width_aligned;
+       int byte_per_pix;
+       u64 timestamp_ms;
+};
+
+struct src_cap_rect {
+       int x;
+       int y;
+       int width;
+       int height;
+};
+
+struct amvideocap_private {
+       int flags;
+       int buf_size;
+       unsigned long phyaddr;
+       u8 *vaddr;
+       enum amvideocap_state state;
+       int sended_end_frame_cap_req;
+       int wait_max_ms;
+
+       struct video_frame_info src;
+       struct video_frame_info want;
+       struct video_frame_info out;
+       struct src_cap_rect src_rect;
+};
+
+struct amvideocap_req_data {
+       struct amvideocap_private *privdata;
+};
+
+struct amvideocap_req {
+       int (*callback)(unsigned long data, struct vframe_s *vfput,
+                                       int index);
+       unsigned long data;
+       int at_flags;           /*AT_ */
+       u64 timestamp_ms;
+};
+
+s32 amvideocap_register_memory(unsigned char *phybufaddr, int phybufsize);
+
+#endif
index 5933a6c..349007b 100644 (file)
@@ -64,7 +64,7 @@
 #include <linux/amlogic/media/utils/amports_config.h>
 #include <linux/amlogic/media/vpu/vpu.h>
 #include "videolog.h"
-#ifdef CONFIG_AM_VIDEOCAPTURE
+#ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
 #include "amvideocap_priv.h"
 #endif
 #ifdef CONFIG_AM_VIDEO_LOG
@@ -82,17 +82,19 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_DEFAULT_LEVEL_DESC, LOG_MASK_DESC);
 #endif
 #include <linux/amlogic/media/video_sink/video_prot.h>
 #include <linux/amlogic/media/video_sink/video.h>
+#include <linux/amlogic/media/codec_mm/configs.h>
+
+#include "../common/vfm/vfm.h"
 
 static u32 osd_vpp_misc;
 static u32 osd_vpp_misc_mask;
 static bool update_osd_vpp_misc;
 int video_vsync = -ENXIO;
-
+/*global video manage cmd. */
 
 #define DEBUG_TMP 0
 
-
-#define CONFIG_AM_VOUT
+static int video_global_output = 1;
 
 #ifdef CONFIG_GE2D_KEEP_FRAME
 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
@@ -114,6 +116,12 @@ static int output_fps;
 static u32 omx_pts;
 static int omx_pts_interval_upper = 11000;
 static int omx_pts_interval_lower = -5500;
+static int drop_frame_count;
+static int receive_frame_count;
+static int display_frame_count;
+
+#define DURATION_GCD 750
+
 static bool bypass_pps;
 /*For 3D usage ----0:  mbx   1: tv */
 bool platform_type = 1;
@@ -128,6 +136,7 @@ bool omx_secret_mode;
 #define RECEIVER_NAME "amvideo"
 
 static s32 amvideo_poll_major;
+/*static s8 dolby_first_delay;*/ /* for bug 145902 */
 
 static int video_receiver_event_fun(int type, void *data, void *);
 
@@ -183,6 +192,8 @@ static DEFINE_SPINLOCK(video_onoff_lock);
 static int video_onoff_state = VIDEO_ENABLE_STATE_IDLE;
 static DEFINE_SPINLOCK(video2_onoff_lock);
 static int video2_onoff_state = VIDEO_ENABLE_STATE_IDLE;
+static u32 hdmiin_frame_check = 1;
+static u32 hdmiin_frame_check_cnt;
 
 #ifdef FIQ_VSYNC
 #define BRIDGE_IRQ INT_TIMER_C
@@ -266,6 +277,7 @@ static int video2_onoff_state = VIDEO_ENABLE_STATE_IDLE;
                spin_lock_irqsave(&video_onoff_lock, flags); \
                video_onoff_state = VIDEO_ENABLE_STATE_ON_REQ; \
                video_enabled = 1;\
+               video_status_saved = 1;\
                spin_unlock_irqrestore(&video_onoff_lock, flags); \
        } while (0)
 
@@ -275,6 +287,7 @@ static int video2_onoff_state = VIDEO_ENABLE_STATE_IDLE;
                spin_lock_irqsave(&video_onoff_lock, flags); \
                video_onoff_state = VIDEO_ENABLE_STATE_OFF_REQ; \
                video_enabled = 0;\
+               video_status_saved = 0;\
                spin_unlock_irqrestore(&video_onoff_lock, flags); \
        } while (0)
 
@@ -394,7 +407,7 @@ static int video2_onoff_state = VIDEO_ENABLE_STATE_IDLE;
 #define DisableVPP2VideoLayer() \
        CLEAR_VCBUS_REG_MASK(VPP2_MISC, \
                VPP_VD1_PREBLEND|VPP_VD2_PREBLEND|\
-               VPP_VD2_POSTBLEND|VPP_VD1_POSTBLEND);
+               VPP_VD2_POSTBLEND|VPP_VD1_POSTBLEND)
 
 #endif
 /*********************************************************/
@@ -427,6 +440,11 @@ static int vpts_chase_counter;
 static int vpts_chase_pts_diff;
 #endif
 
+
+static int step_enable;
+static int step_flag;
+
+
 /*seek values on.video_define.h*/
 static int debug_flag;
 int get_video_debug_flags(void)
@@ -457,6 +475,16 @@ static int pause_one_3d_fl_frame;
 MODULE_PARM_DESC(pause_one_3d_fl_frame, "\n pause_one_3d_fl_frame\n");
 module_param(pause_one_3d_fl_frame, uint, 0664);
 
+/*debug info control for skip & repeate vframe case*/
+static unsigned int video_dbg_vf;
+MODULE_PARM_DESC(video_dbg_vf, "\n video_dbg_vf\n");
+module_param(video_dbg_vf, uint, 0664);
+
+static unsigned int video_get_vf_cnt;
+static unsigned int video_drop_vf_cnt;
+MODULE_PARM_DESC(video_drop_vf_cnt, "\n video_drop_vf_cnt\n");
+module_param(video_drop_vf_cnt, uint, 0664);
+
 enum toggle_out_fl_frame_e {
        OUT_FA_A_FRAME,
        OUT_FA_BANK_FRAME,
@@ -518,9 +546,8 @@ static u32 video_scaler_mode;
 static int content_top = 0, content_left = 0, content_w = 0, content_h;
 static int scaler_pos_changed;
 #endif
-#if DEBUG_TMP
+
 static struct amvideocap_req *capture_frame_req;
-#endif
 static struct video_prot_s video_prot;
 static u32 video_angle;
 u32 get_video_angle(void)
@@ -590,7 +617,6 @@ void amvideo_set_scaler_para(int x, int y, int w, int h, int flag)
                vpp_set_video_layer_position(x, y, w, h);
        video_property_changed = true;
        mutex_unlock(&video_module_mutex);
-       return;
 }
 
 u32 amvideo_get_scaler_mode(void)
@@ -606,12 +632,12 @@ bool to_notify_trick_wait;
 #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
 static struct vframe_s *cur_rdma_buf;
 /*
-void vsync_rdma_config(void);
-void vsync_rdma_config_pre(void);
-bool is_vsync_rdma_enable(void);
-void start_rdma(void);
-void enable_rdma_log(int flag);
-*/
+ *void vsync_rdma_config(void);
+ *void vsync_rdma_config_pre(void);
+ *bool is_vsync_rdma_enable(void);
+ *void start_rdma(void);
+ *void enable_rdma_log(int flag);
+ */
 static int enable_rdma_log_count;
 
 bool rdma_enable_pre;
@@ -695,6 +721,7 @@ static u32 force_blackout;
 /* disable video */
 static u32 disable_video = VIDEO_DISABLE_NONE;
 static u32 video_enabled __nosavedata;
+static u32 video_status_saved __nosavedata;
 u32 get_video_enabled(void)
 {
        return video_enabled;
@@ -726,6 +753,7 @@ int get_video0_frame_info(struct vframe_s *vf)
 {
        unsigned long flags;
        int ret = -1;
+
        spin_lock_irqsave(&lock, flags);
        if (is_vpp_postblend() && cur_dispbuf && vf) {
                *vf = *cur_dispbuf;
@@ -753,6 +781,8 @@ static u32 vsync_slow_factor = 1;
 static u32 last_frame_count;
 static u32 frame_count;
 static u32 new_frame_count;
+static u32 first_frame_toggled;
+static u32 toggle_count;
 static u32 last_frame_time;
 static u32 timer_count;
 static u32 vsync_count;
@@ -791,6 +821,11 @@ char file_name[512];
 #define FREERUN_DUR     2      /* freerun with duration */
 static u32 freerun_mode;
 static u32 slowsync_repeat_enable;
+static bool dmc_adjust = true;
+module_param_named(dmc_adjust, dmc_adjust, bool, 0644);
+static u32 dmc_config_state;
+static u32 last_toggle_count;
+static u32 toggle_same_count;
 
 void set_freerun_mode(int mode)
 {
@@ -819,6 +854,7 @@ static wait_queue_head_t amvideo_sizechange_wait;
 #define VPU_DELAYWORK_MEM_POWER_OFF_VD2  4
 #define VPU_DELAYWORK_MEM_POWER_OFF_PROT 8
 #define VPU_VIDEO_LAYER1_CHANGED               16
+#define VPU_UPDATE_DOLBY_VISION                        32
 
 #define VPU_MEM_POWEROFF_DELAY           100
 static struct work_struct vpu_delay_work;
@@ -837,6 +873,9 @@ static int video_play_clone_rate = 60;
 static int android_clone_rate = 30;
 static int noneseamless_play_clone_rate = 5;
 #endif
+
+#define CONFIG_AM_VOUT //DEBUG_TMP
+
 void safe_disble_videolayer(void)
 {
 #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER_PPSCALER
@@ -859,6 +898,7 @@ static inline struct vframe_s *video_vf_peek(void)
 static inline struct vframe_s *video_vf_get(void)
 {
        struct vframe_s *vf = NULL;
+
        vf = vf_get(RECEIVER_NAME);
 
        if (vf) {
@@ -882,11 +922,11 @@ static inline struct vframe_s *video_vf_get(void)
                        mvc_flag = 0;
                }
                if (((process_3d_type & MODE_FORCE_3D_TO_2D_LR)
-#if DEBUG_TMP
                || (process_3d_type & MODE_FORCE_3D_LR)
-#endif
+               || (process_3d_type & MODE_FORCE_3D_FA_LR)
                )
-               && (!(vf->type & VIDTYPE_MVC))) {
+               && (!(vf->type & VIDTYPE_MVC))
+               && (vf->trans_fmt != TVIN_TFMT_3D_FP)) {
                        vf->trans_fmt = TVIN_TFMT_3D_DET_LR;
                        vf->left_eye.start_x = 0;
                        vf->left_eye.start_y = 0;
@@ -898,11 +938,11 @@ static inline struct vframe_s *video_vf_get(void)
                        vf->right_eye.width = vf->width / 2;
                }
                if (((process_3d_type & MODE_FORCE_3D_TO_2D_TB)
-#if DEBUG_TMP
                || (process_3d_type & MODE_FORCE_3D_TB)
-#endif
+               || (process_3d_type & MODE_FORCE_3D_FA_TB)
                )
-               && (!(vf->type & VIDTYPE_MVC))) {
+               && (!(vf->type & VIDTYPE_MVC))
+               && (vf->trans_fmt != TVIN_TFMT_3D_FP)) {
                        vf->trans_fmt = TVIN_TFMT_3D_TB;
                        vf->left_eye.start_x = 0;
                        vf->left_eye.start_y = 0;
@@ -914,22 +954,20 @@ static inline struct vframe_s *video_vf_get(void)
                        vf->right_eye.width = vf->width;
                        vf->right_eye.height = vf->height/2;
                }
-
+               receive_frame_count++;
 #endif
        }
        return vf;
 
 }
 
-static int vf_get_states(struct vframe_states *states)
+static int video_vf_get_states(struct vframe_states *states)
 {
        int ret = -1;
        unsigned long flags;
-       struct vframe_provider_s *vfp;
-       vfp = vf_get_provider(RECEIVER_NAME);
+
        spin_lock_irqsave(&lock, flags);
-       if (vfp && vfp->ops && vfp->ops->vf_states)
-               ret = vfp->ops->vf_states(states, vfp->op_arg);
+       ret = vf_get_states_by_name(RECEIVER_NAME, states);
        spin_unlock_irqrestore(&lock, flags);
        return ret;
 }
@@ -937,7 +975,8 @@ static int vf_get_states(struct vframe_states *states)
 static inline void video_vf_put(struct vframe_s *vf)
 {
        struct vframe_provider_s *vfp = vf_get_provider(RECEIVER_NAME);
-       if (vfp && atomic_dec_and_test(&vf->use_cnt)) {
+
+       if (vfp && vf && atomic_dec_and_test(&vf->use_cnt)) {
                vf_put(vf, RECEIVER_NAME);
 #if DEBUG_TMP
                if (is_dolby_vision_enable())
@@ -956,7 +995,39 @@ int ext_get_cur_video_frame(struct vframe_s **vf, int *canvas_index)
        *vf = cur_dispbuf;
        return 0;
 }
-#ifdef CONFIG_AM_VIDEOCAPTURE
+static void dump_vframe_status(const char *name)
+{
+       int ret = 0;
+       struct vframe_states states;
+       struct vframe_provider_s *vfp;
+
+       vfp = vf_get_provider_by_name(name);
+       if (vfp && vfp->ops && vfp->ops->vf_states)
+               ret = vfp->ops->vf_states(&states, vfp->op_arg);
+
+       if (ret == 0) {
+               ret += pr_info("%s_pool_size=%d\n",
+                       name, states.vf_pool_size);
+               ret += pr_info("%s buf_free_num=%d\n",
+                       name, states.buf_free_num);
+               ret += pr_info("%s buf_avail_num=%d\n",
+                       name, states.buf_avail_num);
+       } else {
+               ret += pr_info("%s vframe no states\n", name);
+       }
+}
+
+static void dump_vdin_reg(void)
+{
+       unsigned int reg001, reg002;
+
+       reg001 = READ_VCBUS_REG(0x1204);
+       reg002 = READ_VCBUS_REG(0x1205);
+       pr_info("VDIN_LCNT_STATUS:0x%x,VDIN_COM_STATUS0:0x%x\n",
+               reg001, reg002);
+}
+
+#ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
 
 int ext_put_video_frame(struct vframe_s *vf)
 {
@@ -965,8 +1036,8 @@ int ext_put_video_frame(struct vframe_s *vf)
        video_vf_put(vf);
        return 0;
 }
-#if DEBUG_TMP
-int is_need_framepacking_output(void)
+
+static int is_need_framepacking_output(void)
 {
        int ret = 0;
 
@@ -976,7 +1047,6 @@ int is_need_framepacking_output(void)
        }
        return ret;
 }
-#endif
 
 int ext_register_end_frame_callback(struct amvideocap_req *req)
 {
@@ -993,6 +1063,7 @@ int ext_frame_capture_poll(int endflags)
                int index;
                int ret;
                struct amvideocap_req *req = capture_frame_req;
+
                ret = ext_get_cur_video_frame(&vf, &index);
                if (!ret) {
                        req->callback(req->data, vf, index);
@@ -1139,6 +1210,7 @@ static void vpp_settings_v(struct vpp_frame_par_s *framePtr)
        u32 v_phase;
        u32 v_skip_flag = 0;
        int x, y, w, h;
+
        r = framePtr->VPP_vsc_endp - framePtr->VPP_vsc_startp;
        afbc_enble_flag = 0;
        if (is_meson_gxbb_cpu())
@@ -1224,8 +1296,7 @@ static void vpp_settings_v(struct vpp_frame_par_s *framePtr)
                                VPP_VD1_END_BIT));
                        }
 
-                       if (/*is_need_framepacking_output()*/0) {
-#if DEBUG_TMP
+                       if (is_need_framepacking_output()) {
                                VSYNC_WR_MPEG_REG(VPP_BLEND_VD2_V_START_END +
                                cur_dev->vpp_off,
                                (((((framePtr->VPP_vd_end_lines_ -
@@ -1233,7 +1304,6 @@ static void vpp_settings_v(struct vpp_frame_par_s *framePtr)
                                VPP_VD_SIZE_MASK) << VPP_VD1_START_BIT) |
                                (((framePtr->VPP_vd_end_lines_) &
                                VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT));
-#endif
                        } else {
                                VSYNC_WR_MPEG_REG(VPP_BLEND_VD2_V_START_END +
                                cur_dev->vpp_off,
@@ -1265,8 +1335,7 @@ static void vpp_settings_v(struct vpp_frame_par_s *framePtr)
                                        VPP_VD_SIZE_MASK) <<
                                        VPP_VD1_END_BIT));
                        }
-                       if (/*is_need_framepacking_output()*/0) {
-#if DEBUG_TMP
+                       if (is_need_framepacking_output()) {
                                VSYNC_WR_MPEG_REG(VPP_BLEND_VD2_V_START_END +
                                cur_dev->vpp_off,
                                (((((framePtr->VPP_vd_end_lines_ -
@@ -1274,7 +1343,6 @@ static void vpp_settings_v(struct vpp_frame_par_s *framePtr)
                                VPP_VD_SIZE_MASK) << VPP_VD1_START_BIT) |
                                (((framePtr->VPP_vd_end_lines_) &
                                VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT));
-#endif
                        } else {
                                VSYNC_WR_MPEG_REG(VPP_BLEND_VD2_V_START_END +
                                cur_dev->vpp_off,
@@ -1327,6 +1395,9 @@ static void zoom_get_horz_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls,
                              u32 *le, u32 *rs, u32 *re)
 {
        u32 crop_sx, crop_ex, crop_sy, crop_ey;
+
+       if (!vf)
+               return;
        vpp_get_video_source_crop(&crop_sy, &crop_sx, &crop_ey, &crop_ex);
 
        switch (vpp_3d_mode) {
@@ -1367,14 +1438,13 @@ static void zoom_get_horz_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls,
                }
                break;
        }
-
-       return;
 }
 
 static void zoom_get_vert_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls,
                        u32 *le, u32 *rs, u32 *re)
 {
        u32 crop_sx, crop_ex, crop_sy, crop_ey, height;
+
        vpp_get_video_source_crop(&crop_sy, &crop_sx, &crop_ey, &crop_ex);
 
        if (vf->type & VIDTYPE_INTERLACE)
@@ -1487,15 +1557,15 @@ static void zoom_get_vert_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls,
                *le = *re = zoom_end_y_lines;
                break;
        }
-
-       return;
 }
 
 #endif
 static void zoom_display_horz(int hscale)
 {
        u32 ls, le, rs, re;
+#ifdef TV_REVERSE
        int content_w, content_l, content_r;
+#endif
 #ifdef TV_3D_FUNCTION_OPEN
        if (process_3d_type & MODE_3D_ENABLE) {
                zoom_get_horz_pos(cur_dispbuf, cur_frame_par->vpp_3d_mode, &ls,
@@ -1533,6 +1603,7 @@ static void zoom_display_horz(int hscale)
        if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) {
                int l_aligned;
                int r_aligned;
+               int h_skip = cur_frame_par->hscale_skip_count + 1;
                if ((zoom_start_x_lines > 0) ||
                (zoom_end_x_lines < ori_end_x_lines)) {
                        l_aligned = round_down(ori_start_x_lines, 32);
@@ -1542,8 +1613,8 @@ static void zoom_display_horz(int hscale)
                        r_aligned = round_up(zoom_end_x_lines + 1, 32);
                }
                VSYNC_WR_MPEG_REG(AFBC_VD_CFMT_W,
-                         ((r_aligned - l_aligned) << 16) |
-                         (r_aligned / 2 - l_aligned / 2));
+                         (((r_aligned - l_aligned) / h_skip) << 16) |
+                         ((r_aligned / 2 - l_aligned / 2) / h_skip));
 
                VSYNC_WR_MPEG_REG(AFBC_MIF_HOR_SCOPE,
                          ((l_aligned / 32) << 16) |
@@ -1552,7 +1623,7 @@ static void zoom_display_horz(int hscale)
                if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) {
                        VSYNC_WR_MPEG_REG(AFBC_SIZE_OUT,
                                (VSYNC_RD_MPEG_REG(AFBC_SIZE_OUT) & 0xffff) |
-                               ((r_aligned - l_aligned) << 16));
+                               (((r_aligned - l_aligned) / h_skip) << 16));
                }
 #ifdef TV_REVERSE
                if (reverse) {
@@ -1601,8 +1672,9 @@ static void zoom_display_horz(int hscale)
 static void vd2_zoom_display_horz(int hscale)
 {
        u32 ls, le, rs, re;
+#ifdef TV_REVERSE
        int content_w, content_l, content_r;
-
+#endif
        ls = rs = zoom2_start_x_lines;
        le = re = zoom2_end_x_lines;
 
@@ -1666,9 +1738,9 @@ static void vd2_zoom_display_horz(int hscale)
                          (re / 2 << VDIF_PIC_END_BIT));
 
        VSYNC_WR_MPEG_REG(VIU_VD2_FMT_W + cur_dev->viu_off,
-                         (((zoom2_end_x_lines - zoom2_start_x_lines +
+                         (((le - ls +
                             1) >> hscale) << VD1_FMT_LUMA_WIDTH_BIT) |
-                         (((zoom2_end_x_lines / 2 - zoom2_start_x_lines / 2 +
+                         (((le / 2 - ls / 2 +
                             1) >> hscale) << VD1_FMT_CHROMA_WIDTH_BIT));
 }
 #endif
@@ -1677,6 +1749,7 @@ static void zoom_display_vert(void)
 {
 
        u32 ls, le, rs, re;
+
        if (platform_type == 1) {
                if (process_3d_type & MODE_3D_ENABLE) {
                        zoom_get_vert_pos(cur_dispbuf,
@@ -1698,8 +1771,7 @@ static void zoom_display_vert(void)
        }
 
        if ((cur_dispbuf) && (cur_dispbuf->type & VIDTYPE_MVC)) {
-               if (/*is_need_framepacking_output()*/0) {
-#if DEBUG_TMP
+               if (is_need_framepacking_output()) {
                        VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_Y0,
                                        (ls << VDIF_PIC_START_BIT) |
                                        (le << VDIF_PIC_END_BIT));
@@ -1715,7 +1787,6 @@ static void zoom_display_vert(void)
                        VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_Y0,
                                        ((rs / 2) << VDIF_PIC_START_BIT) |
                                        ((re / 2) << VDIF_PIC_END_BIT));
-#endif
                } else {
                        VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_Y0 + cur_dev->viu_off,
                                        (ls * 2 << VDIF_PIC_START_BIT) |
@@ -1772,10 +1843,16 @@ static void zoom_display_vert(void)
        if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) {
                int t_aligned;
                int b_aligned;
+               int ori_t_aligned;
+               int ori_b_aligned;
+               int v_skip = cur_frame_par->vscale_skip_count + 1;
                t_aligned = round_down(zoom_start_y_lines, 4);
                b_aligned = round_up(zoom_end_y_lines + 1, 4);
+
+               ori_t_aligned = round_down(ori_start_y_lines, 4);
+               ori_b_aligned = round_up(ori_end_y_lines + 1, 4);
                VSYNC_WR_MPEG_REG(AFBC_VD_CFMT_H,
-                   b_aligned - t_aligned);
+                   (b_aligned - t_aligned) / 2 / v_skip);
 
                VSYNC_WR_MPEG_REG(AFBC_MIF_VER_SCOPE,
                    ((t_aligned / 4) << 16) |
@@ -1784,15 +1861,22 @@ static void zoom_display_vert(void)
                VSYNC_WR_MPEG_REG(AFBC_PIXEL_VER_SCOPE,
                    ((zoom_start_y_lines - t_aligned) << 16) |
                    (zoom_end_y_lines - t_aligned));
+       /* afbc pixel vertical output region must be
+        * [0, zoom_end_y_lines - zoom_start_y_lines]
+        */
+               VSYNC_WR_MPEG_REG(AFBC_PIXEL_VER_SCOPE,
+               (zoom_end_y_lines - zoom_start_y_lines));
 
                VSYNC_WR_MPEG_REG(AFBC_SIZE_IN,
-                       (VSYNC_RD_MPEG_REG(AFBC_SIZE_IN) & 0xffff0000) |
-                       (b_aligned - t_aligned));
+                       (VSYNC_RD_MPEG_REG(AFBC_SIZE_IN)
+                       & 0xffff0000) |
+                       (ori_b_aligned - ori_t_aligned));
                if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) {
                        VSYNC_WR_MPEG_REG(AFBC_SIZE_OUT,
                                (VSYNC_RD_MPEG_REG(AFBC_SIZE_OUT) &
-                               0xffff0000) | (b_aligned - t_aligned));
-                       }
+                               0xffff0000) |
+                               ((b_aligned - t_aligned) / v_skip));
+               }
        }
 }
 
@@ -1802,8 +1886,8 @@ static void vd2_zoom_display_vert(void)
 
        u32 ls, le, rs, re;
 
-       ls = rs = zoom2_start_x_lines;
-       le = re = zoom2_end_x_lines;
+       ls = rs = zoom2_start_y_lines;
+       le = re = zoom2_end_y_lines;
 
        /* vd2 */
        VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_Y0,
@@ -1829,8 +1913,9 @@ static void vd2_zoom_display_vert(void)
                t_aligned = round_down(zoom2_start_y_lines, 4);
                b_aligned = round_up(zoom2_end_y_lines + 1, 4);
 
+               /* TODO: afbc setting only support 420 for now */
                VSYNC_WR_MPEG_REG(VD2_AFBC_VD_CFMT_H,
-                   b_aligned - t_aligned);
+                   (b_aligned - t_aligned) / 2);
 
                VSYNC_WR_MPEG_REG(VD2_AFBC_MIF_VER_SCOPE,
                    ((t_aligned / 4) << 16) |
@@ -1867,26 +1952,26 @@ static void judge_3d_fa_out_mode(void)
                /* toggle_3d_fa_frame  determine*/
                /*the out frame is L or R or blank */
                if ((process_3d_type & MODE_3D_OUT_FA_L_FIRST)) {
-                       if ((vsync_count == 0) % 2)
+                       if ((vsync_count % 2) == 0)
                                toggle_3d_fa_frame = OUT_FA_A_FRAME;
                        else
                                toggle_3d_fa_frame = OUT_FA_B_FRAME;
                } else if ((process_3d_type & MODE_3D_OUT_FA_R_FIRST)) {
-                       if ((vsync_count == 0) % 2)
+                       if ((vsync_count % 2) == 0)
                                toggle_3d_fa_frame = OUT_FA_B_FRAME;
                        else
                                toggle_3d_fa_frame = OUT_FA_A_FRAME;
                } else if ((process_3d_type & MODE_3D_OUT_FA_LB_FIRST)) {
-                       if ((vsync_count == 0) % 4)
+                       if ((vsync_count % 4) == 0)
                                toggle_3d_fa_frame = OUT_FA_A_FRAME;
-                       else if ((vsync_count == 2) % 4)
+                       else if ((vsync_count % 4) == 2)
                                toggle_3d_fa_frame = OUT_FA_B_FRAME;
                        else
                                toggle_3d_fa_frame = OUT_FA_BANK_FRAME;
                } else if ((process_3d_type & MODE_3D_OUT_FA_RB_FIRST)) {
-                       if ((vsync_count == 0) % 4)
+                       if ((vsync_count % 4) == 0)
                                toggle_3d_fa_frame = OUT_FA_B_FRAME;
-                       else if ((vsync_count == 2) % 4)
+                       else if ((vsync_count % 4) == 2)
                                toggle_3d_fa_frame = OUT_FA_A_FRAME;
                        else
                                toggle_3d_fa_frame = OUT_FA_BANK_FRAME;
@@ -1896,24 +1981,56 @@ static void judge_3d_fa_out_mode(void)
 }
 
 #endif
-#if DEBUG_TMP
+
 static void vframe_canvas_set(struct canvas_config_s *config, u32 planes,
                                u32 *index)
 {
        int i;
        u32 *canvas_index = index;
+
        struct canvas_config_s *cfg = config;
 
        for (i = 0; i < planes; i++, canvas_index++, cfg++)
                canvas_config_config(*canvas_index, cfg);
 }
+
+bool has_enhanced_layer(struct vframe_s *vf)
+{
+       struct provider_aux_req_s req;
+
+       if (!vf)
+               return 0;
+       if (vf->source_type != VFRAME_SOURCE_TYPE_OTHERS)
+               return 0;
+#if DEBUG_TMP
+       if (!is_dolby_vision_on())
+               return 0;
 #endif
+       req.vf = vf;
+       req.bot_flag = 0;
+       req.aux_buf = NULL;
+       req.aux_size = 0;
+       req.dv_enhance_exist = 0;
+       vf_notify_provider_by_name("dvbldec",
+               VFRAME_EVENT_RECEIVER_GET_AUX_DATA,
+               (void *)&req);
+       return req.dv_enhance_exist;
+}
 u32 property_changed_true;
 static void vsync_toggle_frame(struct vframe_s *vf)
 {
        u32 first_picture = 0;
-       unsigned long flags;
+       unsigned long flags = 0;
+       bool vf_with_el = false;
+
+       if (vf == NULL)
+               return;
        frame_count++;
+       toggle_count++;
+#if DEBUG_TMP
+       if (is_dolby_vision_enable())
+               vf_with_el = has_enhanced_layer(vf);
+#endif
        ori_start_x_lines = 0;
        ori_end_x_lines = ((vf->type & VIDTYPE_COMPRESS) ?
                vf->compWidth : vf->width) - 1;
@@ -1967,6 +2084,8 @@ static void vsync_toggle_frame(struct vframe_s *vf)
                        }
                } else {
                        new_frame_count++;
+                       if (new_frame_count == 1)
+                               first_picture = 1;
 #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
                        if (is_vsync_rdma_enable()) {
 #ifdef RDMA_RECYCLE_ORDERED_VFRAMES
@@ -1985,6 +2104,7 @@ static void vsync_toggle_frame(struct vframe_s *vf)
 #endif
                        } else {
                                int i;
+
                                for (i = 0; i < dispbuf_to_put_num; i++) {
                                        if (dispbuf_to_put[i]) {
                                                video_vf_put(
@@ -2044,17 +2164,19 @@ static void vsync_toggle_frame(struct vframe_s *vf)
                                vf->plane_num,
                                &disp_canvas_index[rdma_canvas_id][0]);
                }
-               if (vf->canvas1Addr != (u32)-1) {
-                       canvas_copy(vf->canvas1Addr & 0xff,
-                               disp_canvas_index[rdma_canvas_id][3]);
-                       canvas_copy((vf->canvas1Addr >> 8) & 0xff,
-                               disp_canvas_index[rdma_canvas_id][4]);
-                       canvas_copy((vf->canvas1Addr >> 16) & 0xff,
-                               disp_canvas_index[rdma_canvas_id][5]);
-               } else {
-                       vframe_canvas_set(&vf->canvas1_config[0],
-                               vf->plane_num,
-                               &disp_canvas_index[rdma_canvas_id][3]);
+               if (!vf_with_el) {
+                       if (vf->canvas1Addr != (u32)-1) {
+                               canvas_copy(vf->canvas1Addr & 0xff,
+                                       disp_canvas_index[rdma_canvas_id][3]);
+                               canvas_copy((vf->canvas1Addr >> 8) & 0xff,
+                                       disp_canvas_index[rdma_canvas_id][4]);
+                               canvas_copy((vf->canvas1Addr >> 16) & 0xff,
+                                       disp_canvas_index[rdma_canvas_id][5]);
+                       } else {
+                               vframe_canvas_set(&vf->canvas1_config[0],
+                                       vf->plane_num,
+                                       &disp_canvas_index[rdma_canvas_id][3]);
+                       }
                }
 
                VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS0 + cur_dev->viu_off,
@@ -2062,34 +2184,43 @@ static void vsync_toggle_frame(struct vframe_s *vf)
                if (platform_type == 0) {
                        VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS1 + cur_dev->viu_off,
                                          disp_canvas[rdma_canvas_id][0]);
-                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS0 + cur_dev->viu_off,
-                                         disp_canvas[rdma_canvas_id][1]);
-                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 + cur_dev->viu_off,
-                                         disp_canvas[rdma_canvas_id][1]);
+                       if (!vf_with_el) {
+                               VSYNC_WR_MPEG_REG(
+                                       VD2_IF0_CANVAS0 + cur_dev->viu_off,
+                                       disp_canvas[rdma_canvas_id][1]);
+                               VSYNC_WR_MPEG_REG(
+                                       VD2_IF0_CANVAS1 + cur_dev->viu_off,
+                                       disp_canvas[rdma_canvas_id][1]);
+                       }
                } else {
-                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS0 + cur_dev->viu_off,
-                                         disp_canvas[rdma_canvas_id][0]);
+                       if (!vf_with_el)
+                               VSYNC_WR_MPEG_REG(
+                                       VD2_IF0_CANVAS0 + cur_dev->viu_off,
+                                       disp_canvas[rdma_canvas_id][1]);
                        if (cur_frame_par &&
                        (cur_frame_par->vpp_2pic_mode == 1)) {
                                VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS1 +
                                cur_dev->viu_off,
                                disp_canvas[rdma_canvas_id][0]);
-                               VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 +
-                               cur_dev->viu_off,
-                               disp_canvas[rdma_canvas_id][0]);
+                               if (!vf_with_el)
+                                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 +
+                                       cur_dev->viu_off,
+                                       disp_canvas[rdma_canvas_id][0]);
                        } else {
                                VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS1 +
                                cur_dev->viu_off,
                                disp_canvas[rdma_canvas_id][1]);
-                               VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 +
-                               cur_dev->viu_off,
-                               disp_canvas[rdma_canvas_id][1]);
+                               if (!vf_with_el)
+                                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 +
+                                       cur_dev->viu_off,
+                                       disp_canvas[rdma_canvas_id][0]);
                        }
                }
                if (cur_frame_par
                && (process_3d_type & MODE_3D_ENABLE)
                && (process_3d_type & MODE_3D_TO_2D_R)
-               && (cur_frame_par->vpp_2pic_mode == VPP_SELECT_PIC1)) {
+               && (cur_frame_par->vpp_2pic_mode == VPP_SELECT_PIC1)
+               && !vf_with_el) {
                        VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS0 + cur_dev->viu_off,
                                          disp_canvas[rdma_canvas_id][1]);
                        VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS1 + cur_dev->viu_off,
@@ -2131,34 +2262,44 @@ static void vsync_toggle_frame(struct vframe_s *vf)
                canvas_copy((vf->canvas1Addr >> 16) & 0xff,
                            disp_canvas_index[5]);
                if (platform_type == 0) {
-                       VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS0 + cur_dev->viu_off,
-                                         disp_canvas[0]);
-                       VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS1 + cur_dev->viu_off,
-                                         disp_canvas[0]);
-                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS0 + cur_dev->viu_off,
-                                         disp_canvas[1]);
-                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 + cur_dev->viu_off,
-                                         disp_canvas[1]);
+                       VSYNC_WR_MPEG_REG(
+                               VD1_IF0_CANVAS0 + cur_dev->viu_off,
+                               disp_canvas[0]);
+                       VSYNC_WR_MPEG_REG(
+                               VD1_IF0_CANVAS1 + cur_dev->viu_off,
+                               disp_canvas[0]);
+                       if (!vf_with_el)
+                               VSYNC_WR_MPEG_REG(
+                                       VD2_IF0_CANVAS0 + cur_dev->viu_off,
+                                       disp_canvas[1]);
+                               VSYNC_WR_MPEG_REG(
+                                       VD2_IF0_CANVAS1 + cur_dev->viu_off,
+                                       disp_canvas[1]);
+                       }
                } else {
                        VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS0 + cur_dev->viu_off,
                                          disp_canvas[0]);
-                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS0 + cur_dev->viu_off,
-                                         disp_canvas[0]);
+                       if (!vf_with_el)
+                               VSYNC_WR_MPEG_REG(
+                                       VD2_IF0_CANVAS0 + cur_dev->viu_off,
+                                       disp_canvas[0]);
                        if (cur_frame_par &&
                        (cur_frame_par->vpp_2pic_mode == 1)) {
                                VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS1 +
                                cur_dev->viu_off,
                                disp_canvas[0]);
-                               VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 +
-                               cur_dev->viu_off,
-                               disp_canvas[0]);
+                               if (!vf_with_el)
+                                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 +
+                                       cur_dev->viu_off,
+                                       disp_canvas[0]);
                        } else {
                                VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS1 +
                                cur_dev->viu_off,
                                disp_canvas[1]);
-                               VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 +
-                               cur_dev->viu_off,
-                               disp_canvas[1]);
+                               if (!vf_with_el)
+                                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 +
+                                       cur_dev->viu_off,
+                                       disp_canvas[1]);
                        }
                        /* VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS0 +*/
                        /*cur_dev->viu_off, disp_canvas[0]); */
@@ -2220,8 +2361,8 @@ static void vsync_toggle_frame(struct vframe_s *vf)
        }
 
        /* enable new config on the new frames */
-       if ((first_picture) ||
-           (cur_dispbuf->bufWidth != vf->bufWidth) ||
+       if ((first_picture) ||  (cur_dispbuf &&
+           ((cur_dispbuf->bufWidth != vf->bufWidth) ||
            (cur_dispbuf->width != vf->width) ||
            (cur_dispbuf->height != vf->height) ||
            (cur_dispbuf->bitdepth != vf->bitdepth) ||
@@ -2232,10 +2373,10 @@ static void vsync_toggle_frame(struct vframe_s *vf)
             (vf->type_backup & VIDTYPE_INTERLACE)) ||
            (cur_dispbuf->type != vf->type)
 #if HAS_VPU_PROT
-           || (cur_dispbuf->video_angle != vf->video_angle)
+           || cur_dispbuf && (cur_dispbuf->video_angle != vf->video_angle)
            || video_prot.angle_changed) {
 #else
-           ) {
+           ))) {
 #endif
                last_process_3d_type = process_3d_type;
                atomic_inc(&video_sizechange);
@@ -2259,13 +2400,16 @@ static void vsync_toggle_frame(struct vframe_s *vf)
                if (has_vpu_prot()) {
                        if (use_prot) {
                                struct vframe_s tmp_vf = *vf;
+
                                video_prot.angle = vf->video_angle;
                                if ((first_picture) || video_prot.angle_changed
-                                   || (cur_dispbuf->video_angle !=
+                                   || cur_dispbuf &&
+                                       (cur_dispbuf->video_angle !=
                                        vf->video_angle
                                        || cur_dispbuf->width != vf->width
                                        || cur_dispbuf->height != vf->height)) {
                                        u32 angle_orientation = 0;
+
                                        video_prot_init(&video_prot, &tmp_vf);
                                        angle_orientation = vf->video_angle;
                                        video_prot_set_angle(&video_prot,
@@ -2405,18 +2549,31 @@ static void vsync_toggle_frame(struct vframe_s *vf)
                        if ((vf->type & VIDTYPE_MVC) ||
                        (cur_dispbuf2 && (cur_dispbuf2->type & VIDTYPE_VD2)))
                                EnableVideoLayer2();
+                       else if (cur_dispbuf2 &&
+                       !(cur_dispbuf2->type & VIDTYPE_COMPRESS))
+                               VD2_MEM_POWER_ON();
+                       else if (vf_with_el)
+                               EnableVideoLayer2();
                }
        }
        if (cur_dispbuf && (cur_dispbuf->type != vf->type)) {
                if ((vf->type & VIDTYPE_MVC) ||
                (cur_dispbuf2 && (cur_dispbuf2->type & VIDTYPE_VD2)))
                        EnableVideoLayer2();
-               else
-                       DisableVideoLayer2();
+               else {
+                       if (cur_dispbuf2 &&
+                       !(cur_dispbuf2->type & VIDTYPE_COMPRESS))
+                               VD2_MEM_POWER_ON();
+                       else if (vf_with_el)
+                               EnableVideoLayer2();
+                       else
+                               DisableVideoLayer2();
+               }
        }
        cur_dispbuf = vf;
        if (first_picture) {
                frame_par_ready_to_set = 1;
+               first_frame_toggled = 1;
 
 #ifdef VIDEO_PTS_CHASE
                av_sync_flag = 0;
@@ -2429,11 +2586,12 @@ static void vsync_toggle_frame(struct vframe_s *vf)
 static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
 {
        u32 r;
-       u32 vphase, vini_phase;
+       u32 vphase, vini_phase, vformatter;
        u32 pat, loop;
        static const u32 vpat[] = { 0, 0x8, 0x9, 0xa, 0xb, 0xc };
        u32 u, v;
        u32 type = vf->type, bit_mode = 0;
+       bool vf_with_el = false;
 
        if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) {
                if (frame_par->nocomp)
@@ -2467,25 +2625,56 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                                0x80 << (u + 10) |
                                0x80 << v);
                        /* chroma formatter */
+                       /* TODO: afbc setting only cover 420 for now */
 #ifdef TV_REVERSE
                        if (reverse) {
-                               VSYNC_WR_MPEG_REG(AFBC_VD_CFMT_CTRL,
-                                       /*HFORMATTER_RRT_PIXEL0 |*/
-                                       HFORMATTER_YC_RATIO_2_1 |
-                                       HFORMATTER_EN |
-                                       VFORMATTER_RPTLINE0_EN |
-                                       /*(0xa << VFORMATTER_INIPHASE_BIT) |*/
-                                       (0x8 << VFORMATTER_PHASE_BIT) |
-                                       VFORMATTER_EN);
+                               if (is_meson_txlx_package_962X()
+                               /*&& !is_dolby_vision_stb_mode()*/
+                               /*&& is_dolby_vision_on()*/)/*DEBUG_TMP*/
+                                       VSYNC_WR_MPEG_REG(
+                                               AFBC_VD_CFMT_CTRL,
+                                               HFORMATTER_REPEAT |
+                                               HFORMATTER_YC_RATIO_2_1 |
+                                               HFORMATTER_EN |
+                                               VFORMATTER_ALWAYS_RPT |
+                                               (0 << VFORMATTER_INIPHASE_BIT) |
+                                               (0x8 << VFORMATTER_PHASE_BIT) |
+                                               VFORMATTER_EN);
+                               else
+                                       VSYNC_WR_MPEG_REG(AFBC_VD_CFMT_CTRL,
+                                       (is_dolby_vision_on() ?
+                                       HFORMATTER_REPEAT |
+                                       (0xc << VFORMATTER_INIPHASE_BIT)  :
+                                               HFORMATTER_RRT_PIXEL0) |
+                                               HFORMATTER_YC_RATIO_2_1 |
+                                               HFORMATTER_EN |
+                                               VFORMATTER_RPTLINE0_EN |
+                                               (0x8 << VFORMATTER_PHASE_BIT) |
+                                               VFORMATTER_EN);
                        } else
 #endif
                        {
-                               VSYNC_WR_MPEG_REG(AFBC_VD_CFMT_CTRL,
-                                       HFORMATTER_RRT_PIXEL0 |
+                               if (is_meson_txlx_package_962X()
+                               /*&& !is_dolby_vision_stb_mode()*/
+                               /*&& is_dolby_vision_on()*/)/*DEBUG_TMP*/
+                                       VSYNC_WR_MPEG_REG(
+                                               AFBC_VD_CFMT_CTRL,
+                                               HFORMATTER_REPEAT |
+                                               HFORMATTER_YC_RATIO_2_1 |
+                                               HFORMATTER_EN |
+                                               VFORMATTER_ALWAYS_RPT |
+                                               (0 << VFORMATTER_INIPHASE_BIT) |
+                                               (0x8 << VFORMATTER_PHASE_BIT) |
+                                               VFORMATTER_EN);
+                               else
+                                       VSYNC_WR_MPEG_REG(AFBC_VD_CFMT_CTRL,
+                                       (is_dolby_vision_on() ?
+                                       HFORMATTER_REPEAT |
+                                       (0xc << VFORMATTER_INIPHASE_BIT)  :
+                                       HFORMATTER_RRT_PIXEL0) |
                                        HFORMATTER_YC_RATIO_2_1 |
                                        HFORMATTER_EN |
                                        VFORMATTER_RPTLINE0_EN |
-                                       /*(0xa << VFORMATTER_INIPHASE_BIT) |*/
                                        (0x8 << VFORMATTER_PHASE_BIT) |
                                        VFORMATTER_EN);
                        }
@@ -2511,13 +2700,13 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                        } else {
                                bit_mode = 0;
                        }
-                       VSYNC_WR_MPEG_REG(VD1_IF0_GEN_REG3,
-                               ((bit_mode&0x3)<<8) | (3<<4) | 3);
-                       VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG3,
-                               ((bit_mode&0x3)<<8) | (3<<4) | 3);
-                       if (is_meson_txl_cpu())
-                               VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG3,
-                               ((bit_mode&0x3)<<8) | (3<<4) | 3);
+                       VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG3,
+                               (bit_mode&0x3), 8, 2);
+                       VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG3,
+                               (bit_mode&0x3), 8, 2);
+                       if (is_meson_txl_cpu() || is_meson_txlx_cpu())
+                               VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG3,
+                               (bit_mode&0x3), 8, 2);
                        if ((VSYNC_RD_MPEG_REG(DI_POST_CTRL) & 0x100) == 0)
                                VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0 +
                                        cur_dev->viu_off, 0, 16, 3);
@@ -2556,11 +2745,16 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                }
        }
 #endif
+#if DEBUG_TMP
+       if (is_dolby_vision_enable())
+               vf_with_el = has_enhanced_layer(vf);
+#endif
        if (frame_par->hscale_skip_count)
                r |= VDIF_CHROMA_HZ_AVG | VDIF_LUMA_HZ_AVG;
 
        VSYNC_WR_MPEG_REG(VD1_IF0_GEN_REG + cur_dev->viu_off, r);
-       VSYNC_WR_MPEG_REG(VD2_IF0_GEN_REG, r);
+       if (!vf_with_el)
+               VSYNC_WR_MPEG_REG(VD2_IF0_GEN_REG, r);
 
        /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
        if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M6) {
@@ -2592,13 +2786,13 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                if (reverse) {
                        VSYNC_WR_MPEG_REG_BITS((VD1_IF0_GEN_REG2 +
                                cur_dev->viu_off), 0xf, 2, 4);
-                       if (vf->type & VIDTYPE_MVC)
+                       if ((vf->type & VIDTYPE_MVC) && (!vf_with_el))
                                VSYNC_WR_MPEG_REG_BITS((VD2_IF0_GEN_REG2 +
                                        cur_dev->viu_off), 0xf, 2, 4);
                } else {
                        VSYNC_WR_MPEG_REG_BITS((VD1_IF0_GEN_REG2 +
                                cur_dev->viu_off), 0, 2, 4);
-                       if (vf->type & VIDTYPE_MVC)
+                       if ((vf->type & VIDTYPE_MVC) && (!vf_with_el))
                                VSYNC_WR_MPEG_REG_BITS((VD2_IF0_GEN_REG2 +
                                        cur_dev->viu_off), 0, 2, 4);
                }
@@ -2611,47 +2805,89 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
        if (type & VIDTYPE_VIU_444) {
                VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL + cur_dev->viu_off,
                                  HFORMATTER_YC_RATIO_1_1);
-               VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+               if (!vf_with_el)
+                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
                                  HFORMATTER_YC_RATIO_1_1);
        } else if (type & VIDTYPE_VIU_FIELD) {
                vini_phase = 0xc << VFORMATTER_INIPHASE_BIT;
                vphase =
                    ((type & VIDTYPE_VIU_422) ? 0x10 : 0x08) <<
                    VFORMATTER_PHASE_BIT;
-       if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) {
-               if ((vf->width >= 3840) &&
+
+               /*vlsi suggest only for yuv420 vformatter shold be 1*/
+               if (type & VIDTYPE_VIU_NV21)
+                       vformatter = VFORMATTER_EN;
+               else
+                       vformatter = 0;
+               if (is_meson_txlx_package_962X()
+               /*&& !is_dolby_vision_stb_mode()*/
+               /*&& is_dolby_vision_on()*/) {/*DEBUG_TMP*/
+                       VSYNC_WR_MPEG_REG(
+                               VIU_VD1_FMT_CTRL + cur_dev->viu_off,
+                               HFORMATTER_REPEAT |
+                               HFORMATTER_YC_RATIO_2_1 |
+                               HFORMATTER_EN |
+                               ((type & VIDTYPE_VIU_422) ?
+                               VFORMATTER_RPTLINE0_EN :
+                               VFORMATTER_ALWAYS_RPT) |
+                               (0 << VFORMATTER_INIPHASE_BIT) |
+                               (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
+                               << VFORMATTER_PHASE_BIT) |
+                               ((type & VIDTYPE_VIU_422) ?
+                               0 :
+                               VFORMATTER_EN));
+                       pr_info("\tvd1 set fmt(dovi tv)\n");
+               } else if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() ||
+                       is_meson_txlx_cpu()) {
+                       if ((vf->width >= 3840) &&
                        (vf->height >= 2160) &&
                        (type & VIDTYPE_VIU_422)) {
-                       VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL + cur_dev->viu_off,
-                       HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
-                       VFORMATTER_RPTLINE0_EN | vini_phase | vphase);
-
-                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
-                       HFORMATTER_RRT_PIXEL0 | HFORMATTER_YC_RATIO_2_1 |
-                       HFORMATTER_EN | VFORMATTER_RPTLINE0_EN |
-                       vini_phase | vphase);
+                               VSYNC_WR_MPEG_REG(
+                               VIU_VD1_FMT_CTRL + cur_dev->viu_off,
+                               HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
+                               VFORMATTER_RPTLINE0_EN | vini_phase | vphase);
+                               if (!vf_with_el)
+                                       VSYNC_WR_MPEG_REG(
+                                       VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                                       HFORMATTER_RRT_PIXEL0 |
+                                       HFORMATTER_YC_RATIO_2_1 |
+                                       HFORMATTER_EN |
+                                       VFORMATTER_RPTLINE0_EN |
+                                       vini_phase | vphase);
                        } else {
-                       VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL + cur_dev->viu_off,
-                       HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
-                       VFORMATTER_RPTLINE0_EN | vini_phase | vphase |
-                       VFORMATTER_EN);
-
-                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
-                       HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
-                       VFORMATTER_RPTLINE0_EN | vini_phase | vphase |
-                       VFORMATTER_EN);
+                               VSYNC_WR_MPEG_REG(
+                               VIU_VD1_FMT_CTRL + cur_dev->viu_off,
+                               (/*is_dolby_vision_on()*/0 ?/*DEBUG_TMP*/
+                               HFORMATTER_REPEAT : 0) |
+                               HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
+                               VFORMATTER_RPTLINE0_EN | vini_phase | vphase |
+                               vformatter);
+                               if (!vf_with_el)
+                                       VSYNC_WR_MPEG_REG(
+                                       VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                                       HFORMATTER_YC_RATIO_2_1 |
+                                       HFORMATTER_EN |
+                                       VFORMATTER_RPTLINE0_EN |
+                                       vini_phase | vphase |
+                                       vformatter);
                        }
                } else {
-                       VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL + cur_dev->viu_off,
+                       VSYNC_WR_MPEG_REG(
+                               VIU_VD1_FMT_CTRL + cur_dev->viu_off,
+                               (/*is_dolby_vision_on()*/0 ?/*DEBUG_TMP*/
+                               HFORMATTER_REPEAT : 0) |
                                HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
                                VFORMATTER_RPTLINE0_EN |
                                vini_phase | vphase |
-                               VFORMATTER_EN);
-
-                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
-                               HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
-                               VFORMATTER_RPTLINE0_EN | vini_phase | vphase |
-                               VFORMATTER_EN);
+                               vformatter);
+                       if (!vf_with_el)
+                               VSYNC_WR_MPEG_REG(
+                                       VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                                       HFORMATTER_YC_RATIO_2_1 |
+                                       HFORMATTER_EN |
+                                       VFORMATTER_RPTLINE0_EN |
+                                       vini_phase | vphase |
+                                       vformatter);
                }
        } else if (type & VIDTYPE_MVC) {
                VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL + cur_dev->viu_off,
@@ -2661,23 +2897,23 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                                (0xe << VFORMATTER_INIPHASE_BIT) |
                                (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
                                << VFORMATTER_PHASE_BIT) | VFORMATTER_EN);
-               VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+               if (!vf_with_el)
+                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
                                HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
                                VFORMATTER_RPTLINE0_EN | (0xa <<
                                VFORMATTER_INIPHASE_BIT) |
                                (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
                                << VFORMATTER_PHASE_BIT) | VFORMATTER_EN);
        } else if ((type & VIDTYPE_INTERLACE)
-                  &&
-                  (((type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP))) {
+       && (((type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP))) {
                VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL + cur_dev->viu_off,
                                HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
                                VFORMATTER_RPTLINE0_EN | (0xe <<
                                VFORMATTER_INIPHASE_BIT) |
                                (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
                                << VFORMATTER_PHASE_BIT) | VFORMATTER_EN);
-
-               VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+               if (!vf_with_el)
+                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
                                HFORMATTER_YC_RATIO_2_1 |
                                HFORMATTER_EN |
                                VFORMATTER_RPTLINE0_EN |
@@ -2685,15 +2921,33 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                                (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
                                << VFORMATTER_PHASE_BIT) | VFORMATTER_EN);
        } else {
-               VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL + cur_dev->viu_off,
-                                 HFORMATTER_YC_RATIO_2_1 |
-                                 HFORMATTER_EN |
-                                 VFORMATTER_RPTLINE0_EN |
-                                 (0xa << VFORMATTER_INIPHASE_BIT) |
-                                 (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
-                                  << VFORMATTER_PHASE_BIT) | VFORMATTER_EN);
-
-               VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+               if (is_meson_txlx_package_962X()
+               /*&& !is_dolby_vision_stb_mode()*/
+               /*&& is_dolby_vision_on()*/) {/*DEBUG_TMP*/
+                       VSYNC_WR_MPEG_REG(
+                               VIU_VD1_FMT_CTRL + cur_dev->viu_off,
+                               HFORMATTER_REPEAT |
+                               HFORMATTER_YC_RATIO_2_1 |
+                               HFORMATTER_EN |
+                               VFORMATTER_ALWAYS_RPT |
+                               (0 << VFORMATTER_INIPHASE_BIT) |
+                               (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
+                               << VFORMATTER_PHASE_BIT) |
+                               VFORMATTER_EN);
+               } else {
+                       VSYNC_WR_MPEG_REG(
+                               VIU_VD1_FMT_CTRL + cur_dev->viu_off,
+                               (/*is_dolby_vision_on()*/0 ?/*DEBUG_TMP*/
+                               HFORMATTER_REPEAT : 0) |
+                               HFORMATTER_YC_RATIO_2_1 |
+                               HFORMATTER_EN |
+                               VFORMATTER_RPTLINE0_EN |
+                               (0xa << VFORMATTER_INIPHASE_BIT) |
+                               (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
+                               << VFORMATTER_PHASE_BIT) | VFORMATTER_EN);
+               }
+               if (!vf_with_el)
+                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
                                HFORMATTER_YC_RATIO_2_1 |
                                HFORMATTER_EN |
                                VFORMATTER_RPTLINE0_EN |
@@ -2724,13 +2978,10 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                        pat = vpat[frame_par->vscale_skip_count >> 1];
        } else if (type & VIDTYPE_MVC) {
                loop = 0x11;
-               if (/*is_need_framepacking_output()*/0) {
-#if DEBUG_TMP
+               if (is_need_framepacking_output()) {
                        pat = 0;
-#endif
-               } else {
+               } else
                        pat = 0x80;
-               }
        } else if ((type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) {
                loop = 0x11;
                pat <<= 4;
@@ -2742,8 +2993,8 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                        (loop << VDIF_LUMA_LOOP1_BIT) |
                        (loop << VDIF_CHROMA_LOOP0_BIT) |
                        (loop << VDIF_LUMA_LOOP0_BIT));
-
-       VSYNC_WR_MPEG_REG(VD2_IF0_RPT_LOOP,
+       if (!vf_with_el)
+               VSYNC_WR_MPEG_REG(VD2_IF0_RPT_LOOP,
                        (loop << VDIF_CHROMA_LOOP1_BIT) |
                        (loop << VDIF_LUMA_LOOP1_BIT) |
                        (loop << VDIF_CHROMA_LOOP0_BIT) |
@@ -2755,18 +3006,17 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
        VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA1_RPT_PAT + cur_dev->viu_off, pat);
 
        if (type & VIDTYPE_MVC) {
-               if (/*is_need_framepacking_output()*/0) {
-#if DEBUG_TMP
+               if (is_need_framepacking_output())
                        pat = 0;
-#endif
-               } else
+               else
                        pat = 0x88;
        }
-
-       VSYNC_WR_MPEG_REG(VD2_IF0_LUMA0_RPT_PAT, pat);
-       VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA0_RPT_PAT, pat);
-       VSYNC_WR_MPEG_REG(VD2_IF0_LUMA1_RPT_PAT, pat);
-       VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA1_RPT_PAT, pat);
+       if (!vf_with_el) {
+               VSYNC_WR_MPEG_REG(VD2_IF0_LUMA0_RPT_PAT, pat);
+               VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA0_RPT_PAT, pat);
+               VSYNC_WR_MPEG_REG(VD2_IF0_LUMA1_RPT_PAT, pat);
+               VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA1_RPT_PAT, pat);
+       }
 
        if (platform_type == 0) {
                /* picture 0/1 control */
@@ -2790,8 +3040,10 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                        cur_dev->viu_off, 0);
                        VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL +
                        cur_dev->viu_off, 0);
-                       VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL, 0);
-                       VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL, 0);
+                       if (!vf_with_el) {
+                               VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL, 0);
+                               VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL, 0);
+                       }
                }
        } else {
                /* picture 0/1 control */
@@ -2839,39 +3091,46 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
                                (0x01));
                                /* loop pattern */
                        }
+               } else if (process_3d_type & MODE_3D_OUT_FA_MASK) {
+                       /*FA LR/TB output , do nothing*/
                } else {
                        if (frame_par->vpp_2pic_mode & VPP_SELECT_PIC1) {
                                VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL +
                                cur_dev->viu_off, 0);
                                VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL +
                                cur_dev->viu_off, 0);
-                               VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL +
-                               cur_dev->viu_off, 0);
-                               VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL +
-                               cur_dev->viu_off, 0);
+                               if (!vf_with_el) {
+                                       VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL +
+                                       cur_dev->viu_off, 0);
+                                       VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL +
+                                       cur_dev->viu_off, 0);
+                               }
                        } else {
                                VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_PSEL +
                                cur_dev->viu_off, 0);
                                VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_PSEL +
                                cur_dev->viu_off, 0);
-                               VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL, 0);
-                               VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL, 0);
+                               if (!vf_with_el) {
+                                       VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL, 0);
+                                       VSYNC_WR_MPEG_REG(
+                                               VD2_IF0_CHROMA_PSEL, 0);
+                               }
                        }
                }
        }
 }
 
-static void vd2_set_dcu(struct vframe_s *vf)
+static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf)
 {
        u32 r;
        u32 vphase, vini_phase;
        u32 pat, loop;
        static const u32 vpat[] = { 0, 0x8, 0x9, 0xa, 0xb, 0xc };
        u32 u, v;
-       u32 type = vf->type;
+       u32 type = vf->type, bit_mode = 0;
        u32 skip_count = 0;
 
-       pr_info("set dcu for vd2\n");
+       pr_info("set dcu for vd2 %p, type:0x%x\n", vf, type);
        if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) {
                if (type & VIDTYPE_COMPRESS) {
                        r = (3 << 24) |
@@ -2890,6 +3149,8 @@ static void vd2_set_dcu(struct vframe_s *vf)
 #endif
                        if (vf->bitdepth & BITDEPTH_SAVING_MODE)
                                r |= (1<<28); /* mem_saving_mode */
+                       if (type & VIDTYPE_SCATTER)
+                               r |= (1<<29);
                        VSYNC_WR_MPEG_REG(VD2_AFBC_MODE, r);
                        VSYNC_WR_MPEG_REG(VD2_AFBC_ENABLE, 0x1700);
                        VSYNC_WR_MPEG_REG(VD2_AFBC_CONV_CTRL, 0x100);
@@ -2900,36 +3161,91 @@ static void vd2_set_dcu(struct vframe_s *vf)
                                0x80 << (u + 10) |
                                0x80 << v);
                        /* chroma formatter */
+                       /* TODO: afbc setting only cover 420 for now */
 #ifdef TV_REVERSE
                        if (reverse) {
-                               VSYNC_WR_MPEG_REG(VD2_AFBC_VD_CFMT_CTRL,
-                                       /*HFORMATTER_RRT_PIXEL0 |*/
-                                       HFORMATTER_YC_RATIO_2_1 |
-                                       HFORMATTER_EN |
-                                       VFORMATTER_RPTLINE0_EN |
-                                       /*(0xa << VFORMATTER_INIPHASE_BIT) |*/
-                                       (0x8 << VFORMATTER_PHASE_BIT) |
-                                       VFORMATTER_EN);
-                       } else
+                               if (is_meson_txlx_package_962X()
+                               /*&& !is_dolby_vision_stb_mode()*/
+                               /*&& is_dolby_vision_on()*/) {/*DEBUG_TMP*/
+                                       VSYNC_WR_MPEG_REG(
+                                               VD2_AFBC_VD_CFMT_CTRL,
+                                               HFORMATTER_REPEAT |
+                                               HFORMATTER_YC_RATIO_2_1 |
+                                               HFORMATTER_EN |
+                                               VFORMATTER_ALWAYS_RPT |
+                                               (0 << VFORMATTER_INIPHASE_BIT) |
+                                               (0x8 << VFORMATTER_PHASE_BIT) |
+                                               VFORMATTER_EN);
+                               } else
+                                       VSYNC_WR_MPEG_REG(VD2_AFBC_VD_CFMT_CTRL,
+                                       (is_dolby_vision_on() ?
+                                               HFORMATTER_REPEAT :
+                                               HFORMATTER_RRT_PIXEL0) |
+                                               HFORMATTER_YC_RATIO_2_1 |
+                                               HFORMATTER_EN |
+                                               VFORMATTER_RPTLINE0_EN |
+                                       (is_dolby_vision_on() ?
+                                       (0xc << VFORMATTER_INIPHASE_BIT) : 0) |
+                                               (0x8 << VFORMATTER_PHASE_BIT) |
+                                               VFORMATTER_EN);
+                       } else {
 #endif
-                       {
-                               VSYNC_WR_MPEG_REG(VD2_AFBC_VD_CFMT_CTRL,
-                                       HFORMATTER_RRT_PIXEL0 |
+                               if (is_meson_txlx_package_962X()
+                               /*&& !is_dolby_vision_stb_mode()*/
+                               /*&& is_dolby_vision_on()*/) {/*DEBUG_TMP*/
+                                       VSYNC_WR_MPEG_REG(
+                                               VD2_AFBC_VD_CFMT_CTRL,
+                                               HFORMATTER_REPEAT |
+                                               HFORMATTER_YC_RATIO_2_1 |
+                                               HFORMATTER_EN |
+                                               VFORMATTER_ALWAYS_RPT |
+                                               (0 << VFORMATTER_INIPHASE_BIT) |
+                                               (0x8 << VFORMATTER_PHASE_BIT) |
+                                               VFORMATTER_EN);
+                               } else
+                                       VSYNC_WR_MPEG_REG(VD2_AFBC_VD_CFMT_CTRL,
+                                       (is_dolby_vision_on() ?
+                                       HFORMATTER_REPEAT :
+                                       HFORMATTER_RRT_PIXEL0) |
                                        HFORMATTER_YC_RATIO_2_1 |
                                        HFORMATTER_EN |
                                        VFORMATTER_RPTLINE0_EN |
-                                       /*(0xa << VFORMATTER_INIPHASE_BIT) |*/
+                                       (is_dolby_vision_on() ?
+                                       (0xc << VFORMATTER_INIPHASE_BIT) : 0) |
                                        (0x8 << VFORMATTER_PHASE_BIT) |
                                        VFORMATTER_EN);
+#ifdef TV_REVERSE
                        }
+#endif
                        VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL1 +
                                        cur_dev->viu_off, 1, 1, 1);
                        return;
-
                } else {
+                       if ((vf->bitdepth & BITDEPTH_Y10) &&
+                       (!frame_par->nocomp)) {
+                               if (vf->type & VIDTYPE_VIU_444) {
+                                       bit_mode = 2;
+                               } else {
+                                       if (vf->bitdepth & FULL_PACK_422_MODE)
+                                               bit_mode = 3;
+                                       else
+                                               bit_mode = 1;
+                               }
+                       } else {
+                               bit_mode = 0;
+                       }
+                       VSYNC_WR_MPEG_REG_BITS(
+                               VD2_IF0_GEN_REG3,
+                               (bit_mode&0x3), 8, 2);
                        VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL1 +
                                        cur_dev->viu_off, 0, 1, 1);
                        VSYNC_WR_MPEG_REG(VD2_AFBC_ENABLE, 0);
+                       if (type & VIDTYPE_VIU_NV21)
+                               VSYNC_WR_MPEG_REG_BITS(
+                                       VD2_IF0_GEN_REG2, 1, 0, 1);
+                       else
+                               VSYNC_WR_MPEG_REG_BITS(
+                                       VD2_IF0_GEN_REG2, 0, 0, 1);
                }
        }
 
@@ -2978,24 +3294,46 @@ static void vd2_set_dcu(struct vframe_s *vf)
                vphase =
                    ((type & VIDTYPE_VIU_422) ? 0x10 : 0x08) <<
                    VFORMATTER_PHASE_BIT;
-       if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) {
-               if ((vf->width >= 3840) &&
-                       (vf->height >= 2160) &&
-                       (type & VIDTYPE_VIU_422)) {
-
-                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
-                       HFORMATTER_RRT_PIXEL0 | HFORMATTER_YC_RATIO_2_1 |
-                       HFORMATTER_EN | VFORMATTER_RPTLINE0_EN |
-                       vini_phase | vphase);
+               if (is_meson_txlx_package_962X()
+               /*&& !is_dolby_vision_stb_mode()*/
+               /*&& is_dolby_vision_on()*/) {/*DEBUG_TMP*/
+                       VSYNC_WR_MPEG_REG(
+                               VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                               HFORMATTER_REPEAT |
+                               HFORMATTER_YC_RATIO_2_1 |
+                               HFORMATTER_EN |
+                               VFORMATTER_ALWAYS_RPT |
+                               (0 << VFORMATTER_INIPHASE_BIT) |
+                               (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
+                               << VFORMATTER_PHASE_BIT) |
+                               VFORMATTER_EN);
+                       pr_info("\tvd2 set fmt(dovi tv)\n");
+               } else if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() ||
+               is_meson_txlx_cpu()) {
+                       if ((vf->width >= 3840) &&
+                               (vf->height >= 2160) &&
+                               (type & VIDTYPE_VIU_422)) {
+                               VSYNC_WR_MPEG_REG(
+                               VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                               HFORMATTER_RRT_PIXEL0 |
+                               HFORMATTER_YC_RATIO_2_1 |
+                               HFORMATTER_EN | VFORMATTER_RPTLINE0_EN |
+                               vini_phase | vphase);
                        } else {
-                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
-                       HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
-                       VFORMATTER_RPTLINE0_EN | vini_phase | vphase |
-                       VFORMATTER_EN);
+                               VSYNC_WR_MPEG_REG(
+                               VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                               (/*is_dolby_vision_on()*/0 ?/*DEBUG_TMP*/
+                               HFORMATTER_REPEAT : 0) |
+                               HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
+                               VFORMATTER_RPTLINE0_EN |
+                               vini_phase | vphase |
+                               VFORMATTER_EN);
                        }
                } else {
-
-                       VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                       VSYNC_WR_MPEG_REG(
+                               VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                               (/*is_dolby_vision_on()*/0 ?/*DEBUG_TMP*/
+                               HFORMATTER_REPEAT : 0) |
                                HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
                                VFORMATTER_RPTLINE0_EN | vini_phase | vphase |
                                VFORMATTER_EN);
@@ -3023,15 +3361,37 @@ static void vd2_set_dcu(struct vframe_s *vf)
                                VFORMATTER_RPTLINE0_EN |
                                (0xe << VFORMATTER_INIPHASE_BIT) |
                                (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
-                               << VFORMATTER_PHASE_BIT) | VFORMATTER_EN);
+                               << VFORMATTER_PHASE_BIT) |
+                               VFORMATTER_EN);
        } else {
-               VSYNC_WR_MPEG_REG(VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+               if (is_meson_txlx_package_962X()
+               /*&& !is_dolby_vision_stb_mode()*/
+               /*&& is_dolby_vision_on()*/) {/*DEBUG_TMP*/
+                       VSYNC_WR_MPEG_REG(
+                               VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                               HFORMATTER_REPEAT |
+                               HFORMATTER_YC_RATIO_2_1 |
+                               HFORMATTER_EN |
+                               VFORMATTER_ALWAYS_RPT |
+                               (0 << VFORMATTER_INIPHASE_BIT) |
+                               (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
+                               << VFORMATTER_PHASE_BIT) |
+                               VFORMATTER_EN);
+                       pr_info("\tvd2 set fmt(dovi tv)\n");
+               } else {
+                       VSYNC_WR_MPEG_REG(
+                               VIU_VD2_FMT_CTRL + cur_dev->viu_off,
+                               (/*is_dolby_vision_on()*/0 ?/*DEBUG_TMP*/
+                               HFORMATTER_REPEAT : 0) |
                                HFORMATTER_YC_RATIO_2_1 |
                                HFORMATTER_EN |
                                VFORMATTER_RPTLINE0_EN |
-                               (0xa << VFORMATTER_INIPHASE_BIT) |
+                               (0xc << VFORMATTER_INIPHASE_BIT) |
                                (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08)
                                << VFORMATTER_PHASE_BIT) | VFORMATTER_EN);
+                       pr_info("\tvd2 set fmt(dovi:%d)\n",
+                               /*is_dolby_vision_on()*/0);/*DEBUG_TMP*/
+               }
        }
        /* LOOP/SKIP pattern */
        pat = vpat[skip_count];
@@ -3079,12 +3439,20 @@ static void vd2_set_dcu(struct vframe_s *vf)
                /* picture 0/1 control */
                if ((((type & VIDTYPE_INTERLACE) == 0) &&
                         ((type & VIDTYPE_VIU_FIELD) == 0) &&
-                        ((type & VIDTYPE_MVC) == 0))) {
+                        ((type & VIDTYPE_MVC) == 0)) ||
+                       (next_frame_par->vpp_2pic_mode & 0x3)) {
                        /* progressive frame in two pictures */
 
                } else {
-                       VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL, 0);
-                       VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL, 0);
+                       if (next_frame_par->vpp_2pic_mode & VPP_SELECT_PIC1) {
+                               VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL +
+                               cur_dev->viu_off, 0);
+                               VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL +
+                               cur_dev->viu_off, 0);
+                       } else {
+                               VSYNC_WR_MPEG_REG(VD2_IF0_LUMA_PSEL, 0);
+                               VSYNC_WR_MPEG_REG(VD2_IF0_CHROMA_PSEL, 0);
+                       }
                }
        }
 }
@@ -3220,6 +3588,15 @@ static inline bool vpts_expire(struct vframe_s *cur_vf,
        if ((freerun_mode == FREERUN_NODUR) || hdmi_in_onvideo)
                return true;
 
+       if (step_enable) {
+               if (step_flag)
+                       return false;
+               if (!step_flag) {
+                       step_flag = 1;
+                       return true;
+               }
+       }
+
        if ((trickmode_i == 1) || ((trickmode_fffb == 1))) {
                if (((atomic_read(&trickmode_framedone) == 0)
                     || (trickmode_i == 1)) && (!to_notify_trick_wait)
@@ -3251,6 +3628,7 @@ static inline bool vpts_expire(struct vframe_s *cur_vf,
        }
        /* check video PTS discontinuity */
        else if ((enable_video_discontinue_report) &&
+                (first_frame_toggled) &&
                 (abs(systime - pts) > tsync_vpts_discontinuity_margin()) &&
                 ((next_vf->flag & VFRAME_FLAG_NO_DISCONTINUE) == 0)) {
                /*
@@ -3293,12 +3671,14 @@ static inline bool vpts_expire(struct vframe_s *cur_vf,
        if (vsync_pts_inc_upint && (!freerun_mode)) {
                struct vframe_states frame_states;
                u32 delayed_ms, t1, t2;
+
                delayed_ms =
                    calculation_stream_delayed_ms(PTS_TYPE_VIDEO, &t1, &t2);
-               if (vf_get_states(&frame_states) == 0) {
+               if (video_vf_get_states(&frame_states) == 0) {
                        u32 pcr = timestamp_pcrscr_get();
                        u32 vpts = timestamp_vpts_get();
                        u32 diff = pcr - vpts;
+
                        if (delayed_ms > 200) {
                                vsync_freerun++;
                                if (pcr < next_vf->pts
@@ -3375,12 +3755,12 @@ static inline bool vpts_expire(struct vframe_s *cur_vf,
        } else {
                int aud_start = (timestamp_apts_get() != -1);
 
-               if (!av_sync_flag && aud_start && (abs(scr_pts - pts) < 9000)
-                   && ((int)(scr_pts - pts) < 0)) {
-                       av_sync_flag = 1;
-                       pr_info("av sync ok\n");
-               }
-               return ((int)(scr_pts - pts)) >= 0;
+       if (!av_sync_flag && aud_start && (abs(scr_pts - pts) < 9000)
+           && ((int)(scr_pts - pts) < 0)) {
+               av_sync_flag = 1;
+               pr_info("av sync ok\n");
+       }
+       return ((int)(scr_pts - pts)) >= 0;
        }
 #else
        if (smooth_sync_enable) {
@@ -3502,7 +3882,50 @@ void vsync_rdma_process(void)
 static enum vmode_e old_vmode = VMODE_MAX;
 /* #endif */
 static enum vmode_e new_vmode = VMODE_MAX;
-
+static inline bool video_vf_disp_mode_check(struct vframe_s *vf)
+{
+       struct provider_disp_mode_req_s req;
+       //int ret = -1;
+       req.vf = vf;
+       req.disp_mode = 0;
+       req.req_mode = 1;
+#if DEBUG_TMP
+       if (is_dolby_vision_enable()) {
+               ret = vf_notify_provider_by_name("dv_vdin",
+                       VFRAME_EVENT_RECEIVER_DISP_MODE, (void *)&req);
+               if (ret == -1)
+                       vf_notify_provider_by_name("vdin0",
+                               VFRAME_EVENT_RECEIVER_DISP_MODE, (void *)&req);
+       } else
+#endif
+               vf_notify_provider_by_name("vdin0",
+                       VFRAME_EVENT_RECEIVER_DISP_MODE, (void *)&req);
+       if (req.disp_mode == VFRAME_DISP_MODE_OK)
+               return false;
+       /*whether need to check pts??*/
+       video_vf_put(vf);
+       return true;
+}
+static enum vframe_disp_mode_e video_vf_disp_mode_get(struct vframe_s *vf)
+{
+       struct provider_disp_mode_req_s req;
+       //int ret = -1;
+       req.vf = vf;
+       req.disp_mode = 0;
+       req.req_mode = 0;
+#if DEBUG_TMP
+       if (is_dolby_vision_enable()) {
+               ret = vf_notify_provider_by_name("dv_vdin",
+                       VFRAME_EVENT_RECEIVER_DISP_MODE, (void *)&req);
+               if (ret == -1)
+                       vf_notify_provider_by_name("vdin0",
+                               VFRAME_EVENT_RECEIVER_DISP_MODE, (void *)&req);
+       } else
+#endif
+               vf_notify_provider_by_name("vdin0",
+                       VFRAME_EVENT_RECEIVER_DISP_MODE, (void *)&req);
+       return req.disp_mode;
+}
 static inline bool video_vf_dirty_put(struct vframe_s *vf)
 {
        if (!vf->frame_dirty)
@@ -3538,6 +3961,173 @@ static inline bool video_vf_dirty_put(struct vframe_s *vf)
        return true;
 
 }
+
+#if DEBUG_TMP
+struct vframe_s *dolby_vision_toggle_frame(struct vframe_s *vf)
+{
+       struct vframe_s *toggle_vf = NULL;
+       int width_bl, width_el;
+       int height_bl, height_el;
+       int ret = dolby_vision_update_metadata(vf);
+
+       cur_dispbuf2 = dolby_vision_vf_peek_el(vf);
+       if (cur_dispbuf2) {
+               if (cur_dispbuf2->type & VIDTYPE_COMPRESS) {
+                       VSYNC_WR_MPEG_REG(VD2_AFBC_HEAD_BADDR,
+                               cur_dispbuf2->compHeadAddr>>4);
+                       VSYNC_WR_MPEG_REG(VD2_AFBC_BODY_BADDR,
+                               cur_dispbuf2->compBodyAddr>>4);
+               } else {
+                       vframe_canvas_set(&cur_dispbuf2->canvas0_config[0],
+                               cur_dispbuf2->plane_num,
+                               &disp_canvas_index[rdma_canvas_id][3]);
+                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS0 + cur_dev->viu_off,
+                               disp_canvas[rdma_canvas_id][1]);
+                       VSYNC_WR_MPEG_REG(VD2_IF0_CANVAS1 + cur_dev->viu_off,
+                         disp_canvas[rdma_canvas_id][1]);
+               }
+
+               width_el = (cur_dispbuf2->type
+                       & VIDTYPE_COMPRESS) ?
+                       cur_dispbuf2->compWidth :
+                       cur_dispbuf2->width;
+               if (!(cur_dispbuf2->type & VIDTYPE_VD2)) {
+                       width_bl = (vf->type
+                               & VIDTYPE_COMPRESS) ?
+                               vf->compWidth :
+                               vf->width;
+                       if (width_el >= width_bl)
+                               width_el = width_bl;
+                       else if (width_el != width_bl / 2)
+                               width_el = width_bl / 2;
+               }
+               ori2_start_x_lines = 0;
+               ori2_end_x_lines =
+                       width_el - 1;
+
+               height_el = (cur_dispbuf2->type
+                       & VIDTYPE_COMPRESS) ?
+                       cur_dispbuf2->compHeight :
+                       cur_dispbuf2->height;
+               if (!(cur_dispbuf2->type & VIDTYPE_VD2)) {
+                       height_bl =     (vf->type
+                               & VIDTYPE_COMPRESS) ?
+                               vf->compHeight :
+                               vf->height;
+                       if (height_el >= height_bl)
+                               height_el = height_bl;
+                       else if (height_el != height_bl / 2)
+                               height_el = height_bl / 2;
+               }
+               ori2_start_y_lines = 0;
+               ori2_end_y_lines =
+                       height_el - 1;
+       }
+       if (ret == 0) {
+               /* setting generated for this frame */
+               /* or DOVI in bypass mode */
+               toggle_vf = vf;
+               dolby_vision_set_toggle_flag(1);
+       } else {
+               /* fail generating setting for this frame */
+               toggle_vf = NULL;
+               dolby_vision_set_toggle_flag(0);
+       }
+       return toggle_vf;
+}
+#endif
+
+#if DEBUG_TMP
+static int dolby_vision_need_wait(void)
+{
+       struct vframe_s *vf;
+
+       vf = video_vf_peek();
+       if (!vf || (dolby_vision_wait_metadata(vf) == 1))
+               return 1;
+       return 0;
+}
+#endif
+
+/* patch for 4k2k bandwidth issue, skiw mali and vpu mif */
+static void dmc_adjust_for_mali_vpu(unsigned int width, unsigned int height)
+{
+       if (toggle_count == last_toggle_count)
+               toggle_same_count++;
+       else {
+               last_toggle_count = toggle_count;
+               toggle_same_count = 0;
+       }
+       /*avoid 3840x2160 crop*/
+       if ((width >= 2000) && (height >= 1400) &&
+               (dmc_config_state != 1) && (toggle_same_count < 30)) {
+               if (0) {/* if (is_dolby_vision_enable()) { */
+                       /* vpu dmc */
+                       WRITE_DMCREG(
+                               DMC_AM0_CHAN_CTRL,
+                               0x85f403f4);
+                       WRITE_DMCREG(
+                               DMC_AM1_CHAN_CTRL,
+                               0x85f403f4);
+                       WRITE_DMCREG(
+                               DMC_AM2_CHAN_CTRL,
+                               0x85f403f4);
+
+                       /* mali dmc */
+                       WRITE_DMCREG(
+                               DMC_AXI1_CHAN_CTRL,
+                               0xff10ff4);
+                       WRITE_DMCREG(
+                               DMC_AXI2_CHAN_CTRL,
+                               0xff10ff4);
+                       WRITE_DMCREG(
+                               DMC_AXI1_HOLD_CTRL,
+                               0x08040804);
+                       WRITE_DMCREG(
+                               DMC_AXI2_HOLD_CTRL,
+                               0x08040804);
+               } else {
+                       /* mali dmc */
+                       WRITE_DMCREG(
+                               DMC_AXI1_HOLD_CTRL,
+                               0x10080804);
+                       WRITE_DMCREG(
+                               DMC_AXI2_HOLD_CTRL,
+                               0x10080804);
+               }
+               dmc_config_state = 1;
+       } else if (((toggle_same_count >= 30) ||
+               ((width < 2000) && (height < 1400))) &&
+               (dmc_config_state != 2)) {
+               /* vpu dmc */
+               WRITE_DMCREG(
+                       DMC_AM0_CHAN_CTRL,
+                       0x8FF003C4);
+               WRITE_DMCREG(
+                       DMC_AM1_CHAN_CTRL,
+                       0x8FF003C4);
+               WRITE_DMCREG(
+                       DMC_AM2_CHAN_CTRL,
+                       0x8FF003C4);
+
+               /* mali dmc */
+               WRITE_DMCREG(
+                       DMC_AXI1_CHAN_CTRL,
+                       0x8FF00FF4);
+               WRITE_DMCREG(
+                       DMC_AXI2_CHAN_CTRL,
+                       0x8FF00FF4);
+               WRITE_DMCREG(
+                       DMC_AXI1_HOLD_CTRL,
+                       0x18101810);
+               WRITE_DMCREG(
+                       DMC_AXI2_HOLD_CTRL,
+                       0x18101810);
+               toggle_same_count = 30;
+               dmc_config_state = 2;
+       }
+}
+
 #ifdef FIQ_VSYNC
 void vsync_fisr(void)
 #else
@@ -3565,6 +4155,7 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
        int ret;
 #endif
        int video1_off_req = 0;
+       struct vframe_s *cur_dispbuf_back = cur_dispbuf;
 
        if (debug_flag & DEBUG_FLAG_VSYNC_DONONE)
                return IRQ_HANDLED;
@@ -3572,6 +4163,7 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
 #ifdef CONFIG_SUPPORT_VIDEO_ON_VPP2
        const char *dev_id_s = (const char *)dev_id;
        int dev_id_len = strlen(dev_id_s);
+
        if (cur_dev == &video_dev[1]) {
                if (cur_dev_idx == 0) {
                        cur_dev = &video_dev[0];
@@ -3636,6 +4228,18 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
        if (enc_line > vsync_enter_line_max)
                vsync_enter_line_max = enc_line;
 
+       if (is_meson_txlx_cpu() && dmc_adjust) {
+               if (vf)
+                       dmc_adjust_for_mali_vpu(
+                               vf->width, vf->height);
+               else if (cur_dispbuf)
+                       dmc_adjust_for_mali_vpu(
+                               cur_dispbuf->width,
+                               cur_dispbuf->height);
+               else
+                       dmc_adjust_for_mali_vpu(
+                               0, 0);
+       }
 #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
        vsync_rdma_config_pre();
 
@@ -3655,10 +4259,15 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                        enable_rdma_log_count--;
        }
 #endif
-
+#if DEBUG_TMP
+       /* check video frame before VECM process */
+       if (is_dolby_vision_enable() && vf)
+               dolby_vision_check_hdr10(vf);
 #if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM)
        amvecm_on_vs(vf);
 #endif
+#endif
+
 #ifdef CONFIG_TVIN_VDIN
        /* patch for m8 4k2k wifidisplay bandwidth bottleneck */
        if (get_cpu_type() == MESON_CPU_MAJOR_ID_M8) {
@@ -3701,12 +4310,16 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
        if (omx_secret_mode == true) {
                u32 system_time = timestamp_pcrscr_get();
                int diff = system_time - omx_pts;
+
                if ((diff - omx_pts_interval_upper) > 0
                        || (diff - omx_pts_interval_lower) < 0) {
                        timestamp_pcrscr_enable(1);
                        /*pr_info("system_time=%d, omx_pts=%d, diff=%d\n",*/
                        /*system_time, omx_pts, diff);*/
-                       timestamp_pcrscr_set(omx_pts);
+                       /*add  greatest common divisor of duration*/
+                       /*1500(60fps) 3000(30fps) 3750(24fps) for some video*/
+                       /*that pts is not evenly*/
+                       timestamp_pcrscr_set(omx_pts + DURATION_GCD);
                }
        } else
                omx_pts = 0;
@@ -3801,7 +4414,8 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                } else if ((cur_dispbuf == &vf_local)
                           && (video_property_changed)) {
                        if (!(blackout | force_blackout)) {
-                               if ((READ_VCBUS_REG(DI_IF1_GEN_REG) &
+                               if (cur_dispbuf &&
+                                       (VSYNC_RD_MPEG_REG(DI_IF1_GEN_REG) &
                                        0x1) == 0) {
                                        /* setting video display*/
                                        /*property in unregister mode */
@@ -3834,8 +4448,21 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
        if ((!vf) && cur_dispbuf && (video_property_changed))
                vsync_toggle_frame(cur_dispbuf);
 
-       if (!vf)
+       /*debug info for skip & repeate vframe case*/
+       if (!vf) {
                underflow++;
+               if (video_dbg_vf&(1<<0))
+                       dump_vframe_status("vdin0");
+               if (video_dbg_vf&(1<<1))
+                       dump_vframe_status("deinterlace");
+               if (video_dbg_vf&(1<<2))
+                       dump_vframe_status("amlvideo2");
+               if (video_dbg_vf&(1<<3))
+                       dump_vframe_status("ppmgr");
+               if (video_dbg_vf&(1<<4))
+                       dump_vdin_reg();
+       }
+       video_get_vf_cnt = 0;
        if (platform_type == 1) {
                /* toggle_3d_fa_frame*/
                /* determine the out frame is L or R or blank */
@@ -3854,22 +4481,39 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                                      "skipped\n");
 
 #if DEBUG_TMP
-                       if (is_dolby_vision_enable()) {
-                               ret = dolby_vision_wait_metadata(vf);
-                               if (ret == 2)
-                                       break;
-                       }
-#endif
 
 #if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM)
                        refresh_on_vs(vf);
 #endif
 
+                       if (is_dolby_vision_enable()
+                       && dolby_vision_need_wait())
+                               break;
+#endif
+                       /*
+                        *two special case:
+                        *case1:4k display case,input buffer not enough &
+                        *      quickly for display
+                        *case2:input buffer all not OK
+                        */
+                       if (vf && hdmiin_frame_check &&
+                               (vf->source_type == VFRAME_SOURCE_TYPE_HDMI) &&
+                               (video_vf_disp_mode_get(vf) !=
+                               VFRAME_DISP_MODE_OK) &&
+                               (hdmiin_frame_check_cnt++ < 10))
+                               break;
+
+                       hdmiin_frame_check_cnt = 0;
+
                        vf = video_vf_get();
                        if (!vf)
                                break;
                        if (video_vf_dirty_put(vf))
                                break;
+                       if (vf && hdmiin_frame_check && (vf->source_type ==
+                               VFRAME_SOURCE_TYPE_HDMI) &&
+                               video_vf_disp_mode_check(vf))
+                               break;
                        force_blackout = 0;
                        if ((platform_type == 1) ||
                        (platform_type == 0)) {
@@ -3885,43 +4529,9 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                        }
                        vsync_toggle_frame(vf);
 #if DEBUG_TMP
-                       if (is_dolby_vision_enable()) {
-                               ret = dolby_vision_update_metadata(vf);
-                               cur_dispbuf2 = dolby_vision_vf_peek_el(vf);
-                               if (cur_dispbuf2) {
-                                       VSYNC_WR_MPEG_REG(VD2_AFBC_HEAD_BADDR,
-                                               cur_dispbuf2->compHeadAddr>>4);
-                                       VSYNC_WR_MPEG_REG(VD2_AFBC_BODY_BADDR,
-                                               cur_dispbuf2->compBodyAddr>>4);
-                                       ori2_start_x_lines = 0;
-                                       ori2_end_x_lines =
-                                               ((cur_dispbuf2->type
-                                               & VIDTYPE_COMPRESS) ?
-                                               cur_dispbuf2->compWidth :
-                                               cur_dispbuf2->width) - 1;
-                                       ori2_start_y_lines = 0;
-                                       ori2_end_y_lines =
-                                               ((cur_dispbuf2->type
-                                               & VIDTYPE_COMPRESS) ?
-                                               cur_dispbuf2->compHeight :
-                                               cur_dispbuf2->height) - 1;
-                               }
-                               if (ret == 0) {
-                                       toggle_vf = vf;
-                                       dolby_vision_set_toggle_flag(1);
-                               } else if (ret == -1) {
-                                       /* not enough meta, wait */
-                                       toggle_vf = NULL;
-                                       dolby_vision_set_toggle_flag(0);
-                                       break;
-                               } else if (ret == -2) {
-                                       /* no meta, mostly SDR */
-                                       toggle_vf = NULL;
-                                       dolby_vision_set_toggle_flag(1);
-                                       dolby_vision_process(toggle_vf);
-                                       break;
-                               }
-                       } else
+                       if (is_dolby_vision_enable())
+                               toggle_vf = dolby_vision_toggle_frame(vf);
+                       else
 #endif
                                cur_dispbuf2 = NULL;
 
@@ -3947,20 +4557,27 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                        vf = video_vf_peek();
                        if (!vf)
                                next_peek_underflow++;
-
+#if DEBUG_TMP
+                       if (for_dolby_vision_certification()
+                       && toggle_vf)
+                               break;
+#endif
                        if (debug_flag & DEBUG_FLAG_TOGGLE_FRAME_PER_VSYNC)
                                break;
+                       video_get_vf_cnt++;
+                       if (video_get_vf_cnt >= 2)
+                               video_drop_vf_cnt++;
                } else {
                        /* check if current frame's duration has expired,
-                       *in this example
-                       * it compares current frame display duration
-                       * with 1/1/1/1.5 frame duration
-                       * every 4 frames there will be one frame play
-                       * longer than usual.
-                       * you can adjust this array for any slow sync
-                       * control as you want.
-                       * The playback can be smoother than previous method.
-                       */
+                        *in this example
+                        * it compares current frame display duration
+                        * with 1/1/1/1.5 frame duration
+                        * every 4 frames there will be one frame play
+                        * longer than usual.
+                        * you can adjust this array for any slow sync
+                        * control as you want.
+                        * The playback can be smoother than previous method.
+                        */
                        if (slowsync_repeat_enable) {
                                if (duration_expire
                                    (cur_dispbuf, vf,
@@ -3973,10 +4590,22 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                                        "sys.time = 0x%x, video time = 0x%x\n",
                                        timestamp_pcrscr_get(),
                                        timestamp_vpts_get());
+#if DEBUG_TMP
+                                       if (is_dolby_vision_enable()
+                                       && dolby_vision_need_wait())
+                                               break;
+#endif
                                        vf = video_vf_get();
                                        if (!vf)
                                                break;
                                        vsync_toggle_frame(vf);
+#if DEBUG_TMP
+                                       if (is_dolby_vision_enable())
+                                               toggle_vf =
+                                               dolby_vision_toggle_frame(vf);
+                                       else
+#endif
+                                               cur_dispbuf2 = NULL;
                                        frame_repeat_count = 0;
 
                                        vf = video_vf_peek();
@@ -4013,10 +4642,6 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                toggle_cnt++;
 #endif
        }
-#if DEBUG_TMP
-       if (toggle_vf && is_dolby_vision_enable())
-               dolby_vision_process(toggle_vf);
-#endif
 
 #ifdef INTERLACE_FIELD_MATCH_PROCESS
        if (interlace_field_type_need_match(vout_type, vf)) {
@@ -4030,7 +4655,19 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                field_matching_count = 0;
 #endif
 
- SET_FILTER:
+SET_FILTER:
+#if DEBUG_TMP
+       if (is_dolby_vision_enable()) {
+               u32 skip_mode = 0;
+
+               if (cur_frame_par)
+                       skip_mode =
+                       (cur_frame_par->hscale_skip_count << 16)
+                       | cur_frame_par->vscale_skip_count;
+               dolby_vision_process(toggle_vf, skip_mode);
+               dolby_vision_update_setting();
+       }
+#endif
        /* filter setting management */
        if ((frame_par_ready_to_set) || (frame_par_force_to_set)) {
                cur_frame_par = next_frame_par;
@@ -4042,19 +4679,26 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                        frame_par_force_to_set = 1;
                }
        }
+       if (cur_dispbuf_back != cur_dispbuf) {
+               display_frame_count++;
+               drop_frame_count = receive_frame_count - display_frame_count;
+       }
        if (cur_dispbuf) {
                struct f2v_vphase_s *vphase;
                u32 vin_type = cur_dispbuf->type & VIDTYPE_TYPEMASK;
                {
                        int need_afbc = (cur_dispbuf->type & VIDTYPE_COMPRESS);
-                       int afbc_need_reset = video_enabled && need_afbc &&
-                       (!(READ_VCBUS_REG(AFBC_ENABLE) & 0x100));
+                       int afbc_need_reset =
+                               video_enabled &&
+                               need_afbc &&
+                               (!(READ_VCBUS_REG(AFBC_ENABLE) & 0x100));
                        /*video on && afbc is off && is compress frame.*/
-                       if (frame_par_ready_to_set || afbc_need_reset)
+                       if (frame_par_ready_to_set || afbc_need_reset) {
                                viu_set_dcu(cur_frame_par, cur_dispbuf);
-                       if ((cur_dispbuf2)
-                               && (frame_par_ready_to_set || afbc_need_reset))
-                               vd2_set_dcu(cur_dispbuf2);
+                               if (cur_dispbuf2)
+                                       vd2_set_dcu(cur_frame_par,
+                                               cur_dispbuf2);
+                       }
                }
                {
 #if 0
@@ -4075,7 +4719,8 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
 
                if (platform_type == 1) {
                        if ((cur_frame_par->hscale_skip_count)
-                               && (cur_dispbuf->type & VIDTYPE_VIU_FIELD)) {
+                               && cur_dispbuf &&
+                               (cur_dispbuf->type & VIDTYPE_VIU_FIELD)) {
                                VSYNC_WR_MPEG_REG_BITS(VIU_VD1_FMT_CTRL +
                                        cur_dev->viu_off, 0, 20, 1);
                                /* HFORMATTER_EN */
@@ -4148,30 +4793,30 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
                                        cur_dev->viu_off, 0x4000000);
                                }
 /*
-VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
-cur_dev->vpp_off,1,15,1);//VPP_VD2_PREBLEND enable
-//VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
-cur_dev->vpp_off,1,11,1);//VPP_VD2_POSTBLEND enable
-VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
-cur_dev->vpp_off,1,6,1);//PREBLEND enable must be set!
-VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
-cur_dev->vpp_off,0x1ff,
-VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
-*/
+ *VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
+ *cur_dev->vpp_off,1,15,1);//VPP_VD2_PREBLEND enable
+ *VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
+ *cur_dev->vpp_off,1,11,1);//VPP_VD2_POSTBLEND enable
+ *VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
+ *cur_dev->vpp_off,1,6,1);//PREBLEND enable must be set!
+ *VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
+ *cur_dev->vpp_off,0x1ff,
+ *VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
+ */
                        }
 
 /*
-else{
-VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
-cur_dev->vpp_off,0,15,1);//VPP_VD2_PREBLEND enable
-//VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
-cur_dev->vpp_off,1,11,1);//VPP_VD2_POSTBLEND enable
-VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
-cur_dev->vpp_off,0,6,1);//PREBLEND enable
-VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
-cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
-}
-*/
+ *else{
+ *VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
+ *cur_dev->vpp_off,0,15,1);//VPP_VD2_PREBLEND enable
+ *VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
+ *cur_dev->vpp_off,1,11,1);//VPP_VD2_POSTBLEND enable
+ *VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
+ *cur_dev->vpp_off,0,6,1);//PREBLEND enable
+ *VSYNC_WR_MPEG_REG_BITS(VPP_MISC +
+ *cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
+ *}
+ */
                }
                        /* vertical phase */
                        vphase =
@@ -4257,15 +4902,12 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                                        zoom_end_y =
                                        cur_frame_par->VPP_vd_end_lines_;
                                } else {
-                                       //if (is_need_framepacking_output()) {
-                                       if (0) {
-#if DEBUG_TMP
+                                       if (is_need_framepacking_output()) {
                                                zoom_start_y =
        cur_frame_par->VPP_vd_start_lines_ >> 1;
                                                zoom_end_y =
        ((cur_frame_par->VPP_vd_end_lines_
        - framepacking_blank + 1) >> 1) - 1;
-#endif
                                        } else {
                                                zoom_start_y =
        cur_frame_par->VPP_vd_start_lines_ >> 1;
@@ -4283,7 +4925,6 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                        zoom_start_y_lines = zoom_start_y;
                        zoom_end_y_lines = zoom_end_y;
                        zoom_display_vert();
-
 #if DEBUG_TMP
                        if (is_dolby_vision_enable() && cur_dispbuf2) {
                                zoom2_start_x_lines = ori2_start_x_lines;
@@ -4308,27 +4949,35 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                                cur_frame_par->spsc1_w_in,
                                cur_frame_par->spsc1_h_in,
                                cur_frame_par->supsc1_hori_ratio,
-                               cur_frame_par->supsc1_vert_ratio);
+                               cur_frame_par->supsc1_vert_ratio,
+                               cur_frame_par->vpp_postblend_out_width,
+                               cur_frame_par->vpp_postblend_out_height);
 
                /* vpp filters */
                /* SET_MPEG_REG_MASK(VPP_SC_MISC + cur_dev->vpp_off, */
                /* VPP_SC_TOP_EN | VPP_SC_VERT_EN | VPP_SC_HORZ_EN); */
-               VSYNC_WR_MPEG_REG(VPP_SC_MISC + cur_dev->vpp_off,
+               if (/*for_dolby_vision_certification()*/0) {/*DEBUG_TMP*/
+                       /* turn off PPS for Dolby Vision certification */
+                       VSYNC_WR_MPEG_REG_BITS(VPP_SC_MISC + cur_dev->vpp_off,
+                               0, VPP_SC_TOP_EN_BIT, VPP_SC_TOP_EN_WID);
+               } else {
+                       VSYNC_WR_MPEG_REG(VPP_SC_MISC + cur_dev->vpp_off,
                                  READ_VCBUS_REG(VPP_SC_MISC +
                                                 cur_dev->vpp_off) |
                                  VPP_SC_TOP_EN | VPP_SC_VERT_EN |
                                  VPP_SC_HORZ_EN);
 
-               /* pps pre hsc&vsc en */
-               VSYNC_WR_MPEG_REG_BITS(VPP_SC_MISC + cur_dev->vpp_off,
-                       vpp_filter->vpp_pre_hsc_en,
-                       VPP_SC_PREHORZ_EN_BIT, 1);
-               VSYNC_WR_MPEG_REG_BITS(VPP_SC_MISC + cur_dev->vpp_off,
-                       vpp_filter->vpp_pre_vsc_en,
-                       VPP_SC_PREVERT_EN_BIT, 1);
-               VSYNC_WR_MPEG_REG_BITS(VPP_SC_MISC + cur_dev->vpp_off,
-                       vpp_filter->vpp_pre_vsc_en,
-                       VPP_LINE_BUFFER_EN_BIT, 1);
+                       /* pps pre hsc&vsc en */
+                       VSYNC_WR_MPEG_REG_BITS(VPP_SC_MISC + cur_dev->vpp_off,
+                               vpp_filter->vpp_pre_hsc_en,
+                               VPP_SC_PREHORZ_EN_BIT, 1);
+                       VSYNC_WR_MPEG_REG_BITS(VPP_SC_MISC + cur_dev->vpp_off,
+                               vpp_filter->vpp_pre_vsc_en,
+                               VPP_SC_PREVERT_EN_BIT, 1);
+                       VSYNC_WR_MPEG_REG_BITS(VPP_SC_MISC + cur_dev->vpp_off,
+                               vpp_filter->vpp_pre_vsc_en,
+                               VPP_LINE_BUFFER_EN_BIT, 1);
+               }
                /* for bypass pps debug */
                if ((vpp_filter->vpp_hsc_start_phase_step == 0x1000000) &&
                        (vpp_filter->vpp_vsc_start_phase_step == 0x1000000) &&
@@ -4395,6 +5044,7 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                /* vertical chroma filter settings */
                if (vpp_filter->vpp_vert_chroma_filter_en) {
                        const u32 *pCoeff = vpp_filter->vpp_vert_chroma_coeff;
+
                        VSYNC_WR_MPEG_REG(
                                VPP_SCALE_COEF_IDX + cur_dev->vpp_off,
                                VPP_COEF_VERT_CHROMA|VPP_COEF_SEP_EN);
@@ -4417,19 +5067,16 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                                (cur_frame_par->vscale_skip_count + 1);
                                if (cur_dispbuf->type & VIDTYPE_MVC)
                                        cur_frame_par->VPP_pic_in_height_ *= 2;
-                               if (/*is_need_framepacking_output()*/0) {
-#if DEBUG_TMP
+                               if (is_need_framepacking_output()) {
                                        cur_frame_par->VPP_pic_in_height_ +=
                                        framepacking_blank;
-#endif
                                }
                                cur_frame_par->VPP_line_in_length_ =
                                (zoom_end_x_lines - zoom_start_x_lines + 1) /
                                (cur_frame_par->hscale_skip_count + 1);
                        }
                }
-               if ((is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) &&
-                       cur_dispbuf) {
+               if (super_scaler && cur_dispbuf) {
                        if (cur_dispbuf->type & VIDTYPE_INTERLACE) {
                                cur_frame_par->VPP_pic_in_height_ =
                                (zoom_end_y_lines - zoom_start_y_lines + 1)  <<
@@ -4444,11 +5091,9 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                                cur_frame_par->supsc0_vert_ratio;
                                if (cur_dispbuf->type & VIDTYPE_MVC)
                                        cur_frame_par->VPP_pic_in_height_ *= 2;
-                               if (/*is_need_framepacking_output()*/0) {
-#if DEBUG_TMP
+                               if (is_need_framepacking_output()) {
                                        cur_frame_par->VPP_pic_in_height_ +=
                                        framepacking_blank;
-#endif
                                }
                                cur_frame_par->VPP_line_in_length_ =
                                ((zoom_end_x_lines - zoom_start_x_lines + 1) /
@@ -4518,6 +5163,12 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
        /* VPP one time settings */
        wait_sync = 0;
 
+       if (vinfo && VSYNC_RD_MPEG_REG(
+               VPP_POSTBLEND_H_SIZE + cur_dev->vpp_off)
+               != vinfo->width)
+               VSYNC_WR_MPEG_REG(
+                       VPP_POSTBLEND_H_SIZE + cur_dev->vpp_off,
+                       vinfo->width);
        if (cur_dispbuf && cur_dispbuf->process_fun) {
                /* for new deinterlace driver */
 #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
@@ -4538,7 +5189,10 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
        vpp_misc_save = READ_VCBUS_REG(VPP_MISC + cur_dev->vpp_off);
        vpp_misc_set = vpp_misc_save;
 #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
-       vpp_misc_set |= VPP_CM_ENABLE;
+       if (!0/*is_dolby_vision_on()*/)/*DEBUG_TMP*/
+               vpp_misc_set |= VPP_CM_ENABLE;
+       else
+               vpp_misc_set &= ~VPP_CM_ENABLE;
 #endif
        if (update_osd_vpp_misc) {
                vpp_misc_set &= ~osd_vpp_misc_mask;
@@ -4550,10 +5204,16 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
        }
        if ((video_enabled == 1) && ((vpp_misc_save & VPP_VD1_POSTBLEND) == 0)
        && (video_onoff_state == VIDEO_ENABLE_STATE_IDLE)) {
-               SET_VCBUS_REG_MASK(VPP_MISC + cur_dev->vpp_off,
-                               VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND
-                                  | VPP_POSTBLEND_EN);
-               pr_info("VPP_VD1_POSTBLEND register rdma write fail!");
+               /*
+                *SET_VCBUS_REG_MASK(VPP_MISC + cur_dev->vpp_off,
+                *      VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND
+                *      | VPP_POSTBLEND_EN);
+                *pr_info("VPP_VD1_POSTBLEND register rdma write fail!");
+                */
+               vpp_misc_set |=
+                       VPP_VD1_PREBLEND |
+                       VPP_VD1_POSTBLEND |
+                       VPP_POSTBLEND_EN;
        }
        if ((video_enabled == 1) && cur_frame_par
        && (cur_dispbuf != &vf_local) && (first_set == 0)
@@ -4579,9 +5239,9 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
 
                if (video_onoff_state == VIDEO_ENABLE_STATE_ON_REQ) {
                        /*
-                       * the video layer is enabled one vsync later,assumming
-                       * all registers are ready from RDMA.
-                       */
+                        * the video layer is enabled one vsync later,assumming
+                        * all registers are ready from RDMA.
+                        */
                        video_onoff_state = VIDEO_ENABLE_STATE_ON_PENDING;
                } else if (video_onoff_state ==
                                VIDEO_ENABLE_STATE_ON_PENDING) {
@@ -4642,6 +5302,16 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                spin_unlock_irqrestore(&video_onoff_lock, flags);
        }
 
+       if (video_global_output == 0) {
+               video_enabled = 0;
+               vpp_misc_set &= ~(VPP_VD1_PREBLEND |
+                               VPP_VD2_PREBLEND |
+                               VPP_VD2_POSTBLEND |
+                               VPP_VD1_POSTBLEND);
+       } else {
+               video_enabled = video_status_saved;
+       }
+
        if (likely(video2_onoff_state != VIDEO_ENABLE_STATE_IDLE)) {
                /* state change for video layer2 enable/disable */
 
@@ -4661,8 +5331,10 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                                           VPP_PREBLEND_EN | VPP_VD2_PREBLEND |
                                           (0x1ff << VPP_VD2_ALPHA_BIT));
 #else
-                       vpp_misc_set |= VPP_PREBLEND_EN | VPP_VD2_PREBLEND |
-                                       (0x1ff << VPP_VD2_ALPHA_BIT);
+                       if (!0/*is_dolby_vision_on()*/) /*DEBUG_TMP*/
+                               vpp_misc_set |=
+                                       VPP_PREBLEND_EN | VPP_VD2_PREBLEND;
+                       vpp_misc_set |= (0x1ff << VPP_VD2_ALPHA_BIT);
 #endif
                        video2_onoff_state = VIDEO_ENABLE_STATE_IDLE;
 
@@ -4702,8 +5374,18 @@ cur_dev->vpp_off,0,VPP_VD2_ALPHA_BIT,9);//vd2 alpha must set
                spin_unlock_irqrestore(&video2_onoff_lock, flags);
        }
 
+#if 0 //DEBUG_TMP
+       if (is_dolby_vision_on()
+               && (dolby_first_delay > 0)
+               && (vpp_misc_set & VPP_VD1_POSTBLEND)) {
+               vpp_misc_set &=
+                       ~(VPP_VD1_PREBLEND | VPP_VD1_POSTBLEND);
+               dolby_first_delay--;
+       }
+#endif
        if (vpp_misc_save != vpp_misc_set) {
-               VSYNC_WR_MPEG_REG(VPP_MISC + cur_dev->vpp_off,
+               VSYNC_WR_MPEG_REG(
+                       VPP_MISC + cur_dev->vpp_off,
                        vpp_misc_set);
        }
        /*vpp_misc_set maybe have same,but need off.*/
@@ -4816,6 +5498,7 @@ static void vsync_fiq_down(void)
 static void vsync2_fiq_up(void)
 {
        int r;
+
        r = request_irq(INT_VIU2_VSYNC, &vsync_isr,
                        IRQF_SHARED, "vsync", (void *)video_dev_id2);
 }
@@ -4873,6 +5556,7 @@ static void video_vf_unreg_provider(void)
        ulong flags;
 
        new_frame_count = 0;
+       first_frame_toggled = 0;
 
        atomic_set(&video_unreg_flag, 1);
        spin_lock_irqsave(&lock, flags);
@@ -4890,7 +5574,10 @@ static void video_vf_unreg_provider(void)
                cur_dispbuf = &vf_local;
                cur_dispbuf->video_angle = 0;
        }
-
+#if DEBUG_TMP
+       if (is_dolby_vision_enable())
+               cur_dispbuf2 = NULL;
+#endif
        if (trickmode_fffb) {
                atomic_set(&trickmode_framedone, 0);
                to_notify_trick_wait = false;
@@ -5004,8 +5691,6 @@ static int  get_display_info(void *data)
 
 static int video_receiver_event_fun(int type, void *data, void *private_data)
 {
-       char *configured[2];
-       char framerate[20] = {0};
 #ifdef CONFIG_AM_VIDEO2
        char *provider_name;
 #endif
@@ -5014,12 +5699,18 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
 #ifdef CONFIG_AM_VIDEO2
                set_clone_frame_rate(android_clone_rate, 200);
 #endif
+               drop_frame_count = 0;
+               receive_frame_count = 0;
+               display_frame_count = 0;
        } else if (type == VFRAME_EVENT_PROVIDER_RESET) {
                video_vf_light_unreg_provider();
        } else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG)
                video_vf_light_unreg_provider();
        else if (type == VFRAME_EVENT_PROVIDER_REG) {
                enable_video_discontinue_report = 1;
+               drop_frame_count = 0;
+               receive_frame_count = 0;
+               display_frame_count = 0;
 #ifdef CONFIG_AM_VIDEO2
                provider_name = (char *)data;
                if (strncmp(provider_name, "decoder", 7) == 0
@@ -5049,31 +5740,13 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                }
        } else if (type == VFRAME_EVENT_PROVIDER_FR_HINT) {
 #ifdef CONFIG_AM_VOUT
-               if (data != NULL) {
-                       if (video_seek_flag == 0) {
-                               /*set_vframe_rate_hint((unsigned long)(data));*/
-                               sprintf(framerate, "FRAME_RATE_HINT=%lu",
-                                               (unsigned long)data);
-                               configured[0] = framerate;
-                               configured[1] = NULL;
-                               kobject_uevent_env(&(amvideo_dev->kobj),
-                                               KOBJ_CHANGE, configured);
-                               pr_info("%s: sent uevent %s\n",
-                                       __func__, configured[0]);
-                       }
-               }
+               if ((data != NULL) && (video_seek_flag == 0))
+                       set_vframe_rate_hint((unsigned long)data);
 #endif
        } else if (type == VFRAME_EVENT_PROVIDER_FR_END_HINT) {
 #ifdef CONFIG_AM_VOUT
-               if (video_seek_flag == 0) {
-                       configured[0] = "FRAME_RATE_END_HINT";
-                       configured[1] = NULL;
-                       /*set_vframe_rate_end_hint();*/
-                       kobject_uevent_env(&(amvideo_dev->kobj),
-                                       KOBJ_CHANGE, configured);
-                       pr_info("%s: sent uevent %s\n",
-                               __func__, configured[0]);
-               }
+               if (video_seek_flag == 0)
+                       set_vframe_rate_end_hint();
 #endif
        } else if (type == VFRAME_EVENT_PROVIDER_QUREY_DISPLAY_INFO) {
                get_display_info(data);
@@ -5157,9 +5830,16 @@ int _video_set_disable(u32 val)
 
 static void _set_video_crop(int *p)
 {
-       vpp_set_video_source_crop(p[0], p[1], p[2], p[3]);
+       int last_l, last_r, last_t, last_b;
+       int new_l, new_r, new_t, new_b;
 
-       video_property_changed = true;
+       vpp_get_video_source_crop(&last_t, &last_l, &last_b, &last_r);
+       vpp_set_video_source_crop(p[0], p[1], p[2], p[3]);
+       vpp_get_video_source_crop(&new_t, &new_l, &new_b, &new_r);
+       if ((new_t != last_t) || (new_l != last_l)
+       || (new_b != last_b) || (new_r != last_r)) {
+               video_property_changed = true;
+       }
 }
 
 static void _set_video_window(int *p)
@@ -5271,6 +5951,7 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
        switch (cmd) {
        case AMSTREAM_IOC_SET_OMX_VPTS:{
                        u32 pts;
+
                        get_user(pts, (u32 __user *)argp);
                        omx_pts = pts;
                }
@@ -5354,7 +6035,8 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
        case AMSTREAM_IOC_VF_STATUS:{
                        struct vframe_states vfsta;
                        struct vframe_states states;
-                       vf_get_states(&vfsta);
+
+                       video_vf_get_states(&vfsta);
                        states.vf_pool_size = vfsta.vf_pool_size;
                        states.buf_avail_num = vfsta.buf_avail_num;
                        states.buf_free_num = vfsta.buf_free_num;
@@ -5368,9 +6050,14 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
                put_user(disable_video, (u32 __user *)argp);
                break;
 
-       case AMSTREAM_IOC_SET_VIDEO_DISABLE:
-               ret = _video_set_disable(arg);
-               break;
+       case AMSTREAM_IOC_SET_VIDEO_DISABLE:{
+               u32 val;
+
+               if (copy_from_user(&val, argp, sizeof(u32)) == 0)
+                       ret = _video_set_disable(val);
+               else
+                       ret = -EFAULT;
+       }
 
        case AMSTREAM_IOC_GET_VIDEO_DISCONTINUE_REPORT:
                put_user(enable_video_discontinue_report, (u32 __user *)argp);
@@ -5407,6 +6094,7 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
 
        case AMSTREAM_IOC_SET_VIDEO_AXIS:{
                        int axis[4];
+
                        if (copy_from_user(axis, argp, sizeof(axis)) == 0)
                                _set_video_window(axis);
                        else
@@ -5428,6 +6116,7 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
 
        case AMSTREAM_IOC_SET_VIDEO_CROP:{
                        int crop[4];
+
                        if (copy_from_user(crop, argp, sizeof(crop)) == 0)
                                _set_video_crop(crop);
                        else
@@ -5442,6 +6131,7 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
 
        case AMSTREAM_IOC_SET_SCREEN_MODE:{
                        u32 mode;
+
                        if (copy_from_user(&mode, argp, sizeof(u32)) == 0) {
                                if (mode >= VIDEO_WIDEOPTION_MAX)
                                        ret = -EINVAL;
@@ -5461,6 +6151,7 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
 
        case AMSTREAM_IOC_SET_BLACKOUT_POLICY:{
                        u32 mode;
+
                        if (copy_from_user(&mode, argp, sizeof(u32)) == 0) {
                                if (mode > 2)
                                        ret = -EINVAL;
@@ -5473,6 +6164,7 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
 
        case AMSTREAM_IOC_CLEAR_VBUF:{
                        unsigned long flags;
+
                        spin_lock_irqsave(&lock, flags);
                        cur_dispbuf = NULL;
                        spin_unlock_irqrestore(&lock, flags);
@@ -5512,13 +6204,15 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
                        unsigned int set_3d =
                                VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE;
                        unsigned int type = (unsigned int)arg;
+
                        if (type != process_3d_type) {
                                process_3d_type = type;
                                if (mvc_flag)
                                        process_3d_type |= MODE_3D_MVC;
                                video_property_changed = true;
                                if ((process_3d_type & MODE_3D_FA)
-                                               && !cur_dispbuf->trans_fmt)
+                                       && cur_dispbuf
+                                       && !cur_dispbuf->trans_fmt)
                                        /*notify di 3d mode is frame*/
                                          /*alternative mode,passing two*/
                                          /*buffer in one frame */
@@ -5545,14 +6239,13 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
 #ifdef TV_3D_FUNCTION_OPEN
        {
                int source_video_3d_type = VPP_3D_MODE_NULL;
+
                if (!cur_frame_par)
                        source_video_3d_type =
                VPP_3D_MODE_NULL;
-#if DEBUG_TMP
                else
                        get_vpp_3d_mode(process_3d_type,
                        cur_frame_par->trans_fmt, &source_video_3d_type);
-#endif
                put_user(source_video_3d_type, (u32 __user *)argp);
        }
 #endif
@@ -5569,6 +6262,17 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg)
                vsync_slow_factor = arg;
                break;
 
+       case AMSTREAM_IOC_GLOBAL_SET_VIDEO_OUTPUT:
+               if (arg != 0)
+                       video_global_output = 1;
+               else
+                       video_global_output = 0;
+               break;
+
+       case AMSTREAM_IOC_GLOBAL_GET_VIDEO_OUTPUT:
+               put_user(video_global_output, (u32 __user *)argp);
+               break;
+
        default:
                return -EINVAL;
        }
@@ -5605,6 +6309,7 @@ static long amvideo_compat_ioctl(struct file *file, unsigned int cmd, ulong arg)
        case AMSTREAM_IOC_GET_3D_TYPE:
        case AMSTREAM_IOC_GET_SOURCE_VIDEO_3D_TYPE:
        case AMSTREAM_IOC_GET_VSYNC_SLOW_FACTOR:
+       case AMSTREAM_IOC_GLOBAL_GET_VIDEO_OUTPUT:
                arg = (unsigned long) compat_ptr(arg);
        case AMSTREAM_IOC_TRICKMODE:
        case AMSTREAM_IOC_VPAUSE:
@@ -5624,6 +6329,7 @@ static long amvideo_compat_ioctl(struct file *file, unsigned int cmd, ulong arg)
        case AMSTREAM_IOC_SET_3D_TYPE:
        case AMSTREAM_IOC_SET_VSYNC_UPINT:
        case AMSTREAM_IOC_SET_VSYNC_SLOW_FACTOR:
+       case AMSTREAM_IOC_GLOBAL_SET_VIDEO_OUTPUT:
                return amvideo_ioctl(file, cmd, arg);
        default:
                return -EINVAL;
@@ -5799,6 +6505,7 @@ static ssize_t video_state_show(struct class *cla,
 {
        ssize_t len = 0;
        struct vppfilter_mode_s *vpp_filter = NULL;
+
        if (!cur_frame_par)
                return len;
        vpp_filter = &cur_frame_par->vpp_filter;
@@ -5921,6 +6628,7 @@ static ssize_t video_global_offset_show(struct class *cla,
                        struct class_attribute *attr, char *buf)
 {
        int x, y;
+
        vpp_get_global_offset(&x, &y);
 
        return snprintf(buf, 40, "%d %d\n", x, y);
@@ -6396,7 +7104,18 @@ static u32 eight2ten(u32 yuv)
        int y = (yuv >> 16) & 0xff;
        int cb = (yuv >> 8) & 0xff;
        int cr = yuv & 0xff;
-       return  (y << 20) | (cb << 10) | cr;
+       u32 data32;
+
+       /* txlx need check vd1 path bit width by s2u registers */
+       if (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX) {
+               data32 = READ_VCBUS_REG(0x1d94) & 0xffff;
+               if ((data32 == 0x2000) ||
+                       (data32 == 0x800))
+                       return  ((y << 20)<<2) | ((cb << 10)<<2) | (cr<<2);
+               else
+                       return  (y << 20) | (cb << 10) | cr;
+       } else
+               return  (y << 20) | (cb << 10) | cr;
 }
 
 static u32 rgb2yuv(u32 rgb)
@@ -6436,19 +7155,23 @@ static ssize_t video_test_screen_store(struct class *cla,
        else
                data &= (~VPP_VD1_POSTBLEND);
 #endif
-       /*
-          if (test_screen & 0x04000000)
-          data |= VPP_VD2_PREBLEND;
-          else
-          data &= (~VPP_VD2_PREBLEND);
-
-          if (test_screen & 0x08000000)
-          data |= VPP_VD2_POSTBLEND;
-          else
-          data &= (~VPP_VD2_POSTBLEND);
-        */
+
+#if 0 //DEBUG_TMP
+       if (test_screen & 0x04000000)
+               data |= VPP_VD2_PREBLEND;
+       else
+               data &= (~VPP_VD2_PREBLEND);
+
+       if (test_screen & 0x08000000)
+               data |= VPP_VD2_POSTBLEND;
+       else
+               data &= (~VPP_VD2_POSTBLEND);
+#endif
+
        /* show test screen  YUV blend*/
-       if (is_meson_gxm_cpu()) /* bit width change to 10bit in gxm */
+       if (is_meson_gxm_cpu() ||
+               (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX))
+               /* bit width change to 10bit in gxm, 10/12 in txlx*/
                WRITE_VCBUS_REG(VPP_DUMMY_DATA1,
                        eight2ten(test_screen & 0x00ffffff));
        else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB)
@@ -6485,8 +7208,9 @@ static ssize_t video_rgb_screen_store(struct class *cla,
        if (r < 0)
                return -EINVAL;
 
+#if 0 //DEBUG_TMP
        /* vdin0 pre post blend enable or disabled */
-       /*
+
        data = READ_VCBUS_REG(VPP_MISC);
        if (rgb_screen & 0x01000000)
                data |= VPP_VD1_PREBLEND;
@@ -6497,18 +7221,17 @@ static ssize_t video_rgb_screen_store(struct class *cla,
                data |= VPP_VD1_POSTBLEND;
        else
                data &= (~VPP_VD1_POSTBLEND);
-       */
-       /*
-          if (test_screen & 0x04000000)
-          data |= VPP_VD2_PREBLEND;
-          else
-          data &= (~VPP_VD2_PREBLEND);
-
-          if (test_screen & 0x08000000)
-          data |= VPP_VD2_POSTBLEND;
-          else
-          data &= (~VPP_VD2_POSTBLEND);
-        */
+
+       if (test_screen & 0x04000000)
+               data |= VPP_VD2_PREBLEND;
+       else
+               data &= (~VPP_VD2_PREBLEND);
+
+       if (test_screen & 0x08000000)
+               data |= VPP_VD2_POSTBLEND;
+       else
+               data &= (~VPP_VD2_POSTBLEND);
+#endif
        /* show test screen  YUV blend*/
        if (is_meson_gxtvbb_cpu())   {
                WRITE_VCBUS_REG(VPP_DUMMY_DATA1,
@@ -6638,8 +7361,9 @@ static ssize_t threedim_mode_store(struct class *cla,
                if (mvc_flag)
                        process_3d_type |= MODE_3D_MVC;
                video_property_changed = true;
-               if ((process_3d_type & MODE_3D_FA) && !cur_dispbuf->trans_fmt)
-                       /*notify di 3d mode is frame alternative mode,*/
+               if ((process_3d_type & MODE_3D_FA)
+                       && cur_dispbuf && !cur_dispbuf->trans_fmt)
+                       /*notify di 3d mode is frame alternative mode,1*/
                        /*passing two buffer in one frame */
                        vf_notify_receiver_by_name("deinterlace",
                        VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE,
@@ -6841,7 +7565,7 @@ static ssize_t vframe_states_show(struct class *cla,
        unsigned long flags;
        struct vframe_s *vf;
 
-       if (vf_get_states(&states) == 0) {
+       if (video_vf_get_states(&states) == 0) {
                ret += sprintf(buf + ret, "vframe_pool_size=%d\n",
                        states.vf_pool_size);
                ret += sprintf(buf + ret, "vframe buf_free_num=%d\n",
@@ -6912,6 +7636,7 @@ static ssize_t device_resolution_show(struct class *cla,
 {
 #ifdef CONFIG_SUPPORT_VIDEO_ON_VPP2
        const struct vinfo_s *info;
+
        if (cur_dev == &video_dev[0])
                info = get_current_vinfo();
        else
@@ -6950,6 +7675,7 @@ static ssize_t video_debugflags_show(struct class *cla,
                                     struct class_attribute *attr, char *buf)
 {
        int len = 0;
+
        len += sprintf(buf + len, "value=%d\n", debugflags);
        len += sprintf(buf + len, "bit0:playing as fast!\n");
        len += sprintf(buf + len,
@@ -6965,18 +7691,18 @@ static ssize_t video_debugflags_store(struct class *cla,
        int value = -1, seted = 1;
 
 /*
      r = sscanf(buf, "%d", &value);
      if (r == 1) {
              debugflags = value;
              seted = 1;
      } else {
              r = sscanf(buf, "0x%x", &value);
              if (r == 1) {
                      debugflags = value;
                      seted = 1;
              }
      }
-*/
*     r = sscanf(buf, "%d", &value);
*     if (r == 1) {
*             debugflags = value;
*             seted = 1;
*     } else {
*             r = sscanf(buf, "0x%x", &value);
*             if (r == 1) {
*                     debugflags = value;
*                     seted = 1;
*             }
*     }
+ */
 
        r = kstrtoint(buf, 0, &value);
        if (r < 0)
@@ -7208,6 +7934,7 @@ static ssize_t video_free_keep_buffer_store(struct class *cla,
 {
        size_t r;
        int val;
+
        if (debug_flag & DEBUG_FLAG_BLACKOUT)
                pr_info("%s(%s)\n", __func__, buf);
        r = kstrtoint(buf, 0, &val);
@@ -7526,6 +8253,7 @@ static struct class amvideo_poll_class = {
 static int __init vpp_axis_reverse(char *str)
 {
        unsigned char *ptr = str;
+
        pr_info("%s: bootargs is %s\n", __func__, str);
        if (strstr(ptr, "1"))
                reverse = true;
@@ -7636,8 +8364,6 @@ static void vout_hook(void)
 #if DEBUG_TMP
                set_current_vmode(VMODE_720P);
 #endif
-               set_current_vmode(10);
-
                vinfo = get_current_vinfo();
        }
 
@@ -7719,12 +8445,19 @@ static void do_vpu_delay_work(struct work_struct *work)
        unsigned long flags;
        unsigned int r;
 
+#if DEBUG_TMP
+       if (vpu_delay_work_flag & VPU_UPDATE_DOLBY_VISION) {
+               vpu_delay_work_flag &= ~VPU_UPDATE_DOLBY_VISION;
+               dolby_vision_update_setting();
+               if (!vpu_delay_work_flag)
+                       return;
+       }
        if (vpu_delay_work_flag & VPU_VIDEO_LAYER1_CHANGED) {
                vpu_delay_work_flag &= ~VPU_VIDEO_LAYER1_CHANGED;
-#if DEBUG_TMP
+
                switch_set_state(&video1_state_sdev, !!video_enabled);
-#endif
        }
+#endif
        spin_lock_irqsave(&delay_work_lock, flags);
 
        if (vpu_delay_work_flag & VPU_DELAYWORK_VPU_CLK) {
@@ -7800,23 +8533,16 @@ struct device *get_video_device(void)
 
 static int __init video_early_init(void)
 {
-       const struct vinfo_s *vinfo;
-
        /* todo: move this to clock tree, enable VPU clock */
-#if DEBUG_TMP
-       WRITE_CBUS_REG(HHI_VPU_CLK_CNTL,
-       (1<<9) | (1<<8) | (3)); // fclk_div3/4 = ~200M
-       WRITE_CBUS_REG(HHI_VPU_CLK_CNTL,
-       (3<<9) | (1<<8) | (0)); // fclk_div7/1 = 364M
-       //moved to vpu.c, default config by dts
-#endif
-       vinfo = get_current_vinfo();
-       if (!vinfo)
-               return -1;
+       /* WRITE_CBUS_REG(HHI_VPU_CLK_CNTL,*/
+       /*(1<<9) | (1<<8) | (3)); // fclk_div3/4 = ~200M */
+       /* WRITE_CBUS_REG(HHI_VPU_CLK_CNTL,*/
+       /*(3<<9) | (1<<8) | (0)); // fclk_div7/1 = 364M*/
+       /*moved to vpu.c, default config by dts */
 
-       if (vinfo->mode >= VMODE_MAX) {
+       if (/*get_logo_vmode()*/0 >= VMODE_MAX) {/*DEBUG_TMP*/
 #if 1                          /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
-               if (is_meson_gxtvbb_cpu())
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB))
                        WRITE_VCBUS_REG_BITS(VPP_OFIFO_SIZE, 0xfff,
                                VPP_OFIFO_SIZE_BIT, VPP_OFIFO_SIZE_WID);
                else
@@ -7828,7 +8554,7 @@ static int __init video_early_init(void)
 #endif
 #endif                 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
        } else {
-               if (is_meson_gxtvbb_cpu())
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB))
                        WRITE_VCBUS_REG_BITS(VPP_OFIFO_SIZE, 0xfff,
                                VPP_OFIFO_SIZE_BIT, VPP_OFIFO_SIZE_WID);
        }
@@ -7836,7 +8562,7 @@ static int __init video_early_init(void)
        WRITE_VCBUS_REG(VPP_PREBLEND_VD1_H_START_END, 4096);
        WRITE_VCBUS_REG(VPP_BLEND_VD2_H_START_END, 4096);
 #endif
-       if (is_meson_txl_cpu()) {
+       if (is_meson_txl_cpu() || is_meson_txlx_cpu()) {
                /* fifo max size on txl :128*3=384[0x180]  */
                WRITE_VCBUS_REG(VD1_IF0_LUMA_FIFO_SIZE, 0x180);
                WRITE_VCBUS_REG(VD2_IF0_LUMA_FIFO_SIZE, 0x180);
@@ -7846,7 +8572,7 @@ static int __init video_early_init(void)
        if (is_meson_gxbb_cpu())
                SET_VCBUS_REG_MASK(VPP_MISC, VPP_OUT_SATURATE);
 
-       if (vinfo->mode >= VMODE_MAX) {
+       if (/*get_logo_vmode()*/0 >= VMODE_MAX) {/*DEBUG_TMP*/
                CLEAR_VCBUS_REG_MASK(VPP_VSC_PHASE_CTRL,
                                     VPP_PHASECTL_TYPE_INTERLACE);
 #ifndef CONFIG_FB_AML_TCON
@@ -7855,7 +8581,7 @@ static int __init video_early_init(void)
                WRITE_VCBUS_REG(VPP_HOLD_LINES + cur_dev->vpp_off, 0x08080808);
        }
 #ifdef CONFIG_SUPPORT_VIDEO_ON_VPP2
-       if (vinfo->mode >= VMODE_MAX) {
+       if (/*get_logo_vmode()*/0 >= VMODE_MAX) {/*DEBUG_TMP*/
                CLEAR_VCBUS_REG_MASK(VPP2_VSC_PHASE_CTRL,
                                     VPP_PHASECTL_TYPE_INTERLACE);
 #ifndef CONFIG_FB_AML_TCON
@@ -7871,9 +8597,9 @@ static int __init video_early_init(void)
                             VPP_OFIFO_SIZE_BIT, VPP_OFIFO_SIZE_WID);
 #endif
        /*
-       WRITE_VCBUS_REG_BITS(VPU_OSD3_MMC_CTRL, 1, 12, 2);
-       select vdisp_mmc_arb for VIU2_OSD1 request
-       */
+        *WRITE_VCBUS_REG_BITS(VPU_OSD3_MMC_CTRL, 1, 12, 2);
+        *select vdisp_mmc_arb for VIU2_OSD1 request
+        */
        WRITE_VCBUS_REG_BITS(VPU_OSD3_MMC_CTRL, 2, 12, 2);
        /* select vdin_mmc_arb for VIU2_OSD1 request */
 #endif
@@ -7882,13 +8608,16 @@ static int __init video_early_init(void)
                WRITE_VCBUS_REG_BITS(VIU_MISC_CTRL1, 0xff, 16, 8);
                WRITE_VCBUS_REG(VPP_DOLBY_CTRL, 0x22000);
                /*
-               default setting is black for dummy data1& dumy data0,
-               for dummy data1 the y/cb/cr data width is 10bit on gxm,
-               for dummy data the y/cb/cr data width is 8bit but
-               vpp_dummy_data will be left shift 2bit auto on gxm!!!
-               */
+                *default setting is black for dummy data1& dumy data0,
+                *for dummy data1 the y/cb/cr data width is 10bit on gxm,
+                *for dummy data the y/cb/cr data width is 8bit but
+                *vpp_dummy_data will be left shift 2bit auto on gxm!!!
+                */
                WRITE_VCBUS_REG(VPP_DUMMY_DATA1, 0x1020080);
                WRITE_VCBUS_REG(VPP_DUMMY_DATA, 0x42020);
+       } else if (is_meson_txlx_cpu()) {
+               /*black 10bit*/
+               WRITE_VCBUS_REG(VPP_DUMMY_DATA, 0x4080200);
        }
        /* temp: enable VPU arb mem */
        if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
@@ -7897,6 +8626,51 @@ static int __init video_early_init(void)
        return 0;
 }
 
+static struct mconfig video_configs[] = {
+       MC_PI32("pause_one_3d_fl_frame", &pause_one_3d_fl_frame),
+       MC_PI32("debug_flag", &debug_flag),
+       MC_PU32("force_3d_scaler", &force_3d_scaler),
+       MC_PU32("video_3d_format", &video_3d_format),
+       MC_PI32("vsync_enter_line_max", &vsync_enter_line_max),
+       MC_PI32("vsync_exit_line_max", &vsync_exit_line_max),
+#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
+       MC_PI32("vsync_rdma_line_max", &vsync_rdma_line_max),
+#endif
+       MC_PU32("underflow", &underflow),
+       MC_PU32("next_peek_underflow", &next_peek_underflow),
+       MC_PU32("smooth_sync_enable", &smooth_sync_enable),
+       MC_PU32("hdmi_in_onvideo", &hdmi_in_onvideo),
+#ifdef CONFIG_AM_VIDEO2
+       MC_PI32("video_play_clone_rate", &video_play_clone_rate),
+       MC_PI32("android_clone_rate", &android_clone_rate),
+       MC_PI32("video_play_clone_rate", &video_play_clone_rate),
+       MC_PI32("android_clone_rate", &android_clone_rate),
+       MC_PI32("noneseamless_play_clone_rate", &noneseamless_play_clone_rate),
+#endif
+       MC_PU32("smooth_sync_enable", &smooth_sync_enable),
+       MC_PU32("hdmi_in_onvideo", &hdmi_in_onvideo),
+       MC_PI32("cur_dev_idx", &cur_dev_idx),
+       MC_PU32("new_frame_count", &new_frame_count),
+       MC_PU32("omx_pts", &omx_pts),
+       MC_PI32("omx_pts_interval_upper", &omx_pts_interval_upper),
+       MC_PI32("omx_pts_interval_lower", &omx_pts_interval_lower),
+       MC_PBOOL("bypass_pps", &bypass_pps),
+       MC_PBOOL("platform_type", &platform_type),
+       MC_PU32("process_3d_type", &process_3d_type),
+       MC_PU32("omx_pts", &omx_pts),
+       MC_PU32("framepacking_support", &framepacking_support),
+       MC_PU32("framepacking_width", &framepacking_width),
+       MC_PU32("framepacking_height", &framepacking_height),
+       MC_PU32("framepacking_blank", &framepacking_blank),
+       MC_PU32("video_seek_flag", &video_seek_flag),
+       MC_PU32("slowsync_repeat_enable", &slowsync_repeat_enable),
+       MC_PU32("toggle_count", &toggle_count),
+       MC_PBOOL("show_first_frame_nosync", &show_first_frame_nosync),
+#ifdef TV_REVERSE
+       MC_PBOOL("reverse", &reverse),
+#endif
+};
+
 static int amvideom_probe(struct platform_device *pdev)
 {
        int ret = 0;
@@ -7944,11 +8718,11 @@ static int __init video_init(void)
 {
        int r = 0;
        /*
-          #ifdef CONFIG_ARCH_MESON1
-          ulong clk = clk_get_rate(clk_get_sys("clk_other_pll", NULL));
-          #elif !defined(CONFIG_ARCH_MESON3) && !defined(CONFIG_ARCH_MESON6)
-          ulong clk = clk_get_rate(clk_get_sys("clk_misc_pll", NULL));
-          #endif
+        *#ifdef CONFIG_ARCH_MESON1
+        *ulong clk = clk_get_rate(clk_get_sys("clk_other_pll", NULL));
+        *#elif !defined(CONFIG_ARCH_MESON3) && !defined(CONFIG_ARCH_MESON6)
+        *ulong clk = clk_get_rate(clk_get_sys("clk_misc_pll", NULL));
+        *#endif
         */
 
 #ifdef CONFIG_ARCH_MESON1
@@ -8125,7 +8899,7 @@ static int __init video_init(void)
 #ifdef CONFIG_AM_VIDEO2
        set_clone_frame_rate(android_clone_rate, 0);
 #endif
-
+       REG_PATH_CONFIGS("media.video", video_configs);
        return 0;
  err5:
        device_destroy(&amvideo_class, MKDEV(AMVIDEO_MAJOR, 0));
@@ -8209,6 +8983,15 @@ MODULE_PARM_DESC(underflow, "\n Underflow count\n");
 module_param(next_peek_underflow, uint, 0664);
 MODULE_PARM_DESC(skip, "\n Underflow count\n");
 
+module_param(hdmiin_frame_check, uint, 0664);
+MODULE_PARM_DESC(hdmiin_frame_check, "\n hdmiin_frame_check\n");
+
+module_param(step_enable, uint, 0664);
+MODULE_PARM_DESC(step_enable, "\n step_enable\n");
+
+module_param(step_flag, uint, 0664);
+MODULE_PARM_DESC(step_flag, "\n step_flag\n");
+
 /*arch_initcall(video_early_init);*/
 
 module_init(video_init);
@@ -8239,6 +9022,9 @@ module_param(cur_dev_idx, uint, 0664);
 MODULE_PARM_DESC(new_frame_count, "\n new_frame_count\n");
 module_param(new_frame_count, uint, 0664);
 
+MODULE_PARM_DESC(first_frame_toggled, "\n first_frame_toggled\n");
+module_param(first_frame_toggled, uint, 0664);
+
 MODULE_PARM_DESC(omx_pts, "\n omx_pts\n");
 module_param(omx_pts, uint, 0664);
 
@@ -8248,6 +9034,15 @@ module_param(omx_pts_interval_upper, int, 0664);
 MODULE_PARM_DESC(omx_pts_interval_lower, "\n omx_pts_interval\n");
 module_param(omx_pts_interval_lower, int, 0664);
 
+MODULE_PARM_DESC(drop_frame_count, "\n drop_frame_count\n");
+module_param(drop_frame_count, int, 0664);
+
+MODULE_PARM_DESC(receive_frame_count, "\n receive_frame_count\n");
+module_param(receive_frame_count, int, 0664);
+
+MODULE_PARM_DESC(display_frame_count, "\n display_frame_count\n");
+module_param(display_frame_count, int, 0664);
+
 MODULE_PARM_DESC(bypass_pps, "\n pps_bypass\n");
 module_param(bypass_pps, bool, 0664);
 
@@ -8274,6 +9069,10 @@ module_param(framepacking_blank, uint, 0664);
 module_param(reverse, bool, 0644);
 MODULE_PARM_DESC(reverse, "reverse /disable reverse");
 #endif
+
+MODULE_PARM_DESC(toggle_count, "\n toggle count\n");
+module_param(toggle_count, uint, 0664);
+
 MODULE_DESCRIPTION("AMLOGIC video output driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");
index df11c89..dfaf9bd 100644 (file)
@@ -665,10 +665,11 @@ static int alloc_keep_buffer(void)
                        goto err1;
                }
        }
-       pr_info("alloced keep buffer yaddr=%p,u_addr=%p,v_addr=%p\n",
+       pr_info("alloced keep buffer yaddr=%p,u_addr=%p,v_addr=%p,tvp=%d\n",
                (void *)keep_y_addr,
                (void *)keep_u_addr,
-               (void *)keep_v_addr);
+               (void *)keep_v_addr,
+               codec_mm_video_tvp_enabled());
        return 0;
 
  err1:
@@ -782,7 +783,7 @@ unsigned int vf_keep_current(struct vframe_s *cur_dispbuf)
                return 0;
        }
 
-#ifdef CONFIG_AM_VIDEOCAPTURE
+#ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
        ext_frame_capture_poll(1);      /*pull  if have capture end frame */
 #endif
        if (get_blackout_policy()) {
@@ -825,6 +826,14 @@ unsigned int vf_keep_current(struct vframe_s *cur_dispbuf)
                        }
                }
        }
+
+#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
+       if (codec_mm_video_tvp_enabled()) {
+               pr_info("keep exit is TVP\n");
+               return 0;
+       }
+#endif
+
        if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) &&
                (cur_dispbuf->type & VIDTYPE_COMPRESS)) {
                /* todo: duplicate compressed video frame */
index 77144c3..1ef5955 100644 (file)
@@ -54,13 +54,10 @@ int get_video_debug_flags(void);
 int _video_set_disable(u32 val);
 u32 get_video_enabled(void);
 
-#ifdef CONFIG_AM_VIDEOCAPTURE
+#ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE
 int ext_frame_capture_poll(int endflags);
 #endif
 
-#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
 extern u32 disp_canvas_index[2][6];
 #endif
-#endif
-
 /*VIDEO_PRIV_HEADER_HH*/
index 3b7eb09..0cf1dc3 100644 (file)
@@ -307,8 +307,8 @@ static uint coeff(uint *settings, uint ratio, uint phase,
        }
        coeff_type = settings[coeff_select];
        /* TODO: add future TV chips */
-       if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) ||
-               (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL)) {
+       if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() ||
+               is_meson_txlx_cpu()) {
                if (coeff_type == COEF_BICUBIC_SHARP)
                        coeff_type = COEF_BICUBIC;
        } else {
@@ -407,7 +407,7 @@ static unsigned int super_debug;
 module_param(super_debug, uint, 0664);
 MODULE_PARM_DESC(super_debug, "super_debug");
 
-static unsigned int super_scaler = 1;
+unsigned int super_scaler = 1;
 module_param(super_scaler, uint, 0664);
 MODULE_PARM_DESC(super_scaler, "super_scaler");
 
@@ -435,6 +435,7 @@ static unsigned int horz_scaler_filter = 0xff;
 module_param(horz_scaler_filter, uint, 0664);
 MODULE_PARM_DESC(horz_scaler_filter, "horz_scaler_filter");
 
+/*need check this value,*/
 static unsigned int bypass_ratio = 205;
 module_param(bypass_ratio, uint, 0664);
 MODULE_PARM_DESC(bypass_ratio, "bypass_ratio");
@@ -455,7 +456,7 @@ module_param(force_vskip_cnt, uint, 0664);
 #define DECL_PARM(name)\
 static int name;\
 MODULE_PARM_DESC(name, #name);\
-module_param(name, int, 0664)
+module_param(name, int, 0664);
 
 DECL_PARM(debug_wide_mode)
 DECL_PARM(debug_video_left)
@@ -582,6 +583,31 @@ calculate_non_linear_ratio(unsigned int middle_ratio,
  * (1.25 * 3840 / 1920) for 1080p mode.
  */
 #define MIN_RATIO_1000 1250
+unsigned int cur_skip_ratio;
+MODULE_PARM_DESC(cur_skip_ratio, "cur_skip_ratio");
+module_param(cur_skip_ratio, uint, 0444);
+unsigned int cur_vf_type;
+MODULE_PARM_DESC(cur_vf_type, "cur_vf_type");
+module_param(cur_vf_type, uint, 0444);
+
+/*
+ *test on txlx:
+ *Time_out = (V_out/V_screen_total)/FPS_out;
+ *if di bypas:
+ *Time_in = (H_in * V_in)/Clk_vpu;
+ *if di work; for di clk is less than vpu usually;
+ *Time_in = (H_in * V_in)/Clk_di;
+ *if Time_in < Time_out,need do vskip;
+ *but in effect,test result may have some error.
+ *ratio1:V_out test result may larger than calc result;
+ *--after test is large ratio is 1.09;
+ *--so wo should choose the largest ratio_v_out = 110/100;
+ *ratio2:use clk_di or clk_vpu;
+ *--txlx di clk is 250M or 500M;
+ *--before txlx di clk is 333M;
+ *So need adjust bypass_ratio;
+ */
+
 static int
 vpp_process_speed_check(s32 width_in,
                s32 height_in,
@@ -590,25 +616,72 @@ vpp_process_speed_check(s32 width_in,
                struct vpp_frame_par_s *next_frame_par,
                const struct vinfo_s *vinfo, struct vframe_s *vf)
 {
-       u32 cur_ratio;
+       u32 cur_ratio, bpp = 1;
+       int min_ratio_1000 = 0;
+       u32 vtotal, clk_in_pps = 0;
 
+       if (vf)
+               cur_vf_type = vf->type;
+       if (force_vskip_cnt == 0xff)/*for debug*/
+               return SPEED_CHECK_DONE;
        if (next_frame_par->vscale_skip_count < force_vskip_cnt)
                return SPEED_CHECK_VSKIP;
 
+       if (vf->type & VIDTYPE_PRE_INTERLACE) {
+               if (is_meson_txlx_cpu())
+                       clk_in_pps = 250000000;
+               else
+                       clk_in_pps = 333000000;
+       } else {
+               clk_in_pps = get_vpu_clk();
+       }
+       if (vf->type & VIDTYPE_COMPRESS) {
+               if (vf->width > 720)
+                       min_ratio_1000 = (MIN_RATIO_1000 * 1400)/1000;
+               else
+                       min_ratio_1000 = (1750 * 1400)/1000;
+       } else {
+               if (vf->width > 720)
+                       min_ratio_1000 =  MIN_RATIO_1000;
+               else
+                       min_ratio_1000 = 1750;
+       }
+       if (vinfo->field_height < vinfo->height)
+               vtotal = 525 / 2;//vinfo->vtotal/2;
+       else
+               vtotal = 525;//vinfo->vtotal;//DEBUG_TMP
        /* #if (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8) */
        if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) && !is_meson_mtvd_cpu()) {
                if ((width_in <= 0) || (height_in <= 0) || (height_out <= 0)
                        || (height_screen <= 0))
                        return SPEED_CHECK_DONE;
 
-               if (height_in > height_out) {
+               if ((next_frame_par->vscale_skip_count > 0)
+                       && (vf->type & VIDTYPE_VIU_444))
+                       bpp = 2;
+               if (height_in * bpp > height_out) {
+                       /*
+                        *don't need do skip for under 5% scaler down
+                        *reason:for 1080p input,4k output, if di clk is 250M,
+                        *the clac height is 1119;which is bigger than 1080!
+                        */
+                       if (height_in > height_out &&
+                               ((height_in - height_out) < height_in/20))
+                               return SPEED_CHECK_DONE;
                        if (get_cpu_type() >=
                                MESON_CPU_MAJOR_ID_GXBB) {
                                cur_ratio = div_u64((u64)height_in *
                                                (u64)vinfo->height *
                                                1000,
                                                height_out * 2160);
-                               if ((cur_ratio > MIN_RATIO_1000) &&
+                               /* di process first, need more a bit of ratio */
+                               if (vf->type & VIDTYPE_PRE_INTERLACE)
+                                       cur_ratio = (cur_ratio * 105) / 100;
+                               if ((next_frame_par->vscale_skip_count > 0)
+                                       && (vf->type & VIDTYPE_VIU_444))
+                                       cur_ratio = cur_ratio * 2;
+                               cur_skip_ratio = cur_ratio;
+                               if ((cur_ratio > min_ratio_1000) &&
                                (vf->source_type != VFRAME_SOURCE_TYPE_TUNER) &&
                                (vf->source_type != VFRAME_SOURCE_TYPE_CVBS))
                                        return SPEED_CHECK_VSKIP;
@@ -620,10 +693,10 @@ vpp_process_speed_check(s32 width_in,
                                                (u64)width_in *
                                                (u64)height_in *
                                                (u64)vinfo->sync_duration_num *
-                                               (u64)height_screen,
+                                               (u64)vtotal,
                                                height_out *
                                                vinfo->sync_duration_den *
-                                               bypass_ratio) > get_vpu_clk())
+                                               bypass_ratio) > clk_in_pps)
                                        return SPEED_CHECK_VSKIP;
                                else
                                        return SPEED_CHECK_DONE;
@@ -634,10 +707,10 @@ vpp_process_speed_check(s32 width_in,
                                        (u64)width_in *
                                        (u64)height_in *
                                        (u64)vinfo->sync_duration_num *
-                                       (u64)height_screen,
+                                       (u64)vtotal,
                                        height_out *
                                        vinfo->sync_duration_den * 256)
-                                       > get_vpu_clk())
+                                       > clk_in_pps)
                                        return SPEED_CHECK_VSKIP;
                                /* 4K down scaling to non 4K > 30hz,*/
                                   /*skip lines for memory bandwidth */
@@ -649,7 +722,9 @@ vpp_process_speed_check(s32 width_in,
                                         (vinfo->sync_duration_num >
                                          (30 * vinfo->sync_duration_den)) &&
                                         (get_cpu_type() !=
-                                               MESON_CPU_MAJOR_ID_GXTVBB))
+                                               MESON_CPU_MAJOR_ID_GXTVBB) &&
+                                        (get_cpu_type() !=
+                                               MESON_CPU_MAJOR_ID_GXM))
                                        return SPEED_CHECK_VSKIP;
                                else
                                        return SPEED_CHECK_DONE;
@@ -756,6 +831,10 @@ vpp_set_filters2(u32 process_3d_type, u32 width_in,
                }
        }
 
+       if (is_meson_txlx_cpu()) {
+               next_frame_par->vpp_postblend_out_width = vinfo->width;
+               next_frame_par->vpp_postblend_out_height = vinfo->height;
+       }
 #ifndef TV_3D_FUNCTION_OPEN
        next_frame_par->vscale_skip_count = 0;
        next_frame_par->hscale_skip_count = 0;
@@ -941,9 +1020,9 @@ RESTART:
 
                ratio_y = (height_after_ratio << 18) / screen_height;
                if (super_debug)
-                       pr_info("height_after_ratio=%d,%d,%d,%d\n",
+                       pr_info("height_after_ratio=%d,%d,%d,%d,%d\n",
                                   height_after_ratio, ratio_x, ratio_y,
-                                  aspect_factor);
+                                  aspect_factor, wide_mode);
 
                if (wide_mode == VIDEO_WIDEOPTION_NORMAL) {
                        ratio_x = ratio_y = max(ratio_x, ratio_y);
@@ -1132,7 +1211,8 @@ RESTART:
                (vpp_zoom_center_x << 10)) /
                ratio_x;
        end = (w_in << 18) / ratio_x + start - 1;
-       pr_info("left:start =%d,%d,%d,%d  %d,%d,%d\n",
+       if (super_debug)
+               pr_info("left:start =%d,%d,%d,%d  %d,%d,%d\n",
                        start, end, video_left,
                        video_width, w_in, ratio_x, vpp_zoom_center_x);
 #endif
@@ -1239,9 +1319,9 @@ RESTART:
                        (next_frame_par->VPP_vd_end_lines_ -
                        next_frame_par->VPP_vd_start_lines_ + 1) /
                        (next_frame_par->vscale_skip_count + 1),
-                       next_frame_par->VPP_vsc_endp -
-                       next_frame_par->VPP_vsc_startp,
-                       height_out >>
+                       (next_frame_par->VPP_vsc_endp -
+                       next_frame_par->VPP_vsc_startp + 1),
+                       vinfo->height >>
                        ((vpp_flags & VPP_FLAG_INTERLACE_OUT) ? 1 : 0),
                        next_frame_par,
                        vinfo,
@@ -1290,8 +1370,9 @@ RESTART:
                        next_frame_par->vscale_skip_count = skip_policy & 0xf;
                        goto RESTART;
                } else if (skip_policy & 0x80) {
-                       if ((vf->width >= 4096) &&
-                       (!(vf->type & VIDTYPE_COMPRESS))
+                       if ((((vf->width >= 4096) &&
+                       (!(vf->type & VIDTYPE_COMPRESS))) ||
+                       (vf->flag & VFRAME_FLAG_HIGH_BANDWIDTH))
                        && (next_frame_par->vscale_skip_count == 0)) {
                                next_frame_par->vscale_skip_count =
                                skip_policy & 0xf;
@@ -1331,7 +1412,7 @@ RESTART:
                cur_vert_chroma_filter = COEF_NULL;
                filter->vpp_vert_chroma_filter_en = false;
        }
-
+       /* avoid hscaler fitler adjustion affect on picture shift*/
        filter->vpp_horz_filter =
                coeff(horz_coeff_settings,
                        filter->vpp_hf_start_phase_step,
@@ -1340,8 +1421,7 @@ RESTART:
                                != VIDTYPE_PROGRESSIVE),
                        vf->combing_cur_lev);
        /*for gxl cvbs out index*/
-       if ((vinfo->mode == VMODE_CVBS) &&
-               (vinfo->height == 576) &&
+       if ((vinfo->mode == VMODE_CVBS) && //DEBUG_TMP
                (filter->vpp_hf_start_phase_step == (1 << 24)))
                filter->vpp_horz_filter = COEF_BICUBIC_SHARP;
        filter->vpp_horz_coeff =
@@ -1512,7 +1592,9 @@ int vpp_set_super_scaler_regs(int scaler_path_sel,
                int reg_srscl1_hsize,
                int reg_srscl1_vsize,
                int reg_srscl1_hori_ratio,
-               int reg_srscl1_vert_ratio)
+               int reg_srscl1_vert_ratio,
+               int vpp_postblend_out_width,
+               int vpp_postblend_out_height)
 {
 
        int tmp_data = 0;
@@ -1600,19 +1682,33 @@ int vpp_set_super_scaler_regs(int scaler_path_sel,
                VSYNC_WR_MPEG_REG(SRSHARP1_SHARP_HVSIZE, tmp_data);
                sharpness1_sr2_ctrl_3280 = tmp_data;
        }
-
-       if (scaler_path_sel == sup0_pp_sp1_scpath) {
-               tmp_data = ((reg_srscl1_hsize & 0x1fff) << 16) |
-                                  (reg_srscl1_vsize & 0x1fff);
-               tmp_data2 = READ_VCBUS_REG(VPP_VE_H_V_SIZE);
-               if (tmp_data != tmp_data2)
-                       VSYNC_WR_MPEG_REG(VPP_VE_H_V_SIZE, tmp_data);
-       } else if (scaler_path_sel == sup0_pp_post_blender) {
-               tmp_data = ((reg_srscl1_hsize & 0x1fff) << 16) |
-                                  (reg_srscl1_vsize & 0x1fff);
-               tmp_data2 = READ_VCBUS_REG(VPP_PSR_H_V_SIZE);
-               if (tmp_data != tmp_data2)
-                       VSYNC_WR_MPEG_REG(VPP_PSR_H_V_SIZE, tmp_data);
+       /*ve input size setting*/
+       tmp_data = ((reg_srscl1_hsize & 0x1fff) << 16) |
+               (reg_srscl1_vsize & 0x1fff);
+       tmp_data2 = READ_VCBUS_REG(VPP_VE_H_V_SIZE);
+       if (tmp_data != tmp_data2)
+               VSYNC_WR_MPEG_REG(VPP_VE_H_V_SIZE, tmp_data);
+       /*chroma blue stretch size setting*/
+       if (is_meson_txlx_cpu()) {
+               tmp_data = (((vpp_postblend_out_width & 0x1fff) << 16) |
+                       (vpp_postblend_out_height & 0x1fff));
+               VSYNC_WR_MPEG_REG(VPP_OUT_H_V_SIZE, tmp_data);
+       } else {
+               if (scaler_path_sel == sup0_pp_sp1_scpath) {
+                       tmp_data = (((reg_srscl1_hsize & 0x1fff) <<
+                               reg_srscl1_hori_ratio) << 16) |
+                               ((reg_srscl1_vsize & 0x1fff) <<
+                               reg_srscl1_vert_ratio);
+                       tmp_data2 = READ_VCBUS_REG(VPP_PSR_H_V_SIZE);
+                       if (tmp_data != tmp_data2)
+                               VSYNC_WR_MPEG_REG(VPP_PSR_H_V_SIZE, tmp_data);
+               } else if (scaler_path_sel == sup0_pp_post_blender) {
+                       tmp_data = ((reg_srscl1_hsize & 0x1fff) << 16) |
+                                          (reg_srscl1_vsize & 0x1fff);
+                       tmp_data2 = READ_VCBUS_REG(VPP_PSR_H_V_SIZE);
+                       if (tmp_data != tmp_data2)
+                               VSYNC_WR_MPEG_REG(VPP_PSR_H_V_SIZE, tmp_data);
+               }
        }
 
        /* path config */
@@ -1664,64 +1760,72 @@ static void vpp_set_scaler(u32 process_3d_type, u32 src_width,
        ver_sc_multiple_num = height_out*SUPER_SCALER_V_FACTOR / src_height;
 
        /* just calcuate the enable sclaer module */
-       if ((hor_sc_multiple_num >= 4) || (ver_sc_multiple_num >=
-                               (4*SUPER_SCALER_V_FACTOR))) {
-               if (bypass_spscl0 == 0)
-                       next_frame_par->supsc0_enable = 1;
-               if (bypass_spscl1 == 0)
-                       next_frame_par->supsc1_enable = 1;
-       } else if ((hor_sc_multiple_num >= 2) || (ver_sc_multiple_num >=
-                               (2*SUPER_SCALER_V_FACTOR))) {
-               if (((src_width > SUPER_CORE0_WIDTH_MAX/2)
-                       && (src_width <= SUPER_CORE0_WIDTH_MAX)
-                       && (bypass_spscl1 == 0))
-                       || (bypass_spscl0 == 1)) {
-                       next_frame_par->supsc0_enable = 0;
-                       next_frame_par->supsc1_enable = 1;
-               } else if ((src_width > SUPER_CORE0_WIDTH_MAX/2)
-                       && (src_width <= SUPER_CORE0_WIDTH_MAX)
-                       && (bypass_spscl1 == 1)) {
-                       next_frame_par->supsc0_enable = 0;
-                       next_frame_par->supsc1_enable = 0;
-               } else {
-                       next_frame_par->supsc0_enable = 1;
-                       next_frame_par->supsc1_enable = 0;
-               }
-       } else {
-               next_frame_par->supsc0_enable = 0;
-               next_frame_par->supsc1_enable = 0;
-       }
-       if (src_width > SUPER_CORE0_WIDTH_MAX)
-               next_frame_par->supsc0_enable = 0;
-       if (width_out > SUPER_CORE1_WIDTH_MAX*2)
-               next_frame_par->supsc1_enable = 0;
-
-       if (ver_sc_multiple_num >= (2*SUPER_SCALER_V_FACTOR)) {
-               if (src_width > SUPER_CORE0_WIDTH_MAX/2)
-                       next_frame_par->supsc0_vert_ratio = 0;
-               else
-                       next_frame_par->supsc0_vert_ratio =
-                               next_frame_par->supsc0_enable ? 1 : 0;
-               if (width_out > SUPER_CORE1_WIDTH_MAX*2)
+       /*
+        *note:if first check h may cause v can't do scaling;
+        * for example: 1920x1080(input),3840x2160(output);
+        * todo:if you have better idea,you can improve it
+        */
+       /* step1: judge core0&core1 vertical enable or disable*/
+       if (ver_sc_multiple_num >= 2*SUPER_SCALER_V_FACTOR) {
+               next_frame_par->supsc0_vert_ratio =
+                       (src_width < SUPER_CORE0_WIDTH_MAX/2) ? 1 : 0;
+               next_frame_par->supsc1_vert_ratio =
+                       ((width_out < SUPER_CORE1_WIDTH_MAX) &&
+                       (src_width < SUPER_CORE1_WIDTH_MAX/2)) ? 1 : 0;
+               if (next_frame_par->supsc0_vert_ratio &&
+                       (ver_sc_multiple_num < 4*SUPER_SCALER_V_FACTOR))
                        next_frame_par->supsc1_vert_ratio = 0;
-               else
-                       next_frame_par->supsc1_vert_ratio =
-                               next_frame_par->supsc1_enable ? 1 : 0;
+               next_frame_par->supsc0_enable =
+                       next_frame_par->supsc0_vert_ratio ? 1 : 0;
+               next_frame_par->supsc1_enable =
+                       next_frame_par->supsc1_vert_ratio ? 1 : 0;
        } else {
+               next_frame_par->supsc0_enable = 0;
                next_frame_par->supsc0_vert_ratio = 0;
+               next_frame_par->supsc1_enable = 0;
                next_frame_par->supsc1_vert_ratio = 0;
        }
+       /* step2: judge core0&core1 horizontal enable or disable*/
        if (hor_sc_multiple_num >= 2) {
-               next_frame_par->supsc0_hori_ratio =
-                       next_frame_par->supsc0_enable ? 1 : 0;
-               next_frame_par->supsc1_hori_ratio =
-                       next_frame_par->supsc1_enable ? 1 : 0;
+               if ((src_width > SUPER_CORE0_WIDTH_MAX) ||
+                       ((src_width > SUPER_CORE0_WIDTH_MAX/2) &&
+                       next_frame_par->supsc0_vert_ratio) ||
+                       (((src_width << 1) > SUPER_CORE1_WIDTH_MAX/2) &&
+                       next_frame_par->supsc1_vert_ratio))
+                       next_frame_par->supsc0_hori_ratio = 0;
+               else
+                       next_frame_par->supsc0_hori_ratio = 1;
+               if (((width_out >> 1) > SUPER_CORE1_WIDTH_MAX) ||
+                       (((width_out >> 1) > SUPER_CORE1_WIDTH_MAX/2) &&
+                       next_frame_par->supsc1_vert_ratio) ||
+                       (next_frame_par->supsc0_hori_ratio &&
+                       (hor_sc_multiple_num < 4)))
+                       next_frame_par->supsc1_hori_ratio = 0;
+               else
+                       next_frame_par->supsc1_hori_ratio = 1;
+               next_frame_par->supsc0_enable =
+                       (next_frame_par->supsc0_hori_ratio ||
+                       next_frame_par->supsc0_enable) ? 1 : 0;
+               next_frame_par->supsc1_enable =
+                       (next_frame_par->supsc1_hori_ratio ||
+                       next_frame_par->supsc1_enable) ? 1 : 0;
        } else {
+               next_frame_par->supsc0_enable =
+                       next_frame_par->supsc0_vert_ratio ? 1 : 0;
                next_frame_par->supsc0_hori_ratio = 0;
+               next_frame_par->supsc1_enable =
+                       next_frame_par->supsc1_vert_ratio ? 1 : 0;
                next_frame_par->supsc1_hori_ratio = 0;
-               next_frame_par->supsc0_vert_ratio = 0;
+       }
+       /*double check core1 input width for core1_vert_ratio!!!*/
+       if (next_frame_par->supsc1_vert_ratio &&
+               (width_out >> next_frame_par->supsc1_hori_ratio >
+               SUPER_CORE1_WIDTH_MAX/2)) {
                next_frame_par->supsc1_vert_ratio = 0;
+               if (next_frame_par->supsc1_hori_ratio == 0)
+                       next_frame_par->supsc1_enable = 0;
        }
+       /* option add patch */
        if ((ver_sc_multiple_num <= super_scaler_v_ratio) &&
                (src_height >= SUPER_CORE0_WIDTH_MAX/2) &&
                (src_height <= 1088) &&
@@ -1874,7 +1978,7 @@ static void vpp_set_scaler(u32 process_3d_type, u32 src_width,
 }
 
 #ifdef TV_3D_FUNCTION_OPEN
-void get_vpp_3d_mode(u32 trans_fmt, u32 *vpp_3d_mode)
+void get_vpp_3d_mode(u32 process_3d_type, u32 trans_fmt, u32 *vpp_3d_mode)
 {
        switch (trans_fmt) {
        case TVIN_TFMT_3D_LRH_OLOR:
@@ -1889,6 +1993,8 @@ void get_vpp_3d_mode(u32 trans_fmt, u32 *vpp_3d_mode)
        case TVIN_TFMT_3D_DET_TB:
        case TVIN_TFMT_3D_FA:
                *vpp_3d_mode = VPP_3D_MODE_TB;
+               if (process_3d_type & MODE_3D_MVC)
+                       *vpp_3d_mode = VPP_3D_MODE_FA;
                break;
        case TVIN_TFMT_3D_LA:
        case TVIN_TFMT_3D_DET_INTERLACE:
@@ -1957,7 +2063,8 @@ vpp_get_video_source_size(u32 *src_width, u32 *src_height,
                        break;
                }
 
-       } else if (process_3d_type & MODE_3D_LR) {
+       } else if ((process_3d_type & MODE_3D_LR) ||
+       (process_3d_type & MODE_FORCE_3D_LR)) {
                next_frame_par->vpp_3d_mode = VPP_3D_MODE_LR;
                if (process_3d_type & MODE_3D_TO_2D_MASK) {
                        *src_width = vf->width >> 1;
@@ -1972,7 +2079,8 @@ vpp_get_video_source_size(u32 *src_width, u32 *src_height,
                        next_frame_par->vpp_2pic_mode = 1;
                }
 
-       } else if (process_3d_type & MODE_3D_TB) {
+       } else if ((process_3d_type & MODE_3D_TB) ||
+       (process_3d_type & MODE_FORCE_3D_TB)) {
                next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB;
                if (process_3d_type & MODE_3D_TO_2D_MASK) {
                        *src_width = vf->width;
@@ -1986,6 +2094,12 @@ vpp_get_video_source_size(u32 *src_width, u32 *src_height,
                        *src_height = vf->height;
                        next_frame_par->vpp_2pic_mode = 1;
                }
+               if (process_3d_type & MODE_3D_MVC) {
+                       *src_width = vf->width;
+                       *src_height = vf->height << 1;
+                       next_frame_par->vpp_2pic_mode = 2;
+                       next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA;
+               }
        } else if (process_3d_type & MODE_3D_LA) {
                next_frame_par->vpp_3d_mode = VPP_3D_MODE_LA;
                *src_height = vf->height - 1;
@@ -2004,11 +2118,34 @@ vpp_get_video_source_size(u32 *src_width, u32 *src_height,
                        next_frame_par->vscale_skip_count = 1;
                        next_frame_par->vpp_3d_scale = 0;
                }
-       } else if (process_3d_type & MODE_3D_FA) {
+       } else if ((process_3d_type & MODE_3D_FA)
+                       || (process_3d_type & MODE_FORCE_3D_FA_LR)
+                       || (process_3d_type & MODE_FORCE_3D_FA_TB)) {
+
                next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA;
                if (process_3d_type & MODE_3D_TO_2D_MASK) {
-                       *src_width = vf->width;
-                       *src_height = vf->height;
+
+                       if (process_3d_type & MODE_FORCE_3D_FA_TB) {
+                               next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB;
+                               *src_width = vf->width;
+                               *src_height = vf->height >> 1;
+                       }
+                       if (process_3d_type & MODE_FORCE_3D_FA_LR) {
+                               next_frame_par->vpp_3d_mode = VPP_3D_MODE_LR;
+                               *src_width = vf->width >> 1;
+                               *src_height = vf->height;
+                       }
+                       if (process_3d_type & MODE_3D_MVC) {
+                               *src_width = vf->width;
+                               *src_height = vf->height;
+                               next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA;
+                       }
+                       if (vf->trans_fmt == TVIN_TFMT_3D_FP) {
+                               next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB;
+                               *src_width = vf->width;
+                               *src_height = vf->left_eye.height;
+                       }
+                       next_frame_par->vpp_2pic_mode = 0;
                } else if (process_3d_type & MODE_3D_OUT_LR) {
                        *src_width = vf->width << 1;
                        *src_height = vf->height;
@@ -2092,7 +2229,7 @@ vpp_set_filters(u32 process_3d_type, u32 wide_mode,
                next_frame_par->vpp_3d_scale = 0;
        }
        next_frame_par->trans_fmt = vf->trans_fmt;
-       get_vpp_3d_mode(next_frame_par->trans_fmt,
+       get_vpp_3d_mode(process_3d_type, next_frame_par->trans_fmt,
                &next_frame_par->vpp_3d_mode);
        if (vpp_3d_scale)
                next_frame_par->vpp_3d_scale = 1;
@@ -2384,8 +2521,8 @@ void vpp_set_3d_scale(bool enable)
 
 void vpp_super_scaler_support(void)
 {
-       if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) ||
-               (get_cpu_type() == MESON_CPU_MAJOR_ID_TXL))
+       if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() ||
+               is_meson_txlx_cpu())
                super_scaler = 1;
        else
                super_scaler = 0;
@@ -2393,10 +2530,11 @@ void vpp_super_scaler_support(void)
 
 void vpp_bypass_ratio_config(void)
 {
-       if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB)
-               || (get_cpu_type() == MESON_CPU_MAJOR_ID_GXL)
-               || (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM))
+       if (is_meson_gxbb_cpu() || is_meson_gxl_cpu() ||
+               is_meson_gxm_cpu())
                bypass_ratio = 125;
+       else if (is_meson_txlx_cpu() || is_meson_txl_cpu())
+               bypass_ratio = 247;/*0x110 * (100/110)=0xf7*/
        else
                bypass_ratio = 205;
 }
index be0d53f..a8923c7 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <linux/amlogic/cpu_version.h>
-#include <linux/amlogic/media/old_cpu_version.h>
 #include <linux/amlogic/iomap.h>
 #include <linux/io.h>
 #include <linux/uaccess.h>
index a4bdc71..407f2fd 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef __PLAT_MESON_CPU_H
 #define __PLAT_MESON_CPU_H
 
-#define MESON_CPU_MAJOR_ID_M8B      0x1B
+#define MESON_CPU_MAJOR_ID_M8B         0x1B
 #define MESON_CPU_MAJOR_ID_GXBB                0x1F
 #define MESON_CPU_MAJOR_ID_GXTVBB      0x20
 #define MESON_CPU_MAJOR_ID_GXL         0x21
@@ -145,4 +145,13 @@ static inline bool cpu_after_eq(unsigned int id)
        return get_cpu_type() >= id;
 }
 
+static inline bool is_meson_txlx_package_962X(void)
+{
+       return is_meson_txlx_cpu() && package_id_is(0x10);
+}
+
+static inline bool is_meson_txlx_package_962E(void)
+{
+       return is_meson_txlx_cpu() && package_id_is(0x20);
+}
 #endif
index f52db1d..4d2f9c2 100644 (file)
@@ -27,7 +27,8 @@
 #define AMAUDIO_MAJOR          (11+(AML_BASE))
 #define AMVIDEO2_MAJOR         (12+(AML_BASE))
 #define AMAUDIO2_MAJOR         (13+(AML_BASE))
-
+#define VFM_MAJOR               (14+(AML_BASE))
+#define IONVIDEO_MAJOR         (15+(AML_BASE))
 /*
  *#define UIO_MAJOR                    4+(AML_BASE)
  *#define USB_DEV_EP_MAJOR     5+(AML_BASE)
index 8044448..b5ad471 100644 (file)
@@ -58,8 +58,8 @@ struct canvas_config_s {
 /*for progressive mjpeg (nv21 output)use*/
 #define PPMGR_DEINTERLACE_BUF_NV21_CANVAS 0x7e
 
-#define PPMGR2_MAX_CANVAS 8
-#define PPMGR2_CANVAS_INDEX 0x70       /* 0x70-0x7f for PPMGR2 (IONVIDEO)/ */
+#define PPMGR2_MAX_CANVAS 16
+#define PPMGR2_CANVAS_INDEX 0x70    /* 0x70-0x7f for PPMGR2 (IONVIDEO)/ */
 
 /*
  *the following reserved canvas index value
index 56ca7aa..dc48eca 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef CANVAS_MGR_HEADER_
 #define CANVAS_MGR_HEADER_
 
+#include <linux/types.h>
+
 #define CANVAS_MAX_NUM 256
 
 struct canvas_info {
@@ -34,7 +36,7 @@ struct canvas_pool {
        int canvas_max;
        int free_num;
        struct canvas_info info[CANVAS_MAX_NUM];
-       unsigned long canvas_map[CANVAS_MAX_NUM / sizeof(unsigned long)];
+       unsigned long canvas_map[(CANVAS_MAX_NUM / BITS_PER_LONG) + 1];
        int next_alloced_index;
        int next_dump_index;
        unsigned long last_cat_map;
index 02ea099..5de94ec 100644 (file)
 #define CODEC_MM_FLAGS_DMA_CPU  (CODEC_MM_FLAGS_DMA | CODEC_MM_FLAGS_CPU)
 #define CODEC_MM_FLAGS_ANY     CODEC_MM_FLAGS_DMA_CPU
 
+/*--------------------------------------------------*/
 struct codec_mm_s {
        /*can be shared by many user */
        const char *owner[8];
+       int ins_id;/*used by with channel?*/
+       int ins_buffer_id;/*canbe for buffer id*/
        /*virtual buffer of this memory */
        char *vbuffer;
        void *mem_handle;       /*used for top level.alloc/free */
@@ -101,17 +104,30 @@ struct codec_mm_s {
        char *pagemap;
        int pagemap_size;
        int alloced_page_num;
+       u64 alloced_jiffies;
        int mem_id;
        int next_bit;
        struct list_head list;
 };
 struct codec_mm_s *codec_mm_alloc(const char *owner, int size,
                int align2n, int memflags);
+unsigned long codec_mm_alloc_for_dma_ex(
+               const char *owner,
+               int page_cnt,
+               int align2n,
+               int memflags,
+               int ins_id,
+               int buffer_id);
+
 void codec_mm_release(struct codec_mm_s *mem, const char *owner);
 int codec_mm_request_shared_mem(struct codec_mm_s *mem, const char *owner);
 /*call if not make sure valid data.*/
 void codec_mm_release_with_check(struct codec_mm_s *mem, const char *owner);
 unsigned long dma_get_cma_size_int_byte(struct device *dev);
+
+
+/*---------------------------------------------------------------*/
+
 unsigned long codec_mm_alloc_for_dma(const char *owner, int page_cnt,
        int align2n, int memflags);
 int codec_mm_free_for_dma(const char *owner, unsigned long phy_addr);
@@ -119,7 +135,9 @@ int codec_mm_free_for_dma(const char *owner, unsigned long phy_addr);
 void *codec_mm_phys_to_virt(unsigned long phy_addr);
 unsigned long codec_mm_virt_to_phys(void *vaddr);
 
-void codec_mm_dma_flush(void *vaddr, int size, enum dma_data_direction dir);
+void codec_mm_dma_flush(void *vaddr,
+       int size,
+       enum dma_data_direction dir);
 
 int codec_mm_get_total_size(void);
 int codec_mm_get_free_size(void);
index 920b237..5e02182 100644 (file)
@@ -34,6 +34,7 @@
 #define PAGE_INDEX(page) (page >> PAGE_SHIFT)
 
 struct codec_mm_scatter {
+       void *manager;
        phy_addr_type *pages_list;
        int page_max_cnt;
        int page_cnt;           /*page num */
@@ -55,11 +56,12 @@ int codec_mm_scatter_free_tail_pages_fast(struct codec_mm_scatter *mms,
 int codec_mm_scatter_free_tail_pages_fast(struct codec_mm_scatter *mms,
        int start_free_id);
 
-struct codec_mm_scatter *codec_mm_scatter_alloc(int max_page, int page_num);
+struct codec_mm_scatter *codec_mm_scatter_alloc(int max_page,
+       int page_num, int istvp);
 int codec_mm_scatter_alloc_want_pages(struct codec_mm_scatter *mms,
                        int want_pages);
 int codec_mm_scatter_mgt_delay_free_swith(int on, int delay_ms,
-       int wait_size_M);
+       int wait_size_M, int istvp);
 int codec_mm_dump_scatter(struct codec_mm_scatter *mms, void *buf, int size);
 int codec_mm_scatter_dec_owner_user(void *sc_mm, int delay_ms);
 
diff --git a/include/linux/amlogic/media/codec_mm/configs.h b/include/linux/amlogic/media/codec_mm/configs.h
new file mode 100644 (file)
index 0000000..e0147f3
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * include/linux/amlogic/media/codec_mm/configs.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef AMLOGIC_MEDIA_CONFIG_HEADER__
+#define AMLOGIC_MEDIA_CONFIG_HEADER__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/amlogic/media/codec_mm/configs_api.h>
+
+#define MAX_DEPTH 8
+
+typedef int (*get_fun)(const char *trigger, int id, char *buf, int size);
+
+typedef int (*set_fun)(const char *trigger, int id, const char *buf, int size);
+
+struct mconfig {
+#define CONFIG_TYPE_PI32 1
+#define CONFIG_TYPE_PU32 2
+#define CONFIG_TYPE_PU64 4
+#define CONFIG_TYPE_PBOOL 5
+
+#define CONFIG_TYPE_PSTR 7
+#define CONFIG_TYPE_PCSTR 8
+#define CONFIG_TYPE_I32 21
+#define CONFIG_TYPE_U32 22
+#define CONFIG_TYPE_U64 24
+#define CONFIG_TYPE_BOOL 25
+
+#define CONFIG_TYPE_FUN 100
+       int type;
+       int id;
+       const char *item_name;
+       union {
+               void *buf_ptr;
+               char *str;
+               const char *cstr;
+
+               int *pival;
+               u32 *pu32val;
+               u64 *pu64val;
+
+               int ival;
+               u32 u32val;
+               u32 u32mval[2];
+               u64 u64val;
+               bool boolval;
+               bool *pboolval;
+               char b[8];
+               long ldata[2];
+               struct {
+                       get_fun f_get;  /*used 0 */
+                       set_fun f_set;  /*used 1 */
+               };
+       };
+       int size;
+};
+
+struct mconfig_node {
+       char prefix[MAX_PREFIX_NAME];
+       const char *name;
+       int active;
+       int depth;
+       struct mconfig_node *parent_node;
+       struct list_head list;
+       int son_node_num;
+       struct list_head son_node_list;
+       struct mutex lock;
+       int configs_num;
+       struct mconfig *configs;
+       atomic_t ref_cnt;
+        /*
+         *rw_flags:
+         * CONFIG_FOR_R: support read.
+         * CONFIG_FOR_W: support write.
+         * CONFIG_FOR_T: CONFIG FOR TRIGGER;
+         */
+#define CONFIG_FOR_R 1
+#define CONFIG_FOR_W 2
+#define CONFIG_FOR_T 4
+#define CONFIG_FOR_RW (CONFIG_FOR_R | CONFIG_FOR_W)
+       int rw_flags;
+};
+
+#define MC_U32(n, v) \
+       {.type = CONFIG_TYPE_U32, .item_name = (n), .u32val = (v)}
+
+#define MC_I32(n, v) \
+       {.type = CONFIG_TYPE_I32, .item_name = (n), .ival = (v)}
+
+#define MC_U64(n, v) \
+       {.type = CONFIG_TYPE_U32, .item_name = (n), .u64val = (v)}
+#define MC_BOOL(n, v) \
+       {.type = CONFIG_TYPE_BOOL, .item_name = (n), .boolval = (v)}
+
+#define MC_STR(n, v) \
+       {.type = CONFIG_TYPE_PSTR, .item_name = (n), .str = (v)}
+
+#define MC_CSTR(n, v) \
+       {.type = CONFIG_TYPE_PCSTR, .item_name = (n), .cstr = (v)}
+
+#define MC_PI32(n, v) \
+       {.type = CONFIG_TYPE_PI32, .item_name = (n), .pival = (v)}
+
+#define MC_PU32(n, v) \
+       {.type = CONFIG_TYPE_PU32, .item_name = (n), .pu32val = (v)}
+
+#define MC_PU64(n, v) \
+       {.type = CONFIG_TYPE_PU64, .item_name = (n), .pu64val = (v)}
+
+#define MC_PBOOL(n, v) \
+       {.type = CONFIG_TYPE_PBOOL, .item_name = (n), .pboolval = (v)}
+
+#define MC_FUN(n, fget, fset) \
+       {.type = CONFIG_TYPE_FUN, .item_name = (n),\
+       .f_get = (fget), .f_set = (fset)}
+
+#define MC_FUN_ID(n, fget, fset, cid) \
+       {.type = CONFIG_TYPE_FUN, .item_name = (n),\
+       .f_get = (fget), .f_set = (fset), .id = (cid)}
+
+
+#define REG_CONFIGS(node, configs) \
+       configs_register_configs(node, configs,\
+       sizeof(configs)/sizeof(struct mconfig))
+
+#define REG_PATH_CONFIGS(path, configs) \
+               configs_register_path_configs(path, configs,\
+               sizeof(configs)/sizeof(struct mconfig))
+
+#define INIT_REG_NODE_CONFIGS(prefix, node, name, config, rw)\
+       do {\
+               configs_init_new_node(node, name, rw);\
+               REG_CONFIGS(node, config);\
+               configs_register_path_node(prefix, node);\
+       } while (0)
+
+int configs_inc_node_ref(struct mconfig_node *node);
+int configs_dec_node_ref(struct mconfig_node *node);
+
+int configs_init_new_node(
+       struct mconfig_node *node, const char *name,
+       int rw_flags);
+
+int configs_register_node(
+       struct mconfig_node *parent,
+       struct mconfig_node *new_node);
+int configs_register_path_node(
+       const char *path, struct mconfig_node *new_node);
+
+int configs_register_configs(
+       struct mconfig_node *node, struct mconfig *configs,
+       int num);
+int configs_register_path_configs(
+       const char *path, struct mconfig *configs,
+       int num);
+
+int configs_del_endnode(
+       struct mconfig_node *parent, struct mconfig_node *node);
+int configs_get_node_path_u32(
+       struct mconfig_node *topnode, const char *path,
+       u32 *val);
+int configs_get_node_path_u64(
+       struct mconfig_node *topnode, const char *path,
+       u64 *val);
+int configs_get_node_path_2u32(
+       struct mconfig_node *topnode, const char *path,
+       u32 *val);
+int configs_get_node_path_buf(
+       struct mconfig_node *topnode, const char *path,
+       char *buf, int size);
+int configs_set_node_path_u32(
+       struct mconfig_node *topnode, const char *path,
+       u32 val);
+int configs_set_node_path_u64(
+       struct mconfig_node *topnode, const char *path,
+       u64 val);
+int configs_set_node_path_2u32(
+       struct mconfig_node *topnode, const char *path,
+       u32 val1, u32 val2);
+
+int configs_set_node_path_str(
+       struct mconfig_node *topnode, const char *path,
+       const char *val);
+int configs_set_node_path_valonpath(
+       struct mconfig_node *topnode,
+       const char *path);
+
+static inline int configs_set_path_str(
+       const char *path, const char *val)
+{
+       return configs_set_node_path_str(NULL, path, val);
+}
+
+int configs_set_node_path_str(
+       struct mconfig_node *topnode, const char *path,
+       const char *val);
+
+int configs_set_node_nodepath_str(
+       struct mconfig_node *topnode,
+       const char *path, const char *val);
+
+static inline int configs_set_path_valonpath(
+       const char *path)
+{
+       return configs_set_node_path_valonpath(NULL, path);
+}
+
+int configs_set_prefix_path_valonpath(
+       const char *prfix, const char *pathval);
+int configs_set_prefix_path_str(
+       const char *prfix, const char *path,
+       const char *str);
+
+int configs_get_node_path_str(
+       struct mconfig_node *topnode, const char *path,
+       char *buf, int size);
+
+int configs_get_node_nodepath_str(
+       struct mconfig_node *topnode,
+       const char *path, char *buf, int size);
+
+#define LIST_MODE_LIST_RD                      (CONFIG_FOR_R)
+#define LIST_MODE_LIST_WD                      (CONFIG_FOR_W)
+#define LIST_MODE_LIST_RW (LIST_MODE_LIST_RD | LIST_MODE_LIST_WD)
+#define LIST_MODE_VAL                          (1<<8)
+#define LIST_MODE_CONFIGS                      (1<<9)
+#define LIST_MODE_CONFIGS_VAL  (LIST_MODE_VAL | LIST_MODE_CONFIGS)
+#define LIST_MODE_NODE_INFO            (1<<10)
+#define LIST_MODE_PATH_NODE            (1<<11)
+#define LIST_MODE_PATH_PREFIX  (1<<12)
+#define LIST_MODE_PATH_FULLPREFIX   (1<<13)
+#define LIST_MODE_SUB_NODES            (1<<15)
+
+#define LIST_MODE_NODE_PATH_CONFIGS \
+       (LIST_MODE_LIST_RW | LIST_MODE_PATH_PREFIX | LIST_MODE_CONFIGS)
+#define LIST_MODE_NODE_CMD_VAL \
+               (LIST_MODE_NODE_PATH_CONFIGS | LIST_MODE_VAL)
+#define LIST_MODE_NODE_CMD_ALL \
+       (LIST_MODE_NODE_CMD_VAL | LIST_MODE_SUB_NODES | LIST_MODE_NODE_INFO)
+#define LIST_MODE_NODE_CMDVAL_ALL \
+       (LIST_MODE_NODE_CMD_ALL | LIST_MODE_VAL)
+#define LIST_MODE_FULL_CMA_ALL \
+       (LIST_MODE_NODE_CMD_ALL | LIST_MODE_PATH_FULLPREFIX)
+#define LIST_MODE_FULL_CMDVAL_ALL \
+       (LIST_MODE_FULL_CMA_ALL | LIST_MODE_VAL)
+
+int configs_list_node_configs(struct mconfig_node *node, char *buf, int size,
+                                                         int mode);
+int configs_list_nodes(struct mconfig_node *node, char *buf, int size,
+                                          int mode);
+int configs_list_path_nodes(const char *prefix, char *buf, int size, int mode);
+
+#endif
diff --git a/include/linux/amlogic/media/codec_mm/configs_api.h b/include/linux/amlogic/media/codec_mm/configs_api.h
new file mode 100644 (file)
index 0000000..0bf44fc
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * include/linux/amlogic/media/codec_mm/configs_api.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef AMLOGIC_MEDIA_CONFIG_API__
+#define AMLOGIC_MEDIA_CONFIG_API__
+#include <linux/ioctl.h>
+#define MAX_ITEM_NAME 128
+#define MAX_PREFIX_NAME 128
+#define MAX_VALUE_NAME  256
+struct media_config_io_str {
+       union{
+               int subcmd;
+               int ret;
+       };
+       union {
+               int para[10];
+               char cmd_path[MAX_PREFIX_NAME + MAX_ITEM_NAME + 4];
+       };
+       union {
+               char val[MAX_VALUE_NAME];
+               char *ptr;
+       };
+};
+
+
+#define AML_CONFIG  'C'
+#define MEDIA_CONFIG_SET_CMD_STR _IOW((AML_CONFIG), 0x1,\
+                               struct media_config_io_str)
+#define MEDIA_CONFIG_GET_CMD_STR _IOWR((AML_CONFIG), 0x2,\
+                               struct media_config_io_str)
+
+#endif
+
+
index 0e1d74e..1422adc 100644 (file)
@@ -54,6 +54,8 @@ extern int pts_set_resolution(u8 type, u32 level);
 
 extern int pts_set_rec_size(u8 type, u32 val);
 
+extern int pts_get_rec_num(u8 type, u32 val);
+
 extern int pts_start(u8 type);
 
 extern int pts_stop(u8 type);
index bba553b..1fc9d6c 100644 (file)
@@ -34,7 +34,8 @@ enum avevent_e {
        AUDIO_RESUME,
        AUDIO_STOP,
        AUDIO_TSTAMP_DISCONTINUITY,
-       AUDIO_PRE_START
+       AUDIO_PRE_START,
+       AUDIO_WAIT
 };
 
 enum tsync_mode_e {
index 7999e57..d638fec 100644 (file)
@@ -29,4 +29,12 @@ int codecio_read_vcbus(unsigned int reg);
 void codecio_write_vcbus(unsigned int reg, unsigned int val);
 int codecio_read_dmcbus(unsigned int reg);
 void codecio_write_dmcbus(unsigned int reg, unsigned int val);
+int codecio_read_parsbus(unsigned int reg);
+void codecio_write_parsbus(unsigned int reg, unsigned int val);
+int codecio_read_aiubus(unsigned int reg);
+void codecio_write_aiubus(unsigned int reg, unsigned int val);
+int codecio_read_demuxbus(unsigned int reg);
+void codecio_write_demuxbus(unsigned int reg, unsigned int val);
+int codecio_read_resetbus(unsigned int reg);
+void codecio_write_resetbus(unsigned int reg, unsigned int val);
 #endif
index 3887eb1..23d28a4 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/amlogic/iomap.h>
 #include <linux/io.h>
+#include <linux/amlogic/cpu_version.h>
 #include <linux/amlogic/media/old_cpu_version.h>
 #include <linux/types.h>
 #include <linux/init.h>
@@ -41,6 +42,7 @@ enum
        IO_HEVC_BUS,
        IO_VPP_BUS,
        IO_DMC_BUS,
+       IO_RESET_BUS,
        BUS_MAX
 };
 
@@ -107,5 +109,9 @@ DEF_BUS_OPS(IO_C_BUS, c);
 DEF_BUS_OPS(IO_VC_BUS, vc);
 DEF_BUS_OPS(IO_HHI_BUS, hhi);
 DEF_BUS_OPS(IO_DMC_BUS, dmc);
+DEF_BUS_OPS(IO_PARSER_BUS, pars);
+DEF_BUS_OPS(IO_AIU_BUS, aiu);
+DEF_BUS_OPS(IO_DEMUX_BUS, demux);
+DEF_BUS_OPS(IO_RESET_BUS, reset);
 
 #endif
index 9b6d3ca..90c0924 100644 (file)
 #ifndef _AML_AIU_REGS_H
 #define _AML_AIU_REGS_H
 
+/*
+ * pay attention : the regs range has
+ * changed to 0x14xx in txlx, it was
+ * converted automatically based on
+ * the platform at init.
+ * #define AIU_958_BPF 0x1400
+ */
 
 #define AIU_958_BPF                    0x1500
 #define AIU_958_BRST           0x1501
index 96e0713..b5dd501 100644 (file)
 
 #ifndef DEMUX_REGS_HEADER_
 #define DEMUX_REGS_HEADER_
+/*
+ * pay attention : the regs range has
+ * changed to 0x18xx in txlx, it was
+ * converted automatically based on
+ * the platform at init.
+ * #define FEC_INPUT_CONTROL 0x1802
+ */
 
 #define FEC_INPUT_CONTROL 0x1602
 #define FEC_INPUT_CONTROL_2 0x1652
index a91921e..08411ef 100644 (file)
@@ -71,6 +71,7 @@
 #define MC_CTRL_GCLK_CTRL 0x094d
 #define MC_OTHER_GCLK_CTRL 0x094e
 #define MC_CTRL2 0x094f
+#define MDEC_PIC_DC_MUX_CTRL 0x98d
 #define MDEC_PIC_DC_CTRL 0x098e
 #define MDEC_PIC_DC_STATUS 0x098f
 #define ANC0_CANVAS_ADDR 0x0990
 #define MDEC_DOUBLEW_CFG6 0x09e1
 #define MDEC_DOUBLEW_CFG7 0x09e2
 #define MDEC_DOUBLEW_STATUS 0x09e3
+#define MDEC_EXTIF_CFG0 0x09e4
+#define MDEC_EXTIF_CFG1 0x09e5
+
+
 /**/
 #define DBLK_RST 0x0950
 #define DBLK_CTRL 0x0951
index cd0fdc9..d0423f2 100644 (file)
 #define HEVCD_MPP_ANC_CANVAS_DATA_ADDR 0x34c1
 #define HEVCD_MPP_DECOMP_CTL1 0x34c2
 #define HEVCD_MPP_DECOMP_CTL2 0x34c3
+#define HEVCD_MPP_DECOMP_PERFMON_CTL 0x34c5
+#define HEVCD_MPP_DECOMP_PERFMON_DATA 0x34c6
 #define HEVCD_MCRCC_CTL1 0x34f0
 #define HEVCD_MCRCC_CTL2 0x34f1
 #define HEVCD_MCRCC_CTL3 0x34f2
index 532638a..cb0f133 100644 (file)
 #ifndef PARSER_REGS_HEADER_
 #define PARSER_REGS_HEADER_
 
+/*
+ * pay attention : the regs range has
+ * changed to 0x38xx in txlx, it was
+ * converted automatically based on
+ * the platform at init.
+ * #define PARSER_CONTROL 0x3860
+ */
 #define PARSER_CONTROL 0x2960
 #define PARSER_FETCH_ADDR 0x2961
 #define PARSER_FETCH_CMD 0x2962
index 630c162..a68ef52 100644 (file)
 #ifndef SYS_REGS_HEADER_
 #define SYS_REGS_HEADER_
 
+/*
+ * pay attention : the regs range has
+ * changed to 0x04xx in txlx, it was
+ * converted automatically based on
+ * the platform at init.
+ * #define RESET0_REGISTER 0x0401
+ */
+
 #define RESET0_REGISTER 0x1101
 #define RESET1_REGISTER 0x1102
 #define RESET2_REGISTER 0x1103
index 25b5cde..8b6276c 100644 (file)
@@ -48,6 +48,7 @@
 #define VDIN_LFIFO_CTRL 0x121a
 #define VDIN_COM_GCLK_CTRL 0x121b
 #define VDIN_INTF_WIDTHM1 0x121c
+#define VDIN_LFIFO_URG_CTRL 0x121e
 #define VDIN_WR_CTRL2 0x121f
 #define VDIN_WR_CTRL 0x1220
 #define VDIN_WR_H_START_END 0x1221
index 90c8da1..059e2d7 100644 (file)
 #define VD2_AFBC_PIXEL_VER_SCOPE 0x3190
 #define VD2_AFBC_VD_CFMT_H 0x3191
 
+#define VD2_IF0_GEN_REG3 0x1aa8
+
 #endif
 
index 39a4764..4b7aed5 100644 (file)
 #define VPP_VE_DEMO_CENTER_BAR 0x1da3
 #define VPP_VE_H_V_SIZE 0x1da4
 #define VPP_PSR_H_V_SIZE 0x1da5
+#define VPP_OUT_H_V_SIZE 0x1da5
 #define VPP_IN_H_V_SIZE 0x1da6
 #define VPP_VDO_MEAS_CTRL 0x1da8
 #define VPP_VDO_MEAS_VS_COUNT_HI 0x1da9
diff --git a/include/linux/amlogic/media/tvin/tvin.h b/include/linux/amlogic/media/tvin/tvin.h
new file mode 100644 (file)
index 0000000..cba2613
--- /dev/null
@@ -0,0 +1,868 @@
+/*
+ * include/linux/amlogic/media/tvin/tvin.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __TVIN_H
+#define __TVIN_H
+
+#include <linux/types.h>
+#include <linux/amlogic/media/amvecm/cm.h>
+
+enum {
+       MEMP_VDIN_WITHOUT_3D = 0,
+       MEMP_VDIN_WITH_3D,
+       MEMP_DCDR_WITHOUT_3D,
+       MEMP_DCDR_WITH_3D,
+       MEMP_ATV_WITHOUT_3D,
+       MEMP_ATV_WITH_3D,
+};
+
+/* *********************************************************************** */
+/* * TVIN general definition/enum/struct *********************************** */
+/* ************************************************************************ */
+/* tvin input port select */
+enum tvin_port_e {
+       TVIN_PORT_NULL = 0x00000000,
+       TVIN_PORT_MPEG0 = 0x00000100,
+       TVIN_PORT_BT656 = 0x00000200,
+       TVIN_PORT_BT601,
+       TVIN_PORT_CAMERA,
+       TVIN_PORT_BT656_HDMI,
+       TVIN_PORT_BT601_HDMI,
+       TVIN_PORT_VGA0 = 0x00000400,
+       TVIN_PORT_VGA1,
+       TVIN_PORT_VGA2,
+       TVIN_PORT_VGA3,
+       TVIN_PORT_VGA4,
+       TVIN_PORT_VGA5,
+       TVIN_PORT_VGA6,
+       TVIN_PORT_VGA7,
+       TVIN_PORT_COMP0 = 0x00000800,
+       TVIN_PORT_COMP1,
+       TVIN_PORT_COMP2,
+       TVIN_PORT_COMP3,
+       TVIN_PORT_COMP4,
+       TVIN_PORT_COMP5,
+       TVIN_PORT_COMP6,
+       TVIN_PORT_COMP7,
+       TVIN_PORT_CVBS0 = 0x00001000,
+       TVIN_PORT_CVBS1,
+       TVIN_PORT_CVBS2,
+       TVIN_PORT_CVBS3,
+       TVIN_PORT_CVBS4,
+       TVIN_PORT_CVBS5,
+       TVIN_PORT_CVBS6,
+       TVIN_PORT_CVBS7,
+       TVIN_PORT_SVIDEO0 = 0x00002000,
+       TVIN_PORT_SVIDEO1,
+       TVIN_PORT_SVIDEO2,
+       TVIN_PORT_SVIDEO3,
+       TVIN_PORT_SVIDEO4,
+       TVIN_PORT_SVIDEO5,
+       TVIN_PORT_SVIDEO6,
+       TVIN_PORT_SVIDEO7,
+       TVIN_PORT_HDMI0 = 0x00004000,
+       TVIN_PORT_HDMI1,
+       TVIN_PORT_HDMI2,
+       TVIN_PORT_HDMI3,
+       TVIN_PORT_HDMI4,
+       TVIN_PORT_HDMI5,
+       TVIN_PORT_HDMI6,
+       TVIN_PORT_HDMI7,
+       TVIN_PORT_DVIN0 = 0x00008000,
+       TVIN_PORT_VIDEO = 0x0000a000,
+       TVIN_PORT_VIU = 0x0000C000,
+       TVIN_PORT_MIPI = 0x00010000,
+       TVIN_PORT_ISP = 0x00020000,
+       TVIN_PORT_MAX = 0x80000000,
+};
+
+const char *tvin_port_str(enum tvin_port_e port);
+
+/* tvin signal format table */
+enum tvin_sig_fmt_e {
+       TVIN_SIG_FMT_NULL = 0,
+       /* VGA Formats */
+       TVIN_SIG_FMT_VGA_512X384P_60HZ_D147 = 0x001,
+       TVIN_SIG_FMT_VGA_560X384P_60HZ_D147 = 0x002,
+       TVIN_SIG_FMT_VGA_640X200P_59HZ_D924 = 0x003,
+       TVIN_SIG_FMT_VGA_640X350P_85HZ_D080 = 0x004,
+       TVIN_SIG_FMT_VGA_640X400P_59HZ_D940 = 0x005,
+       TVIN_SIG_FMT_VGA_640X400P_85HZ_D080 = 0x006,
+       TVIN_SIG_FMT_VGA_640X400P_59HZ_D638 = 0x007,
+       TVIN_SIG_FMT_VGA_640X400P_56HZ_D416 = 0x008,
+       TVIN_SIG_FMT_VGA_640X480P_66HZ_D619 = 0x009,
+       TVIN_SIG_FMT_VGA_640X480P_66HZ_D667 = 0x00a,
+       TVIN_SIG_FMT_VGA_640X480P_59HZ_D940 = 0x00b,
+       TVIN_SIG_FMT_VGA_640X480P_60HZ_D000 = 0x00c,
+       TVIN_SIG_FMT_VGA_640X480P_72HZ_D809 = 0x00d,
+       TVIN_SIG_FMT_VGA_640X480P_75HZ_D000_A = 0x00e,
+       TVIN_SIG_FMT_VGA_640X480P_85HZ_D008 = 0x00f,
+       TVIN_SIG_FMT_VGA_640X480P_59HZ_D638 = 0x010,
+       TVIN_SIG_FMT_VGA_640X480P_75HZ_D000_B = 0x011,
+       TVIN_SIG_FMT_VGA_640X870P_75HZ_D000 = 0x012,
+       TVIN_SIG_FMT_VGA_720X350P_70HZ_D086 = 0x013,
+       TVIN_SIG_FMT_VGA_720X400P_85HZ_D039 = 0x014,
+       TVIN_SIG_FMT_VGA_720X400P_70HZ_D086 = 0x015,
+       TVIN_SIG_FMT_VGA_720X400P_87HZ_D849 = 0x016,
+       TVIN_SIG_FMT_VGA_720X400P_59HZ_D940 = 0x017,
+       TVIN_SIG_FMT_VGA_720X480P_59HZ_D940 = 0x018,
+       TVIN_SIG_FMT_VGA_768X480P_59HZ_D896 = 0x019,
+       TVIN_SIG_FMT_VGA_800X600P_56HZ_D250 = 0x01a,
+       TVIN_SIG_FMT_VGA_800X600P_60HZ_D000 = 0x01b,
+       TVIN_SIG_FMT_VGA_800X600P_60HZ_D000_A = 0x01c,
+       TVIN_SIG_FMT_VGA_800X600P_60HZ_D317 = 0x01d,
+       TVIN_SIG_FMT_VGA_800X600P_72HZ_D188 = 0x01e,
+       TVIN_SIG_FMT_VGA_800X600P_75HZ_D000 = 0x01f,
+       TVIN_SIG_FMT_VGA_800X600P_85HZ_D061 = 0x020,
+       TVIN_SIG_FMT_VGA_832X624P_75HZ_D087 = 0x021,
+       TVIN_SIG_FMT_VGA_848X480P_84HZ_D751 = 0x022,
+       TVIN_SIG_FMT_VGA_960X600P_59HZ_D635 = 0x023,
+       TVIN_SIG_FMT_VGA_1024X768P_59HZ_D278 = 0x024,
+       TVIN_SIG_FMT_VGA_1024X768P_60HZ_D000 = 0x025,
+       TVIN_SIG_FMT_VGA_1024X768P_60HZ_D000_A = 0x026,
+       TVIN_SIG_FMT_VGA_1024X768P_60HZ_D000_B = 0x027,
+       TVIN_SIG_FMT_VGA_1024X768P_74HZ_D927 = 0x028,
+       TVIN_SIG_FMT_VGA_1024X768P_60HZ_D004 = 0x029,
+       TVIN_SIG_FMT_VGA_1024X768P_70HZ_D069 = 0x02a,
+       TVIN_SIG_FMT_VGA_1024X768P_75HZ_D029 = 0x02b,
+       TVIN_SIG_FMT_VGA_1024X768P_84HZ_D997 = 0x02c,
+       TVIN_SIG_FMT_VGA_1024X768P_74HZ_D925 = 0x02d,
+       TVIN_SIG_FMT_VGA_1024X768P_60HZ_D020 = 0x02e,
+       TVIN_SIG_FMT_VGA_1024X768P_70HZ_D008 = 0x02f,
+       TVIN_SIG_FMT_VGA_1024X768P_75HZ_D782 = 0x030,
+       TVIN_SIG_FMT_VGA_1024X768P_77HZ_D069 = 0x031,
+       TVIN_SIG_FMT_VGA_1024X768P_71HZ_D799 = 0x032,
+       TVIN_SIG_FMT_VGA_1024X1024P_60HZ_D000 = 0x033,
+       TVIN_SIG_FMT_VGA_1152X864P_60HZ_D000 = 0x034,
+       TVIN_SIG_FMT_VGA_1152X864P_70HZ_D012 = 0x035,
+       TVIN_SIG_FMT_VGA_1152X864P_75HZ_D000 = 0x036,
+       TVIN_SIG_FMT_VGA_1152X864P_84HZ_D999 = 0x037,
+       TVIN_SIG_FMT_VGA_1152X870P_75HZ_D062 = 0x038,
+       TVIN_SIG_FMT_VGA_1152X900P_65HZ_D950 = 0x039,
+       TVIN_SIG_FMT_VGA_1152X900P_66HZ_D004 = 0x03a,
+       TVIN_SIG_FMT_VGA_1152X900P_76HZ_D047 = 0x03b,
+       TVIN_SIG_FMT_VGA_1152X900P_76HZ_D149 = 0x03c,
+       TVIN_SIG_FMT_VGA_1280X720P_59HZ_D855 = 0x03d,
+       TVIN_SIG_FMT_VGA_1280X720P_60HZ_D000_A = 0x03e,
+       TVIN_SIG_FMT_VGA_1280X720P_60HZ_D000_B = 0x03f,
+       TVIN_SIG_FMT_VGA_1280X720P_60HZ_D000_C = 0x040,
+       TVIN_SIG_FMT_VGA_1280X720P_60HZ_D000_D = 0x041,
+       TVIN_SIG_FMT_VGA_1280X768P_59HZ_D870 = 0x042,
+       TVIN_SIG_FMT_VGA_1280X768P_59HZ_D995 = 0x043,
+       TVIN_SIG_FMT_VGA_1280X768P_60HZ_D100 = 0x044,
+       TVIN_SIG_FMT_VGA_1280X768P_85HZ_D000 = 0x045,
+       TVIN_SIG_FMT_VGA_1280X768P_74HZ_D893 = 0x046,
+       TVIN_SIG_FMT_VGA_1280X768P_84HZ_D837 = 0x047,
+       TVIN_SIG_FMT_VGA_1280X800P_59HZ_D810 = 0x048,
+       TVIN_SIG_FMT_VGA_1280X800P_59HZ_D810_A = 0x049,
+       TVIN_SIG_FMT_VGA_1280X800P_60HZ_D000 = 0x04a,
+       TVIN_SIG_FMT_VGA_1280X800P_85HZ_D000 = 0x04b,
+       TVIN_SIG_FMT_VGA_1280X960P_60HZ_D000 = 0x04c,
+       TVIN_SIG_FMT_VGA_1280X960P_60HZ_D000_A = 0x04d,
+       TVIN_SIG_FMT_VGA_1280X960P_75HZ_D000 = 0x04e,
+       TVIN_SIG_FMT_VGA_1280X960P_85HZ_D002 = 0x04f,
+       TVIN_SIG_FMT_VGA_1280X1024P_60HZ_D020 = 0x050,
+       TVIN_SIG_FMT_VGA_1280X1024P_60HZ_D020_A = 0x051,
+       TVIN_SIG_FMT_VGA_1280X1024P_75HZ_D025 = 0x052,
+       TVIN_SIG_FMT_VGA_1280X1024P_85HZ_D024 = 0x053,
+       TVIN_SIG_FMT_VGA_1280X1024P_59HZ_D979 = 0x054,
+       TVIN_SIG_FMT_VGA_1280X1024P_72HZ_D005 = 0x055,
+       TVIN_SIG_FMT_VGA_1280X1024P_60HZ_D002 = 0x056,
+       TVIN_SIG_FMT_VGA_1280X1024P_67HZ_D003 = 0x057,
+       TVIN_SIG_FMT_VGA_1280X1024P_74HZ_D112 = 0x058,
+       TVIN_SIG_FMT_VGA_1280X1024P_76HZ_D179 = 0x059,
+       TVIN_SIG_FMT_VGA_1280X1024P_66HZ_D718 = 0x05a,
+       TVIN_SIG_FMT_VGA_1280X1024P_66HZ_D677 = 0x05b,
+       TVIN_SIG_FMT_VGA_1280X1024P_76HZ_D107 = 0x05c,
+       TVIN_SIG_FMT_VGA_1280X1024P_59HZ_D996 = 0x05d,
+       TVIN_SIG_FMT_VGA_1280X1024P_60HZ_D000 = 0x05e,
+       TVIN_SIG_FMT_VGA_1360X768P_59HZ_D799 = 0x05f,
+       TVIN_SIG_FMT_VGA_1360X768P_60HZ_D015 = 0x060,
+       TVIN_SIG_FMT_VGA_1360X768P_60HZ_D015_A = 0x061,
+       TVIN_SIG_FMT_VGA_1360X850P_60HZ_D000 = 0x062,
+       TVIN_SIG_FMT_VGA_1360X1024P_60HZ_D000 = 0x063,
+       TVIN_SIG_FMT_VGA_1366X768P_59HZ_D790 = 0x064,
+       TVIN_SIG_FMT_VGA_1366X768P_60HZ_D000 = 0x065,
+       TVIN_SIG_FMT_VGA_1400X1050P_59HZ_D978 = 0x066,
+       TVIN_SIG_FMT_VGA_1440X900P_59HZ_D887 = 0x067,
+       TVIN_SIG_FMT_VGA_1440X1080P_60HZ_D000 = 0x068,
+       TVIN_SIG_FMT_VGA_1600X900P_60HZ_D000 = 0x069,
+       TVIN_SIG_FMT_VGA_1600X1024P_60HZ_D000 = 0x06a,
+       TVIN_SIG_FMT_VGA_1600X1200P_59HZ_D869 = 0x06b,
+       TVIN_SIG_FMT_VGA_1600X1200P_60HZ_D000 = 0x06c,
+       TVIN_SIG_FMT_VGA_1600X1200P_65HZ_D000 = 0x06d,
+       TVIN_SIG_FMT_VGA_1600X1200P_70HZ_D000 = 0x06e,
+       TVIN_SIG_FMT_VGA_1680X1050P_59HZ_D954 = 0x06f,
+       TVIN_SIG_FMT_VGA_1680X1080P_60HZ_D000 = 0x070,
+       TVIN_SIG_FMT_VGA_1920X1080P_49HZ_D929 = 0x071,
+       TVIN_SIG_FMT_VGA_1920X1080P_59HZ_D963_A = 0x072,
+       TVIN_SIG_FMT_VGA_1920X1080P_59HZ_D963 = 0x073,
+       TVIN_SIG_FMT_VGA_1920X1080P_60HZ_D000 = 0x074,
+       TVIN_SIG_FMT_VGA_1920X1200P_59HZ_D950 = 0x075,
+       TVIN_SIG_FMT_VGA_1024X768P_60HZ_D000_C = 0x076,
+       TVIN_SIG_FMT_VGA_1024X768P_60HZ_D000_D = 0x077,
+       TVIN_SIG_FMT_VGA_1920X1200P_59HZ_D988 = 0x078,
+       TVIN_SIG_FMT_VGA_1400X900P_60HZ_D000 = 0x079,
+       TVIN_SIG_FMT_VGA_1680X1050P_60HZ_D000 = 0x07a,
+       TVIN_SIG_FMT_VGA_800X600P_60HZ_D062 = 0x07b,
+       TVIN_SIG_FMT_VGA_800X600P_60HZ_317_B = 0x07c,
+       TVIN_SIG_FMT_VGA_RESERVE8 = 0x07d,
+       TVIN_SIG_FMT_VGA_RESERVE9 = 0x07e,
+       TVIN_SIG_FMT_VGA_RESERVE10 = 0x07f,
+       TVIN_SIG_FMT_VGA_RESERVE11 = 0x080,
+       TVIN_SIG_FMT_VGA_RESERVE12 = 0x081,
+       TVIN_SIG_FMT_VGA_MAX = 0x082,
+       TVIN_SIG_FMT_VGA_THRESHOLD = 0x200,
+       /* Component Formats */
+       TVIN_SIG_FMT_COMP_480P_60HZ_D000 = 0x201,
+       TVIN_SIG_FMT_COMP_480I_59HZ_D940 = 0x202,
+       TVIN_SIG_FMT_COMP_576P_50HZ_D000 = 0x203,
+       TVIN_SIG_FMT_COMP_576I_50HZ_D000 = 0x204,
+       TVIN_SIG_FMT_COMP_720P_59HZ_D940 = 0x205,
+       TVIN_SIG_FMT_COMP_720P_50HZ_D000 = 0x206,
+       TVIN_SIG_FMT_COMP_1080P_23HZ_D976 = 0x207,
+       TVIN_SIG_FMT_COMP_1080P_24HZ_D000 = 0x208,
+       TVIN_SIG_FMT_COMP_1080P_25HZ_D000 = 0x209,
+       TVIN_SIG_FMT_COMP_1080P_30HZ_D000 = 0x20a,
+       TVIN_SIG_FMT_COMP_1080P_50HZ_D000 = 0x20b,
+       TVIN_SIG_FMT_COMP_1080P_60HZ_D000 = 0x20c,
+       TVIN_SIG_FMT_COMP_1080I_47HZ_D952 = 0x20d,
+       TVIN_SIG_FMT_COMP_1080I_48HZ_D000 = 0x20e,
+       TVIN_SIG_FMT_COMP_1080I_50HZ_D000_A = 0x20f,
+       TVIN_SIG_FMT_COMP_1080I_50HZ_D000_B = 0x210,
+       TVIN_SIG_FMT_COMP_1080I_50HZ_D000_C = 0x211,
+       TVIN_SIG_FMT_COMP_1080I_60HZ_D000 = 0x212,
+       TVIN_SIG_FMT_COMP_MAX = 0x213,
+       TVIN_SIG_FMT_COMP_THRESHOLD = 0x400,
+       /* HDMI Formats */
+       TVIN_SIG_FMT_HDMI_640X480P_60HZ = 0x401,
+       TVIN_SIG_FMT_HDMI_720X480P_60HZ = 0x402,
+       TVIN_SIG_FMT_HDMI_1280X720P_60HZ = 0x403,
+       TVIN_SIG_FMT_HDMI_1920X1080I_60HZ = 0x404,
+       TVIN_SIG_FMT_HDMI_1440X480I_60HZ = 0x405,
+       TVIN_SIG_FMT_HDMI_1440X240P_60HZ = 0x406,
+       TVIN_SIG_FMT_HDMI_2880X480I_60HZ = 0x407,
+       TVIN_SIG_FMT_HDMI_2880X240P_60HZ = 0x408,
+       TVIN_SIG_FMT_HDMI_1440X480P_60HZ = 0x409,
+       TVIN_SIG_FMT_HDMI_1920X1080P_60HZ = 0x40a,
+       TVIN_SIG_FMT_HDMI_720X576P_50HZ = 0x40b,
+       TVIN_SIG_FMT_HDMI_1280X720P_50HZ = 0x40c,
+       TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_A = 0x40d,
+       TVIN_SIG_FMT_HDMI_1440X576I_50HZ = 0x40e,
+       TVIN_SIG_FMT_HDMI_1440X288P_50HZ = 0x40f,
+       TVIN_SIG_FMT_HDMI_2880X576I_50HZ = 0x410,
+       TVIN_SIG_FMT_HDMI_2880X288P_50HZ = 0x411,
+       TVIN_SIG_FMT_HDMI_1440X576P_50HZ = 0x412,
+       TVIN_SIG_FMT_HDMI_1920X1080P_50HZ = 0x413,
+       TVIN_SIG_FMT_HDMI_1920X1080P_24HZ = 0x414,
+       TVIN_SIG_FMT_HDMI_1920X1080P_25HZ = 0x415,
+       TVIN_SIG_FMT_HDMI_1920X1080P_30HZ = 0x416,
+       TVIN_SIG_FMT_HDMI_2880X480P_60HZ = 0x417,
+       TVIN_SIG_FMT_HDMI_2880X576P_50HZ = 0x418,
+       TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_B = 0x419,
+       TVIN_SIG_FMT_HDMI_1920X1080I_100HZ = 0x41a,
+       TVIN_SIG_FMT_HDMI_1280X720P_100HZ = 0x41b,
+       TVIN_SIG_FMT_HDMI_720X576P_100HZ = 0x41c,
+       TVIN_SIG_FMT_HDMI_1440X576I_100HZ = 0x41d,
+       TVIN_SIG_FMT_HDMI_1920X1080I_120HZ = 0x41e,
+       TVIN_SIG_FMT_HDMI_1280X720P_120HZ = 0x41f,
+       TVIN_SIG_FMT_HDMI_720X480P_120HZ = 0x420,
+       TVIN_SIG_FMT_HDMI_1440X480I_120HZ = 0x421,
+       TVIN_SIG_FMT_HDMI_720X576P_200HZ = 0x422,
+       TVIN_SIG_FMT_HDMI_1440X576I_200HZ = 0x423,
+       TVIN_SIG_FMT_HDMI_720X480P_240HZ = 0x424,
+       TVIN_SIG_FMT_HDMI_1440X480I_240HZ = 0x425,
+       TVIN_SIG_FMT_HDMI_1280X720P_24HZ = 0x426,
+       TVIN_SIG_FMT_HDMI_1280X720P_25HZ = 0x427,
+       TVIN_SIG_FMT_HDMI_1280X720P_30HZ = 0x428,
+       TVIN_SIG_FMT_HDMI_1920X1080P_120HZ = 0x429,
+       TVIN_SIG_FMT_HDMI_1920X1080P_100HZ = 0x42a,
+       TVIN_SIG_FMT_HDMI_1280X720P_60HZ_FRAME_PACKING = 0x42b,
+       TVIN_SIG_FMT_HDMI_1280X720P_50HZ_FRAME_PACKING = 0x42c,
+       TVIN_SIG_FMT_HDMI_1280X720P_24HZ_FRAME_PACKING = 0x42d,
+       TVIN_SIG_FMT_HDMI_1280X720P_30HZ_FRAME_PACKING = 0x42e,
+       TVIN_SIG_FMT_HDMI_1920X1080I_60HZ_FRAME_PACKING = 0x42f,
+       TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_FRAME_PACKING = 0x430,
+       TVIN_SIG_FMT_HDMI_1920X1080P_24HZ_FRAME_PACKING = 0x431,
+       TVIN_SIG_FMT_HDMI_1920X1080P_30HZ_FRAME_PACKING = 0x432,
+       TVIN_SIG_FMT_HDMI_800X600_00HZ = 0x433,
+       TVIN_SIG_FMT_HDMI_1024X768_00HZ = 0x434,
+       TVIN_SIG_FMT_HDMI_720X400_00HZ = 0x435,
+       TVIN_SIG_FMT_HDMI_1280X768_00HZ = 0x436,
+       TVIN_SIG_FMT_HDMI_1280X800_00HZ = 0x437,
+       TVIN_SIG_FMT_HDMI_1280X960_00HZ = 0x438,
+       TVIN_SIG_FMT_HDMI_1280X1024_00HZ = 0x439,
+       TVIN_SIG_FMT_HDMI_1360X768_00HZ = 0x43a,
+       TVIN_SIG_FMT_HDMI_1366X768_00HZ = 0x43b,
+       TVIN_SIG_FMT_HDMI_1600X1200_00HZ = 0x43c,
+       TVIN_SIG_FMT_HDMI_1920X1200_00HZ = 0x43d,
+       TVIN_SIG_FMT_HDMI_1440X900_00HZ = 0x43e,
+       TVIN_SIG_FMT_HDMI_1400X1050_00HZ = 0x43f,
+       TVIN_SIG_FMT_HDMI_1680X1050_00HZ = 0x440,
+       /* for alternative and 4k2k */
+       TVIN_SIG_FMT_HDMI_1920X1080I_60HZ_ALTERNATIVE = 0x441,
+       TVIN_SIG_FMT_HDMI_1920X1080I_50HZ_ALTERNATIVE = 0x442,
+       TVIN_SIG_FMT_HDMI_1920X1080P_24HZ_ALTERNATIVE = 0x443,
+       TVIN_SIG_FMT_HDMI_1920X1080P_30HZ_ALTERNATIVE = 0x444,
+       TVIN_SIG_FMT_HDMI_3840_2160_00HZ = 0x445,
+       TVIN_SIG_FMT_HDMI_4096_2160_00HZ = 0x446,
+       TVIN_SIG_FMT_HDMI_1600X900_60HZ = 0x447,
+       TVIN_SIG_FMT_HDMI_RESERVE8 = 0x448,
+       TVIN_SIG_FMT_HDMI_RESERVE9 = 0x449,
+       TVIN_SIG_FMT_HDMI_RESERVE10 = 0x44a,
+       TVIN_SIG_FMT_HDMI_RESERVE11 = 0x44b,
+       TVIN_SIG_FMT_HDMI_720X480P_60HZ_FRAME_PACKING = 0x44c,
+       TVIN_SIG_FMT_HDMI_720X576P_50HZ_FRAME_PACKING = 0x44d,
+       TVIN_SIG_FMT_HDMI_640X480P_72HZ = 0x44e,
+       TVIN_SIG_FMT_HDMI_640X480P_75HZ = 0x44f,
+       TVIN_SIG_FMT_HDMI_MAX = 0x450,
+       TVIN_SIG_FMT_HDMI_THRESHOLD = 0x600,
+       /* Video Formats */
+       TVIN_SIG_FMT_CVBS_NTSC_M = 0x601,
+       TVIN_SIG_FMT_CVBS_NTSC_443 = 0x602,
+       TVIN_SIG_FMT_CVBS_PAL_I = 0x603,
+       TVIN_SIG_FMT_CVBS_PAL_M = 0x604,
+       TVIN_SIG_FMT_CVBS_PAL_60 = 0x605,
+       TVIN_SIG_FMT_CVBS_PAL_CN = 0x606,
+       TVIN_SIG_FMT_CVBS_SECAM = 0x607,
+       TVIN_SIG_FMT_CVBS_NTSC_50 = 0x608,
+       TVIN_SIG_FMT_CVBS_MAX = 0x609,
+       TVIN_SIG_FMT_CVBS_THRESHOLD = 0x800,
+       /* 656 Formats */
+       TVIN_SIG_FMT_BT656IN_576I_50HZ = 0x801,
+       TVIN_SIG_FMT_BT656IN_480I_60HZ = 0x802,
+       /* 601 Formats */
+       TVIN_SIG_FMT_BT601IN_576I_50HZ = 0x803,
+       TVIN_SIG_FMT_BT601IN_480I_60HZ = 0x804,
+       /* Camera Formats */
+       TVIN_SIG_FMT_CAMERA_640X480P_30HZ = 0x805,
+       TVIN_SIG_FMT_CAMERA_800X600P_30HZ = 0x806,
+       TVIN_SIG_FMT_CAMERA_1024X768P_30HZ = 0x807,
+       TVIN_SIG_FMT_CAMERA_1920X1080P_30HZ = 0x808,
+       TVIN_SIG_FMT_CAMERA_1280X720P_30HZ = 0x809,
+       TVIN_SIG_FMT_BT601_MAX = 0x80a,
+       TVIN_SIG_FMT_BT601_THRESHOLD = 0xa00,
+       TVIN_SIG_FMT_MAX,
+};
+
+/* tvin signal status */
+enum tvin_sig_status_e {
+       TVIN_SIG_STATUS_NULL = 0,
+/* processing status from init to the finding of the 1st confirmed status */
+
+       TVIN_SIG_STATUS_NOSIG,  /* no signal - physically no signal */
+       TVIN_SIG_STATUS_UNSTABLE,       /* unstable - physically bad signal */
+       TVIN_SIG_STATUS_NOTSUP,
+/* not supported - physically good signal & not supported */
+
+       TVIN_SIG_STATUS_STABLE,
+/* stable - physically good signal & supported */
+};
+
+const char *tvin_sig_status_str(enum tvin_sig_status_e status);
+
+/* tvin parameters */
+#define TVIN_PARM_FLAG_CAP      0x00000001
+/* tvin_parm_t.flag[ 0]: 1/enable or 0/disable frame capture function */
+
+#define TVIN_PARM_FLAG_CAL      0x00000002
+/* tvin_parm_t.flag[ 1]: 1/enable or 0/disable adc calibration */
+
+
+/*used for processing 3d in ppmgr set this flag*/
+/*to drop one field and send real height in vframe*/
+#define TVIN_PARM_FLAG_2D_TO_3D 0x00000004
+/* tvin_parm_t.flag[ 2]: 1/enable or 0/disable 2D->3D mode */
+
+enum tvin_trans_fmt {
+       TVIN_TFMT_2D = 0,
+       TVIN_TFMT_3D_LRH_OLOR,
+/* 1 Primary: Side-by-Side(Half) Odd/Left picture, Odd/Right p */
+
+       TVIN_TFMT_3D_LRH_OLER,
+/* 2 Primary: Side-by-Side(Half) Odd/Left picture, Even/Right picture */
+
+       TVIN_TFMT_3D_LRH_ELOR,
+/* 3 Primary: Side-by-Side(Half) Even/Left picture, Odd/Right picture */
+
+       TVIN_TFMT_3D_LRH_ELER,
+/* 4 Primary: Side-by-Side(Half) Even/Left picture, Even/Right picture */
+
+       TVIN_TFMT_3D_TB,        /* 5 Primary: Top-and-Bottom */
+       TVIN_TFMT_3D_FP,        /* 6 Primary: Frame Packing */
+       TVIN_TFMT_3D_FA,        /* 7 Secondary: Field Alternative */
+       TVIN_TFMT_3D_LA,        /* 8 Secondary: Line Alternative */
+       TVIN_TFMT_3D_LRF,       /* 9 Secondary: Side-by-Side(Full) */
+       TVIN_TFMT_3D_LD,        /* 10 Secondary: L+depth */
+       TVIN_TFMT_3D_LDGD,/* 11 Secondary: L+depth+Graphics+Graphics-depth */
+       /* normal 3D format */
+       TVIN_TFMT_3D_DET_TB,    /* 12 */
+       TVIN_TFMT_3D_DET_LR,    /* 13 */
+       TVIN_TFMT_3D_DET_INTERLACE,     /* 14 */
+       TVIN_TFMT_3D_DET_CHESSBOARD,    /* 15 */
+};
+
+const char *tvin_trans_fmt_str(enum tvin_trans_fmt trans_fmt);
+
+enum tvin_color_fmt_e {
+       TVIN_RGB444 = 0,
+       TVIN_YUV422,            /* 1 */
+       TVIN_YUV444,            /* 2 */
+       TVIN_YUYV422,           /* 3 */
+       TVIN_YVYU422,           /* 4 */
+       TVIN_UYVY422,           /* 5 */
+       TVIN_VYUY422,           /* 6 */
+       TVIN_NV12,              /* 7 */
+       TVIN_NV21,              /* 8 */
+       TVIN_BGGR,              /* 9  raw data */
+       TVIN_RGGB,              /* 10 raw data */
+       TVIN_GBRG,              /* 11 raw data */
+       TVIN_GRBG,              /* 12 raw data */
+       TVIN_COLOR_FMT_MAX,
+};
+
+enum tvin_color_fmt_range_e {
+       TVIN_FMT_RANGE_NULL = 0,  /* depend on vedio fromat */
+       TVIN_RGB_FULL,  /* 1 */
+       TVIN_RGB_LIMIT, /* 2 */
+       TVIN_YUV_FULL,  /* 3 */
+       TVIN_YUV_LIMIT, /* 4 */
+       TVIN_COLOR_FMT_RANGE_MAX,
+};
+
+const char *tvin_color_fmt_str(enum tvin_color_fmt_e color_fmt);
+enum tvin_scan_mode_e {
+       TVIN_SCAN_MODE_NULL = 0,
+       TVIN_SCAN_MODE_PROGRESSIVE,
+       TVIN_SCAN_MODE_INTERLACED,
+};
+
+struct tvin_info_s {
+       enum tvin_trans_fmt trans_fmt;
+       enum tvin_sig_fmt_e fmt;
+       enum tvin_sig_status_e status;
+       enum tvin_color_fmt_e cfmt;
+       unsigned int fps;
+       unsigned int reserved;
+};
+
+struct tvin_buf_info_s {
+       unsigned int vf_size;
+       unsigned int buf_count;
+       unsigned int buf_width;
+       unsigned int buf_height;
+       unsigned int buf_size;
+       unsigned int wr_list_size;
+};
+
+struct tvin_video_buf_s {
+       unsigned int index;
+       unsigned int reserved;
+};
+
+/* hs=he=vs=ve=0 is to disable Cut Window */
+struct tvin_cutwin_s {
+       unsigned short hs;
+       unsigned short he;
+       unsigned short vs;
+       unsigned short ve;
+};
+
+struct tvin_parm_s {
+       int index;              /* index of frontend for vdin */
+       enum tvin_port_e port;  /* must set port in IOCTL */
+       struct tvin_info_s info;
+       unsigned int hist_pow;
+       unsigned int luma_sum;
+       unsigned int pixel_sum;
+       unsigned short histgram[64];
+       unsigned int flag;
+       unsigned short dest_width;      /* for vdin horizontal scale down */
+       unsigned short dest_height;     /* for vdin vertical scale down */
+       bool h_reverse;         /* for vdin horizontal reverse */
+       bool v_reverse;         /* for vdin vertical reverse */
+       unsigned int reserved;
+};
+
+/* ************************************************************************* */
+/* *** AFE module definition/enum/struct *********************************** */
+/* ************************************************************************* */
+#if 0
+enum tvafe_cmd_status_e {
+       /* idle, be ready for TVIN_IOC_S_AFE_VGA_AUTO command */
+       TVAFE_CMD_STATUS_IDLE = 0,
+       /* TVIN_IOC_S_AFE_VGA_AUTO command is in process */
+       TVAFE_CMD_STATUS_PROCESSING,
+       /* TVIN_IOC_S_AFE_VGA_AUTO command is done with success */
+       TVAFE_CMD_STATUS_SUCCESSFUL,
+       /* TVIN_IOC_S_AFE_VGA_AUTO command is done with failure */
+       TVAFE_CMD_STATUS_FAILED,
+       /* TVIN_IOC_S_AFE_VGA_AUTO command is terminated by others related */
+       TVAFE_CMD_STATUS_TERMINATED,
+};
+
+struct tvafe_vga_edid_s {
+       unsigned char value[256];       /* 256 byte EDID */
+};
+
+struct tvafe_comp_wss_s {
+       unsigned int wss1[5];
+       unsigned int wss2[5];
+};
+#endif
+struct tvafe_vga_parm_s {
+       signed short clk_step;  /* clock < 0, tune down clock freq */
+       /* clock > 0, tune up clock freq */
+       unsigned short phase;   /* phase is 0~31, it is absolute value */
+       signed short hpos_step; /* hpos_step < 0, shift display to left */
+       /* hpos_step > 0, shift display to right */
+       signed short vpos_step; /* vpos_step < 0, shift display to top */
+       /* vpos_step > 0, shift display to bottom */
+       unsigned int vga_in_clean;      /* flage for vga clean screen */
+};
+#if 0
+#define TVAFE_ADC_CAL_VALID 0x00000001
+struct tvafe_adc_cal_s {
+       /* ADC A */
+       unsigned short a_analog_clamp;  /* 0x00~0x7f */
+       unsigned short a_analog_gain;   /* 0x00~0xff, means 0dB~6dB */
+       unsigned short a_digital_offset1;       /* offset for fine-tuning */
+       /* s11.0:   signed value, 11 integer bits,  0 fraction bits */
+       unsigned short a_digital_gain;  /* 0~3.999 */
+       /* u2.10: unsigned value,  2 integer bits, 10 fraction bits */
+       unsigned short a_digital_offset2;       /* offset for format */
+       /* s11.0:   signed value, 11 integer bits,  0 fraction bits */
+       /* ADC B */
+       unsigned short b_analog_clamp;  /* ditto to ADC A */
+       unsigned short b_analog_gain;
+       unsigned short b_digital_offset1;
+       unsigned short b_digital_gain;
+       unsigned short b_digital_offset2;
+       /* ADC C */
+       unsigned short c_analog_clamp;  /* ditto to ADC A */
+       unsigned short c_analog_gain;
+       unsigned short c_digital_offset1;
+       unsigned short c_digital_gain;
+       unsigned short c_digital_offset2;
+       /* ADC D */
+       unsigned short d_analog_clamp;  /* ditto to ADC A */
+       unsigned short d_analog_gain;
+       unsigned short d_digital_offset1;
+       unsigned short d_digital_gain;
+       unsigned short d_digital_offset2;
+       unsigned int reserved;  /* bit[ 0]: TVAFE_ADC_CAL_VALID */
+};
+
+struct tvafe_adc_cal_clamp_s {
+       short a_analog_clamp_diff;
+       short b_analog_clamp_diff;
+       short c_analog_clamp_diff;
+};
+
+struct tvafe_adc_comp_cal_s {
+       struct tvafe_adc_cal_s comp_cal_val[3];
+};
+#endif
+enum tvafe_cvbs_video_e {
+       TVAFE_CVBS_VIDEO_HV_UNLOCKED = 0,
+       TVAFE_CVBS_VIDEO_H_LOCKED,
+       TVAFE_CVBS_VIDEO_V_LOCKED,
+       TVAFE_CVBS_VIDEO_HV_LOCKED,
+};
+
+/* for pin selection */
+enum tvafe_adc_pin_e {
+       TVAFE_ADC_PIN_NULL = 0,
+       /* TODO Only M8 first */
+       /*(MESON_CPU_TYPE > MESON_CPU_TYPE_MESONG9TV)*/
+       TVAFE_CVBS_IN0               = 1,
+       TVAFE_CVBS_IN1               = 2,
+       TVAFE_CVBS_IN2               = 3,
+       TVAFE_CVBS_IN3               = 4,/*as atvdemod to tvafe*/
+       /*for (MESON_CPU_TYPE < MESON_CPU_TYPE_MESONG9TV)*/
+       TVAFE_ADC_PIN_A_PGA_0 = 1,
+       TVAFE_ADC_PIN_A_PGA_1 = 2,
+       TVAFE_ADC_PIN_A_PGA_2 = 3,
+       TVAFE_ADC_PIN_A_PGA_3 = 4,
+       TVAFE_ADC_PIN_A_PGA_4 = 5,
+       TVAFE_ADC_PIN_A_PGA_5 = 6,
+       TVAFE_ADC_PIN_A_PGA_6 = 7,
+       TVAFE_ADC_PIN_A_PGA_7 = 8,
+       TVAFE_ADC_PIN_A_0 = 9,
+       TVAFE_ADC_PIN_A_1 = 10,
+       TVAFE_ADC_PIN_A_2 = 11,
+       TVAFE_ADC_PIN_A_3 = 12,
+       TVAFE_ADC_PIN_A_4 = 13,
+       TVAFE_ADC_PIN_A_5 = 14,
+       TVAFE_ADC_PIN_A_6 = 15,
+       TVAFE_ADC_PIN_A_7 = 16,
+       TVAFE_ADC_PIN_B_0 = 17,
+       TVAFE_ADC_PIN_B_1 = 18,
+       TVAFE_ADC_PIN_B_2 = 19,
+       TVAFE_ADC_PIN_B_3 = 20,
+       TVAFE_ADC_PIN_B_4 = 21,
+       TVAFE_ADC_PIN_B_5 = 22,
+       TVAFE_ADC_PIN_B_6 = 23,
+       TVAFE_ADC_PIN_B_7 = 24,
+       TVAFE_ADC_PIN_C_0 = 25,
+       TVAFE_ADC_PIN_C_1 = 26,
+       TVAFE_ADC_PIN_C_2 = 27,
+       TVAFE_ADC_PIN_C_3 = 28,
+       TVAFE_ADC_PIN_C_4 = 29,
+       TVAFE_ADC_PIN_C_5 = 30,
+       TVAFE_ADC_PIN_C_6 = 31,
+       TVAFE_ADC_PIN_C_7 = 32,
+       TVAFE_ADC_PIN_D_0 = 33,
+       TVAFE_ADC_PIN_D_1 = 34,
+       TVAFE_ADC_PIN_D_2 = 35,
+       TVAFE_ADC_PIN_D_3 = 36,
+       TVAFE_ADC_PIN_D_4 = 37,
+       TVAFE_ADC_PIN_D_5 = 38,
+       TVAFE_ADC_PIN_D_6 = 39,
+       TVAFE_ADC_PIN_D_7 = 40,
+       TVAFE_ADC_PIN_SOG_0 = 41,
+       TVAFE_ADC_PIN_SOG_1 = 42,
+       TVAFE_ADC_PIN_SOG_2 = 43,
+       TVAFE_ADC_PIN_SOG_3 = 44,
+       TVAFE_ADC_PIN_SOG_4 = 45,
+       TVAFE_ADC_PIN_SOG_5 = 46,
+       TVAFE_ADC_PIN_SOG_6 = 47,
+       TVAFE_ADC_PIN_SOG_7 = 48,
+       TVAFE_ADC_PIN_MAX,
+};
+
+enum tvafe_src_sig_e {
+       /* TODO Only M8 first */
+
+/*#if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV)*/
+       CVBS_IN0 = 0,
+       CVBS_IN1,
+       CVBS_IN2,
+       CVBS_IN3,
+#if 0
+       /*m6tv*/
+       CVBS0_Y = 0,
+       CVBS0_SOG,
+       CVBS1_Y,
+       CVBS1_SOG,
+       CVBS2_Y,
+       CVBS2_SOG,
+       CVBS3_Y,
+       CVBS3_SOG,
+       CVBS4_Y,
+       CVBS4_SOG,
+       CVBS5_Y,
+       CVBS5_SOG,
+       CVBS6_Y,
+       CVBS6_SOG,
+       CVBS7_Y,
+       CVBS7_SOG,
+       S_VIDEO0_Y,
+       S_VIDEO0_C,
+       S_VIDEO0_SOG,
+       S_VIDEO1_Y,
+       S_VIDEO1_C,
+       S_VIDEO1_SOG,
+       S_VIDEO2_Y,
+       S_VIDEO2_C,
+       S_VIDEO2_SOG,
+       S_VIDEO3_Y,
+       S_VIDEO3_C,
+       S_VIDEO3_SOG,
+       S_VIDEO4_Y,
+       S_VIDEO4_C,
+       S_VIDEO4_SOG,
+       S_VIDEO5_Y,
+       S_VIDEO5_C,
+       S_VIDEO5_SOG,
+       S_VIDEO6_Y,
+       S_VIDEO6_C,
+       S_VIDEO6_SOG,
+       S_VIDEO7_Y,
+       S_VIDEO7_C,
+       S_VIDEO7_SOG,
+       VGA0_G,
+       VGA0_B,
+       VGA0_R,
+       VGA0_SOG,
+       VGA1_G,
+       VGA1_B,
+       VGA1_R,
+       VGA1_SOG,
+       VGA2_G,
+       VGA2_B,
+       VGA2_R,
+       VGA2_SOG,
+       VGA3_G,
+       VGA3_B,
+       VGA3_R,
+       VGA3_SOG,
+       VGA4_G,
+       VGA4_B,
+       VGA4_R,
+       VGA4_SOG,
+       VGA5_G,
+       VGA5_B,
+       VGA5_R,
+       VGA5_SOG,
+       VGA6_G,
+       VGA6_B,
+       VGA6_R,
+       VGA6_SOG,
+       VGA7_G,
+       VGA7_B,
+       VGA7_R,
+       VGA7_SOG,
+       COMP0_Y,
+       COMP0_PB,
+       COMP0_PR,
+       COMP0_SOG,
+       COMP1_Y,
+       COMP1_PB,
+       COMP1_PR,
+       COMP1_SOG,
+       COMP2_Y,
+       COMP2_PB,
+       COMP2_PR,
+       COMP2_SOG,
+       COMP3_Y,
+       COMP3_PB,
+       COMP3_PR,
+       COMP3_SOG,
+       COMP4_Y,
+       COMP4_PB,
+       COMP4_PR,
+       COMP4_SOG,
+       COMP5_Y,
+       COMP5_PB,
+       COMP5_PR,
+       COMP5_SOG,
+       COMP6_Y,
+       COMP6_PB,
+       COMP6_PR,
+       COMP6_SOG,
+       COMP7_Y,
+       COMP7_PB,
+       COMP7_PR,
+       COMP7_SOG,
+       SCART0_G,
+       SCART0_B,
+       SCART0_R,
+       SCART0_CVBS,
+       SCART1_G,
+       SCART1_B,
+       SCART1_R,
+       SCART1_CVBS,
+       SCART2_G,
+       SCART2_B,
+       SCART2_R,
+       SCART2_CVBS,
+       SCART3_G,
+       SCART3_B,
+       SCART3_R,
+       SCART3_CVBS,
+       SCART4_G,
+       SCART4_B,
+       SCART4_R,
+       SCART4_CVBS,
+       SCART5_G,
+       SCART5_B,
+       SCART5_R,
+       SCART5_CVBS,
+       SCART6_G,
+       SCART6_B,
+       SCART6_R,
+       SCART6_CVBS,
+       SCART7_G,
+       SCART7_B,
+       SCART7_R,
+       SCART7_CVBS,
+#endif
+       TVAFE_SRC_SIG_MAX_NUM,
+};
+
+struct tvafe_pin_mux_s {
+       enum tvafe_adc_pin_e pin[TVAFE_SRC_SIG_MAX_NUM];
+};
+
+/* ************************************************************************* */
+/* *** IOCTL command definition ******************************************* */
+/* ************************************************************************* */
+
+#define _TM_T 'T'
+
+/* GENERAL */
+#define TVIN_IOC_OPEN               _IOW(_TM_T, 0x01, struct tvin_parm_s)
+#define TVIN_IOC_START_DEC          _IOW(_TM_T, 0x02, struct tvin_parm_s)
+#define TVIN_IOC_STOP_DEC           _IO(_TM_T, 0x03)
+#define TVIN_IOC_CLOSE              _IO(_TM_T, 0x04)
+#define TVIN_IOC_G_PARM             _IOR(_TM_T, 0x05, struct tvin_parm_s)
+#define TVIN_IOC_S_PARM             _IOW(_TM_T, 0x06, struct tvin_parm_s)
+#define TVIN_IOC_G_SIG_INFO         _IOR(_TM_T, 0x07, struct tvin_info_s)
+#define TVIN_IOC_G_BUF_INFO         _IOR(_TM_T, 0x08, struct tvin_buf_info_s)
+#define TVIN_IOC_START_GET_BUF      _IO(_TM_T, 0x09)
+#define TVIN_IOC_GET_BUF            _IOR(_TM_T, 0x10, struct tvin_video_buf_s)
+#define TVIN_IOC_PAUSE_DEC          _IO(_TM_T, 0x41)
+#define TVIN_IOC_RESUME_DEC         _IO(_TM_T, 0x42)
+#define TVIN_IOC_VF_REG             _IO(_TM_T, 0x43)
+#define TVIN_IOC_VF_UNREG           _IO(_TM_T, 0x44)
+#define TVIN_IOC_FREEZE_VF          _IO(_TM_T, 0x45)
+#define TVIN_IOC_UNFREEZE_VF        _IO(_TM_T, 0x46)
+#define TVIN_IOC_SNOWON             _IO(_TM_T, 0x47)
+#define TVIN_IOC_SNOWOFF            _IO(_TM_T, 0x48)
+
+/* TVAFE */
+#if 0
+#define TVIN_IOC_S_AFE_ADC_CAL      _IOW(_TM_T, 0x11, struct tvafe_adc_cal_s)
+#define TVIN_IOC_G_AFE_ADC_CAL      _IOR(_TM_T, 0x12, struct tvafe_adc_cal_s)
+#define TVIN_IOC_G_AFE_COMP_WSS     _IOR(_TM_T, 0x13, struct tvafe_comp_wss_s)
+#define TVIN_IOC_S_AFE_VGA_EDID     _IOW(_TM_T, 0x14, struct tvafe_vga_edid_s)
+#define TVIN_IOC_G_AFE_VGA_EDID     _IOR(_TM_T, 0x15, struct tvafe_vga_edid_s)
+#endif
+#define TVIN_IOC_S_AFE_VGA_PARM     _IOW(_TM_T, 0x16, struct tvafe_vga_parm_s)
+#define TVIN_IOC_G_AFE_VGA_PARM     _IOR(_TM_T, 0x17, struct tvafe_vga_parm_s)
+#define TVIN_IOC_S_AFE_VGA_AUTO     _IO(_TM_T, 0x18)
+#if 0
+#define TVIN_IOC_G_AFE_CMD_STATUS   _IOR(_TM_T, 0x19, enum tvafe_cmd_status_e)
+#endif
+#define TVIN_IOC_G_AFE_CVBS_LOCK    _IOR(_TM_T, 0x1a, enum tvafe_cvbs_video_e)
+#define TVIN_IOC_S_AFE_CVBS_STD     _IOW(_TM_T, 0x1b, enum tvin_sig_fmt_e)
+#define TVIN_IOC_CALLMASTER_SET     _IOW(_TM_T, 0x1c, enum tvin_port_e)
+#define TVIN_IOC_CALLMASTER_GET            _IO(_TM_T, 0x1d)
+#if 0
+#define TVIN_IOC_S_AFE_ADC_COMP_CAL \
+       _IOW(_TM_T, 0x1e, struct tvafe_adc_comp_cal_s)
+#define TVIN_IOC_G_AFE_ADC_COMP_CAL  \
+       _IOR(_TM_T, 0x1f, struct tvafe_adc_comp_cal_s)
+#endif
+#define TVIN_IOC_LOAD_REG          _IOW(_TM_T, 0x20, struct am_regs_s)
+#if 0
+#define TVIN_IOC_S_AFE_ADC_DIFF _IOW(_TM_T, 0x21, struct tvafe_adc_cal_clamp_s)
+#endif
+#define TVIN_IOC_S_AFE_SONWON     _IO(_TM_T, 0x22)
+#define TVIN_IOC_S_AFE_SONWOFF     _IO(_TM_T, 0x23)
+
+/*
+ *  function defined applied for other driver
+ */
+/*
+ * adc pll ctl, atv demod & tvafe use the same adc module
+ * module index: atv demod:0x01; tvafe:0x2
+ */
+extern void adc_set_pll_cntl(bool on, unsigned int module_sel);
+
+#endif
diff --git a/include/linux/amlogic/media/tvin/tvin_v4l2.h b/include/linux/amlogic/media/tvin/tvin_v4l2.h
new file mode 100644 (file)
index 0000000..23561b4
--- /dev/null
@@ -0,0 +1,825 @@
+/*
+ * include/linux/amlogic/media/tvin/tvin_v4l2.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __TVIN_V4L2_H
+#define __TVIN_V4L2_H
+#include "tvin.h"
+/*below macro defined applied to camera driver*/
+enum camera_light_mode_e {
+       ADVANCED_AWB = 0,
+       SIMPLE_AWB,
+       MANUAL_DAY,
+       MANUAL_A,
+       MANUAL_CWF,
+       MANUAL_CLOUDY,
+};
+
+enum camera_saturation_e {
+       SATURATION_N4_STEP = 0,
+       SATURATION_N3_STEP,
+       SATURATION_N2_STEP,
+       SATURATION_N1_STEP,
+       SATURATION_0_STEP,
+       SATURATION_P1_STEP,
+       SATURATION_P2_STEP,
+       SATURATION_P3_STEP,
+       SATURATION_P4_STEP,
+};
+
+enum camera_brightness_e {
+       BRIGHTNESS_N4_STEP = 0,
+       BRIGHTNESS_N3_STEP,
+       BRIGHTNESS_N2_STEP,
+       BRIGHTNESS_N1_STEP,
+       BRIGHTNESS_0_STEP,
+       BRIGHTNESS_P1_STEP,
+       BRIGHTNESS_P2_STEP,
+       BRIGHTNESS_P3_STEP,
+       BRIGHTNESS_P4_STEP,
+};
+
+enum camera_contrast_e {
+       CONTRAST_N4_STEP = 0,
+       CONTRAST_N3_STEP,
+       CONTRAST_N2_STEP,
+       CONTRAST_N1_STEP,
+       CONTRAST_0_STEP,
+       CONTRAST_P1_STEP,
+       CONTRAST_P2_STEP,
+       CONTRAST_P3_STEP,
+       CONTRAST_P4_STEP,
+};
+
+enum camera_hue_e {
+       HUE_N180_DEGREE = 0,
+       HUE_N150_DEGREE,
+       HUE_N120_DEGREE,
+       HUE_N90_DEGREE,
+       HUE_N60_DEGREE,
+       HUE_N30_DEGREE,
+       HUE_0_DEGREE,
+       HUE_P30_DEGREE,
+       HUE_P60_DEGREE,
+       HUE_P90_DEGREE,
+       HUE_P120_DEGREE,
+       HUE_P150_DEGREE,
+};
+
+enum camera_special_effect_e {
+       SPECIAL_EFFECT_NORMAL = 0,
+       SPECIAL_EFFECT_BW,
+       SPECIAL_EFFECT_BLUISH,
+       SPECIAL_EFFECT_SEPIA,
+       SPECIAL_EFFECT_REDDISH,
+       SPECIAL_EFFECT_GREENISH,
+       SPECIAL_EFFECT_NEGATIVE,
+};
+
+enum camera_exposure_e {
+       EXPOSURE_N4_STEP = 0,
+       EXPOSURE_N3_STEP,
+       EXPOSURE_N2_STEP,
+       EXPOSURE_N1_STEP,
+       EXPOSURE_0_STEP,
+       EXPOSURE_P1_STEP,
+       EXPOSURE_P2_STEP,
+       EXPOSURE_P3_STEP,
+       EXPOSURE_P4_STEP,
+};
+
+enum camera_sharpness_e {
+       SHARPNESS_1_STEP = 0,
+       SHARPNESS_2_STEP,
+       SHARPNESS_3_STEP,
+       SHARPNESS_4_STEP,
+       SHARPNESS_5_STEP,
+       SHARPNESS_6_STEP,
+       SHARPNESS_7_STEP,
+       SHARPNESS_8_STEP,
+       SHARPNESS_AUTO_STEP,
+};
+
+enum camera_mirror_flip_e {
+       MF_NORMAL = 0,
+       MF_MIRROR,
+       MF_FLIP,
+       MF_MIRROR_FLIP,
+};
+
+enum camera_wb_flip_e {
+       CAM_WB_AUTO = 0,
+       CAM_WB_CLOUD,
+       CAM_WB_DAYLIGHT,
+       CAM_WB_INCANDESCENCE,
+       CAM_WB_TUNGSTEN,
+       CAM_WB_FLUORESCENT,
+       CAM_WB_MANUAL,
+       CAM_WB_SHADE,
+       CAM_WB_TWILIGHT,
+       CAM_WB_WARM_FLUORESCENT,
+};
+
+enum camera_focus_mode_e {
+       CAM_FOCUS_MODE_RELEASE = 0,
+       CAM_FOCUS_MODE_FIXED,
+       CAM_FOCUS_MODE_INFINITY,
+       CAM_FOCUS_MODE_AUTO,
+       CAM_FOCUS_MODE_MACRO,
+       CAM_FOCUS_MODE_EDOF,
+       CAM_FOCUS_MODE_CONTI_VID,
+       CAM_FOCUS_MODE_CONTI_PIC,
+};
+
+/* removed this when move to new v4l2 */
+#define V4L2_CID_AUTO_FOCUS_START               (V4L2_CID_CAMERA_CLASS_BASE+28)
+#define V4L2_CID_AUTO_FOCUS_STOP                (V4L2_CID_CAMERA_CLASS_BASE+29)
+#define V4L2_CID_AUTO_FOCUS_STATUS              (V4L2_CID_CAMERA_CLASS_BASE+30)
+#define V4L2_AUTO_FOCUS_STATUS_IDLE             (0 << 0)
+#define V4L2_AUTO_FOCUS_STATUS_BUSY             (1 << 0)
+#define V4L2_AUTO_FOCUS_STATUS_REACHED          (1 << 1)
+#define V4L2_AUTO_FOCUS_STATUS_FAILED           (1 << 2)
+/* removed this when move to new v4l2 */
+
+enum camera_night_mode_flip_e {
+       CAM_NM_AUTO = 0,
+       CAM_NM_ENABLE,
+};
+
+enum camera_effect_flip_e {
+       CAM_EFFECT_ENC_NORMAL = 0,
+       CAM_EFFECT_ENC_GRAYSCALE,
+       CAM_EFFECT_ENC_SEPIA,
+       CAM_EFFECT_ENC_SEPIAGREEN,
+       CAM_EFFECT_ENC_SEPIABLUE,
+       CAM_EFFECT_ENC_COLORINV,
+};
+
+enum camera_banding_flip_e {
+       CAM_BANDING_DISABLED = 0,
+       CAM_BANDING_50HZ,
+       CAM_BANDING_60HZ,
+       CAM_BANDING_AUTO,
+       CAM_BANDING_OFF,
+};
+
+struct camera_info_s {
+       const char *camera_name;
+       enum camera_saturation_e saturation;
+       enum camera_brightness_e brighrness;
+       enum camera_contrast_e contrast;
+       enum camera_hue_e hue;
+       /* enum camera_special_effect_e special_effect; */
+       enum camera_exposure_e exposure;
+       enum camera_sharpness_e sharpness;
+       enum camera_mirror_flip_e mirro_flip;
+       enum tvin_sig_fmt_e resolution;
+       enum camera_wb_flip_e white_balance;
+       enum camera_night_mode_flip_e night_mode;
+       enum camera_effect_flip_e effect;
+       int qulity;
+};
+
+/* ---------- enum ---------- */
+
+/* LPF responding time: cycles to reach 90% target */
+enum xml_resp_s {
+       XML_RESP_0 = 0,         /* immediately */
+       XML_RESP_1,             /* 10 cycles */
+       XML_RESP_2,             /* 20 cycles */
+       XML_RESP_3,             /* 50 cycles */
+       XML_RESP_4,             /* 100 cycles */
+       XML_RESP_5,             /* 200 cycles */
+       XML_RESP_6,             /* 400 cycles */
+       XML_RESP_7,             /* 800 cycles */
+       XML_RESP_8,             /* 1600 cycles */
+       XML_RESP_9,             /* 3200 cycles */
+};
+
+enum cam_scanmode_e {
+       CAM_SCANMODE_NULL = 0,  /* turn off af */
+       CAM_SCANMODE_PROBE,
+       CAM_SCANMODE_FULL,
+};
+/*state for cmd*/
+enum cam_cmd_state_e {
+       CAM_STATE_NULL,
+       CAM_STATE_DOING,
+       CAM_STATE_ERROR,
+       CAM_STATE_SUCCESS,
+};
+
+enum cam_command_e {
+       /* common */
+       CAM_COMMAND_INIT = 0,
+       CAM_COMMAND_GET_STATE,
+       CAM_COMMAND_SCENES,
+       CAM_COMMAND_EFFECT,
+       CAM_COMMAND_AWB,
+       CAM_COMMAND_MWB,
+       CAM_COMMAND_SET_WORK_MODE,
+       /* ae related */
+       CAM_COMMAND_AE_ON,
+       CAM_COMMAND_AE_OFF,
+       CAM_COMMAND_SET_AE_LEVEL,
+       /* af related */
+       CAM_COMMAND_AF,
+       CAM_COMMAND_FULLSCAN,
+       CAM_COMMAND_TOUCH_FOCUS,
+       CAM_COMMAND_CONTINUOUS_FOCUS_ON,
+       CAM_COMMAND_CONTINUOUS_FOCUS_OFF,
+       CAM_COMMAND_BACKGROUND_FOCUS_ON,
+       CAM_COMMAND_BACKGROUND_FOCUS_OFF,
+       /* flash related */
+       CAM_COMMAND_SET_FLASH_MODE,
+       /* torch related */
+       CAM_COMMAND_TORCH,
+       /* bypass isp for raw data */
+       CMD_ISP_BYPASS,
+};
+extern const char *cam_cmd_to_str(enum cam_command_e cmd);
+
+/* ---------- xml struct ---------- */
+
+/* all "0" means no vcm */
+struct xml_vcm_s {
+       unsigned short vcm_max;
+       unsigned short vcm_min;
+       unsigned short vcm_reseponding_time;
+       /* in the unit of mS, responding_cycle =*/
+       /*responding_time/sensor_frame_rate + 1, 1 for IIC and so on */
+};
+
+/* "0" means no flash */
+enum flash_mode_s {
+       FLASH_MODE_NULL = 0,    /* no use flash */
+       FLASH_MODE_ON,
+       FLASH_MODE_OFF,
+       FLASH_MODE_AUTO,
+};
+
+#define WAVE_PARM_NUM          12
+struct wave_s {
+       unsigned int torch_rising_time;
+       unsigned int flash_rising_time;
+       unsigned int torch_flash_ratio;
+       unsigned int wave_clock_div;    /* u16 */
+       unsigned int pulse_init_time;   /* u11 */
+       unsigned int pulse_high_time;   /* u11 */
+       unsigned int pulse_low_time;    /* u11 */
+       unsigned int time_to_latch;     /* u26 */
+       unsigned int latch_time;        /* u26 */
+       unsigned int latch_time_timeout;        /* u26 */
+       unsigned int time_to_off;       /* u11 */
+       unsigned int pulse_qty_max;     /* u8 */
+};
+
+struct xml_window_s {
+       unsigned char ratio_x0; /* 0 ~ 255, x0 = (format.h * ratio_x0) >> 8 */
+       unsigned char ratio_y0; /* 0 ~ 255, y0 = (format.v * ratio_y0) >> 8 */
+       unsigned char ratio_x1; /* 0 ~ 255, x1 = (format.h * ratio_x1) >> 8 */
+       unsigned char ratio_y1; /* 0 ~ 255, y1 = (format.v * ratio_y1) >> 8 */
+};
+
+#define AE_PARM_NUM                    67
+struct xml_algorithm_ae_s {
+       unsigned int ae_algorithm;      /* 0:basic;    1:enhanced */
+       unsigned int ae_statistics[3];  /* 0: false, 1: true */
+       unsigned int ae_exp[3]; /* 0: false, 1: true */
+       unsigned int ae_ag[3];  /* 0: false, 1: true */
+       unsigned int ae_skip[3];        /* 0: false, 1: true */
+       unsigned int ratio_winl;        /* 0 ~ 1024 */
+       unsigned int ratio_winr;        /* 0 ~ 1024 */
+       unsigned int ratio_wint;        /* 0 ~ 1024 */
+       unsigned int ratio_winb;        /* 0 ~ 1024 */
+       unsigned int alert_mode;        /* 0: disable, 1: enable */
+       unsigned int tune_mode; /* 0: average mode, 1: blind up mode */
+       unsigned int ratio_r;   /* 0 ~ 255 */
+       unsigned int ratio_g;   /* 0 ~ 255 */
+       unsigned int ratio_b;   /* 0 ~ 255 */
+       unsigned int stepdnr;   /* 0 ~ 255 */
+       unsigned int stepdng;   /* 0 ~ 255 */
+       unsigned int stepdnb;   /* 0 ~ 255 */
+       unsigned int stepup;    /* 0 ~ 255 */
+       unsigned int slow_lpfcoef;      /* 0 ~ 255 */
+       unsigned int fast_lpfcoef;      /* 0 ~ 255 */
+       unsigned int coef_cur[16];      /* 0 ~ 1023 */
+       unsigned int coef_env[16];      /* 0 ~ 1023 */
+       unsigned int env_hign;  /* 0 ~ 255 */
+       unsigned int env_hign2mid;      /* 0 ~ 255 */
+       unsigned int env_low2mid;       /* 0 ~ 255 */
+       unsigned int env_low;   /* 0 ~ 255 */
+       unsigned int thr_r_high;        /* 0 ~ 255 */
+       unsigned int thr_r_mid; /* 0 ~ 255 */
+       unsigned int thr_r_low; /* 0 ~ 255 */
+       unsigned int thr_g_high;        /* 0 ~ 255 */
+       unsigned int thr_g_mid; /* 0 ~ 255 */
+       unsigned int thr_g_low; /* 0 ~ 255 */
+       unsigned int thr_b_high;        /* 0 ~ 255 */
+       unsigned int thr_b_mid; /* 0 ~ 255 */
+       unsigned int thr_b_low; /* 0 ~ 255 */
+       unsigned int lpftype_high;      /* 0 ~ 255 */
+       unsigned int lpftype_mid;       /* 0 ~ 255 */
+       unsigned int lpftype_low;       /* 0 ~ 255 */
+       unsigned int targethigh;        /* 0 ~ 255 */
+       unsigned int targetmid; /* 0 ~ 255 */
+       unsigned int targetlow; /* 0 ~ 255 */
+       unsigned int radium_inner_h;    /* 0 ~ 255 */
+       unsigned int radium_inner_m;    /* 0 ~ 255 */
+       unsigned int radium_inner_l;    /* 0 ~ 255 */
+       unsigned int radium_outer_h;    /* 0 ~ 255 */
+       unsigned int radium_outer_m;    /* 0 ~ 255 */
+       unsigned int radium_outer_l;    /* 0 ~ 255 */
+       unsigned int flash_thr; /* 0 ~ 255 */
+
+       /***********************AE_ENH********************************/
+
+       unsigned int ratio_histr;       /* 0 ~1023 */
+       unsigned int ratio_histg;       /* 0 ~1023 */
+       unsigned int ratio_histb;       /* 0 ~1023 */
+       unsigned int target_r;  /* 0 ~ 255 */
+       unsigned int target_g;  /* 0 ~ 255 */
+       unsigned int target_b;  /* 0 ~ 255 */
+       unsigned int maxrate_inner;     /* 0 ~1023 */
+       unsigned int maxrate_outer;     /* 0 ~1023 */
+       unsigned int slow_lpfcoef_enh;  /* 0 ~ 255 */
+       unsigned int fast_lpfcoef_enh;  /* 0 ~ 255 */
+       unsigned int flash_thr_enh;     /* 0 ~ 255 */
+       /***********************AE_ADD********************************/
+       unsigned int ae_ratio_low;      /* 0 ~ 1024             0x00000005 */
+       unsigned int ae_ratio_low2mid;  /* 0 ~ 1024             0x0000000f */
+       unsigned int ae_ratio_mid2high; /* 0 ~ 1024             0x0000001e */
+       unsigned int ae_ratio_high;     /* 0 ~ 1024             0x00000028 */
+       unsigned int ae_min_diff;       /* 0 ~ 255              0x00000032 */
+       unsigned int ae_max_diff;       /* 0 ~ 255              0x0000000f */
+
+       unsigned int reserve[16];
+       unsigned int aet_fmt_gain;      /* 0db for each fmt */
+
+};
+
+#define AWB_PARM_NUM                   58
+struct xml_algorithm_awb_s {
+       unsigned int awb_algorithm;     /* 0:basic;    1:enhanced */
+       unsigned int ratio_winl;        /* 0 ~ 1024 */
+       unsigned int ratio_winr;        /* 0 ~ 1024 */
+       unsigned int ratio_wint;        /* 0 ~ 1024 */
+       unsigned int ratio_winb;        /* 0 ~ 1024 */
+       unsigned int ratio_rgb; /* 0 ~ 255 */
+       unsigned int ratio_yh;  /* 0 ~ 255 */
+       unsigned int ratio_ym;  /* 0 ~ 255 */
+       unsigned int ratio_yl;  /* 0 ~ 255 */
+       unsigned int yyh;       /* 0 ~ 255 */
+       unsigned int yym;       /* 0 ~ 255 */
+       unsigned int yyl;       /* 0 ~ 255 */
+       unsigned int coef_r[4]; /* 0 ~ 255 */
+       unsigned int coef_g[4]; /* 0 ~ 255 */
+       unsigned int coef_b[4]; /* 0 ~ 255 */
+       unsigned int inner_rg;  /* 0 ~ 1023 */
+       unsigned int inner_bg;  /* 0 ~ 1023 */
+       unsigned int outer_rg;  /* 0 ~ 1023 */
+       unsigned int outer_bg;  /* 0 ~ 1023 */
+       unsigned int r_max;     /* 0 ~ 4095 */
+       unsigned int r_min;     /* 0 ~ 4095 */
+       unsigned int b_max;     /* 0 ~ 4095 */
+       unsigned int b_min;     /* 0 ~ 4095 */
+       unsigned int thr_gb_h;  /* 0 ~ 255 */
+       unsigned int thr_gb_m;  /* 0 ~ 255 */
+       unsigned int thr_gb_l;  /* 0 ~ 255 */
+       unsigned int thr_gr_h;  /* 0 ~ 255 */
+       unsigned int thr_gr_m;  /* 0 ~ 255 */
+       unsigned int thr_gr_l;  /* 0 ~ 255 */
+       unsigned int thr_br_h;  /* 0 ~ 255 */
+       unsigned int thr_br_m;  /* 0 ~ 255 */
+       unsigned int thr_br_l;  /* 0 ~ 255 */
+       unsigned int thr_du_h;  /* 0 ~ 255 */
+       unsigned int thr_du_m;  /* 0 ~ 255 */
+       unsigned int thr_du_l;  /* 0 ~ 255 */
+       unsigned int thr_dv_h;  /* 0 ~ 255 */
+       unsigned int thr_dv_m;  /* 0 ~ 255 */
+       unsigned int thr_dv_l;  /* 0 ~ 255 */
+       unsigned int thr_yh_h;  /* 0 ~ 255 */
+       unsigned int thr_yh_m;  /* 0 ~ 255 */
+       unsigned int thr_yh_l;  /* 0 ~ 255 */
+       unsigned int thr_yl_h;  /* 0 ~ 255 */
+       unsigned int thr_yl_m;  /* 0 ~ 255 */
+       unsigned int thr_yl_l;  /* 0 ~ 255 */
+       /*********************awb_enh****************/
+       unsigned int ratio_yuv;
+       unsigned int slow_lpfcoef;      /* 0 ~ 255 */
+       unsigned int fast_lpfcoef;      /* 0 ~ 255 */
+       unsigned int outer;     /* 0 ~ 1023 */
+       unsigned int inner;     /* 0 ~ 1023 */
+       unsigned int rw_limith; /* 0 ~ 4095 */
+       unsigned int rw_limitl; /* 0 ~ 4095 */
+       unsigned int gw_limith; /* 0 ~ 4095 */
+       unsigned int gw_limitl; /* 0 ~ 4095 */
+       unsigned int bw_limith; /* 0 ~ 4095 */
+       unsigned int bw_limitl; /* 0 ~ 4095 */
+       unsigned int thr_u[20]; /* 0 ~ 255 */
+       unsigned int thr_v[20]; /* 0 ~ 255 */
+       unsigned int reserve[16];
+};
+
+#define AF_PARM_NUM                    13
+
+#define FOCUS_GRIDS 16
+
+struct xml_algorithm_af_s {
+       /*for lose focus */
+       unsigned int enter_static_ratio;        /* 10bit/1024 */
+       unsigned int detect_step_cnt;
+       unsigned int ave_vdc_thr;       /* the threshold of enter move */
+       /*full scan & detect window ratio */
+       unsigned int
+       win_ratio;/* cut 4 border in top bottom left right widht=1/ratio */
+       /*for climbing algorithm */
+       unsigned int step[FOCUS_GRIDS];
+       unsigned int valid_step_cnt;
+       unsigned int jump_offset;
+       unsigned int field_delay;
+       /*window for touch focus */
+       unsigned int x;         /* x coord of touch focus win */
+       unsigned int y;         /* y coord of touch focus win */
+       unsigned int radius_ratio;      /* radius of touch focus win */
+       unsigned int hillside_fall;
+       unsigned int reserve[15];
+};
+
+#define XML_LUT_LS 1025                /* 32*32 32-bit */
+struct xml_lut_ls_s {
+       unsigned int reg_map[XML_LUT_LS];
+};
+
+#define XML_LUT_GC 257         /* 257*3 10-bit */
+struct xml_lut_gc_s {
+       unsigned short gamma_r[XML_LUT_GC];
+       unsigned short gamma_g[XML_LUT_GC];
+       unsigned short gamma_b[XML_LUT_GC];
+};
+
+#define XML_TOP 9              /* top */
+struct xml_top_s {
+       unsigned int reg_map[XML_TOP];
+};
+
+#define XML_TP 20              /* test pattern */
+struct xml_tp_s {
+       unsigned int reg_map[XML_TP];
+};
+
+#define XML_CG 6               /* clamp & gain */
+struct xml_cg_s {
+       unsigned int reg_map[XML_CG];
+};
+
+#define XML_LS 5               /* lens shielding */
+struct xml_ls_s {
+       unsigned int reg_map[XML_LS];
+};
+
+#define XML_GC 1               /* gamma curve */
+struct xml_gc_s {
+       unsigned int reg_map[XML_GC];
+};
+
+#define XML_DP 11              /* defect pixel */
+struct xml_dp_s {
+       unsigned int reg_map[XML_DP];
+};
+
+#define XML_DM 2               /* demosaicing */
+struct xml_dm_s {
+       unsigned int reg_map[XML_DM];
+};
+
+#define XML_CSC 9              /* colr space conversion */
+struct xml_csc_s {
+       unsigned int reg_map[XML_CSC << 1];     /* sd/hd sensitive */
+};
+
+#define XML_NR 13              /* noise reduction */
+struct xml_nr_s {
+       unsigned int reg_map[XML_NR];
+};
+
+#define XML_SH 33              /* shanrpness */
+struct xml_sharp_s {
+       unsigned int reg_map[XML_SH];
+};
+
+#define XML_DBG 2              /* debug */
+struct xml_dbg_s {
+       unsigned int reg_map[XML_DBG];
+};
+
+#define XML_BN 3               /* black level & noise meter */
+struct xml_bn_s {
+       unsigned int reg_map[XML_BN];
+};
+
+#define XML_AE 6               /* auto explosure statistics */
+struct xml_ae_s {
+       unsigned int reg_map[XML_AE];
+};
+
+#define XML_AWB 5              /* auto white balance statistics */
+struct xml_awb_s {
+       unsigned int reg_map[XML_AWB];
+};
+
+#define XML_AF 17              /* auto focus statistics */
+struct xml_af_s {
+       unsigned int reg_map[XML_AF];
+};
+/*
+ *#define XML_WAVE 1 // wave generatore
+ *struct xml_wave_s {
+ *     unsigned int reg_map[XML_WAVE];
+ *} xml_wave_t;
+ */
+struct xml_peripheral_s {
+       /* struct xml_sensor_s sensor; */
+       /* struct xml_ae_level_s  ae_level; */
+       struct xml_vcm_s vcm;
+};
+
+struct xml_default_regs_s {
+       struct xml_top_s top;
+       struct xml_tp_s tp;     /* disable */
+       struct xml_cg_s cg;     /* straight */
+       struct xml_ls_s ls;
+       struct xml_gc_s gc;
+       struct xml_dp_s dp;     /* w/o static lut */
+       struct xml_dm_s dm;
+       struct xml_csc_s csc;   /* RGB->YUV */
+       struct xml_nr_s nr;     /* disable */
+       struct xml_sharp_s sharp;       /* disable */
+       struct xml_dbg_s dbg;   /* disable */
+       struct xml_bn_s bn;     /* disable */
+       struct xml_ae_s ae_reg;
+       struct xml_awb_s awb_reg;
+       struct xml_af_s af_reg;
+       struct xml_lut_ls_s lnsd;
+       struct xml_lut_gc_s lut_gc;
+};
+
+struct xml_scenes_s {
+       struct xml_algorithm_ae_s ae;
+       struct xml_algorithm_awb_s awb;
+       struct xml_algorithm_af_s af;
+};
+/*only G0 R1 B2 G3*/
+struct xml_wb_manual_s {
+       unsigned int reg_map[2];
+};
+
+struct xml_effect_manual_s {
+       struct xml_csc_s csc;
+       /* RGB->YUV with effect: r, g, b,*/
+       /*brightness, contrast, hue, saturation, y_mirror, ... */
+};
+
+/* ---------- camera struct ---------- */
+/* start tvin service will get format information */
+/*
+ *struct cam_format_s {
+ *    unsigned short h;
+ *   unsigned short v;
+ *  unsigned short frame_time; //
+ *   //in the unit of uS, for example, frame_time = 40(mS) means 25Hz format.
+ *} cam_format_t;
+ */
+struct cam_function_s {
+       bool (*set_af_new_step)(void *priv, unsigned int af_debug_control);
+       unsigned int (*get_aet_current_step)(void *priv);
+       unsigned int (*get_aet_current_gain)(void *priv);
+       unsigned int (*get_aet_min_gain)(void *priv);
+       unsigned int (*get_aet_max_gain)(void *priv);
+       unsigned int (*get_aet_max_step)(void *priv);
+       unsigned int (*get_aet_gain_by_step)(void *priv,
+               unsigned int new_step);
+       bool (*set_aet_new_step)(void *priv, unsigned int new_step,
+               bool exp_mode, bool ag_mode);
+       bool (*check_mains_freq)(void *priv);
+       void *priv_data;
+};
+
+struct cam_manual_s {
+       unsigned short ae_step;
+       unsigned short focus;
+       unsigned short torch;
+};
+
+struct cam_window_s {
+       unsigned short x0;
+       unsigned short y0;
+       unsigned short x1;
+       unsigned short y1;
+};
+
+#define CAP_PARM_NUM                   8
+struct xml_capture_s {
+       unsigned int ae_try_max_cnt;
+       unsigned int sigle_count;
+       unsigned int skip_step;
+       unsigned int multi_capture_num;
+       enum cam_scanmode_e af_mode;
+       unsigned int eyetime;   /* ms */
+       unsigned int pretime;   /* ms */
+       unsigned int postime;   /* ms */
+};
+/*for isp work mode*/
+enum camera_mode_e {
+       CAMERA_PREVIEW,
+       CAMERA_CAPTURE,
+       CAMERA_RECORD,
+};
+
+/*this parameter must be passed to vdin when stream on*/
+struct cam_parameter_s {
+       enum cam_command_e cam_command;
+       enum cam_scanmode_e cam_scanmode;
+       struct cam_function_s cam_function;
+       struct cam_manual_s cam_manual;
+       struct cam_window_s cam_touch_window;
+       struct xml_peripheral_s *xml_peripheral;
+       struct xml_scenes_s *xml_scenes;
+       struct xml_default_regs_s *xml_regs_map;
+       struct xml_effect_manual_s *xml_effect_manual;
+       struct xml_wb_manual_s *xml_wb_manual;
+       struct xml_capture_s *xml_capture;
+       struct wave_s *xml_wave;
+       unsigned int level;     /* the torch light level */
+       enum flash_mode_s flash_mode;   /* the flash mode */
+       enum camera_mode_e cam_mode;    /* set the isp work mode */
+       int exposure_level;     /* manual exposure level 2db by each step */
+};
+
+struct isp_status_s {
+       unsigned short focus;
+       bool fullscan_done;
+};
+
+enum vdin_format_convert_e {
+       VDIN_MATRIX_XXX_YUV_BLACK = 0,
+       VDIN_FORMAT_CONVERT_YUV_YUV422,
+       VDIN_FORMAT_CONVERT_YUV_YUV444,
+       VDIN_FORMAT_CONVERT_YUV_RGB,
+       VDIN_FORMAT_CONVERT_YUV_GBR,
+       VDIN_FORMAT_CONVERT_YUV_BRG,
+       VDIN_FORMAT_CONVERT_RGB_YUV422,
+       VDIN_FORMAT_CONVERT_GBR_YUV422,
+       VDIN_FORMAT_CONVERT_BRG_YUV422,
+       VDIN_FORMAT_CONVERT_RGB_YUV444,
+       VDIN_FORMAT_CONVERT_RGB_RGB,
+       VDIN_FORMAT_CONVERT_YUV_NV12,
+       VDIN_FORMAT_CONVERT_YUV_NV21,
+       VDIN_FORMAT_CONVERT_RGB_NV12,
+       VDIN_FORMAT_CONVERT_RGB_NV21,
+       VDIN_FORMAT_CONVERT_MAX,
+};
+
+enum vdin_cmd_e {
+       VDIN_CMD_NULL = 0,
+       VDIN_CMD_SET_CSC,
+       VDIN_CMD_SET_CM2,
+       VDIN_CMD_ISR,
+       VDIN_CMD_MPEGIN_START,
+       VDIN_CMD_GET_HISTGRAM,
+       VDIN_CMD_MPEGIN_STOP,
+       VDIN_CMD_FORCE_GO_FIELD,
+};
+
+struct vdin_arg_s {
+       enum vdin_cmd_e cmd;
+       unsigned int h_active;
+       unsigned int v_active;
+       unsigned char matrix_id;
+       enum vdin_format_convert_e color_convert;
+       unsigned int *cm2;
+       void *private;
+};
+
+enum bt_path_e {
+       BT_PATH_GPIO = 0,
+       BT_PATH_CSI2,
+       BT_PATH_GPIO_B,
+};
+
+enum clk_channel_e {
+       CLK_CHANNEL_A = 0,
+       CLK_CHANNEL_B,
+};
+
+enum cam_interface_e {
+       CAM_DVP = 0,
+       CAM_MIPI,
+};
+
+/* *********************************************************************** */
+/* *** IOCTL command definitions ***************************************** */
+/* *********************************************************************** */
+
+#define CAMERA_IOC_MAGIC 'C'
+
+#define CAMERA_IOC_START        \
+       _IOW(CAMERA_IOC_MAGIC, 0x01, struct camera_info_s)
+#define CAMERA_IOC_STOP         \
+       _IO(CAMERA_IOC_MAGIC, 0x02)
+#define CAMERA_IOC_SET_PARA     \
+       _IOW(CAMERA_IOC_MAGIC, 0x03, struct camera_info_s)
+#define CAMERA_IOC_GET_PARA     \
+       _IOR(CAMERA_IOC_MAGIC, 0x04, struct camera_info_s)
+#define CAMERA_IOC_START_CAPTURE_PARA     \
+       _IOR(CAMERA_IOC_MAGIC, 0x05, struct camera_info_s)
+#define CAMERA_IOC_STOP_CAPTURE_PARA \
+       _IOR(CAMERA_IOC_MAGIC, 0x06, struct camera_info_s)
+
+struct csi_parm_s {
+       /* am_csi2_hw_t *hw_info; */
+       unsigned char lanes;
+       unsigned char channel;
+       unsigned char mode;
+       unsigned char clock_lane_mode;  /* 0 clock gate 1: always on */
+       unsigned int active_pixel;
+       unsigned int active_line;
+       unsigned int frame_size;
+       unsigned int ui_val;    /* ns */
+       unsigned int hs_freq;   /* hz */
+       unsigned int urgent;
+       unsigned int settle;
+
+       unsigned int lane_mask;
+
+       enum clk_channel_e clk_channel;
+       unsigned int skip_frames;
+       enum tvin_color_fmt_e csi_ofmt;
+};
+
+/* add for vdin called by backend driver */
+struct vdin_parm_s {
+       enum tvin_port_e port;
+       enum tvin_sig_fmt_e
+       fmt;/* >max:use the information*/
+               /*from parameter rather than format table */
+       enum tvin_color_fmt_e
+       cfmt;   /* for camera input mainly,the data sequence is different */
+       enum tvin_scan_mode_e scan_mode;/* 1: progressive 2:interlaced */
+       unsigned short h_active;
+       unsigned short v_active;
+       unsigned short frame_rate;
+       /*for bt656 */
+       enum bt_path_e bt_path; /* 0:from gpio,1:from csi2 */
+       unsigned char hsync_phase;      /* 1: inverted 0: original */
+       unsigned char vsync_phase;      /* 1: inverted 0: origianl */
+       unsigned short hs_bp;/* the horizontal start postion of bt656 window */
+       unsigned short vs_bp;/* the vertical start postion of bt656 window */
+       /*for isp tell different frontends such as bt656/mipi */
+       enum tvin_port_e isp_fe_port;
+       /*for vdin cfmt convert & scale&skip */
+       enum tvin_color_fmt_e
+       dfmt;   /* vdin will convert color space accroding to dfmt */
+       unsigned short dest_hactive;    /* for vdin scale down */
+       unsigned short dest_vactive;
+       unsigned short skip_count;      /* for skip frame */
+
+       struct csi_parm_s csi_hw_info;
+       /*for reserved */
+       uintptr_t reserved;
+};
+
+struct fe_arg_s {
+       enum tvin_port_e port;
+       int index;
+       void *arg;
+};
+
+struct vdin_v4l2_ops_s {
+       int (*start_tvin_service)(int no, struct vdin_parm_s *para);
+       int (*stop_tvin_service)(int no);
+       void (*set_tvin_canvas_info)(int start, int num);
+       void (*get_tvin_canvas_info)(int *start, int *num);
+       int (*tvin_fe_func)(int no, struct fe_arg_s *arg);/* for isp command */
+       int (*tvin_vdin_func)(int no, struct vdin_arg_s *arg);
+       void *private;
+};
+
+/*macro defined applied to camera driver is ending*/
+extern int v4l2_vdin_ops_init(struct vdin_v4l2_ops_s *vdin_v4l2p);
+extern struct vdin_v4l2_ops_s *get_vdin_v4l2_ops(void);
+extern int vdin_reg_v4l2(struct vdin_v4l2_ops_s *ops);
+#endif
index 316a476..13b86d0 100644 (file)
@@ -47,8 +47,10 @@ enum aformat_e {
        AFORMAT_MPEG1 = 26,
        AFORMAT_MPEG2 = 27,
        AFORMAT_WMAVOI = 28,
-       AFORMAT_UNSUPPORT = 29,
-       AFORMAT_MAX = 30
+       AFORMAT_WMALOSSLESS = 29,
+       AFORMAT_PCM_S24LE = 30,
+       AFORMAT_UNSUPPORT = 31,
+       AFORMAT_MAX = 32
 };
 
 #endif /* AFORMAT_H */
index 5b1ace2..a184f6e 100644 (file)
@@ -18,6 +18,7 @@
 #ifndef AMPORTS_CONFIG_HHH
 #define AMPORTS_CONFIG_HHH
 #include <linux/kconfig.h>
+#include <linux/amlogic/cpu_version.h>
 #include <linux/amlogic/media/old_cpu_version.h>
 
 /*
index e8daf60..fcef9f8 100644 (file)
@@ -86,6 +86,9 @@
 #define AMSTREAM_IOC_TS_SKIPBYTE _IOW((_A_M), 0x1d, int)
 #define AMSTREAM_IOC_SUB_TYPE    _IOW((_A_M), 0x1e, int)
 #define AMSTREAM_IOC_CLEAR_VIDEO _IOW((_A_M), 0x1f, int)
+#define AMSTREAM_IOC_VDECINFO _IOR((_A_M), 0x20, int)
+#define AMSTREAM_IOC_GLOBAL_GET_VIDEO_OUTPUT  _IOR((_A_M), 0x21, int)
+#define AMSTREAM_IOC_GLOBAL_SET_VIDEO_OUTPUT  _IOW((_A_M), 0x22, int)
 
 #define AMSTREAM_IOC_APTS             _IOR((_A_M), 0x40, int)
 #define AMSTREAM_IOC_VPTS             _IOR((_A_M), 0x41, int)
 #define AMSTREAM_IOC_SET_BLACKOUT_POLICY   _IOW((_A_M), 0x53, int)
 #define AMSTREAM_IOC_UD_LENGTH _IOR((_A_M), 0x54, int)
 #define AMSTREAM_IOC_UD_POC _IOR((_A_M), 0x55, int)
+#define AMSTREAM_IOC_UD_FLUSH_USERDATA _IOR((_A_M), 0x56, int)
 #define AMSTREAM_IOC_GET_SCREEN_MODE _IOR((_A_M), 0x58, int)
 #define AMSTREAM_IOC_SET_SCREEN_MODE _IOW((_A_M), 0x59, int)
 #define AMSTREAM_IOC_GET_VIDEO_DISCONTINUE_REPORT _IOR((_A_M), 0x5a, int)
@@ -255,6 +259,26 @@ struct vdec_status {
        unsigned int status;
 };
 
+struct vdec_info {
+       char vdec_name[16];
+       unsigned int ver;
+       unsigned int frame_width;
+       unsigned int frame_height;
+       unsigned int frame_rate;
+       unsigned int bit_rate;
+       unsigned int frame_dur;
+       unsigned int frame_data;
+       unsigned int error_count;
+       unsigned int status;
+       unsigned int frame_count;
+       unsigned int error_frame_count;
+       unsigned int drop_frame_count;
+       unsigned long long total_data;
+       unsigned int samp_cnt;
+       unsigned int offset;
+       char reserved[32];
+};
+
 struct adec_status {
        unsigned int channels;
        unsigned int sample_rate;
@@ -280,6 +304,19 @@ struct am_io_param {
                struct adec_status astatus;
        };
 };
+
+struct am_io_info {
+       union {
+               int data;
+               int id;
+       };
+       int len;
+       union {
+               char buf[1];
+               struct vdec_info vinfo;
+       };
+};
+
 struct audio_info {
 
        int valid;
@@ -412,6 +449,9 @@ struct userdata_poc_info_t {
 #define AMSTREAM_SET_VSYNC_UPINT 0x172
 #define AMSTREAM_SET_VSYNC_SLOW_FACTOR 0x173
 #define AMSTREAM_SET_FRAME_BASE_PATH 0x174
+#define AMSTREAM_SET_EOS 0x175
+#define AMSTREAM_SET_RECEIVE_ID 0x176
+
 /*  video set ex cmd */
 #define AMSTREAM_SET_EX_VIDEO_AXIS 0x260
 #define AMSTREAM_SET_EX_VIDEO_CROP 0x261
@@ -440,7 +480,7 @@ struct userdata_poc_info_t {
 #define AMSTREAM_GET_AUDIO_AVG_BITRATE_BPS 0x810
 #define AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS 0x811
 #define AMSTREAM_GET_ION_ID 0x812
-
+#define AMSTREAM_GET_NEED_MORE_DATA 0x813
 /*  video get cmd */
 #define AMSTREAM_GET_OMX_VPTS 0x860
 #define AMSTREAM_GET_TRICK_STAT 0x861
@@ -547,12 +587,13 @@ struct tsdemux_ops {
 void tsdemux_set_ops(struct tsdemux_ops *ops);
 int tsdemux_set_reset_flag(void);
 
-void set_adec_func(int (*adec_func) (struct adec_status *));
+void set_adec_func(int (*adec_func)(struct adec_status *));
 void wakeup_sub_poll(void);
-void set_userdata_poc(struct userdata_poc_info_t poc);
 void init_userdata_fifo(void);
-int wakeup_userdata_poll(int wp, unsigned long start_phyaddr, int buf_size,
-       int data_length);
+void reset_userdata_fifo(int bInit);
+int wakeup_userdata_poll(struct userdata_poc_info_t poc,
+                       int wp, unsigned long start_phyaddr,
+                       int buf_size, int data_length);
 int get_sub_type(void);
 
 #endif                         /**/
index 81818eb..37fc657 100644 (file)
 #define SET_MPEG_REG_MASK(r, mask)\
        WRITE_MPEG_REG(r, READ_MPEG_REG(r) | (mask))
 
+#define WRITE_PARSER_REG(r, val) codec_parsbus_write(r, val)
+#define READ_PARSER_REG(r) codec_parsbus_read(r)
+#define WRITE_PARSER_REG_BITS(r, val, start, len) \
+       WRITE_PARSER_REG(r, (READ_PARSER_REG(r) & ~(((1L<<(len))-1)<<(start)))|\
+                   ((unsigned int)((val)&((1L<<(len))-1)) << (start)))
+
+#define CLEAR_PARSER_REG_MASK(r, mask)\
+       WRITE_PARSER_REG(r, READ_PARSER_REG(r) & ~(mask))
+#define SET_PARSER_REG_MASK(r, mask)\
+       WRITE_PARSER_REG(r, READ_PARSER_REG(r) | (mask))
+
 #define WRITE_HHI_REG(r, val)      codec_hhibus_write(r, val)
 #define READ_HHI_REG(r) codec_hhibus_read(r)
 #define WRITE_HHI_REG_BITS(r, val, start, len) \
        WRITE_HHI_REG(r, (READ_HHI_REG(r) & ~(((1L<<(len))-1)<<(start)))|\
                    ((unsigned int)((val)&((1L<<(len))-1)) << (start)))
 
+#define WRITE_AIU_REG(r, val) codec_aiubus_write(r, val)
+#define READ_AIU_REG(r) codec_aiubus_read(r)
+#define WRITE_AIU_REG_BITS(r, val, start, len) \
+       WRITE_AIU_REG(r, (READ_AIU_REG(r) & ~(((1L<<(len))-1)<<(start)))|\
+                   ((unsigned int)((val)&((1L<<(len))-1)) << (start)))
+
+#define CLEAR_AIU_REG_MASK(r, mask)\
+       WRITE_AIU_REG(r, READ_AIU_REG(r) & ~(mask))
+#define SET_AIU_REG_MASK(r, mask)\
+       WRITE_AIU_REG(r, READ_AIU_REG(r) | (mask))
+
+#define WRITE_DEMUX_REG(r, val) codec_demuxbus_write(r, val)
+#define READ_DEMUX_REG(r) codec_demuxbus_read(r)
+#define WRITE_DEMUX_REG_BITS(r, val, start, len) \
+       WRITE_DEMUX_REG(r, (READ_DEMUX_REG(r) & ~(((1L<<(len))-1)<<(start)))|\
+                   ((unsigned int)((val)&((1L<<(len))-1)) << (start)))
+
+#define CLEAR_DEMUX_REG_MASK(r, mask)\
+       WRITE_DEMUX_REG(r, READ_DEMUX_REG(r) & ~(mask))
+#define SET_DEMUX_REG_MASK(r, mask)\
+       WRITE_DEMUX_REG(r, READ_DEMUX_REG(r) | (mask))
+
+#define WRITE_RESET_REG(r, val) codec_resetbus_write(r, val)
+#define READ_RESET_REG(r) codec_resetbus_read(r)
+#define WRITE_RESET_REG_BITS(r, val, start, len) \
+       WRITE_RESET_REG(r, (READ_RESET_REG(r) & ~(((1L<<(len))-1)<<(start)))|\
+                   ((unsigned int)((val)&((1L<<(len))-1)) << (start)))
+
+#define CLEAR_RESET_REG_MASK(r, mask)\
+       WRITE_RESET_REG(r, READ_RESET_REG(r) & ~(mask))
+#define SET_RESET_REG_MASK(r, mask)\
+       WRITE_RESET_REG(r, READ_RESET_REG(r) | (mask))
+
 #define ASSIST_MBOX1_CLR_REG VDEC_ASSIST_MBOX1_CLR_REG
 #define ASSIST_MBOX1_MASK VDEC_ASSIST_MBOX1_MASK
 #define ASSIST_AMR1_INT0 VDEC_ASSIST_AMR1_INT0
index 28abccc..0aa2f38 100644 (file)
 #define VFRAME_FLAG_NO_DISCONTINUE      1
 #define VFRAME_FLAG_SWITCHING_FENSE     2
 #define VFRAME_FLAG_HIGH_BANDWIDTH     4
-
-#define TB_DETECT_MASK                                 0x00000040
-#define TB_DETECT_MASK_BIT                             6
-#define TB_DETECT_NONE                                 0
-#define TB_DETECT_INVERT                               1
-#define TB_DETECT_NC                                   0
-#define TB_DETECT_TFF                                  1
-#define TB_DETECT_BFF                                  2
-#define TB_DETECT_TBF                                  3
+#define VFRAME_FLAG_ERROR_RECOVERY             8
+#define VFRAME_FLAG_SYNCFRAME                  0x10
 
 enum pixel_aspect_ratio_e {
        PIXEL_ASPECT_RATIO_1_1,
@@ -205,6 +198,12 @@ enum vframe_secam_phase_e {
        VFRAME_PHASE_DB = 0,
        VFRAME_PHASE_DR,
 };
+enum vframe_disp_mode_e {
+       VFRAME_DISP_MODE_NULL = 0,
+       VFRAME_DISP_MODE_UNKNOWN,
+       VFRAME_DISP_MODE_SKIP,
+       VFRAME_DISP_MODE_OK,
+};
 
 #define BITDEPTH_Y_SHIFT 8
 #define BITDEPTH_Y8    (0 << BITDEPTH_Y_SHIFT)
index 01a4ad4..081571e 100644 (file)
@@ -38,6 +38,7 @@ struct vframe_states {
 #define VFRAME_EVENT_RECEIVER_RESET                            0x20
 #define VFRAME_EVENT_RECEIVER_FORCE_UNREG                      0x40
 #define VFRAME_EVENT_RECEIVER_GET_AUX_DATA                     0x80
+#define VFRAME_EVENT_RECEIVER_DISP_MODE                                0x100
 
        /* for VFRAME_EVENT_RECEIVER_GET_AUX_DATA*/
 struct provider_aux_req_s {
@@ -49,6 +50,13 @@ struct provider_aux_req_s {
        int aux_size;
        int dv_enhance_exist;
 };
+struct provider_disp_mode_req_s {
+       /*input*/
+       struct vframe_s *vf;
+       unsigned int req_mode;/*0:peak;1:get*/
+       /*output*/
+       enum vframe_disp_mode_e disp_mode;
+};
 
 struct vframe_operations_s {
        struct vframe_s *(*peek)(void *op_arg);
@@ -63,6 +71,7 @@ struct vframe_provider_s {
        const struct vframe_operations_s *ops;
        void *op_arg;
        struct list_head list;
+       atomic_t use_cnt;
        void *traceget;
        void *traceput;
 } /*vframe_provider_t */;
@@ -88,6 +97,10 @@ struct vframe_provider_s *vf_get_provider(const char *name);
 struct vframe_s *vf_peek(const char *receiver);
 struct vframe_s *vf_get(const char *receiver);
 void vf_put(struct vframe_s *vf, const char *receiver);
+int vf_get_states(struct vframe_provider_s *vfp,
+       struct vframe_states *states);
+int vf_get_states_by_name(const char *receiver_name,
+       struct vframe_states *states);
 
 unsigned int get_post_canvas(void);
 
diff --git a/include/linux/amlogic/media/video_sink/amvideocap.h b/include/linux/amlogic/media/video_sink/amvideocap.h
new file mode 100644 (file)
index 0000000..a94f411
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * include/linux/amlogic/media/video_sink/amvideocap.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef __AMVIDEOCAP_HEADHER_
+#define __AMVIDEOCAP_HEADHER_
+#define AC_MAGIC  'V'
+#include <linux/videodev2.h>
+
+#define CAP_FLAG_AT_CURRENT            0
+#define CAP_FLAG_AT_TIME_WINDOW        1
+#define CAP_FLAG_AT_END                        2
+
+/*
+ *format see linux/ge2d/ge2d.h
+ *like:
+ *GE2D_FORMAT_S24_RGB
+ */
+
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT    _IOW((AC_MAGIC), 0x01, int)
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH     _IOW((AC_MAGIC), 0x02, int)
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT    _IOW((AC_MAGIC), 0x03, int)
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_TIMESTAMP_MS _IOW((AC_MAGIC), 0x04, u64)
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_WAIT_MAX_MS _IOW((AC_MAGIC), 0x05, u64)
+#define AMVIDEOCAP_IOW_SET_WANTFRAME_AT_FLAGS  _IOW((AC_MAGIC), 0x06, int)
+
+#define AMVIDEOCAP_IOR_GET_FRAME_FORMAT        _IOR((AC_MAGIC), 0x10, int)
+#define AMVIDEOCAP_IOR_GET_FRAME_WIDTH _IOR((AC_MAGIC), 0x11, int)
+#define AMVIDEOCAP_IOR_GET_FRAME_HEIGHT        _IOR((AC_MAGIC), 0x12, int)
+#define AMVIDEOCAP_IOR_GET_FRAME_TIMESTAMP_MS  _IOR((AC_MAGIC), 0x13, int)
+
+#define AMVIDEOCAP_IOR_GET_SRCFRAME_FORMAT     _IOR((AC_MAGIC), 0x20, int)
+#define AMVIDEOCAP_IOR_GET_SRCFRAME_WIDTH      _IOR((AC_MAGIC), 0x21, int)
+#define AMVIDEOCAP_IOR_GET_SRCFRAME_HEIGHT     _IOR((AC_MAGIC), 0x22, int)
+
+#define AMVIDEOCAP_IOR_GET_STATE       _IOR((AC_MAGIC), 0x31, int)
+#define AMVIDEOCAP_IOW_SET_START_CAPTURE       _IOW((AC_MAGIC), 0x32, int)
+#define AMVIDEOCAP_IOW_SET_CANCEL_CAPTURE      _IOW((AC_MAGIC), 0x33, int)
+
+#define AMVIDEOCAP_IOR_SET_SRC_X _IOR((AC_MAGIC), 0x40, int)
+#define AMVIDEOCAP_IOR_SET_SRC_Y _IOR((AC_MAGIC), 0x41, int)
+#define AMVIDEOCAP_IOR_SET_SRC_WIDTH _IOR((AC_MAGIC), 0x42, int)
+#define AMVIDEOCAP_IOR_SET_SRC_HEIGHT _IOR((AC_MAGIC), 0x43, int)
+
+enum amvideocap_state {
+       AMVIDEOCAP_STATE_INIT = 0,
+       AMVIDEOCAP_STATE_ON_CAPTURE = 200,
+       AMVIDEOCAP_STATE_FINISHED_CAPTURE = 300,
+       AMVIDEOCAP_STATE_ERROR = 0xffff,
+};
+#endif                         /* __AMVIDEOCAP_HEADHER_ */
index 4e93164..2388ae6 100644 (file)
@@ -20,7 +20,7 @@
 
 extern int ionvideo_assign_map(char **receiver_name, int *inst);
 
-extern int ionvideo_alloc_map(char **receiver_name, int *inst);
+extern int ionvideo_alloc_map(int *inst);
 
 extern void ionvideo_release_map(int inst);
 
index c2f5d4b..d6aca57 100644 (file)
@@ -254,7 +254,8 @@ extern void set_clone_frame_rate(unsigned int frame_rate, unsigned int delay);
 #endif
 
 extern void prot_get_parameter(u32 wide_mode, struct vframe_s *vf,
-       struct vpp_frame_par_s *next_frame_par, const struct vinfo_s *vinfo);
+                              struct vpp_frame_par_s *next_frame_par,
+                              const struct vinfo_s *vinfo);
 u32 get_blackout_policy(void);
 int get_video0_frame_info(struct vframe_s *vf);
 
index 1cf1d47..0808cde 100644 (file)
@@ -132,6 +132,8 @@ struct vpp_frame_par_s {
        u32 spsc0_h_in;
        u32 spsc1_w_in;
        u32 spsc1_h_in;
+       u32 vpp_postblend_out_width;
+       u32 vpp_postblend_out_height;
 
        bool nocomp;
 
@@ -152,10 +154,19 @@ struct vpp_frame_par_s {
 extern bool reverse;
 #endif
 extern bool platform_type;
+extern unsigned int super_scaler;
+
 enum select_scaler_path_e {
        sup0_pp_sp1_scpath,
        sup0_pp_post_blender,
 };
+/*
+ * note from vlsi!!!
+ * if core0 v enable,core0 input width max=1024;
+ * if core0 v disable,core0 input width max=2048;
+ * if core1 v enable,core1 input width max=2048;
+ * if core1 v disable,core1 input width max=4096;
+ */
 #define SUPER_CORE0_WIDTH_MAX  2048
 #define SUPER_CORE1_WIDTH_MAX  4096
 
@@ -177,6 +188,11 @@ enum select_scaler_path_e {
 #define MODE_3D_OUT_LR 0x00020000
 #define MODE_FORCE_3D_TO_2D_LR 0x00100000
 #define MODE_FORCE_3D_TO_2D_TB 0x00200000
+#define MODE_FORCE_3D_LR       0x01000000
+#define MODE_FORCE_3D_TB       0x02000000
+#define MODE_3D_FP                     0x04000000
+#define MODE_FORCE_3D_FA_LR    0x10000000
+#define MODE_FORCE_3D_FA_TB    0x20000000
 
 /*when the output mode is field alterlative*/
 
@@ -211,12 +227,13 @@ enum select_scaler_path_e {
 extern
 void vpp_set_3d_scale(bool enable);
 extern
-void get_vpp_3d_mode(u32 trans_fmt, u32 *vpp_3d_mode);
+void get_vpp_3d_mode(u32 process_3d_type, u32 trans_fmt, u32 *vpp_3d_mode);
 #endif
 
 extern void
 vpp_set_filters(u32 process_3d_type, u32 wide_mode, struct vframe_s *vf,
-       struct vpp_frame_par_s *next_frame_par, const struct vinfo_s *vinfo);
+                               struct vpp_frame_par_s *next_frame_par,
+                               const struct vinfo_s *vinfo);
 
 extern void vpp_set_video_source_crop(u32 t, u32 l, u32 b, u32 r);
 
@@ -253,7 +270,8 @@ extern void vpp_bypass_ratio_config(void);
 #ifdef CONFIG_AM_VIDEO2
 extern void
 vpp2_set_filters(u32 wide_mode, struct vframe_s *vf,
-       struct vpp_frame_par_s *next_frame_par, const struct vinfo_s *vinfo);
+                                struct vpp_frame_par_s *next_frame_par,
+                                const struct vinfo_s *vinfo);
 
 extern void vpp2_set_video_layer_position(s32 x, s32 y, s32 w, s32 h);
 
@@ -266,14 +284,17 @@ extern u32 vpp2_get_zoom_ratio(void);
 extern int video_property_notify(int flag);
 
 extern int vpp_set_super_scaler_regs(int scaler_path_sel,
-       int reg_srscl0_enable,
-       int reg_srscl0_hsize,
-       int reg_srscl0_vsize,
-       int reg_srscl0_hori_ratio,
-       int reg_srscl0_vert_ratio,
-       int reg_srscl1_enable,
-       int reg_srscl1_hsize,
-       int reg_srscl1_vsize,
-       int reg_srscl1_hori_ratio, int reg_srscl1_vert_ratio);
+               int reg_srscl0_enable,
+               int reg_srscl0_hsize,
+               int reg_srscl0_vsize,
+               int reg_srscl0_hori_ratio,
+               int reg_srscl0_vert_ratio,
+               int reg_srscl1_enable,
+               int reg_srscl1_hsize,
+               int reg_srscl1_vsize,
+               int reg_srscl1_hori_ratio,
+               int reg_srscl1_vert_ratio,
+               int vpp_postblend_out_width,
+               int vpp_postblend_out_height);
 
 #endif /* VPP_H */