mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-11 05:17:10 +09:00
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:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user