diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c index 0be46a44435a..0defc652e536 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c @@ -49,7 +49,7 @@ /*#define TEST_NO_BUF*/ /*#define HEVC_PIC_STRUCT_SUPPORT*/ #define MULTI_INSTANCE_SUPPORT - +#define USE_UNINIT_SEMA /* .buf_size = 0x100000*16, //4k2k , 0x100000 per buffer */ /* 4096x2304 , 0x120000 per buffer */ @@ -1530,6 +1530,8 @@ struct hevc_state_s { u8 head_error_flag; int valve_count; struct firmware_s *fw; + int max_pic_w; + int max_pic_h; } /*hevc_stru_t */; #ifdef SEND_LMEM_WITH_RPM @@ -2045,7 +2047,11 @@ static int init_mmu_buffers(struct hevc_state_s *hevc) { int tvp_flag = vdec_secure(hw_to_vdec(hevc)) ? CODEC_MM_FLAGS_TVP : 0; - + int buf_size = 64; + if ((hevc->max_pic_w * hevc->max_pic_h) > 0 && (hevc->max_pic_w * hevc->max_pic_h) <= 1920*1088) { + buf_size = 24; + } + pr_err("William max_w %d max_h %d\n",hevc->max_pic_w,hevc->max_pic_h); if (hevc->mmu_enable) { hevc->mmu_box = decoder_mmu_box_alloc_box(DRIVER_NAME, hevc->index, @@ -8694,7 +8700,10 @@ static s32 vh265_init(struct hevc_state_s *hevc) hevc->stat |= STAT_TIMER_ARM;*/ INIT_WORK(&hevc->work, vh265_work); - +#ifdef USE_UNINIT_SEMA + sema_init( + &hevc->h265_uninit_done_sema, 0); +#endif hevc->fw = fw; return 0; @@ -9996,6 +10005,16 @@ static int ammvdec_h265_probe(struct platform_device *pdev) hevc->double_write_mode = config_val; else hevc->double_write_mode = double_write_mode; + + /*use ptr config for max_pic_w, etc*/ + if (get_config_int(pdata->config, "hevc_buf_width", + &config_val) == 0) { + hevc->max_pic_w = config_val; + } + if (get_config_int(pdata->config, "hevc_buf_height", + &config_val) == 0) { + hevc->max_pic_h = config_val; + } #endif } else { hevc->vh265_amstream_dec_info.width = 0; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c index 52ca1adb91ce..9b038421bfd6 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec.c @@ -78,6 +78,12 @@ static unsigned int debug_trace_num = 16 * 20; static int step_mode; static unsigned int clk_config; +/* +&1: sched_priority to MAX_RT_PRIO -1. +&2: always reload firmware. +*/ +static unsigned int debug; + static int hevc_max_reset_count; #define MAX_INSTANCE_MUN 9 @@ -116,6 +122,7 @@ struct vdec_core_s { struct vdec_isr_context_s isr_context[VDEC_IRQ_MAX]; int power_ref_count[VDEC_MAX]; + void *last_vdec; }; static struct vdec_core_s *vdec_core; @@ -1583,7 +1590,7 @@ int vdec_reset(struct vdec_s *vdec) if (vdec->slave) vdec->slave->reset(vdec->slave); } - + vdec->mc_loaded = 0;/*clear for reload firmware.*/ vdec_input_release(&vdec->input); vf_reg_provider(&vdec->vframe_provider); @@ -1594,6 +1601,7 @@ int vdec_reset(struct vdec_s *vdec) vf_reg_provider(&vdec->slave->vframe_provider); vf_notify_receiver(vdec->slave->vf_provider_name, VFRAME_EVENT_PROVIDER_START, vdec->slave); + vdec->slave->mc_loaded = 0;/*clear for reload firmware.*/ } vdec_connect(vdec); @@ -1802,13 +1810,13 @@ static inline void vdec_prepare_run(struct vdec_s *vdec) static int vdec_core_thread(void *data) { struct vdec_core_s *core = (struct vdec_core_s *)data; - - struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1}; + struct vdec_s *lastvdec; + struct sched_param param = {.sched_priority = MAX_RT_PRIO/2}; sched_setscheduler(current, SCHED_FIFO, ¶m); allow_signal(SIGTERM); - + lastvdec = NULL; while (down_interruptible(&core->sem) == 0) { struct vdec_s *vdec, *tmp; LIST_HEAD(disconnecting_list); @@ -1910,6 +1918,10 @@ static int vdec_core_thread(void *data) /* start the vdec instance */ if ((vdec) && (vdec->status != VDEC_STATUS_ACTIVE)) { + if (lastvdec != vdec) + vdec->mc_loaded = 0;/*clear for reload firmware.*/ + if (debug & 2) + vdec->mc_loaded = 0;/*alway reload firmware.*/ vdec_set_status(vdec, VDEC_STATUS_ACTIVE); /* activatate the decoder instance to run */ @@ -1920,6 +1932,7 @@ static int vdec_core_thread(void *data) vdec_prepare_run(vdec); vdec->run(vdec, vdec_callback, core); + lastvdec = vdec; } /* remove disconnected decoder from active list */ @@ -1933,6 +1946,7 @@ static int vdec_core_thread(void *data) msleep(20); up(&core->sem); } + } return 0; @@ -3179,8 +3193,13 @@ static int vdec_probe(struct platform_device *pdev) vdec_core->thread = kthread_run(vdec_core_thread, vdec_core, "vdec-core"); - vdec_core->vdec_core_wq = create_singlethread_workqueue("threadvdec"); - + vdec_core->vdec_core_wq = alloc_ordered_workqueue("%s", + __WQ_LEGACY | + WQ_MEM_RECLAIM | + WQ_HIGHPRI/*high priority*/ + , + "vdec-work"); + /*work queue priority lower than vdec-core.*/ return 0; } @@ -3288,7 +3307,7 @@ static int __init vdec_mem_setup(struct reserved_mem *rmem) } RESERVEDMEM_OF_DECLARE(vdec, "amlogic, vdec-memory", vdec_mem_setup); - +module_param(debug, uint, 0664); module_param(debug_trace_num, uint, 0664); module_param(hevc_max_reset_count, int, 0664); module_param(clk_config, uint, 0664); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_profile.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_profile.c index 638cc3344240..95129aeb90fc 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_profile.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_profile.c @@ -39,6 +39,8 @@ struct vdec_profile_rec_s { struct vdec_s *vdec; u64 timestamp; int event; + int para1; + int para2; }; static struct vdec_profile_rec_s recs[PROFILE_REC_SIZE]; @@ -49,7 +51,8 @@ static const char *event_name[VDEC_PROFILE_MAX_EVENT] = { "check run ready", "run ready", "disconnect", - "dec_work" + "dec_work", + "info" }; static u64 get_us_time(void) @@ -65,13 +68,15 @@ static u64 get_us_time(void) return (((u64)hi1) << 32) | lo; } -void vdec_profile(struct vdec_s *vdec, int event) +void vdec_profile_more(struct vdec_s *vdec, int event, int para1, int para2) { mutex_lock(&vdec_profile_mutex); recs[rec_wp].vdec = vdec; recs[rec_wp].timestamp = get_us_time(); recs[rec_wp].event = event; + recs[rec_wp].para1 = para1; + recs[rec_wp].para2 = para2; rec_wp++; if (rec_wp == PROFILE_REC_SIZE) { @@ -81,6 +86,13 @@ void vdec_profile(struct vdec_s *vdec, int event) mutex_unlock(&vdec_profile_mutex); } +EXPORT_SYMBOL(vdec_profile_more); + +void vdec_profile(struct vdec_s *vdec, int event) +{ + vdec_profile_more(vdec, event, 0 , 0); +} +EXPORT_SYMBOL(vdec_profile); void vdec_profile_flush(struct vdec_s *vdec) { @@ -125,13 +137,24 @@ static int vdec_profile_dbg_show(struct seq_file *m, void *v) break; if (recs[i].vdec) { - seq_printf(m, "[%s:%d] %016llu us : %s\n", + seq_printf(m, "[%s:%d] \t%016llu us : %s (%d,%d)\n", vdec_device_name_str(recs[i].vdec), recs[i].vdec->id, recs[i].timestamp - base_timestamp, - event_str(recs[i].event)); + event_str(recs[i].event), + recs[i].para1, + recs[i].para2 + ); + } else { + seq_printf(m, "[%s:%d] \t%016llu us : %s (%d,%d)\n", + "N/A", + 0, + recs[i].timestamp - base_timestamp, + event_str(recs[i].event), + recs[i].para1, + recs[i].para2 + ); } - if (++i == PROFILE_REC_SIZE) i = 0; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_profile.h b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_profile.h index 6ad23431d703..34f3beed3231 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_profile.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/vdec_profile.h @@ -27,10 +27,11 @@ struct vdec_s; #define VDEC_PROFILE_EVENT_RUN_READY 4 #define VDEC_PROFILE_EVENT_DISCONNECT 5 #define VDEC_PROFILE_EVENT_DEC_WORK 6 -#define VDEC_PROFILE_MAX_EVENT 7 +#define VDEC_PROFILE_EVENT_INFO 7 +#define VDEC_PROFILE_MAX_EVENT 8 extern void vdec_profile(struct vdec_s *vdec, int event); - +extern void vdec_profile_more(struct vdec_s *vdec, int event, int para1, int para2); extern void vdec_profile_flush(struct vdec_s *vdec); int vdec_profile_init_debugfs(void); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c index 1376fd48eb5b..735ca7a57227 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c @@ -5152,11 +5152,11 @@ static void vp9_init_decoder_hw(struct VP9Decoder_s *pbi) WRITE_VREG(HEVC_DEC_STATUS_REG, 0); /*Initial IQIT_SCALELUT memory -- just to avoid X in simulation*/ - + #if 0 /*by CS:only need for simulation*/ WRITE_VREG(HEVC_IQIT_SCALELUT_WR_ADDR, 0);/*cfg_p_addr*/ for (i = 0; i < 1024; i++) WRITE_VREG(HEVC_IQIT_SCALELUT_DATA, 0); - + #endif #ifdef ENABLE_SWAP_TEST WRITE_VREG(HEVC_STREAM_SWAP_TEST, 100); @@ -7920,14 +7920,20 @@ static void run(struct vdec_s *vdec, } vp9_print_cont(pbi, 0, "\r\n"); } - - if (amhevc_loadmc_ex(VFORMAT_VP9, NULL, pbi->fw->data) < 0) { + if (vdec->mc_loaded) { + /*firmware have load before, + and not changes to another. + ignore reload. + */ + } else if ( amhevc_loadmc_ex(VFORMAT_VP9, NULL, pbi->fw->data) < 0) { + vdec->mc_loaded = 0; amhevc_disable(); vp9_print(pbi, 0, "%s: Error amvdec_loadmc fail\n", __func__); return; + } else { + vdec->mc_loaded = 1; } - if (vp9_hw_ctx_restore(pbi) < 0) { vdec_schedule_work(&pbi->work); return;