mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
media_module: optimization for vdec schedule debug and fw load[1/1]
PD#SWPL-895 Problem: optimization for vdec schedule debug and fw load Solution: 1) change vdec_core_thread priority 2) add reload flag in vdec to check if reload fw at every run 3) add mc_type to check if fw need reload at every run Verify: Verified p212 Change-Id: Ic14f14831bf59d913450228ba07e0f94dde5347e Signed-off-by: Hui Zhang <hui.zhang@amlogic.com>
This commit is contained in:
@@ -5662,8 +5662,10 @@ static void run(struct vdec_s *vdec, unsigned long mask,
|
||||
dec->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&dec->work);
|
||||
return;
|
||||
} else
|
||||
} else {
|
||||
vdec->mc_loaded = 1;
|
||||
vdec->mc_type = VFORMAT_AVS2;
|
||||
}
|
||||
|
||||
|
||||
if (avs2_hw_ctx_restore(dec) < 0) {
|
||||
|
||||
@@ -6856,36 +6856,44 @@ static void run(struct vdec_s *vdec, unsigned long mask,
|
||||
size);
|
||||
|
||||
start_process_time(hw);
|
||||
if (vdec->mc_loaded) {
|
||||
/*firmware have load before,
|
||||
and not changes to another.
|
||||
ignore reload.
|
||||
*/
|
||||
} else {
|
||||
|
||||
ret = amvdec_vdec_loadmc_ex(VFORMAT_H264, "mh264", vdec, hw->fw->data);
|
||||
if (ret < 0) {
|
||||
amvdec_enable_flag = false;
|
||||
amvdec_disable();
|
||||
|
||||
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
|
||||
"MH264 the %s fw loading failed, err: %x\n",
|
||||
tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hw->work);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hw->mmu_enable) {
|
||||
ret = amhevc_loadmc_ex(VFORMAT_H264, "mh264_mmu",
|
||||
hw->fw_mmu->data);
|
||||
ret = amvdec_vdec_loadmc_ex(VFORMAT_H264, "mh264", vdec, hw->fw->data);
|
||||
if (ret < 0) {
|
||||
amvdec_enable_flag = false;
|
||||
amhevc_disable();
|
||||
amvdec_disable();
|
||||
|
||||
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
|
||||
"MH264_MMU the %s fw loading failed, err: %x\n",
|
||||
"MH264 the %s fw loading failed, err: %x\n",
|
||||
tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hw->work);
|
||||
return;
|
||||
}
|
||||
}
|
||||
vdec->mc_type = VFORMAT_H264;
|
||||
if (hw->mmu_enable) {
|
||||
ret = amhevc_loadmc_ex(VFORMAT_H264, "mh264_mmu",
|
||||
hw->fw_mmu->data);
|
||||
if (ret < 0) {
|
||||
amvdec_enable_flag = false;
|
||||
amhevc_disable();
|
||||
|
||||
dpb_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
|
||||
"MH264_MMU the %s fw loading failed, err: %x\n",
|
||||
tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hw->work);
|
||||
return;
|
||||
}
|
||||
vdec->mc_type = ((1 << 16) | VFORMAT_H264);
|
||||
}
|
||||
vdec->mc_loaded = 1;
|
||||
}
|
||||
vmh264_reset_udr_mgr(hw);
|
||||
|
||||
if (vh264_hw_ctx_restore(hw) < 0) {
|
||||
|
||||
@@ -10239,23 +10239,30 @@ static void run(struct vdec_s *vdec, unsigned long mask,
|
||||
"\n");
|
||||
}
|
||||
}
|
||||
if (vdec->mc_loaded) {
|
||||
/*firmware have load before,
|
||||
and not changes to another.
|
||||
ignore reload.
|
||||
*/
|
||||
} else {
|
||||
if (hevc->mmu_enable)
|
||||
loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec,
|
||||
"h265_mmu", hevc->fw->data);
|
||||
else
|
||||
loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec,
|
||||
NULL, hevc->fw->data);
|
||||
|
||||
if (hevc->mmu_enable)
|
||||
loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec,
|
||||
"h265_mmu", hevc->fw->data);
|
||||
else
|
||||
loadr = amhevc_vdec_loadmc_ex(VFORMAT_HEVC, vdec,
|
||||
NULL, hevc->fw->data);
|
||||
|
||||
if (loadr < 0) {
|
||||
amhevc_disable();
|
||||
hevc_print(hevc, 0, "H265: the %s fw loading failed, err: %x\n",
|
||||
tee_enabled() ? "TEE" : "local", loadr);
|
||||
hevc->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hevc->work);
|
||||
return;
|
||||
if (loadr < 0) {
|
||||
amhevc_disable();
|
||||
hevc_print(hevc, 0, "H265: the %s fw loading failed, err: %x\n",
|
||||
tee_enabled() ? "TEE" : "local", loadr);
|
||||
hevc->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hevc->work);
|
||||
return;
|
||||
}
|
||||
vdec->mc_loaded = 1;
|
||||
vdec->mc_type = VFORMAT_HEVC;
|
||||
}
|
||||
|
||||
if (vh265_hw_ctx_restore(hevc) < 0) {
|
||||
vdec_schedule_work(&hevc->work);
|
||||
return;
|
||||
|
||||
@@ -923,14 +923,22 @@ static void run(struct vdec_s *vdec, unsigned long mask,
|
||||
}
|
||||
hw->input_empty = 0;
|
||||
hw->dec_result = DEC_RESULT_NONE;
|
||||
|
||||
ret = amvdec_vdec_loadmc_ex(VFORMAT_MJPEG, "mmjpeg", vdec, hw->fw->data);
|
||||
if (ret < 0) {
|
||||
pr_err("[%d] MMJPEG: the %s fw loading failed, err: %x\n",
|
||||
vdec->id, tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hw->work);
|
||||
return;
|
||||
if (vdec->mc_loaded) {
|
||||
/*firmware have load before,
|
||||
and not changes to another.
|
||||
ignore reload.
|
||||
*/
|
||||
} else {
|
||||
ret = amvdec_vdec_loadmc_ex(VFORMAT_MJPEG, "mmjpeg", vdec, hw->fw->data);
|
||||
if (ret < 0) {
|
||||
pr_err("[%d] MMJPEG: the %s fw loading failed, err: %x\n",
|
||||
vdec->id, tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hw->work);
|
||||
return;
|
||||
}
|
||||
vdec->mc_loaded = 1;
|
||||
vdec->mc_type = VFORMAT_MJPEG;
|
||||
}
|
||||
/* if (amvdec_vdec_loadmc_buf_ex(vdec, hw->fw->data, hw->fw->len) < 0) {
|
||||
pr_err("%s: Error amvdec_loadmc fail\n", __func__);
|
||||
|
||||
@@ -1670,17 +1670,24 @@ void (*callback)(struct vdec_s *, void *),
|
||||
hw->chunk->offset, hw->chunk->size);
|
||||
|
||||
hw->dec_result = DEC_RESULT_NONE;
|
||||
|
||||
ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_MPEG12, "mmpeg12", vdec,
|
||||
hw->fw->data, hw->fw->len);
|
||||
if (ret < 0) {
|
||||
pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
|
||||
hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hw->work);
|
||||
return;
|
||||
if (vdec->mc_loaded) {
|
||||
/*firmware have load before,
|
||||
and not changes to another.
|
||||
ignore reload.
|
||||
*/
|
||||
} else {
|
||||
ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_MPEG12, "mmpeg12", vdec,
|
||||
hw->fw->data, hw->fw->len);
|
||||
if (ret < 0) {
|
||||
pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
|
||||
hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&hw->work);
|
||||
return;
|
||||
}
|
||||
vdec->mc_loaded = 1;
|
||||
vdec->mc_type = VFORMAT_MPEG12;
|
||||
}
|
||||
|
||||
if (vmpeg12_hw_ctx_restore(hw) < 0) {
|
||||
hw->dec_result = DEC_RESULT_ERROR;
|
||||
debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR,
|
||||
|
||||
@@ -1675,17 +1675,24 @@ static void run(struct vdec_s *vdec, unsigned long mask,
|
||||
READ_PARSER_REG(PARSER_VIDEO_WP));
|
||||
|
||||
hw->dec_result = DEC_RESULT_NONE;
|
||||
|
||||
ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_MPEG4,hw->fw->name, vdec,
|
||||
hw->fw->data, hw->fw->len);
|
||||
if (ret < 0) {
|
||||
pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
|
||||
hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
schedule_work(&hw->work);
|
||||
return;
|
||||
if (vdec->mc_loaded) {
|
||||
/*firmware have load before,
|
||||
and not changes to another.
|
||||
ignore reload.
|
||||
*/
|
||||
} else {
|
||||
ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_MPEG4,hw->fw->name, vdec,
|
||||
hw->fw->data, hw->fw->len);
|
||||
if (ret < 0) {
|
||||
pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id,
|
||||
hw->fw->name, tee_enabled() ? "TEE" : "local", ret);
|
||||
hw->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
schedule_work(&hw->work);
|
||||
return;
|
||||
}
|
||||
vdec->mc_loaded = 1;
|
||||
vdec->mc_type = VFORMAT_MPEG4;
|
||||
}
|
||||
|
||||
if (vmpeg4_hw_ctx_restore(hw) < 0) {
|
||||
hw->dec_result = DEC_RESULT_ERROR;
|
||||
mmpeg4_debug_print(DECODE_ID(hw), 0,
|
||||
|
||||
@@ -81,6 +81,11 @@ static int keep_vdec_mem;
|
||||
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
|
||||
@@ -122,6 +127,7 @@ struct vdec_core_s {
|
||||
unsigned long sched_mask;
|
||||
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;
|
||||
@@ -1738,7 +1744,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);
|
||||
|
||||
vdec_input_init(&vdec->input, vdec);
|
||||
@@ -1754,6 +1760,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);
|
||||
@@ -2091,13 +2098,13 @@ void vdec_prepare_run(struct vdec_s *vdec, unsigned long mask)
|
||||
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, *worker;
|
||||
unsigned long sched_mask = 0;
|
||||
@@ -2242,7 +2249,12 @@ static int vdec_core_thread(void *data)
|
||||
|
||||
/* vdec's sched_mask is only set from core thread */
|
||||
vdec->sched_mask |= mask;
|
||||
|
||||
if (lastvdec) {
|
||||
if ((lastvdec != vdec) && (lastvdec->mc_type != vdec->mc_type))
|
||||
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);
|
||||
|
||||
core->sched_mask |= mask;
|
||||
@@ -3830,8 +3842,9 @@ 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;
|
||||
}
|
||||
|
||||
@@ -3945,6 +3958,7 @@ EXPORT_SYMBOL(force_hevc_clock_cntl);
|
||||
|
||||
module_param(force_hevc_clock_cntl, uint, 0664);
|
||||
*/
|
||||
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);
|
||||
|
||||
@@ -200,7 +200,7 @@ struct vdec_s {
|
||||
/* mc cache */
|
||||
u32 mc[4096 * 4];
|
||||
bool mc_loaded;
|
||||
|
||||
u32 mc_type;
|
||||
/* frame provider/receiver interface */
|
||||
char vf_provider_name[VDEC_PROVIDER_NAME_SIZE];
|
||||
struct vframe_provider_s vframe_provider;
|
||||
|
||||
@@ -8779,16 +8779,24 @@ static void run_front(struct vdec_s *vdec)
|
||||
}
|
||||
vp9_print_cont(pbi, 0, "\r\n");
|
||||
}
|
||||
|
||||
ret = amhevc_loadmc_ex(VFORMAT_VP9, NULL, pbi->fw->data);
|
||||
if (ret < 0) {
|
||||
amhevc_disable();
|
||||
vp9_print(pbi, PRINT_FLAG_ERROR,
|
||||
"VP9: the %s fw loading failed, err: %x\n",
|
||||
tee_enabled() ? "TEE" : "local", ret);
|
||||
pbi->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&pbi->work);
|
||||
return;
|
||||
if (vdec->mc_loaded) {
|
||||
/*firmware have load before,
|
||||
and not changes to another.
|
||||
ignore reload.
|
||||
*/
|
||||
} else {
|
||||
ret = amhevc_loadmc_ex(VFORMAT_VP9, NULL, pbi->fw->data);
|
||||
if (ret < 0) {
|
||||
amhevc_disable();
|
||||
vp9_print(pbi, PRINT_FLAG_ERROR,
|
||||
"VP9: the %s fw loading failed, err: %x\n",
|
||||
tee_enabled() ? "TEE" : "local", ret);
|
||||
pbi->dec_result = DEC_RESULT_FORCE_EXIT;
|
||||
vdec_schedule_work(&pbi->work);
|
||||
return;
|
||||
}
|
||||
vdec->mc_loaded = 1;
|
||||
vdec->mc_type = VFORMAT_VP9;
|
||||
}
|
||||
|
||||
if (vp9_hw_ctx_restore(pbi) < 0) {
|
||||
|
||||
Reference in New Issue
Block a user