media : optimize decoder timing for vts [1/1]

PD#155696

1) replace msleep with sema in h265
2) decrease scatter mem cache size for non-4k h265
3) set vdec thread to higher priority
4) zz:set vdec work to higher priority
5) zz:don't reload mc code when on instance.
6) zz:del config SCALELUT_WR_ADDR for each frame.
7) zz:profile add some paras for debug.

Change-Id: Ie4be769269c8a485755f5610d3739df26d34cf17
Signed-off-by: Hui Zhang <hui.zhang@amlogic.com>
Signed-off-by: Zhi Zhou <zhi.zhou@amlogic.com>
This commit is contained in:
Hui Zhang
2017-11-20 16:57:37 +08:00
committed by Dongjin Kim
parent a9b14a22a9
commit 7d0e07af7f
5 changed files with 90 additions and 22 deletions

View File

@@ -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;

View File

@@ -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, &param);
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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;