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/*
+
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
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
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/
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;
#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>
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, \
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)
{
{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 = {
{
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));
#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>
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))
}
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;
dump_stack();
return;
}
- canvas_lock();
+ canvas_lock(info, flags, fiqflags);
canvas = &info->canvasPool[index];
canvas->addr = addr;
canvas->width = width;
canvas->blkmode = blkmode;
canvas->endian = endian;
canvas_config_locked(index, canvas);
- canvas_unlock();
+ canvas_unlock(info, flags, fiqflags);
}
EXPORT_SYMBOL(canvas_config_ex);
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;
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;
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);
{
struct canvas_device_info *info = &canvas_info;
struct canvas_s *canvas;
+ unsigned long flags, fiqflags;
if (!CANVAS_VALID(index))
return;
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);
}
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");
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;
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;
#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,
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;
}
*/
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;
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)
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;
}
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;
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. */
}
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/
#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
}
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 {
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 */
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);
/*
*normal cma.
*/
+ alloc_trace_mask |= 1 << 1;
mem->mem_handle = dma_alloc_from_contiguous(mgt->dev,
mem->page_count,
align_2n - PAGE_SHIFT);
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 *)*/
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) {
*/
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,
/*
*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 *)*/
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;
}
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 =
} 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;
(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;
}
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;
!(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);
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);
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);
}
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;
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;
}
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;
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 {
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 {
}
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);
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;
}
tvp_pool->slot_num = ignored;
+ mutex_unlock(&tvp_pool->pool_lock);
return ignored;
}
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,
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),
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),
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;
}
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);
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);
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;
(~((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);
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;
}
}
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;
}
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;
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);
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;
}
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;
}
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;
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;
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,
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;
};
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)
{
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;
}
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);
#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;
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
}
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;
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);
}
}
-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;
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);
}
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))
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);
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;
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)
/*
*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;
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;
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) {
have_alloced = 1;
break;
}
- codec_mm_set_slot_in_hash(slot);
+ codec_mm_set_slot_in_hash(smgt, slot);
return slot;
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)
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;
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);
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;
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;
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");
}
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 */
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;
}
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;
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)
}
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;
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;
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--;
/*
*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;
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",
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;
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;
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);
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++) {
}
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++) {
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;
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;
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)
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.
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;
}
}
/*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;
}
}
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;
}
* 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;
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;
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);
* 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);
*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;
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)
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);
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;
}
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 {
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;
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,
}
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;
}
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;
}
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;
}
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;
}
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];
}
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;
}
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++;
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 >=
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;
if (need > mms->page_cnt) {
alloced =
!codec_mm_scatter_alloc_want_pages_in(
+ smgt,
mms,
need);
} else {
} 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(),
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;
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);
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);
}
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);
*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 {
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. */
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");
}
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++;
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)
{
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 */
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;
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);
--- /dev/null
+##########################################
+########## 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
+
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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");
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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;
+}
+
* 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) |
(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) |
-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
#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);
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;
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))
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);
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));
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)
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);
#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;
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;
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);
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++;
}
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];
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);
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;
}
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;
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);
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);
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);
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);
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) <
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);
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);
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);
}
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);
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)
{
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");
}
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;
#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"
#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];
{
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);
if ((j > 0) &&
((vfm_map[i]->active >> (j - 1)) & 0x1)) {
provider_name = vfm_map[i]->name[j - 1];
- ;
}
break;
}
}
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 */
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 /**/
#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";
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);
#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
}
/*
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]);
}
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;
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;
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) {
count = 0;
} else if (cmd == VFM_CMD_DUMP) {
vfm_dump_provider(token);
+ } else if (cmd == VFM_CMD_ADDDUMMY) {
+ add_dummy_receiver(token);
}
break;
}
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)
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);
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
}
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); */
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); */
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;
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);
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) {
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)
} 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);
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",
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;
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;
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);
{
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);
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);
+
+
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;
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)
#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
#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
*************************************/
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
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);
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);
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);
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;
}
}
}
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)
{
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;
} 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.
*/
/* 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;
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);
#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);
#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 */
AVEVENT_FLAG_PARAM
}, {
"AUDIO_PRE_START", 15, AUDIO_PRE_START, 0
- },
+ }, {
+ "AUDIO_WAIT", 10, AUDIO_WAIT, 0
+ }
};
static const char * const tsync_mode_str[] = {
#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;
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;
/*
*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;
}
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);
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:
/*
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();
.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;
tsync_pcr_init();
+ REG_PATH_CONFIGS("media.tsync", tsync_configs);
+
return 0;
}
#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
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 */
#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
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);
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())){
*/
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;
|| 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);
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 =
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;
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) {
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){
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;
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;
/* 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;
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");
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");
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;
}
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;
}
dev->vf = NULL;
dev->index = 0;
+ mutex_unlock(&dev->vfpMutex);
mutex_lock(&dev->mutex);
dev->users++;
if (dev->users > 1) {
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;
videobuf_mmap_free(&fh->vb_vidq);
kfree(fh);
dev->index = 8;
+ mutex_unlock(&dev->vfpMutex);
/* if (dev->res) { */
kfree(dev->res);
dev->res = NULL;
/* initialize locks */
spin_lock_init(&dev->slock);
mutex_init(&dev->mutex);
+ mutex_init(&dev->vfpMutex);
ret = -ENOMEM;
vfd = video_device_alloc();
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;
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);
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];
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;
}
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;
}
/*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);
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;
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;
}
if (fh == NULL) {
node->users--;
/* node->provider = NULL; */
+ amlvideo2_cma_buf_uninit(node->vid_dev, node->vid);
mutex_unlock(&node->mutex);
return -ENOMEM;
}
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;
}
/* .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;
}
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;
endif
+config AMLOGIC_MEDIA_VIDEOCAPTURE
+ bool "Amlogic Video Capture support"
+ default n
+ help
+ Internal Video Capture driver
+
endmenu
--- /dev/null
+/*
+ * 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
#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
#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 */
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;
#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 *);
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
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)
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)
#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
/*********************************************************/
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)
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,
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)
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)
#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;
/* 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;
{
unsigned long flags;
int ret = -1;
+
spin_lock_irqsave(&lock, flags);
if (is_vpp_postblend() && cur_dispbuf && vf) {
*vf = *cur_dispbuf;
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;
#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)
{
#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;
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
static inline struct vframe_s *video_vf_get(void)
{
struct vframe_s *vf = NULL;
+
vf = vf_get(RECEIVER_NAME);
if (vf) {
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;
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;
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;
}
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())
*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)
{
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;
}
return ret;
}
-#endif
int ext_register_end_frame_callback(struct amvideocap_req *req)
{
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);
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())
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_ -
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,
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_ -
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,
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) {
}
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)
*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,
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);
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) |
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) {
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;
(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
{
u32 ls, le, rs, re;
+
if (platform_type == 1) {
if (process_3d_type & MODE_3D_ENABLE) {
zoom_get_vert_pos(cur_dispbuf,
}
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));
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) |
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) |
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));
+ }
}
}
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,
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) |
/* 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;
}
#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;
}
} 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
#endif
} else {
int i;
+
for (i = 0; i < dispbuf_to_put_num; i++) {
if (dispbuf_to_put[i]) {
video_vf_put(
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,
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,
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]); */
}
/* 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) ||
(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);
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,
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;
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)
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);
}
} 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);
}
}
#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) {
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);
}
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,
(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 |
(((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 |
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;
(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) |
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 */
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 */
(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) |
#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);
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);
}
}
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);
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];
/* 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);
+ }
}
}
}
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)
}
/* 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)) {
/*
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
} 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) {
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)
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
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;
#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];
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();
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) {
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;
} 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 */
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 */
"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)) {
}
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;
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,
"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();
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)) {
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;
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
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 */
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 =
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;
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;
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) &&
/* 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);
(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) <<
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) /
/* 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
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;
}
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)
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) {
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 */
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;
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.*/
static void vsync2_fiq_up(void)
{
int r;
+
r = request_irq(INT_VIU2_VSYNC, &vsync_isr,
IRQF_SHARED, "vsync", (void *)video_dev_id2);
}
ulong flags;
new_frame_count = 0;
+ first_frame_toggled = 0;
atomic_set(&video_unreg_flag, 1);
spin_lock_irqsave(&lock, flags);
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;
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
#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
}
} 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);
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)
switch (cmd) {
case AMSTREAM_IOC_SET_OMX_VPTS:{
u32 pts;
+
get_user(pts, (u32 __user *)argp);
omx_pts = pts;
}
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;
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);
case AMSTREAM_IOC_SET_VIDEO_AXIS:{
int axis[4];
+
if (copy_from_user(axis, argp, sizeof(axis)) == 0)
_set_video_window(axis);
else
case AMSTREAM_IOC_SET_VIDEO_CROP:{
int crop[4];
+
if (copy_from_user(crop, argp, sizeof(crop)) == 0)
_set_video_crop(crop);
else
case AMSTREAM_IOC_SET_SCREEN_MODE:{
u32 mode;
+
if (copy_from_user(&mode, argp, sizeof(u32)) == 0) {
if (mode >= VIDEO_WIDEOPTION_MAX)
ret = -EINVAL;
case AMSTREAM_IOC_SET_BLACKOUT_POLICY:{
u32 mode;
+
if (copy_from_user(&mode, argp, sizeof(u32)) == 0) {
if (mode > 2)
ret = -EINVAL;
case AMSTREAM_IOC_CLEAR_VBUF:{
unsigned long flags;
+
spin_lock_irqsave(&lock, flags);
cur_dispbuf = NULL;
spin_unlock_irqrestore(&lock, flags);
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 */
#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
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;
}
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:
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;
{
ssize_t len = 0;
struct vppfilter_mode_s *vpp_filter = NULL;
+
if (!cur_frame_par)
return len;
vpp_filter = &cur_frame_par->vpp_filter;
struct class_attribute *attr, char *buf)
{
int x, y;
+
vpp_get_global_offset(&x, &y);
return snprintf(buf, 40, "%d %d\n", x, y);
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)
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)
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;
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,
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,
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",
{
#ifdef CONFIG_SUPPORT_VIDEO_ON_VPP2
const struct vinfo_s *info;
+
if (cur_dev == &video_dev[0])
info = get_current_vinfo();
else
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,
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)
{
size_t r;
int val;
+
if (debug_flag & DEBUG_FLAG_BLACKOUT)
pr_info("%s(%s)\n", __func__, buf);
r = kstrtoint(buf, 0, &val);
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;
#if DEBUG_TMP
set_current_vmode(VMODE_720P);
#endif
- set_current_vmode(10);
-
vinfo = get_current_vinfo();
}
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) {
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
#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);
}
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);
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
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
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
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)
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;
{
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
#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));
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);
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);
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);
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>");
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:
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()) {
}
}
}
+
+#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 */
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*/
}
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 {
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");
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");
#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)
* (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,
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;
(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;
(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 */
(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;
}
}
+ 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;
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);
(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
(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,
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;
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,
!= 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 =
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;
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 */
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) &&
}
#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:
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:
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;
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;
*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;
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;
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;
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;
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;
}
#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>
#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
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
#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)
/*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
#ifndef CANVAS_MGR_HEADER_
#define CANVAS_MGR_HEADER_
+#include <linux/types.h>
+
#define CANVAS_MAX_NUM 256
struct canvas_info {
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;
#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 */
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);
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);
#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 */
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);
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
+
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);
AUDIO_RESUME,
AUDIO_STOP,
AUDIO_TSTAMP_DISCONTINUITY,
- AUDIO_PRE_START
+ AUDIO_PRE_START,
+ AUDIO_WAIT
};
enum tsync_mode_e {
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
#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>
IO_HEVC_BUS,
IO_VPP_BUS,
IO_DMC_BUS,
+ IO_RESET_BUS,
BUS_MAX
};
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
#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
#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
#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
#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
#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
#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
#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
#define VD2_AFBC_PIXEL_VER_SCOPE 0x3190
#define VD2_AFBC_VD_CFMT_H 0x3191
+#define VD2_IF0_GEN_REG3 0x1aa8
+
#endif
#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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
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 */
#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>
/*
#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)
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;
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;
#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
#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
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 /**/
#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
#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,
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)
#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 {
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);
const struct vframe_operations_s *ops;
void *op_arg;
struct list_head list;
+ atomic_t use_cnt;
void *traceget;
void *traceput;
} /*vframe_provider_t */;
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);
--- /dev/null
+/*
+ * 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_ */
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);
#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);
u32 spsc0_h_in;
u32 spsc1_w_in;
u32 spsc1_h_in;
+ u32 vpp_postblend_out_width;
+ u32 vpp_postblend_out_height;
bool nocomp;
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
#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*/
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);
#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);
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 */