From 6470478320ffcf4656b2845e5e9c540fff670eb3 Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Sun, 3 Sep 2017 22:47:21 +0800 Subject: [PATCH] media: merged code from c502feca7 on the amlogic-3.14-dev [1/3] PD#150739: merged code from c502feca7 on the amlogic-3.14-dev 1.codec_mm: fixed tvp first wait long time bug 2.pcrmaster: fix some avsync issue in pcrmaster mode 3.vfm: fix vf provider crash issue Change-Id: I64202a38a3ed0c50ba665fb477caea26c67ddcb0 Signed-off-by: Nanxin Qin --- MAINTAINERS | 5 + arch/arm64/configs/meson64_defconfig | 1 + drivers/amlogic/Kconfig | 1 + drivers/amlogic/Makefile | 2 + drivers/amlogic/media/common/codec_mm/codec_mm.c | 8 +- .../media/common/codec_mm/codec_mm_scatter.c | 135 +++++--- drivers/amlogic/media/common/vfm/vframe_provider.c | 113 ++++++- drivers/amlogic/media/frame_sync/timestamp.c | 14 + drivers/amlogic/media/frame_sync/tsync_pcr.c | 40 ++- drivers/amlogic/media/video_sink/video.c | 374 ++++++++++++++++----- drivers/amlogic/media/video_sink/video_keeper.c | 132 +++++--- drivers/amlogic/media/video_sink/vpp.c | 20 ++ drivers/amlogic/tee/Kconfig | 8 + drivers/amlogic/tee/Makefile | 1 + drivers/amlogic/tee/tee.c | 193 +++++++++++ include/linux/amlogic/media/frame_sync/timestamp.h | 2 + include/linux/amlogic/media/utils/amstream.h | 1 + include/linux/amlogic/media/video_sink/video.h | 2 + .../linux/amlogic/media/video_sink/video_keeper.h | 4 +- include/linux/amlogic/tee.h | 25 ++ 20 files changed, 881 insertions(+), 200 deletions(-) create mode 100644 drivers/amlogic/tee/Kconfig create mode 100644 drivers/amlogic/tee/Makefile create mode 100644 drivers/amlogic/tee/tee.c create mode 100644 include/linux/amlogic/tee.h diff --git a/MAINTAINERS b/MAINTAINERS index 9632f6c..f4d1a03 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14079,3 +14079,8 @@ F: arch/arm64/configs/meson64_smarthome_defconfig AMLOGIC MESONGXL ADD P241 DTS M: Lianghu Su F: arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts + +AMLOGIC tee +M: Nanxin Qin +F: drivers/amlogic/tee/* +F: include/linux/amlogic/tee.h diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig index 34d03b8..54a2c55 100644 --- a/arch/arm64/configs/meson64_defconfig +++ b/arch/arm64/configs/meson64_defconfig @@ -312,6 +312,7 @@ CONFIG_AMLOGIC_IRBLASTER=y CONFIG_AMLOGIC_IIO=y CONFIG_AMLOGIC_SARADC=y CONFIG_AMLOGIC_DDR_WINDOW_TOOL=m +CONFIG_AMLOGIC_TEE=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y diff --git a/drivers/amlogic/Kconfig b/drivers/amlogic/Kconfig index eabbb04..2bcd011 100644 --- a/drivers/amlogic/Kconfig +++ b/drivers/amlogic/Kconfig @@ -114,5 +114,6 @@ source "drivers/amlogic/drm/Kconfig" source "drivers/amlogic/secure_monitor/Kconfig" +source "drivers/amlogic/tee/Kconfig" endmenu endif diff --git a/drivers/amlogic/Makefile b/drivers/amlogic/Makefile index 46b8f88..53f5104 100644 --- a/drivers/amlogic/Makefile +++ b/drivers/amlogic/Makefile @@ -104,3 +104,5 @@ obj-$(CONFIG_AMLOGIC_DDR_WINDOW_TOOL) += ddr_window/ obj-$(CONFIG_DRM_MESON) += drm/ obj-$(CONFIG_AMLOGIC_M8B_SM) += secure_monitor/ + +obj-$(CONFIG_AMLOGIC_TEE) += tee/ diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm.c b/drivers/amlogic/media/common/codec_mm/codec_mm.c index 0dcda79..d8f4465 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm.c @@ -638,7 +638,7 @@ void codec_mm_release(struct codec_mm_s *mem, const char *owner) if (!mem) return; - spin_lock_irqsave(&mem->lock, flags); + spin_lock_irqsave(&mgt->lock, flags); index = atomic_dec_return(&mem->use_cnt); max_owner = mem->owner[index]; for (i = 0; i < index; i++) { @@ -651,13 +651,13 @@ void codec_mm_release(struct codec_mm_s *mem, const char *owner) mem->from_flags, index); mem->owner[index] = NULL; if (index == 0) { - spin_unlock_irqrestore(&mem->lock, flags); - codec_mm_free_in(mgt, mem); list_del(&mem->list); + spin_unlock_irqrestore(&mgt->lock, flags); + codec_mm_free_in(mgt, mem); kfree(mem); return; } - spin_unlock_irqrestore(&mem->lock, flags); + spin_unlock_irqrestore(&mgt->lock, flags); } EXPORT_SYMBOL(codec_mm_release); diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c b/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c index 7b3e2c3..fa00ecd 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c @@ -127,6 +127,7 @@ struct codec_mm_scatter_s { u32 enable_slot_from_sys; u32 no_cache_size_M; u32 support_from_slot_sys; + u32 no_alloc_from_sys; }; struct codec_mm_scatter_mgt { @@ -144,6 +145,7 @@ struct codec_mm_scatter_mgt { int alloc_from_cma_first; u32 enable_slot_from_sys; u32 no_cache_size_M; + u32 no_alloc_from_sys; u32 support_from_slot_sys; int one_page_cnt; int scatters_cnt; @@ -577,8 +579,9 @@ static struct codec_mm_slot *codec_mm_slot_alloc( break; /*ignore codec_mm */ if ((try_alloc_size <= 0 || try_alloc_size > 64 * 1024) && /*must > 512K. */ - codec_mm_get_free_size() > - smgt->reserved_block_mm_M * SZ_1M) { + (smgt->tvp_mode || + (codec_mm_get_free_size() > + smgt->reserved_block_mm_M * SZ_1M))) { /*try from codec_mm */ if (try_alloc_size <= 0) { try_alloc_size = @@ -626,9 +629,10 @@ static struct codec_mm_slot *codec_mm_slot_alloc( goto error; /*don't alloc 1 page with slot. */ } } - if (!have_alloced && smgt->tvp_mode) { + if (!have_alloced) { /*tvp not support alloc from sys.*/ - goto error; + if (smgt->tvp_mode || smgt->no_alloc_from_sys) + goto error; } while (!have_alloced) { /*don't alloc 1 page with slot. */ @@ -857,10 +861,11 @@ static int codec_mm_page_alloc_from_slot( int n; codec_mm_list_lock(smgt); - if (list_empty(&smgt->free_list) && - (codec_mm_get_free_size() < /*no codec mm */ - smgt->reserved_block_mm_M * SZ_1M) && - !smgt->support_from_slot_sys) { /*no sys */ + if (!smgt->tvp_mode && + list_empty(&smgt->free_list) && + (codec_mm_get_free_size() reserved_block_mm_M * SZ_1M) && + !smgt->support_from_slot_sys) {/*no sys*/ codec_mm_list_unlock(smgt); return 0; } @@ -1023,7 +1028,7 @@ static int codec_mm_page_alloc_all_locked( num - alloced); if (new_alloc <= 0) can_from_slot = 0; - } else if (!smgt->tvp_mode) { + } else if (!smgt->no_alloc_from_sys && !smgt->tvp_mode) { new_alloc = codec_mm_page_alloc_from_one_pages( smgt, pages + alloced, @@ -1049,7 +1054,7 @@ static int codec_mm_pages_free_to_scatter( if (src_mms->page_used >= src_mms->page_cnt) return -1; /*no need free. */ dst_mms = smgt->cache_sc; - if (!dst_mms) + if (!dst_mms || src_mms == dst_mms) return 0; codec_mm_scatter_lock(dst_mms); moved = min(src_mms->page_cnt - src_mms->page_used, @@ -1142,37 +1147,74 @@ static int codec_mm_scatter_free_pages_in_locked( } codec_mm_list_lock(smgt); smgt->alloced_page_num -= freeNum; + if (smgt->cache_sc == mms) + smgt->cached_pages = mms->page_cnt; codec_mm_list_unlock(smgt); return 0; } /* -*free pages from id(include id); -*/ + *fast_mode: + *1: set page_used: call by owner + *2: free to scatter: call by owner + *3: free to slot or others: call by owner + * + *free_mode: + *0: free from id pages. + *1: free not used pages;call by moniter. + *2: less pages.: call by moniter for cache + * id is negative. + */ static int codec_mm_scatter_free_tail_pages_in( struct codec_mm_scatter *mms, - int start_free_id, - int fast) + int id, + int fast_mode, + int free_mode) { - 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); + int start_free_id = id; + + if (!mms) + return -1; + codec_mm_scatter_lock(mms); + if (free_mode == 1) + start_free_id = mms->page_used; + if (free_mode == 2) { + if (id > 0) { + if (id >= mms->page_cnt) + start_free_id = 0; + else + start_free_id = mms->page_cnt - id; + } else + start_free_id = -1; + } + if ((start_free_id < 0) || + (start_free_id >= mms->page_cnt) || + (mms->page_tail < 0)) { + if (mms && + start_free_id != mms->page_cnt) { + ERR_LOG( + "mms[%p],free error id %d(%d),cnt=%d ,=m:%d,%d\n", + mms, + id, + start_free_id, + mms->page_cnt, + fast_mode, + free_mode); + } + codec_mm_scatter_unlock(mms); return -1; } smgt = (struct codec_mm_scatter_mgt *)mms->manager; - codec_mm_scatter_lock(mms); mms->page_used = start_free_id; - if (fast == 1) { + if (fast_mode == 1) { codec_mm_scatter_unlock(mms); return 0; } - if (fast == 2 || fast == 3) { + if (fast_mode == 2 || fast_mode == 3) { codec_mm_pages_free_to_scatter(smgt, mms); - if (fast == 2 || mms->page_used == mms->page_cnt) { + if (fast_mode == 2 || mms->page_used == mms->page_cnt) { codec_mm_scatter_unlock(mms); return 0; } @@ -1184,14 +1226,12 @@ static int codec_mm_scatter_free_tail_pages_in( int codec_mm_scatter_free_tail_pages( struct codec_mm_scatter *mms, - int start_free_id) + int start_id) { int ret = 0; - - if (start_free_id < mms->page_cnt) - ret = codec_mm_scatter_free_tail_pages_in( + ret = codec_mm_scatter_free_tail_pages_in( mms, - start_free_id, 0); + start_id, 0, 0); return ret; } EXPORT_SYMBOL(codec_mm_scatter_free_tail_pages); @@ -1206,7 +1246,7 @@ int codec_mm_scatter_free_tail_pages_fast( if (start_free_id < mms->page_cnt) ret = codec_mm_scatter_free_tail_pages_in( mms, - start_free_id, 2); + start_free_id, 2, 0); codec_mm_schedule_delay_work( (struct codec_mm_scatter_mgt *)mms->manager, 100, 0); @@ -1217,14 +1257,23 @@ EXPORT_SYMBOL(codec_mm_scatter_free_tail_pages_fast); int codec_mm_scatter_free_unused_pages(struct codec_mm_scatter *mms) { int ret = 0; - - if (mms->page_used < mms->page_cnt) - ret = codec_mm_scatter_free_tail_pages_in(mms, - mms->page_used, 3); + ret = codec_mm_scatter_free_tail_pages_in(mms, + 0, 0, 1); return ret; } EXPORT_SYMBOL(codec_mm_scatter_free_unused_pages); +int codec_mm_scatter_less_pages(struct codec_mm_scatter *mms, + int nums) +{ + int ret = 0; + + ret = codec_mm_scatter_free_tail_pages_in(mms, + nums, 0, 2); + return ret; +} +EXPORT_SYMBOL(codec_mm_scatter_less_pages); + /*free all pages only *don't free scatter */ @@ -1315,7 +1364,7 @@ static int codec_mm_scatter_free_on_nouser_ext( codec_mm_list_unlock(smgt); codec_mm_scatter_unlock(mms); if (mms->page_cnt > 0) - ret = codec_mm_scatter_free_tail_pages_in(mms, 0, 0); + ret = codec_mm_scatter_free_tail_pages_in(mms, 0, 0, 0); if (free >= 256 && (smgt->try_alloc_in_sys_page_cnt < smgt->try_alloc_in_sys_page_cnt_max) && @@ -1364,7 +1413,6 @@ static int codec_mm_scatter_inc_user_in1( codec_mm_list_unlock(smgt); return ret <= 0 ? ret : 0; /*must add before user cnt >= 0 */ } - static int codec_mm_scatter_inc_user_in( struct codec_mm_scatter *mms, int cnt) @@ -1394,6 +1442,7 @@ static int codec_mm_scatter_dec_user_in1( int delay_free_ms, int cnt) { int after_users = 1; + codec_mm_list_lock(smgt); if (!codec_mm_scatter_valid_locked(smgt, mms)) { codec_mm_list_unlock(smgt); @@ -1424,6 +1473,7 @@ static int codec_mm_scatter_dec_user_in( { struct codec_mm_scatter_mgt *smgt; int ret; + if (!mms) return -1; smgt = codec_mm_get_scatter_mgt(0); @@ -1440,6 +1490,7 @@ static int codec_mm_scatter_dec_user_in( } return ret; } + /* *maybe a render/sink.video/osd/ */ @@ -2084,6 +2135,7 @@ int codec_mm_scatter_update_config(struct codec_mm_scatter_mgt *smgt) 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; + smgt->no_alloc_from_sys = g_scatter.no_alloc_from_sys; return 0; } @@ -2207,13 +2259,9 @@ static void codec_mm_scatter_cache_manage( smgt->delay_free_timeout_jiffies64)) { /*wait time out can free.*/ mms = smgt->cache_sc; - if (mms) { /*only free some 1M cache */ - int free_start = smgt->cached_pages - 256; - - if (free_start < smgt->keep_size_PAGE) - free_start = smgt->keep_size_PAGE; - codec_mm_scatter_free_tail_pages(mms, - free_start); + if (mms) {/*only free some 1M cache*/ + codec_mm_scatter_less_pages(mms, + 256); } codec_mm_free_all_free_slots_in(smgt); /*free some slots.*/ @@ -2481,6 +2529,7 @@ static struct mconfig codec_mm_sc_configs[] = { MC_PU32("enable_slot_from_sys", &g_scatter.enable_slot_from_sys), MC_PU32("no_cache_size_M", &g_scatter.no_cache_size_M), + MC_PU32("no_alloc_from_sys", &g_scatter.no_alloc_from_sys), }; static struct mconfig_node codec_mm_sc; @@ -2504,7 +2553,7 @@ int codec_mm_scatter_mgt_init(void) 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; - + g_scatter.no_alloc_from_sys = smgt->no_cache_size_M; INIT_REG_NODE_CONFIGS("media.codec_mm", &codec_mm_sc, "scatter", codec_mm_sc_configs, diff --git a/drivers/amlogic/media/common/vfm/vframe_provider.c b/drivers/amlogic/media/common/vfm/vframe_provider.c index 54ead51..af83ff2 100644 --- a/drivers/amlogic/media/common/vfm/vframe_provider.c +++ b/drivers/amlogic/media/common/vfm/vframe_provider.c @@ -31,7 +31,59 @@ #include "vftrace.h" #define MAX_PROVIDER_NUM 32 -struct vframe_provider_s *provider_table[MAX_PROVIDER_NUM]; +static struct vframe_provider_s *provider_table[MAX_PROVIDER_NUM]; +static atomic_t provider_used = ATOMIC_INIT(0); + +#define providers_lock() atomic_inc(&provider_used) +#define providers_unlock() atomic_dec(&provider_used) +#define providers_used() atomic_read(&provider_used) + +static DEFINE_MUTEX(provider_table_mutex); +#define TABLE_LOCK() mutex_lock(&provider_table_mutex) +#define TABLE_UNLOCK() mutex_unlock(&provider_table_mutex) + +#define VFPROVIER_DEBUG +#ifdef VFPROVIER_DEBUG +static DEFINE_SPINLOCK(provider_lock); +static const char *last_receiver; +static const char *last_provider; +void provider_update_caller(const char *receiver, const char *provider) +{ + unsigned long flags; + + spin_lock_irqsave(&provider_lock, flags); + last_receiver = receiver; + last_provider = provider; + spin_unlock_irqrestore(&provider_lock, flags); +} + +void provider_print_last_info(void) +{ + unsigned long flags; + struct vframe_provider_s *p; + int i; + + spin_lock_irqsave(&provider_lock, flags); + pr_info("last receiver: %s\n", + last_receiver ? last_receiver : "null"); + pr_info("last provider: %s\n", + last_provider ? last_provider : "null"); + pr_info("register provider:\n"); + for (i = 0; i < MAX_PROVIDER_NUM; i++) { + p = provider_table[i]; + if (p) + pr_info("%s: user_cnt:%d\n", p->name, + atomic_read(&p->use_cnt)); + } + spin_unlock_irqrestore(&provider_lock, flags); +} +#else +void provider_update_caller( + const char *receiver, + const char *provider) {return } +void provider_print_last_info(void) {return} + +#endif int provider_list(char *buf) { @@ -135,6 +187,7 @@ static int vf_provider_close(struct vframe_provider_s *prov) if (ret > CLOSED_CNT) { pr_err("**ERR***,release, provider %s not finised,%d, wait=%d\n", prov->name, ret, wait_max); + provider_print_last_info(); } return 0; } @@ -208,11 +261,14 @@ int vf_reg_provider(struct vframe_provider_s *prov) prov->traceget = NULL; prov->traceput = NULL; atomic_set(&prov->use_cnt, 0);/*set it ready for use.*/ + TABLE_LOCK(); for (i = 0; i < MAX_PROVIDER_NUM; i++) { p = provider_table[i]; if (p) { - if (!strcmp(p->name, prov->name)) + if (!strcmp(p->name, prov->name)) { + TABLE_UNLOCK(); return -1; + } } } for (i = 0; i < MAX_PROVIDER_NUM; i++) { @@ -221,6 +277,7 @@ int vf_reg_provider(struct vframe_provider_s *prov) break; } } + TABLE_UNLOCK(); if (i < MAX_PROVIDER_NUM) { vf_update_active_map(); receiver = vf_get_receiver(prov->name); @@ -253,18 +310,20 @@ void vf_unreg_provider(struct vframe_provider_s *prov) int i; for (i = 0; i < MAX_PROVIDER_NUM; i++) { + TABLE_LOCK(); p = provider_table[i]; if (p && !strcmp(p->name, prov->name)) { + provider_table[i] = NULL; + TABLE_UNLOCK(); if (p->traceget) { - vftrace_free_trace(p->traceget); + vftrace_free_trace(prov->traceget); p->traceget = NULL; } if (p->traceput) { - vftrace_free_trace(p->traceput); + vftrace_free_trace(prov->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); @@ -281,6 +340,27 @@ void vf_unreg_provider(struct vframe_provider_s *prov) vf_update_active_map(); break; } + TABLE_UNLOCK(); + } + { + /* + * wait no one used provider, + * if some one have on used. + * the provider memory may free, + * become unreachable. + */ + int cnt = 0; + + while (providers_used()) { + schedule(); + cnt++; + if (cnt > 10000) { + pr_err("unreg provider locked %s,%d!\n", + prov->name, cnt); + provider_print_last_info(); + break; + } + } } } EXPORT_SYMBOL(vf_unreg_provider); @@ -316,9 +396,11 @@ void vf_ext_light_unreg_provider(struct vframe_provider_s *prov) int i; for (i = 0; i < MAX_PROVIDER_NUM; i++) { + TABLE_LOCK(); p = provider_table[i]; if (p && !strcmp(p->name, prov->name)) { provider_table[i] = NULL; + TABLE_UNLOCK(); if (vfm_debug_flag & 1) pr_err("%s:%s\n", __func__, prov->name); @@ -332,6 +414,7 @@ void vf_ext_light_unreg_provider(struct vframe_provider_s *prov) vf_update_active_map(); break; } + TABLE_UNLOCK(); } } EXPORT_SYMBOL(vf_ext_light_unreg_provider); @@ -340,12 +423,14 @@ struct vframe_s *vf_peek(const char *receiver) { struct vframe_provider_s *vfp; struct vframe_s *vf = NULL; + providers_lock(); vfp = vf_get_provider(receiver); if (use_provider(vfp)) { if (vfp->ops && vfp->ops->peek) vf = vfp->ops->peek(vfp->op_arg); unuse_provider(vfp); } + providers_unlock(); return vf; } EXPORT_SYMBOL(vf_peek); @@ -355,14 +440,20 @@ struct vframe_s *vf_get(const char *receiver) struct vframe_provider_s *vfp; struct vframe_s *vf = NULL; + providers_lock(); vfp = vf_get_provider(receiver); + if (use_provider(vfp)) { + provider_update_caller(receiver, vfp->name); if (vfp->ops && vfp->ops->get) vf = vfp->ops->get(vfp->op_arg); if (vf) vftrace_info_in(vfp->traceget, vf); unuse_provider(vfp); - } + } else + provider_update_caller(receiver, NULL); + + providers_unlock(); return vf; } EXPORT_SYMBOL(vf_get); @@ -370,15 +461,19 @@ EXPORT_SYMBOL(vf_get); void vf_put(struct vframe_s *vf, const char *receiver) { struct vframe_provider_s *vfp; - + providers_lock(); vfp = vf_get_provider(receiver); if (use_provider(vfp)) { + provider_update_caller(receiver, vfp->name); if (vfp->ops && vfp->ops->put) vfp->ops->put(vf, vfp->op_arg); if (vf) vftrace_info_in(vfp->traceput, vf); unuse_provider(vfp); + } else { + provider_update_caller(receiver, NULL); } + providers_unlock(); } EXPORT_SYMBOL(vf_put); @@ -386,12 +481,14 @@ int vf_get_states(struct vframe_provider_s *vfp, struct vframe_states *states) { int ret = -1; - + providers_lock(); if (use_provider(vfp)) { + provider_update_caller(NULL, vfp->name); if (vfp->ops && vfp->ops->vf_states) ret = vfp->ops->vf_states(states, vfp->op_arg); unuse_provider(vfp); } + providers_unlock(); return ret; } EXPORT_SYMBOL(vf_get_states); diff --git a/drivers/amlogic/media/frame_sync/timestamp.c b/drivers/amlogic/media/frame_sync/timestamp.c index a6b6812..2bfda61 100644 --- a/drivers/amlogic/media/frame_sync/timestamp.c +++ b/drivers/amlogic/media/frame_sync/timestamp.c @@ -19,6 +19,7 @@ #include #include #include +#include u32 acc_apts_inc; @@ -200,6 +201,19 @@ void timestamp_pcrscr_set_adj(s32 inc) } EXPORT_SYMBOL(timestamp_pcrscr_set_adj); +void timestamp_pcrscr_set_adj_pcr(s32 inc) +{ + const struct vinfo_s *info = get_current_vinfo(); + + if (inc != 0) { + system_time_inc_adj = + 900 * info->sync_duration_den / + (info->sync_duration_num*inc); + } else + system_time_inc_adj = 0; +} +EXPORT_SYMBOL(timestamp_pcrscr_set_adj_pcr); + void timestamp_pcrscr_enable(u32 enable) { system_time_up = enable; diff --git a/drivers/amlogic/media/frame_sync/tsync_pcr.c b/drivers/amlogic/media/frame_sync/tsync_pcr.c index 4868932..950df03 100644 --- a/drivers/amlogic/media/frame_sync/tsync_pcr.c +++ b/drivers/amlogic/media/frame_sync/tsync_pcr.c @@ -330,7 +330,7 @@ u32 tsync_pcr_get_min_checkinpts(void) u32 last_checkin_vpts = get_last_checkin_pts(PTS_TYPE_VIDEO); u32 last_checkin_apts = get_last_checkin_pts(PTS_TYPE_AUDIO); - if (last_checkin_apts > 0 && last_checkin_apts > 0) + if (last_checkin_vpts > 0 && last_checkin_apts > 0) return min(last_checkin_vpts, last_checkin_apts); else if (last_checkin_apts > 0) return last_checkin_apts; @@ -407,7 +407,9 @@ void tsync_pcr_pcrscr_set(void) if (cur_pcr && !(tsync_pcr_inited_flag & complete_init_flag) && (min_checkinpts != 0)) { tsync_pcr_inited_flag |= TSYNC_PCR_INITCHECK_PCR; - ref_pcr = cur_pcr - tsync_pcr_adj_value * 15; + if (cur_pcr > tsync_pcr_adj_value * 15) + ref_pcr = cur_pcr - tsync_pcr_adj_value * 15; + timestamp_pcrscr_set(ref_pcr); tsync_pcr_usepcr = 1; @@ -431,12 +433,14 @@ void tsync_pcr_pcrscr_set(void) ref_pcr = first_apts; /* add it for dolby av sync */ - if (cur_pcr > 0) + if (cur_pcr > tsync_apts_adj_value) ref_pcr = cur_pcr - tsync_apts_adj_value; timestamp_pcrscr_set(ref_pcr); if (cur_pcr > 0) tsync_pcr_usepcr = 1; + else + tsync_pcr_usepcr = 0; timestamp_pcrscr_enable(1); pr_info @@ -456,10 +460,14 @@ void tsync_pcr_pcrscr_set(void) if (first_vpts && !(tsync_pcr_inited_flag & complete_init_flag) && (min_checkinpts != 0)) { tsync_pcr_inited_flag |= TSYNC_PCR_INITCHECK_VPTS; - ref_pcr = first_vpts - tsync_pcr_ref_latency * 15; + if (first_vpts > tsync_pcr_ref_latency * 15) + ref_pcr = first_vpts - tsync_pcr_ref_latency * 15; + timestamp_pcrscr_set(ref_pcr); if (cur_pcr > 0) tsync_pcr_usepcr = 1; + else + tsync_pcr_usepcr = 0; timestamp_pcrscr_enable(1); pr_info @@ -1181,19 +1189,16 @@ static unsigned long tsync_pcr_check(void) } if (need_recovery && !tsync_pcr_vpause_flag) { - if (play_mode == PLAY_MODE_SLOW) { - timestamp_pcrscr_set(timestamp_pcrscr_get() - - tsync_pcr_recovery_span); - } else if (play_mode == PLAY_MODE_FORCE_SLOW) { - timestamp_pcrscr_set(timestamp_pcrscr_get() - - FORCE_RECOVERY_SPAN); - } else if (play_mode == PLAY_MODE_SPEED) { - timestamp_pcrscr_set(timestamp_pcrscr_get() + - tsync_pcr_recovery_span); - } else if (play_mode == PLAY_MODE_FORCE_SPEED) { - timestamp_pcrscr_set(timestamp_pcrscr_get() + - FORCE_RECOVERY_SPAN); - } + if (play_mode == PLAY_MODE_SLOW) + timestamp_pcrscr_set_adj_pcr(-1); + else if (play_mode == PLAY_MODE_FORCE_SLOW) + timestamp_pcrscr_set_adj_pcr(-2); + else if (play_mode == PLAY_MODE_SPEED) + timestamp_pcrscr_set_adj_pcr(1); + else if (play_mode == PLAY_MODE_FORCE_SPEED) + timestamp_pcrscr_set_adj_pcr(2); + else if (play_mode == PLAY_MODE_NORMAL) + timestamp_pcrscr_set_adj_pcr(0); } /* } */ @@ -1294,6 +1299,7 @@ void tsync_pcr_stop(void) del_timer_sync(&tsync_pcr_check_timer); pr_info("[tsync_pcr_stop]PCRMASTER stop success.\n"); } + timestamp_pcrscr_set(0); tsync_pcr_freerun_mode = 0; tsync_pcr_started = 0; } diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index fa285c3..6f0e8ac 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -95,6 +95,8 @@ int video_vsync = -ENXIO; #define DEBUG_TMP 0 static int video_global_output = 1; +/* video_pause_global: 0 is play, 1 is pause, 2 is invalid */ +static int video_pause_global = 1; #ifdef CONFIG_GE2D_KEEP_FRAME /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ @@ -764,7 +766,7 @@ int get_video0_frame_info(struct vframe_s *vf) } EXPORT_SYMBOL(get_video0_frame_info); -static struct vframe_s vf_local; +static struct vframe_s vf_local, vf_local2; static u32 vsync_pts_inc; static u32 vsync_pts_inc_scale; static u32 vsync_pts_inc_scale_base = 1; @@ -808,6 +810,7 @@ u32 trickmode_fffb; atomic_t trickmode_framedone = ATOMIC_INIT(0); atomic_t video_sizechange = ATOMIC_INIT(0); atomic_t video_unreg_flag = ATOMIC_INIT(0); +atomic_t video_inirq_flag = ATOMIC_INIT(0); atomic_t video_pause_flag = ATOMIC_INIT(0); int trickmode_duration; int trickmode_duration_count; @@ -1503,7 +1506,6 @@ static void zoom_get_vert_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls, *rs = *ls + (height >> 1); *re = *le + (height >> 1); } - } if ((process_3d_type & MODE_3D_TO_2D_MASK) || (process_3d_type & MODE_3D_OUT_LR)) { /* same width,half height */ @@ -1511,6 +1513,7 @@ static void zoom_get_vert_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls, *le = zoom_end_y_lines; *rs = zoom_start_y_lines + (height >> 1); *re = zoom_end_y_lines + (height >> 1); + } } break; case VPP_3D_MODE_LR: @@ -1562,7 +1565,7 @@ static void zoom_get_vert_pos(struct vframe_s *vf, u32 vpp_3d_mode, u32 *ls, #endif static void zoom_display_horz(int hscale) { - u32 ls, le, rs, re; + u32 ls = 0, le = 0, rs = 0, re = 0; #ifdef TV_REVERSE int content_w, content_l, content_r; #endif @@ -1622,7 +1625,8 @@ static void zoom_display_horz(int hscale) if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { VSYNC_WR_MPEG_REG(AFBC_SIZE_OUT, - (VSYNC_RD_MPEG_REG(AFBC_SIZE_OUT) & 0xffff) | + (VSYNC_RD_MPEG_REG(AFBC_SIZE_OUT) + & 0xffff) | (((r_aligned - l_aligned) / h_skip) << 16)); } #ifdef TV_REVERSE @@ -1681,25 +1685,28 @@ static void vd2_zoom_display_horz(int hscale) if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { int l_aligned; int r_aligned; + int h_skip = cur_frame_par->hscale_skip_count + 1; if ((zoom2_start_x_lines > 0) || (zoom2_end_x_lines < ori2_end_x_lines)) { l_aligned = round_down(ori2_start_x_lines, 32); r_aligned = round_up(ori2_end_x_lines + 1, 32); } else { - l_aligned = round_down(ori2_start_x_lines, 32); - r_aligned = round_up(ori2_end_x_lines + 1, 32); + l_aligned = round_down(zoom2_start_x_lines, 32); + r_aligned = round_up(zoom2_end_x_lines + 1, 32); } VSYNC_WR_MPEG_REG(VD2_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(VD2_AFBC_MIF_HOR_SCOPE, ((l_aligned / 32) << 16) | ((r_aligned / 32) - 1)); if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { VSYNC_WR_MPEG_REG(VD2_AFBC_SIZE_OUT, - (VSYNC_RD_MPEG_REG(VD2_AFBC_SIZE_OUT) & - 0xffff) | ((r_aligned - l_aligned) << 16)); + (VSYNC_RD_MPEG_REG(VD2_AFBC_SIZE_OUT) + & 0xffff) | + (((r_aligned - l_aligned) / h_skip) << 16)); } #ifdef TV_REVERSE if (reverse) { @@ -1909,13 +1916,18 @@ static void vd2_zoom_display_vert(void) if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { int t_aligned; int b_aligned; - + int ori_t_aligned; + int ori_b_aligned; + int v_skip = cur_frame_par->vscale_skip_count + 1; t_aligned = round_down(zoom2_start_y_lines, 4); b_aligned = round_up(zoom2_end_y_lines + 1, 4); + ori_t_aligned = round_down(ori2_start_y_lines, 4); + ori_b_aligned = round_up(ori2_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) / 2); + (b_aligned - t_aligned) / 2 / v_skip); VSYNC_WR_MPEG_REG(VD2_AFBC_MIF_VER_SCOPE, ((t_aligned / 4) << 16) | @@ -1926,12 +1938,14 @@ static void vd2_zoom_display_vert(void) (zoom2_end_y_lines - t_aligned)); VSYNC_WR_MPEG_REG(VD2_AFBC_SIZE_IN, - (VSYNC_RD_MPEG_REG(VD2_AFBC_SIZE_IN) & 0xffff0000) | - (b_aligned - t_aligned)); + (VSYNC_RD_MPEG_REG(VD2_AFBC_SIZE_IN) + & 0xffff0000) | + (ori_b_aligned - ori_t_aligned)); if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) { VSYNC_WR_MPEG_REG(VD2_AFBC_SIZE_OUT, - (VSYNC_RD_MPEG_REG(VD2_AFBC_SIZE_OUT) & 0xffff0000) - | (b_aligned - t_aligned)); + (VSYNC_RD_MPEG_REG(VD2_AFBC_SIZE_OUT) + & 0xffff0000) | + ((b_aligned - t_aligned) / v_skip)); } } } @@ -2593,6 +2607,7 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) u32 type = vf->type, bit_mode = 0; bool vf_with_el = false; + pr_debug("set dcu for vd1 %p, type:0x%x\n", vf, type); if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { if (frame_par->nocomp) type &= ~VIDTYPE_COMPRESS; @@ -2642,10 +2657,8 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) 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_REPEAT | + (0xc << VFORMATTER_INIPHASE_BIT) | HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN | VFORMATTER_RPTLINE0_EN | @@ -2668,15 +2681,13 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) 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); + HFORMATTER_REPEAT | + (0xc << VFORMATTER_INIPHASE_BIT) | + HFORMATTER_YC_RATIO_2_1 | + HFORMATTER_EN | + VFORMATTER_RPTLINE0_EN | + (0x8 << VFORMATTER_PHASE_BIT) | + VFORMATTER_EN); } if ((VSYNC_RD_MPEG_REG(DI_POST_CTRL) & 0x100) == 0) VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0 + @@ -2684,6 +2695,8 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0 + cur_dev->viu_off, 1, 20, 1); + VSYNC_WR_MPEG_REG(VD1_IF0_GEN_REG + + cur_dev->viu_off, 0); return; } else { @@ -2702,6 +2715,10 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) } VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG3, (bit_mode&0x3), 8, 2); + if ((vf->type & VIDTYPE_MVC) && (!vf_with_el)) + VSYNC_WR_MPEG_REG_BITS( + VD2_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()) @@ -2836,7 +2853,7 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) ((type & VIDTYPE_VIU_422) ? 0 : VFORMATTER_EN)); - pr_info("\tvd1 set fmt(dovi tv)\n"); + pr_debug("\tvd1 set fmt(dovi tv)\n"); } else if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || is_meson_txlx_cpu()) { if ((vf->width >= 3840) && @@ -3128,9 +3145,8 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) static const u32 vpat[] = { 0, 0x8, 0x9, 0xa, 0xb, 0xc }; u32 u, v; u32 type = vf->type, bit_mode = 0; - u32 skip_count = 0; - pr_info("set dcu for vd2 %p, type:0x%x\n", vf, type); + pr_debug("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) | @@ -3138,9 +3154,9 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) (1 << 14) | /*burst1 1*/ (vf->bitdepth & BITDEPTH_MASK); - if (skip_count) + if (frame_par->hscale_skip_count) r |= 0x33; - if (skip_count) + if (frame_par->vscale_skip_count) r |= 0xcc; #ifdef TV_REVERSE @@ -3219,6 +3235,8 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) #endif VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL1 + cur_dev->viu_off, 1, 1, 1); + VSYNC_WR_MPEG_REG(VD2_IF0_GEN_REG + + cur_dev->viu_off, 0); return; } else { if ((vf->bitdepth & BITDEPTH_Y10) && @@ -3268,7 +3286,7 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) } } - if (skip_count) + if (frame_par->hscale_skip_count) r |= VDIF_CHROMA_HZ_AVG | VDIF_LUMA_HZ_AVG; VSYNC_WR_MPEG_REG(VD2_IF0_GEN_REG, r); @@ -3307,7 +3325,7 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) (((type & VIDTYPE_VIU_422) ? 0x10 : 0x08) << VFORMATTER_PHASE_BIT) | VFORMATTER_EN); - pr_info("\tvd2 set fmt(dovi tv)\n"); + pr_debug("\tvd2 set fmt(dovi tv)\n"); } else if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || is_meson_txlx_cpu()) { if ((vf->width >= 3840) && @@ -3394,13 +3412,13 @@ static void vd2_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) } } /* LOOP/SKIP pattern */ - pat = vpat[skip_count]; + pat = vpat[frame_par->vscale_skip_count]; if (type & VIDTYPE_VIU_FIELD) { loop = 0; if (type & VIDTYPE_INTERLACE) - pat = vpat[skip_count >> 1]; + pat = vpat[frame_par->vscale_skip_count >> 1]; } else if (type & VIDTYPE_MVC) { loop = 0x11; pat = 0x80; @@ -3652,10 +3670,12 @@ static inline bool vpts_expire(struct vframe_s *cur_vf, tsync_avevent_locked(VIDEO_TSTAMP_DISCONTINUITY, pts); - pr_info("discontinue, systime=0x%x vpts=0x%x next_vf->pts = 0x%x\n", - systime, - pts, - next_vf->pts); + /* pr_info("discontinue, + * systime=0x%x vpts=0x%x next_vf->pts = 0x%x\n", + * systime, + * pts, + * next_vf->pts); + */ /* pts==0 is a keep frame maybe. */ if (systime > next_vf->pts || next_vf->pts == 0) @@ -4128,10 +4148,113 @@ static void dmc_adjust_for_mali_vpu(unsigned int width, unsigned int height) } } +void correct_vd1_mif_size_for_DV(struct vpp_frame_par_s *par) +{ + u32 aligned_mask = 0xfffffffe; + u32 old_len; + + if ((is_dolby_vision_on() == true) && + (par->VPP_line_in_length_ > 0)) { + if (cur_dispbuf2) { + /* + *if (cur_dispbuf2->type + * & VIDTYPE_COMPRESS) + * aligned_mask = 0xffffffc0; + *else + */ + aligned_mask = 0xfffffffc; + } +#if 0 /* def TV_REVERSE */ + if (reverse) { + par->VPP_line_in_length_ + &= 0xfffffffe; + par->VPP_hd_end_lines_ + &= 0xfffffffe; + par->VPP_hd_start_lines_ = + par->VPP_hd_end_lines_ + 1 + - par->VPP_line_in_length_; + } else +#endif + { + par->VPP_line_in_length_ + &= aligned_mask; + par->VPP_hd_start_lines_ + &= aligned_mask; + par->VPP_hd_end_lines_ = + par->VPP_hd_start_lines_ + + par->VPP_line_in_length_ - 1; + /* if have el layer, need 2 pixel align by height */ + if (cur_dispbuf2) { + old_len = + par->VPP_vd_end_lines_ - + par->VPP_vd_start_lines_ + 1; + if (old_len & 1) + par->VPP_vd_end_lines_--; + if (par->VPP_vd_start_lines_ & 1) { + par->VPP_vd_start_lines_--; + par->VPP_vd_end_lines_--; + } + old_len = + par->VPP_vd_end_lines_ - + par->VPP_vd_start_lines_ + 1; + old_len = old_len >> par->vscale_skip_count; + if (par->VPP_pic_in_height_ < old_len) + par->VPP_pic_in_height_ = old_len; + } + } + } +} + +#if DEBUG_TMP +void correct_vd2_mif_size_for_DV( + struct vpp_frame_par_s *par, + struct vframe_s *bl_vf) +{ + int width_bl, width_el, line_in_length; + int shift; + + if ((is_dolby_vision_on() == true) && + (par->VPP_line_in_length_ > 0)) { + width_el = (cur_dispbuf2->type + & VIDTYPE_COMPRESS) ? + cur_dispbuf2->compWidth : + cur_dispbuf2->width; + width_bl = (bl_vf->type + & VIDTYPE_COMPRESS) ? + bl_vf->compWidth : + bl_vf->width; + if (width_el >= width_bl) + shift = 0; + else + shift = 1; + zoom2_start_x_lines = + par->VPP_hd_start_lines_ >> shift; + line_in_length = + par->VPP_line_in_length_ >> shift; + zoom2_end_x_lines + &= 0xfffffffe; + line_in_length + &= 0xfffffffe; + if (line_in_length > 1) + zoom2_end_x_lines = + zoom2_start_x_lines + + line_in_length - 1; + else + zoom2_end_x_lines = zoom2_start_x_lines; + + zoom2_start_y_lines = + par->VPP_vd_start_lines_ >> shift; + if (zoom2_start_y_lines >= zoom2_end_y_lines) + zoom2_end_y_lines = zoom2_start_y_lines; + /* TODO: if el len is 0, need disable bl */ + } +} +#endif + #ifdef FIQ_VSYNC -void vsync_fisr(void) +void vsync_fisr_in(void) #else -static irqreturn_t vsync_isr(int irq, void *dev_id) +static irqreturn_t vsync_isr_in(int irq, void *dev_id) #endif { int hold_line; @@ -4152,10 +4275,11 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) #endif #if DEBUG_TMP struct vframe_s *toggle_vf = NULL; - int ret; #endif + struct vframe_s *toggle_frame = NULL; int video1_off_req = 0; struct vframe_s *cur_dispbuf_back = cur_dispbuf; + static struct vframe_s *pause_vf; if (debug_flag & DEBUG_FLAG_VSYNC_DONONE) return IRQ_HANDLED; @@ -4263,9 +4387,6 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) /* 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 @@ -4340,7 +4461,9 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) if (atomic_read(&video_unreg_flag)) goto exit; - if (atomic_read(&video_pause_flag)) + if (atomic_read(&video_pause_flag) + && (!((video_global_output == 1) + && (video_enabled != video_status_saved)))) goto exit; #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA if (is_vsync_rdma_enable()) @@ -4484,6 +4607,11 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) #if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) refresh_on_vs(vf); + if (amvecm_on_vs( + (cur_dispbuf != &vf_local) + ? cur_dispbuf : NULL, + vf, CSC_FLAG_CHECK_OUTPUT) == 1) + break; #endif if (is_dolby_vision_enable() @@ -4498,12 +4626,12 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) */ if (vf && hdmiin_frame_check && (vf->source_type == VFRAME_SOURCE_TYPE_HDMI) && - (video_vf_disp_mode_get(vf) != - VFRAME_DISP_MODE_OK) && + (video_vf_disp_mode_get(vf) == + VFRAME_DISP_MODE_UNKNOWN) && (hdmiin_frame_check_cnt++ < 10)) break; - - hdmiin_frame_check_cnt = 0; + else + hdmiin_frame_check_cnt = 0; vf = video_vf_get(); if (!vf) @@ -4528,13 +4656,15 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) } } vsync_toggle_frame(vf); -#if DEBUG_TMP - if (is_dolby_vision_enable()) - toggle_vf = dolby_vision_toggle_frame(vf); - else -#endif + toggle_frame = vf; + if (0/*is_dolby_vision_enable()*/) { /*DEBUG_TMP*/ + //toggle_vf = dolby_vision_toggle_frame(vf); + video_pause_global = 0; + } else { cur_dispbuf2 = NULL; - + video_pause_global = 2; + pause_vf = NULL; + } if (trickmode_fffb == 1) { trickmode_vpts = vf->pts; #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA @@ -4594,11 +4724,20 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) if (is_dolby_vision_enable() && dolby_vision_need_wait()) break; +#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) + refresh_on_vs(vf); + if (amvecm_on_vs( + (cur_dispbuf != &vf_local) + ? cur_dispbuf : NULL, + vf, CSC_FLAG_CHECK_OUTPUT) == 1) + break; +#endif #endif vf = video_vf_get(); if (!vf) break; vsync_toggle_frame(vf); + toggle_frame = vf; #if DEBUG_TMP if (is_dolby_vision_enable()) toggle_vf = @@ -4633,8 +4772,23 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) cur_dispbuf); } else vsync_toggle_frame(cur_dispbuf); + /*DEBUG_TMP*/ + if (0/*is_dolby_vision_enable()*/) { + pause_vf = cur_dispbuf; + video_pause_global = 1; + } else { + pause_vf = NULL; + video_pause_global = 2; + } } - +#if DEBUG_TMP + if (pause_vf && (video_pause_global == 1) + && is_dolby_vision_enable()) { + toggle_vf = pause_vf; + dolby_vision_parse_metadata(cur_dispbuf, true); + dolby_vision_set_toggle_flag(1); + } +#endif break; } @@ -4657,22 +4811,50 @@ static irqreturn_t vsync_isr(int irq, void *dev_id) 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(); - } +#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) + amvecm_on_vs( + (cur_dispbuf != &vf_local) ? cur_dispbuf : NULL, + toggle_frame, + toggle_frame ? CSC_FLAG_TOGGLE_FRAME : 0); +#endif #endif /* filter setting management */ if ((frame_par_ready_to_set) || (frame_par_force_to_set)) { cur_frame_par = next_frame_par; frame_par_di_set = 1; } + +#if DEBUG_TMP + if (is_dolby_vision_enable()) { + u32 frame_size = 0, h_size, v_size; + + if (cur_frame_par) { + if (cur_frame_par->VPP_hd_start_lines_ + >= cur_frame_par->VPP_hd_end_lines_) + h_size = 0; + else + h_size = cur_frame_par->VPP_hd_end_lines_ + - cur_frame_par->VPP_hd_start_lines_ + 1; + h_size /= (cur_frame_par->hscale_skip_count + 1); + if (cur_frame_par->VPP_vd_start_lines_ + >= cur_frame_par->VPP_vd_end_lines_) + v_size = 0; + else + v_size = cur_frame_par->VPP_vd_end_lines_ + - cur_frame_par->VPP_vd_start_lines_ + 1; + v_size /= (cur_frame_par->vscale_skip_count + 1); + frame_size = (h_size << 16) | v_size; + } else if (toggle_vf) { + h_size = (toggle_vf->type & VIDTYPE_COMPRESS) ? + toggle_vf->compWidth : toggle_vf->width; + v_size = (toggle_vf->type & VIDTYPE_COMPRESS) ? + toggle_vf->compHeight : toggle_vf->height; + frame_size = (h_size << 16) | v_size; + } + dolby_vision_process(toggle_vf, frame_size); + dolby_vision_update_setting(); + } +#endif if ((platform_type == 1) || (platform_type == 0)) { if (mode_3d_changed) { mode_3d_changed = 0; @@ -4880,7 +5062,7 @@ SET_FILTER: if (cur_dispbuf) { u32 zoom_start_y, zoom_end_y; - + correct_vd1_mif_size_for_DV(cur_frame_par); if (cur_dispbuf->type & VIDTYPE_INTERLACE) { if (cur_dispbuf->type & VIDTYPE_VIU_FIELD) { zoom_start_y = @@ -4929,9 +5111,11 @@ SET_FILTER: if (is_dolby_vision_enable() && cur_dispbuf2) { zoom2_start_x_lines = ori2_start_x_lines; zoom2_end_x_lines = ori2_end_x_lines; - vd2_zoom_display_horz(0); zoom2_start_y_lines = ori2_start_y_lines; zoom2_end_y_lines = ori2_end_y_lines; + correct_vd2_mif_size_for_DV( + cur_frame_par, cur_dispbuf); + vd2_zoom_display_horz(0); vd2_zoom_display_vert(); } #endif @@ -5108,6 +5292,13 @@ SET_FILTER: cur_frame_par->supsc0_vert_ratio) & 0x1fff)); } #endif + /* work around to cut the last green line*/ + /*when two layer dv display and do vskip */ + if (is_dolby_vision_on() && + (cur_frame_par->vscale_skip_count > 0) + && cur_dispbuf2 + && (cur_frame_par->VPP_pic_in_height_ > 0)) + cur_frame_par->VPP_pic_in_height_--; VSYNC_WR_MPEG_REG(VPP_PIC_IN_HEIGHT + cur_dev->vpp_off, cur_frame_par->VPP_pic_in_height_); @@ -5397,6 +5588,9 @@ SET_FILTER: if (debug_flag & DEBUG_FLAG_BLACKOUT) pr_info("AFBC off now.\n"); VSYNC_WR_MPEG_REG(AFBC_ENABLE, 0); + VSYNC_WR_MPEG_REG(VD2_AFBC_ENABLE, 0); + VSYNC_WR_MPEG_REG(VD1_IF0_GEN_REG, 0); + VSYNC_WR_MPEG_REG(VD2_IF0_GEN_REG, 0); } #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA @@ -5461,6 +5655,24 @@ SET_FILTER: } +#ifdef FIQ_VSYNC +void vsync_fisr(void) +{ + atomic_set(&video_inirq_flag, 1); + vsync_fisr_in(); + atomic_set(&video_inirq_flag, 0); +} +#else +static irqreturn_t vsync_isr(int irq, void *dev_id) +{ + irqreturn_t ret; + + atomic_set(&video_inirq_flag, 1); + ret = vsync_isr_in(irq, dev_id); + atomic_set(&video_inirq_flag, 0); + return ret; +} +#endif /********************************************************* @@ -5554,11 +5766,14 @@ EXPORT_SYMBOL(query_video_status); static void video_vf_unreg_provider(void) { ulong flags; + struct vframe_s *el_vf = NULL; new_frame_count = 0; first_frame_toggled = 0; atomic_set(&video_unreg_flag, 1); + while (atomic_read(&video_inirq_flag) > 0) + schedule(); spin_lock_irqsave(&lock, flags); #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA @@ -5574,10 +5789,15 @@ static void video_vf_unreg_provider(void) cur_dispbuf = &vf_local; cur_dispbuf->video_angle = 0; } -#if DEBUG_TMP - if (is_dolby_vision_enable()) + if (0/*is_dolby_vision_enable()*/) {/*DEBUG_TMP*/ + if (cur_dispbuf2 == &vf_local2) + cur_dispbuf2 = NULL; + else if (cur_dispbuf2 != NULL) { + vf_local2 = *cur_dispbuf2; + el_vf = &vf_local2; + } cur_dispbuf2 = NULL; -#endif + } if (trickmode_fffb) { atomic_set(&trickmode_framedone, 0); to_notify_trick_wait = false; @@ -5599,7 +5819,7 @@ static void video_vf_unreg_provider(void) if (cur_dispbuf) { /* TODO: mod gate */ /* switch_mod_gate_by_name("ge2d", 1); */ - vf_keep_current(cur_dispbuf); + vf_keep_current(cur_dispbuf, el_vf); /* TODO: mod gate */ /* switch_mod_gate_by_name("ge2d", 0); */ } @@ -5608,7 +5828,7 @@ static void video_vf_unreg_provider(void) #else /* if (!trickmode_fffb) */ if (cur_dispbuf) - vf_keep_current(cur_dispbuf); + vf_keep_current(cur_dispbuf, el_vf); if (hdmi_in_onvideo == 0) tsync_avevent(VIDEO_STOP, 0); #endif diff --git a/drivers/amlogic/media/video_sink/video_keeper.c b/drivers/amlogic/media/video_sink/video_keeper.c index a4ae093..78e3f13 100644 --- a/drivers/amlogic/media/video_sink/video_keeper.c +++ b/drivers/amlogic/media/video_sink/video_keeper.c @@ -66,6 +66,8 @@ static unsigned long keep_y_addr, keep_u_addr, keep_v_addr; static int keep_video_on; static int keep_id; static int keep_head_id; +static int keep_el_id; +static int keep_el_head_id; #define Y_BUFFER_SIZE 0x400000 /* for 1920*1088 */ #define U_BUFFER_SIZE 0x100000 /* compatible with NV21 */ @@ -602,8 +604,9 @@ static int canvas_dup(ulong dst, ulong src_paddr, ulong size) #ifdef RESERVE_CLR_FRAME static int free_alloced_keep_buffer(void) { - pr_info("free_alloced_keep_buffer %p.%p.%p\n", + /*pr_info("free_alloced_keep_buffer %p.%p.%p\n", (void *)keep_y_addr, (void *)keep_u_addr, (void *)keep_v_addr); + */ if (keep_y_addr) { codec_mm_free_for_dma(MEM_NAME, keep_y_addr); keep_y_addr = 0; @@ -690,9 +693,8 @@ void try_free_keep_video(int flags) int free_scatter_keeper = flags & 0x1; if (keep_video_on || free_scatter_keeper) { - pr_info("disbled keep video before free keep buffer.\n"); + /*pr_info("disbled keep video before free keep buffer.\n");*/ keep_video_on = 0; - update_cur_dispbuf(NULL); if (!get_video_enabled()) { /*if not disable video,changed to 2 for */ pr_info("disbled video for next before free keep buffer!\n"); @@ -701,46 +703,101 @@ void try_free_keep_video(int flags) safe_disble_videolayer(); } } - if (free_scatter_keeper && keep_id > 0) { - pr_info("try_free_keep_video keepid\n"); - codec_mm_keeper_unmask_keeper(keep_id, 0); - keep_id = -1; - } - if (free_scatter_keeper && keep_head_id > 0) { - pr_info("try_free_keep_video keep_head_id\n"); - codec_mm_keeper_unmask_keeper(keep_head_id, 0); - keep_head_id = -1; - } mutex_lock(&video_keeper_mutex); + video_keeper_new_frame_notify(); free_alloced_keep_buffer(); mutex_unlock(&video_keeper_mutex); - } EXPORT_SYMBOL(try_free_keep_video); #endif +static void video_keeper_update_keeper_mem( + void *mem_handle, int type, + int *id) +{ + int ret; + int old_id = *id; + + if (!mem_handle) + return; + ret = codec_mm_keeper_mask_keep_mem(mem_handle, + type); + if (ret > 0) { + if (old_id > 0 && ret != old_id) { + /*wait 80 ms for vsync post.*/ + codec_mm_keeper_unmask_keeper(old_id, 120); + } + *id = ret; + } +} +static void video_keeper_frame_keep_locked( + struct vframe_s *cur_dispbuf, + struct vframe_s *cur_dispbuf_el) +{ + int type = MEM_TYPE_CODEC_MM; + + if (cur_dispbuf->type & VIDTYPE_SCATTER) + type = MEM_TYPE_CODEC_MM_SCATTER; + video_keeper_update_keeper_mem( + cur_dispbuf->mem_handle, + type, + &keep_id); + video_keeper_update_keeper_mem( + cur_dispbuf->mem_head_handle, + MEM_TYPE_CODEC_MM, + &keep_head_id); + if (cur_dispbuf_el) { + if (cur_dispbuf->type & VIDTYPE_SCATTER) + type = MEM_TYPE_CODEC_MM_SCATTER; + else + type = MEM_TYPE_CODEC_MM; + video_keeper_update_keeper_mem( + cur_dispbuf_el->mem_handle, + type, + &keep_el_id); + video_keeper_update_keeper_mem( + cur_dispbuf_el->mem_head_handle, + MEM_TYPE_CODEC_MM, + &keep_el_head_id); + } +} + +/* + * call in irq. + *don't used mutex + */ void video_keeper_new_frame_notify(void) { if (keep_video_on) { - pr_info("new toggle keep_id\n"); + pr_info("new frame show, free keeper\n"); keep_video_on = 0; } if (keep_id > 0) { /*wait 80 ms for vsync post.*/ - pr_info("new frame show, free keeper\n"); codec_mm_keeper_unmask_keeper(keep_id, 120); keep_id = -1; } if (keep_head_id > 0) { /*wait 80 ms for vsync post.*/ - pr_info("new frame show, free keeper head\n"); codec_mm_keeper_unmask_keeper(keep_head_id, 120); keep_head_id = -1; } + if (keep_el_id > 0) { + /*wait 80 ms for vsync post.*/ + codec_mm_keeper_unmask_keeper(keep_el_id, 120); + keep_el_id = -1; + } + if (keep_el_head_id > 0) { + /*wait 80 ms for vsync post.*/ + codec_mm_keeper_unmask_keeper(keep_el_head_id, 120); + keep_el_head_id = -1; + } return; } -static unsigned int vf_keep_current_locked(struct vframe_s *cur_dispbuf) +static unsigned int vf_keep_current_locked( + struct vframe_s *cur_dispbuf, + struct vframe_s *cur_dispbuf_el) { u32 cur_index; u32 y_index, u_index, v_index; @@ -777,36 +834,8 @@ static unsigned int vf_keep_current_locked(struct vframe_s *cur_dispbuf) pr_info("keep exit is skip VPP_VD1_POSTBLEND\n"); return 0; } - if (1) { - int ret; - int old_keep = keep_id; - int old_head_keep = keep_head_id; - int type = MEM_TYPE_CODEC_MM; - - if (cur_dispbuf->type & VIDTYPE_SCATTER) - type = MEM_TYPE_CODEC_MM_SCATTER; - ret = codec_mm_keeper_mask_keep_mem(cur_dispbuf->mem_handle, - type); - if (ret > 0) { - keep_id = ret; - if (old_keep > 0 && keep_id != old_keep) { - /*wait 80 ms for vsync post.*/ - codec_mm_keeper_unmask_keeper(old_keep, 120); - } - } - ret = codec_mm_keeper_mask_keep_mem( - cur_dispbuf->mem_head_handle, - MEM_TYPE_CODEC_MM); - if (ret > 0) { - keep_head_id = ret; - if (old_head_keep > 0 && - keep_head_id != old_head_keep) { - /*wait 80 ms for vsync post.*/ - codec_mm_keeper_unmask_keeper(old_head_keep, - 120); - } - } - } + video_keeper_frame_keep_locked(cur_dispbuf, + cur_dispbuf_el); #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC if (codec_mm_video_tvp_enabled()) { @@ -999,12 +1028,15 @@ static unsigned int vf_keep_current_locked(struct vframe_s *cur_dispbuf) return 0; } -unsigned int vf_keep_current(struct vframe_s *cur_dispbuf) +unsigned int vf_keep_current( + struct vframe_s *cur_dispbuf, + struct vframe_s *cur_dispbuf2) { unsigned int ret; mutex_lock(&video_keeper_mutex); - ret = vf_keep_current_locked(cur_dispbuf); + ret = vf_keep_current_locked(cur_dispbuf, + cur_dispbuf2); mutex_unlock(&video_keeper_mutex); return ret; } diff --git a/drivers/amlogic/media/video_sink/vpp.c b/drivers/amlogic/media/video_sink/vpp.c index 0cf1dc38..40b045f 100644 --- a/drivers/amlogic/media/video_sink/vpp.c +++ b/drivers/amlogic/media/video_sink/vpp.c @@ -1803,6 +1803,11 @@ static void vpp_set_scaler(u32 process_3d_type, u32 src_width, next_frame_par->supsc1_hori_ratio = 0; else next_frame_par->supsc1_hori_ratio = 1; + /* disble sp1 for this case */ + if ((vpp_wide_mode == VIDEO_WIDEOPTION_NONLINEAR) + && (next_frame_par->supscl_path + == sup0_pp_sp1_scpath)) + next_frame_par->supsc1_hori_ratio = 0; next_frame_par->supsc0_enable = (next_frame_par->supsc0_hori_ratio || next_frame_par->supsc0_enable) ? 1 : 0; @@ -1965,6 +1970,21 @@ static void vpp_set_scaler(u32 process_3d_type, u32 src_width, next_frame_par->supsc1_vert_ratio; } + if ((vpp_wide_mode == VIDEO_WIDEOPTION_NONLINEAR) && + (next_frame_par->VPP_hsc_endp > + next_frame_par->VPP_hsc_startp)) { + s32 start, end; + struct vppfilter_mode_s *filter = + &next_frame_par->vpp_filter; + start = next_frame_par->VPP_hsc_startp; + end = next_frame_par->VPP_hsc_endp; + calculate_non_linear_ratio( + (filter->vpp_hsc_start_phase_step >> 6), + end - start, + next_frame_par); + next_frame_par->VPP_hsc_linear_startp = + next_frame_par->VPP_hsc_linear_endp = (start + end) / 2; + } if (h_crop_enable) { next_frame_par->VPP_hd_start_lines_ += video_source_crop_left; next_frame_par->VPP_hd_end_lines_ += video_source_crop_left; diff --git a/drivers/amlogic/tee/Kconfig b/drivers/amlogic/tee/Kconfig new file mode 100644 index 0000000..b11afb2 --- /dev/null +++ b/drivers/amlogic/tee/Kconfig @@ -0,0 +1,8 @@ +config AMLOGIC_TEE + tristate "TEE Support for Amlogic" + default n + help + Amlogic TEE driver + + Provide TEE APIs and Debug interface in sysfs, depends on the + tee os. diff --git a/drivers/amlogic/tee/Makefile b/drivers/amlogic/tee/Makefile new file mode 100644 index 0000000..d99520b --- /dev/null +++ b/drivers/amlogic/tee/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_AMLOGIC_TEE) += tee.o diff --git a/drivers/amlogic/tee/tee.c b/drivers/amlogic/tee/tee.c new file mode 100644 index 0000000..eb846d2 --- /dev/null +++ b/drivers/amlogic/tee/tee.c @@ -0,0 +1,193 @@ +/* + * drivers/amlogic/tee/tee.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 +#include +#include +#include + +#include + +#define DRIVER_NAME "tee_info" +#define DRIVER_DESC "Amlogic tee driver" + +#define TEE_MSG_UID_0 0x384fb3e0 +#define TEE_MSG_UID_1 0xe7f811e3 +#define TEE_MSG_UID_2 0xaf630002 +#define TEE_MSG_UID_3 0xa5d5c51b + +#define TEE_SMC_FUNCID_CALLS_REVISION 0xFF03 +#define TEE_SMC_CALLS_REVISION \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_TRUSTED_OS_END, \ + TEE_SMC_FUNCID_CALLS_REVISION) + +#define TEE_SMC_FUNCID_CALLS_UID 0xFF01 +#define TEE_SMC_CALLS_UID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_TRUSTED_OS_END, \ + TEE_SMC_FUNCID_CALLS_UID) + + +#define TEE_SMC_FAST_CALL_VAL(func_num) \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_TRUSTED_OS, (func_num)) + +#define TEE_SMC_FUNCID_GET_OS_REVISION 0x0001 +#define TEE_SMC_CALL_GET_OS_REVISION \ + TEE_SMC_FAST_CALL_VAL(TEE_SMC_FUNCID_GET_OS_REVISION) + +#define TEE_SMC_FUNCID_LOAD_VIDEO_FW 15 +#define TEE_SMC_LOAD_VIDEO_FW \ + TEE_SMC_FAST_CALL_VAL(TEE_SMC_FUNCID_LOAD_VIDEO_FW) + +static struct class *tee_sys_class; + +struct tee_smc_calls_revision_result { + unsigned long major; + unsigned long minor; + unsigned long reserved0; + unsigned long reserved1; +}; + +static int tee_msg_os_revision(uint32_t *major, uint32_t *minor) +{ + union { + struct arm_smccc_res smccc; + struct tee_smc_calls_revision_result result; + } res; + + arm_smccc_smc(TEE_SMC_CALL_GET_OS_REVISION, + 0, 0, 0, 0, 0, 0, 0, &res.smccc); + + *major = res.result.major; + *minor = res.result.minor; + + return 0; +} + +static int tee_msg_api_revision(uint32_t *major, uint32_t *minor) +{ + union { + struct arm_smccc_res smccc; + struct tee_smc_calls_revision_result result; + } res; + + arm_smccc_smc(TEE_SMC_CALLS_REVISION, + 0, 0, 0, 0, 0, 0, 0, &res.smccc); + + *major = res.result.major; + *minor = res.result.minor; + + return 0; +} + +static ssize_t tee_os_version_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + int ret; + uint32_t major, minor; + + ret = tee_msg_os_revision(&major, &minor); + if (ret) + return 0; + + ret = sprintf(buf, "os version: V%d.%d\n", major, minor); + + return ret; +} + +static ssize_t tee_api_version_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + int ret; + uint32_t major, minor; + + ret = tee_msg_api_revision(&major, &minor); + if (ret) + return 0; + + ret = sprintf(buf, "api version: V%d.%d\n", major, minor); + + return ret; +} + +static CLASS_ATTR(os_version, 0644, tee_os_version_show, + NULL); +static CLASS_ATTR(api_version, 0644, tee_api_version_show, + NULL); + +int tee_load_video_fw(uint32_t index) +{ + struct arm_smccc_res res; + + arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, + index, 0, 0, 0, 0, 0, 0, &res); + + return res.a0; +} +EXPORT_SYMBOL(tee_load_video_fw); + +bool tee_enabled(void) +{ + struct arm_smccc_res res; + + arm_smccc_smc(TEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res); + + if (res.a0 == TEE_MSG_UID_0 && res.a1 == TEE_MSG_UID_1 && + res.a2 == TEE_MSG_UID_2 && res.a3 == TEE_MSG_UID_3) + return true; + return false; +} +EXPORT_SYMBOL(tee_enabled); + +int tee_create_sysfs(void) +{ + int ret; + + tee_sys_class = class_create(THIS_MODULE, DRIVER_NAME); + ret = class_create_file(tee_sys_class, &class_attr_os_version); + if (ret != 0) { + pr_err("create class file os_version fail\n"); + return ret; + } + ret = class_create_file(tee_sys_class, &class_attr_api_version); + if (ret != 0) { + pr_err("create class file os_version fail\n"); + return ret; + } + + return ret; +} + +static int __init aml_tee_modinit(void) +{ + return tee_create_sysfs(); +} + +arch_initcall(aml_tee_modinit); + +static void __exit aml_tee_modexit(void) +{ + class_destroy(tee_sys_class); +} + +module_exit(aml_tee_modexit); + +MODULE_AUTHOR("pengguang.zhu"); +MODULE_DESCRIPTION(DRIVER_TEE); +MODULE_LICENSE("GPL"); diff --git a/include/linux/amlogic/media/frame_sync/timestamp.h b/include/linux/amlogic/media/frame_sync/timestamp.h index b333947..e653bfa 100644 --- a/include/linux/amlogic/media/frame_sync/timestamp.h +++ b/include/linux/amlogic/media/frame_sync/timestamp.h @@ -48,6 +48,8 @@ extern u32 timestamp_pcrscr_enable_state(void); extern void timestamp_pcrscr_set_adj(s32 inc); +extern void timestamp_pcrscr_set_adj_pcr(s32 inc); + extern void timestamp_apts_enable(u32 enable); extern void timestamp_apts_start(u32 enable); diff --git a/include/linux/amlogic/media/utils/amstream.h b/include/linux/amlogic/media/utils/amstream.h index fcef9f8..7aa5f9f 100644 --- a/include/linux/amlogic/media/utils/amstream.h +++ b/include/linux/amlogic/media/utils/amstream.h @@ -451,6 +451,7 @@ struct userdata_poc_info_t { #define AMSTREAM_SET_FRAME_BASE_PATH 0x174 #define AMSTREAM_SET_EOS 0x175 #define AMSTREAM_SET_RECEIVE_ID 0x176 +#define AMSTREAM_SET_IS_RESET 0x177 /* video set ex cmd */ #define AMSTREAM_SET_EX_VIDEO_AXIS 0x260 diff --git a/include/linux/amlogic/media/video_sink/video.h b/include/linux/amlogic/media/video_sink/video.h index d6aca57..1011c90 100644 --- a/include/linux/amlogic/media/video_sink/video.h +++ b/include/linux/amlogic/media/video_sink/video.h @@ -252,6 +252,8 @@ extern int power_key_pressed; #ifdef CONFIG_AM_VIDEO2 extern void set_clone_frame_rate(unsigned int frame_rate, unsigned int delay); #endif +extern struct vframe_provider_s *vf_get_provider_by_name( + const char *provider_name); extern void prot_get_parameter(u32 wide_mode, struct vframe_s *vf, struct vpp_frame_par_s *next_frame_par, diff --git a/include/linux/amlogic/media/video_sink/video_keeper.h b/include/linux/amlogic/media/video_sink/video_keeper.h index 2bfb806..1594690 100644 --- a/include/linux/amlogic/media/video_sink/video_keeper.h +++ b/include/linux/amlogic/media/video_sink/video_keeper.h @@ -25,6 +25,8 @@ void try_free_keep_video(int flags); int __init video_keeper_init(void); void __exit video_keeper_exit(void); -unsigned int vf_keep_current(struct vframe_s *cur_dispbuf); +unsigned int vf_keep_current( + struct vframe_s *cur_dispbuf, + struct vframe_s *cur_dispbuf2); #endif diff --git a/include/linux/amlogic/tee.h b/include/linux/amlogic/tee.h new file mode 100644 index 0000000..45e80e4 --- /dev/null +++ b/include/linux/amlogic/tee.h @@ -0,0 +1,25 @@ +/* + * include/linux/amlogic/tee.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 __TEE_H__ +#define __TEE_H__ + +extern bool tee_enabled(void); +extern int is_secload_get(void); +extern int tee_load_video_fw(uint32_t index); +#endif /* __TEE_H__ */ + -- 2.7.4