From 63775cf5db5f6a2465577342d029411d39697e90 Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Mon, 28 Aug 2017 17:50:42 +0800 Subject: [PATCH] decoder: fixed firmware load issure in mult-instance mode. PD#149867: fixed firmware load issure in mult-instance mode Change-Id: I68ddae7225e582d2081e4c1e4675c42e3b88ffad Signed-off-by: Nanxin Qin --- .../decoder/h264_multi/vmh264.c | 19 +++++++- .../frame_provider/decoder/h265/vh265.c | 45 ++++++++++++------- .../frame_provider/decoder/utils/amvdec.c | 23 +++++----- .../frame_provider/decoder/utils/amvdec.h | 4 +- 4 files changed, 60 insertions(+), 31 deletions(-) diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c index a0125b525aa7..b5a52f7a1ad6 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c @@ -4805,7 +4805,11 @@ static void run(struct vdec_s *vdec, { struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private; - int size; + int size, firmware_size; + char *buf = vmalloc(0x1000 * 16); + if (IS_ERR_OR_NULL(buf)) + return; + run_count[DECODE_ID(hw)]++; hw->vdec_cb_arg = arg; @@ -4830,6 +4834,7 @@ static void run(struct vdec_s *vdec, "vdec_prepare_input: Insufficient data\n"); vdec_schedule_work(&hw->work); + vfree(buf); return; } input_empty[DECODE_ID(hw)] = 0; @@ -4892,16 +4897,26 @@ static void run(struct vdec_s *vdec, start_process_time(hw); - if (amvdec_vdec_loadmc_ex(vdec, "vmh264_mc") < 0) { + firmware_size = get_firmware_data(VIDEO_DEC_H264_MULTI, buf); + if (firmware_size < 0) { + pr_err("get firmware fail.\n"); + vfree(buf); + return; + } + + if (amvdec_vdec_loadmc_ex(vdec, NULL, buf) < 0) { amvdec_enable_flag = false; amvdec_disable(); if (mmu_enable) amhevc_disable(); + vfree(buf); pr_info("%s: Error amvdec_vdec_loadmc fail\n", __func__); return; } + vfree(buf); + if (vh264_hw_ctx_restore(hw) < 0) { vdec_schedule_work(&hw->work); return; 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 4fbf73035f6f..23b40fa54f2d 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c @@ -8771,7 +8771,7 @@ static void timeout_process(struct hevc_state_s *hevc) hevc->decoding_pic = NULL; hevc->dec_result = DEC_RESULT_DONE; reset_process_time(hevc); - schedule_work(&hevc->work); + vdec_schedule_work(&hevc->work); } static unsigned char is_new_pic_available(struct hevc_state_s *hevc) @@ -9274,6 +9274,11 @@ static void run(struct vdec_s *vdec, (struct hevc_state_s *)vdec->private; int r; unsigned char check_sum = 0; + int size = -1; + char *buf = vmalloc(0x1000 * 16); + if (IS_ERR_OR_NULL(buf)) + return; + run_count[hevc->index]++; hevc->vdec_cb_arg = arg; hevc->vdec_cb = callback; @@ -9289,6 +9294,7 @@ static void run(struct vdec_s *vdec, "ammvdec_vh265: Insufficient data\n"); vdec_schedule_work(&hevc->work); + vfree(buf); return; } input_empty[hevc->index] = 0; @@ -9334,25 +9340,30 @@ static void run(struct vdec_s *vdec, "\n"); } } + if (hevc->mmu_enable && (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) { - if (amhevc_vdec_loadmc_ex(vdec, "vh265_mc_mmu") < 0) { - amhevc_disable(); - hevc_print(hevc, 0, - "%s: Error amvdec_loadmc fail\n", - __func__); - return; - } - } else { - if (amhevc_vdec_loadmc_ex - (vdec, "vh265_mc") < 0) { - amhevc_disable(); - hevc_print(hevc, 0, - "%s: Error amvdec_loadmc fail\n", - __func__); - return; - } + size = get_firmware_data(VIDEO_DEC_HEVC_MMU, buf); + } else + size = get_firmware_data(VIDEO_DEC_HEVC, buf); + + if (size < 0) { + pr_err("get firmware fail.\n"); + vfree(buf); + return; } + + if (amhevc_vdec_loadmc_ex(vdec, NULL, buf) < 0) { + amhevc_disable(); + vfree(buf); + hevc_print(hevc, 0, + "%s: Error amvdec_loadmc fail\n", + __func__); + return; + } + + vfree(buf); + if (vh265_hw_ctx_restore(hevc) < 0) { vdec_schedule_work(&hevc->work); return; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c index 0b310eed7659..67d80c542eb7 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c @@ -243,16 +243,19 @@ int amvdec_wake_unlock(void) #endif static s32 am_vdec_loadmc_ex(struct vdec_s *vdec, - const char *name, s32(*load)(const u32 *)) + const char *name, char *def, s32(*load)(const u32 *)) { int err; if (!vdec->mc_loaded) { - int loaded; - loaded = get_decoder_firmware_data(vdec->format, - name, (u8 *)(vdec->mc), (4096 * 4 * 4)); - if (loaded <= 0) - return -1; + if (!def) { + err = get_decoder_firmware_data(vdec->format, + name, (u8 *)(vdec->mc), + (4096 * 4 * 4)); + if (err <= 0) + return -1; + } else + memcpy((char *)vdec->mc, def, sizeof(vdec->mc)); vdec->mc_loaded = true; } @@ -374,9 +377,9 @@ s32 amvdec_loadmc_ex(enum vformat_e type, const char *name, char *def) return am_loadmc_ex(type, name, def, &amvdec_loadmc); } EXPORT_SYMBOL(amvdec_loadmc_ex); -s32 amvdec_vdec_loadmc_ex(struct vdec_s *vdec, const char *name) +s32 amvdec_vdec_loadmc_ex(struct vdec_s *vdec, const char *name, char *def) { - return am_vdec_loadmc_ex(vdec, name, &amvdec_loadmc); + return am_vdec_loadmc_ex(vdec, name, def, &amvdec_loadmc); } EXPORT_SYMBOL(amvdec_vdec_loadmc_ex); @@ -561,10 +564,10 @@ s32 amhevc_loadmc_ex(enum vformat_e type, const char *name, char *def) return 0; } EXPORT_SYMBOL(amhevc_loadmc_ex); -s32 amhevc_vdec_loadmc_ex(struct vdec_s *vdec, const char *name) +s32 amhevc_vdec_loadmc_ex(struct vdec_s *vdec, const char *name, char *def) { if (has_hevc_vdec()) - return am_vdec_loadmc_ex(vdec, name, &amhevc_loadmc); + return am_vdec_loadmc_ex(vdec, name, def, &amhevc_loadmc); else return 0; } diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.h b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.h index d0b9bd3ca1be..af177c3e7dd1 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.h @@ -38,7 +38,7 @@ extern void amvdec_stop(void); extern void amvdec_enable(void); extern void amvdec_disable(void); s32 amvdec_loadmc_ex(enum vformat_e type, const char *name, char *def); -s32 amvdec_vdec_loadmc_ex(struct vdec_s *vdec, const char *name); +s32 amvdec_vdec_loadmc_ex(struct vdec_s *vdec, const char *name, char *def); extern void amvdec2_start(void); extern void amvdec2_stop(void); @@ -51,7 +51,7 @@ extern void amhevc_stop(void); extern void amhevc_enable(void); extern void amhevc_disable(void); s32 amhevc_loadmc_ex(enum vformat_e type, const char *name, char *def); -s32 amhevc_vdec_loadmc_ex(struct vdec_s *vdec, const char *name); +s32 amhevc_vdec_loadmc_ex(struct vdec_s *vdec, const char *name, char *def); s32 amvdec_vdec_loadmc_buf_ex(struct vdec_s *vdec, char *buf, int size); extern void amhcodec_start(void);