video: driver: enable decoder batching support
Added change to enable decoder batching feature. Batching willbe enabled only when below conditions were met. [1] platform supports batching [2] decode session [3] realtime session [4] non-thumbnail session [5] non-heif session [6] 2-stage decode only(low_latency not supported). Change-Id: I54b601814c3b5fa2077dc41c5b0ac84964c2674a Signed-off-by: Govindaraj Rajagopal <grajagop@codeaurora.org>
This commit is contained in:
@@ -166,8 +166,10 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
|||||||
/* (4096 * 2304) / 256 */
|
/* (4096 * 2304) / 256 */
|
||||||
{LOSSLESS_MBPF, ENC, H264|HEVC, 64, 36864, 1, 36864},
|
{LOSSLESS_MBPF, ENC, H264|HEVC, 64, 36864, 1, 36864},
|
||||||
/* Batch Mode Decode */
|
/* Batch Mode Decode */
|
||||||
|
/* TODO: update with new values based on updated voltage corner */
|
||||||
{BATCH_MBPF, DEC, CODECS_ALL, 64, 34816, 1, 34816},
|
{BATCH_MBPF, DEC, CODECS_ALL, 64, 34816, 1, 34816},
|
||||||
/* (4096 * 2304) / 256 */
|
/* (4096 * 2304) / 256 */
|
||||||
|
{BATCH_FPS, DEC, CODECS_ALL, 1, 120, 1, 120},
|
||||||
{SECURE_MBPF, ENC|DEC, CODECS_ALL, 64, 36864, 1, 36864},
|
{SECURE_MBPF, ENC|DEC, CODECS_ALL, 64, 36864, 1, 36864},
|
||||||
/* ((1920 * 1088) / 256) * 480 fps */
|
/* ((1920 * 1088) / 256) * 480 fps */
|
||||||
{MBPS, ENC, CODECS_ALL, 64, 3916800, 1, 3916800},
|
{MBPS, ENC, CODECS_ALL, 64, 3916800, 1, 3916800},
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include "msm_vidc_inst.h"
|
#include "msm_vidc_inst.h"
|
||||||
#include "msm_vidc_core.h"
|
#include "msm_vidc_core.h"
|
||||||
#include "msm_vidc_driver.h"
|
#include "msm_vidc_driver.h"
|
||||||
|
#include "msm_vidc_control.h"
|
||||||
#include "msm_vidc_dt.h"
|
#include "msm_vidc_dt.h"
|
||||||
#include "msm_vidc_internal.h"
|
#include "msm_vidc_internal.h"
|
||||||
#include "msm_vidc_buffer.h"
|
#include "msm_vidc_buffer.h"
|
||||||
@@ -564,7 +565,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst)
|
|||||||
|
|
||||||
i_vpr_h(inst, "Configuring work mode = %u low latency = %u",
|
i_vpr_h(inst, "Configuring work mode = %u low latency = %u",
|
||||||
work_mode, lowlatency);
|
work_mode, lowlatency);
|
||||||
inst->capabilities->cap[STAGE].value = work_mode;
|
msm_vidc_update_cap_value(inst, STAGE, work_mode, __func__);
|
||||||
|
|
||||||
/* TODO If Encode then Set Low Latency (Enable/Disable)
|
/* TODO If Encode then Set Low Latency (Enable/Disable)
|
||||||
* and Update internal cap struct
|
* and Update internal cap struct
|
||||||
@@ -609,7 +610,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst* inst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
i_vpr_h(inst, "Configuring work route = %u", work_route);
|
i_vpr_h(inst, "Configuring work route = %u", work_route);
|
||||||
inst->capabilities->cap[PIPE].value = work_route;
|
msm_vidc_update_cap_value(inst, PIPE, work_route, __func__);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -643,7 +644,7 @@ int msm_vidc_decide_quality_mode_iris2(struct msm_vidc_inst* inst)
|
|||||||
(mbpf <= max_hq_mbpf && mbps <= max_hq_mbps))
|
(mbpf <= max_hq_mbpf && mbps <= max_hq_mbps))
|
||||||
mode = MSM_VIDC_MAX_QUALITY_MODE;
|
mode = MSM_VIDC_MAX_QUALITY_MODE;
|
||||||
|
|
||||||
capability->cap[QUALITY_MODE].value = mode;
|
msm_vidc_update_cap_value(inst, QUALITY_MODE, mode, __func__);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -29,5 +29,6 @@ int msm_vdec_init_input_subcr_params(struct msm_vidc_inst *inst);
|
|||||||
int msm_vdec_input_port_settings_change(struct msm_vidc_inst *inst);
|
int msm_vdec_input_port_settings_change(struct msm_vidc_inst *inst);
|
||||||
int msm_vdec_output_port_settings_change(struct msm_vidc_inst *inst);
|
int msm_vdec_output_port_settings_change(struct msm_vidc_inst *inst);
|
||||||
int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd);
|
int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd);
|
||||||
|
int msm_vidc_queue_buffer_batch(struct msm_vidc_inst *inst);
|
||||||
|
|
||||||
#endif // _MSM_VDEC_H_
|
#endif // _MSM_VDEC_H_
|
||||||
|
@@ -70,5 +70,7 @@ int msm_vidc_v4l2_menu_to_hfi(struct msm_vidc_inst *inst,
|
|||||||
enum msm_vidc_inst_capability_type cap_id, u32 *value);
|
enum msm_vidc_inst_capability_type cap_id, u32 *value);
|
||||||
int msm_vidc_v4l2_to_hfi_enum(struct msm_vidc_inst *inst,
|
int msm_vidc_v4l2_to_hfi_enum(struct msm_vidc_inst *inst,
|
||||||
enum msm_vidc_inst_capability_type cap_id, u32 *value);
|
enum msm_vidc_inst_capability_type cap_id, u32 *value);
|
||||||
|
int msm_vidc_update_cap_value(struct msm_vidc_inst *inst, u32 cap,
|
||||||
|
s32 adjusted_val, const char *func);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -88,8 +88,8 @@ struct msm_vidc_core {
|
|||||||
struct workqueue_struct *device_workq;
|
struct workqueue_struct *device_workq;
|
||||||
struct delayed_work pm_work;
|
struct delayed_work pm_work;
|
||||||
struct workqueue_struct *pm_workq;
|
struct workqueue_struct *pm_workq;
|
||||||
|
struct workqueue_struct *batch_workq;
|
||||||
struct delayed_work fw_unload_work;
|
struct delayed_work fw_unload_work;
|
||||||
struct delayed_work batch_work;
|
|
||||||
struct work_struct ssr_work;
|
struct work_struct ssr_work;
|
||||||
struct msm_vidc_core_power power;
|
struct msm_vidc_core_power power;
|
||||||
struct msm_vidc_ssr ssr;
|
struct msm_vidc_ssr ssr;
|
||||||
|
@@ -162,6 +162,11 @@ static inline bool is_realtime_session(struct msm_vidc_inst *inst)
|
|||||||
return !inst->capabilities->cap[PRIORITY].value;
|
return !inst->capabilities->cap[PRIORITY].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool is_lowlatency_session(struct msm_vidc_inst *inst)
|
||||||
|
{
|
||||||
|
return !!(inst->capabilities->cap[LOWLATENCY_MODE].value);
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool is_active_session(u64 prev, u64 curr)
|
static inline bool is_active_session(u64 prev, u64 curr)
|
||||||
{
|
{
|
||||||
u64 ts_delta;
|
u64 ts_delta;
|
||||||
@@ -270,7 +275,7 @@ int msm_vidc_map_driver_buf(struct msm_vidc_inst *inst,
|
|||||||
struct msm_vidc_buffer *buf);
|
struct msm_vidc_buffer *buf);
|
||||||
int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst,
|
int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst,
|
||||||
struct msm_vidc_buffer *buf);
|
struct msm_vidc_buffer *buf);
|
||||||
int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
|
int msm_vidc_queue_buffer_single(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
|
||||||
int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
|
int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
|
||||||
struct msm_vidc_buffer *buffer);
|
struct msm_vidc_buffer *buffer);
|
||||||
void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst);
|
void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst);
|
||||||
@@ -317,5 +322,6 @@ int msm_vidc_init_instance_caps(struct msm_vidc_core* core);
|
|||||||
int msm_vidc_deinit_core_caps(struct msm_vidc_core* core);
|
int msm_vidc_deinit_core_caps(struct msm_vidc_core* core);
|
||||||
int msm_vidc_deinit_instance_caps(struct msm_vidc_core* core);
|
int msm_vidc_deinit_instance_caps(struct msm_vidc_core* core);
|
||||||
int msm_vidc_update_debug_str(struct msm_vidc_inst *inst);
|
int msm_vidc_update_debug_str(struct msm_vidc_inst *inst);
|
||||||
|
bool msm_vidc_allow_decode_batch(struct msm_vidc_inst *inst);
|
||||||
#endif // _MSM_VIDC_DRIVER_H_
|
#endif // _MSM_VIDC_DRIVER_H_
|
||||||
|
|
||||||
|
@@ -307,6 +307,7 @@ enum msm_vidc_inst_capability_type {
|
|||||||
MBPF,
|
MBPF,
|
||||||
LOSSLESS_MBPF,
|
LOSSLESS_MBPF,
|
||||||
BATCH_MBPF,
|
BATCH_MBPF,
|
||||||
|
BATCH_FPS,
|
||||||
SECURE_MBPF,
|
SECURE_MBPF,
|
||||||
MBPS,
|
MBPS,
|
||||||
POWER_SAVE_MBPS,
|
POWER_SAVE_MBPS,
|
||||||
|
@@ -18,6 +18,9 @@
|
|||||||
#include "msm_vidc_control.h"
|
#include "msm_vidc_control.h"
|
||||||
#include "venus_hfi.h"
|
#include "venus_hfi.h"
|
||||||
#include "hfi_packet.h"
|
#include "hfi_packet.h"
|
||||||
|
/* TODO: update based on clips */
|
||||||
|
#define MAX_DEC_BATCH_SIZE 6
|
||||||
|
#define SKIP_BATCH_WINDOW 100
|
||||||
|
|
||||||
u32 msm_vdec_subscribe_for_psc_avc[] = {
|
u32 msm_vdec_subscribe_for_psc_avc[] = {
|
||||||
HFI_PROP_BITSTREAM_RESOLUTION,
|
HFI_PROP_BITSTREAM_RESOLUTION,
|
||||||
@@ -206,7 +209,7 @@ static int msm_vdec_set_bit_depth(struct msm_vidc_inst *inst,
|
|||||||
bitdepth = 10 << 16 | 10;
|
bitdepth = 10 << 16 | 10;
|
||||||
|
|
||||||
inst->subcr_params[port].bit_depth = bitdepth;
|
inst->subcr_params[port].bit_depth = bitdepth;
|
||||||
inst->capabilities->cap[BIT_DEPTH].value = bitdepth;
|
msm_vidc_update_cap_value(inst, BIT_DEPTH, bitdepth, __func__);
|
||||||
i_vpr_h(inst, "%s: bit depth: %d", __func__, bitdepth);
|
i_vpr_h(inst, "%s: bit depth: %d", __func__, bitdepth);
|
||||||
rc = venus_hfi_session_property(inst,
|
rc = venus_hfi_session_property(inst,
|
||||||
HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
|
HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
|
||||||
@@ -1393,17 +1396,17 @@ static int msm_vdec_read_input_subcr_params(struct msm_vidc_inst *inst)
|
|||||||
inst->crop.width = inst->fmts[INPUT_PORT].fmt.pix_mp.width -
|
inst->crop.width = inst->fmts[INPUT_PORT].fmt.pix_mp.width -
|
||||||
((subsc_params.crop_offsets[1] >> 16) & 0xFFFF);
|
((subsc_params.crop_offsets[1] >> 16) & 0xFFFF);
|
||||||
|
|
||||||
inst->capabilities->cap[PROFILE].value = subsc_params.profile;
|
msm_vidc_update_cap_value(inst, PROFILE, subsc_params.profile, __func__);
|
||||||
inst->capabilities->cap[LEVEL].value = subsc_params.level;
|
msm_vidc_update_cap_value(inst, LEVEL, subsc_params.level, __func__);
|
||||||
inst->capabilities->cap[HEVC_TIER].value = subsc_params.tier;
|
msm_vidc_update_cap_value(inst, HEVC_TIER, subsc_params.tier, __func__);
|
||||||
inst->capabilities->cap[POC].value = subsc_params.pic_order_cnt;
|
msm_vidc_update_cap_value(inst, POC, subsc_params.pic_order_cnt, __func__);
|
||||||
inst->capabilities->cap[BIT_DEPTH].value = subsc_params.bit_depth;
|
msm_vidc_update_cap_value(inst, BIT_DEPTH, subsc_params.bit_depth, __func__);
|
||||||
if (subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)
|
if (subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)
|
||||||
inst->capabilities->cap[CODED_FRAMES].value =
|
msm_vidc_update_cap_value(inst, CODED_FRAMES, CODED_FRAMES_PROGRESSIVE, __func__);
|
||||||
CODED_FRAMES_PROGRESSIVE;
|
|
||||||
else
|
else
|
||||||
inst->capabilities->cap[CODED_FRAMES].value =
|
msm_vidc_update_cap_value(inst, CODED_FRAMES, CODED_FRAMES_INTERLACE, __func__);
|
||||||
CODED_FRAMES_INTERLACE;
|
|
||||||
|
inst->decode_batch.enable = msm_vidc_allow_decode_batch(inst);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1543,6 +1546,8 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
inst->decode_batch.enable = msm_vidc_allow_decode_batch(inst);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@@ -1551,6 +1556,33 @@ error:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int schedule_batch_work(struct msm_vidc_inst *inst)
|
||||||
|
{
|
||||||
|
struct msm_vidc_core *core;
|
||||||
|
|
||||||
|
if (!inst || !inst->core) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
core = inst->core;
|
||||||
|
cancel_delayed_work(&inst->decode_batch.work);
|
||||||
|
queue_delayed_work(core->batch_workq, &inst->decode_batch.work,
|
||||||
|
msecs_to_jiffies(core->capabilities[DECODE_BATCH_TIMEOUT].value));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cancel_batch_work(struct msm_vidc_inst *inst)
|
||||||
|
{
|
||||||
|
if (!inst) {
|
||||||
|
d_vpr_e("%s: Invalid arguments\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
cancel_delayed_work(&inst->decode_batch.work);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int msm_vdec_streamoff_output(struct msm_vidc_inst *inst)
|
int msm_vdec_streamoff_output(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -1560,6 +1592,8 @@ int msm_vdec_streamoff_output(struct msm_vidc_inst *inst)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cancel pending batch work */
|
||||||
|
cancel_batch_work(inst);
|
||||||
rc = msm_vidc_session_streamoff(inst, OUTPUT_PORT);
|
rc = msm_vidc_session_streamoff(inst, OUTPUT_PORT);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1754,6 +1788,8 @@ int msm_vdec_streamon_output(struct msm_vidc_inst *inst)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
inst->decode_batch.enable = msm_vidc_allow_decode_batch(inst);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@@ -1765,13 +1801,43 @@ error:
|
|||||||
static int msm_vdec_qbuf_batch(struct msm_vidc_inst *inst,
|
static int msm_vdec_qbuf_batch(struct msm_vidc_inst *inst,
|
||||||
struct vb2_buffer *vb2)
|
struct vb2_buffer *vb2)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
struct msm_vidc_buffer *buf;
|
||||||
|
enum msm_vidc_allow allow;
|
||||||
|
int count, rc;
|
||||||
|
|
||||||
if (!inst || !vb2) {
|
if (!inst || !vb2 || !inst->decode_batch.size) {
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
i_vpr_h(inst, "%s()\n", __func__);
|
|
||||||
|
buf = msm_vidc_get_driver_buf(inst, vb2);
|
||||||
|
if (!buf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
allow = msm_vidc_allow_qbuf(inst, vb2->type);
|
||||||
|
if (allow == MSM_VIDC_DISALLOW) {
|
||||||
|
i_vpr_e(inst, "%s: qbuf not allowed\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (allow == MSM_VIDC_DEFER) {
|
||||||
|
print_vidc_buffer(VIDC_HIGH, "high", "qbuf deferred", inst, buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do not defer buffers initially to avoid latency issues */
|
||||||
|
if (inst->power.buffer_counter > SKIP_BATCH_WINDOW) {
|
||||||
|
count = msm_vidc_num_buffers(inst, MSM_VIDC_BUF_OUTPUT, MSM_VIDC_ATTR_DEFERRED);
|
||||||
|
if (count < inst->decode_batch.size) {
|
||||||
|
print_vidc_buffer(VIDC_HIGH, "high", "batch-qbuf deferred", inst, buf);
|
||||||
|
schedule_batch_work(inst);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel_batch_work(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = msm_vidc_queue_buffer_batch(inst);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1780,10 +1846,16 @@ int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (inst->decode_batch.enable)
|
if (!inst || !vb2) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* batch decoder output & meta buffer only */
|
||||||
|
if (inst->decode_batch.enable && vb2->type == OUTPUT_MPLANE)
|
||||||
rc = msm_vdec_qbuf_batch(inst, vb2);
|
rc = msm_vdec_qbuf_batch(inst, vb2);
|
||||||
else
|
else
|
||||||
rc = msm_vidc_queue_buffer(inst, vb2);
|
rc = msm_vidc_queue_buffer_single(inst, vb2);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -2142,11 +2214,9 @@ set_default:
|
|||||||
i_vpr_h(inst, "%s: type %u value %#x\n",
|
i_vpr_h(inst, "%s: type %u value %#x\n",
|
||||||
__func__, s_parm->type, q16_rate);
|
__func__, s_parm->type, q16_rate);
|
||||||
|
|
||||||
if (is_frame_rate) {
|
msm_vidc_update_cap_value(inst,
|
||||||
capability->cap[FRAME_RATE].value = q16_rate;
|
is_frame_rate ? FRAME_RATE : OPERATING_RATE,
|
||||||
} else {
|
q16_rate, __func__);
|
||||||
capability->cap[OPERATING_RATE].value = q16_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2290,6 +2360,10 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
|
|||||||
core = inst->core;
|
core = inst->core;
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&inst->decode_batch.work, msm_vidc_batch_handler);
|
INIT_DELAYED_WORK(&inst->decode_batch.work, msm_vidc_batch_handler);
|
||||||
|
if (core->capabilities[DECODE_BATCH].value) {
|
||||||
|
inst->decode_batch.enable = true;
|
||||||
|
inst->decode_batch.size = MAX_DEC_BATCH_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
f = &inst->fmts[INPUT_PORT];
|
f = &inst->fmts[INPUT_PORT];
|
||||||
f->type = INPUT_MPLANE;
|
f->type = INPUT_MPLANE;
|
||||||
@@ -2372,6 +2446,8 @@ int msm_vdec_inst_deinit(struct msm_vidc_inst *inst)
|
|||||||
d_vpr_e("%s: invalid params\n", __func__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
/* cancel pending batch work */
|
||||||
|
cancel_batch_work(inst);
|
||||||
rc = msm_vidc_ctrl_deinit(inst);
|
rc = msm_vidc_ctrl_deinit(inst);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -353,10 +353,8 @@ static int msm_venc_set_csc(struct msm_vidc_inst* inst,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msm_venc_csc_required(inst))
|
msm_vidc_update_cap_value(inst, CSC,
|
||||||
inst->capabilities->cap[CSC].value = 1;
|
msm_venc_csc_required(inst) ? 1 : 0, __func__);
|
||||||
else
|
|
||||||
inst->capabilities->cap[CSC].value = 0;
|
|
||||||
|
|
||||||
csc = inst->capabilities->cap[CSC].value;
|
csc = inst->capabilities->cap[CSC].value;
|
||||||
i_vpr_h(inst, "%s: csc: %u\n", __func__, csc);
|
i_vpr_h(inst, "%s: csc: %u\n", __func__, csc);
|
||||||
@@ -955,7 +953,7 @@ int msm_venc_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc = msm_vidc_queue_buffer(inst, vb2);
|
rc = msm_vidc_queue_buffer_single(inst, vb2);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -1590,12 +1588,9 @@ set_default:
|
|||||||
i_vpr_h(inst, "%s: type %u value %#x\n",
|
i_vpr_h(inst, "%s: type %u value %#x\n",
|
||||||
__func__, s_parm->type, q16_rate);
|
__func__, s_parm->type, q16_rate);
|
||||||
|
|
||||||
if (!is_frame_rate) {
|
msm_vidc_update_cap_value(inst,
|
||||||
capability->cap[OPERATING_RATE].value = q16_rate;
|
is_frame_rate ? FRAME_RATE : OPERATING_RATE,
|
||||||
goto exit;
|
q16_rate, __func__);
|
||||||
} else {
|
|
||||||
capability->cap[FRAME_RATE].value = q16_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In static case, frame rate is set via
|
* In static case, frame rate is set via
|
||||||
|
@@ -359,9 +359,14 @@ static bool is_parent_available(struct msm_vidc_inst* inst,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int msm_vidc_update_cap_value(struct msm_vidc_inst* inst, u32 cap,
|
int msm_vidc_update_cap_value(struct msm_vidc_inst *inst, u32 cap,
|
||||||
s32 adjusted_val, const char *func)
|
s32 adjusted_val, const char *func)
|
||||||
{
|
{
|
||||||
|
if (!inst || !inst->capabilities) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (inst->capabilities->cap[cap].value != adjusted_val)
|
if (inst->capabilities->cap[cap].value != adjusted_val)
|
||||||
i_vpr_h(inst,
|
i_vpr_h(inst,
|
||||||
"%s: updated database value from %#x to %#x\n",
|
"%s: updated database value from %#x to %#x\n",
|
||||||
@@ -508,7 +513,7 @@ static int msm_vidc_adjust_dynamic_property(struct msm_vidc_inst *inst,
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto exit;
|
goto exit;
|
||||||
} else if (ctrl) {
|
} else if (ctrl) {
|
||||||
capability->cap[cap_id].value = ctrl->val;
|
msm_vidc_update_cap_value(inst, cap_id, ctrl->val, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add children if cap value modified */
|
/* add children if cap value modified */
|
||||||
@@ -741,7 +746,7 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
|||||||
capability->cap[cap_id].flags |= CAP_FLAG_CLIENT_SET;
|
capability->cap[cap_id].flags |= CAP_FLAG_CLIENT_SET;
|
||||||
/* Static setting */
|
/* Static setting */
|
||||||
if (!inst->vb2q[OUTPUT_PORT].streaming) {
|
if (!inst->vb2q[OUTPUT_PORT].streaming) {
|
||||||
capability->cap[cap_id].value = ctrl->val;
|
msm_vidc_update_cap_value(inst, cap_id, ctrl->val, __func__);
|
||||||
|
|
||||||
if (is_meta_ctrl(ctrl->id))
|
if (is_meta_ctrl(ctrl->id))
|
||||||
msm_vidc_update_meta_port_settings(inst);
|
msm_vidc_update_meta_port_settings(inst);
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "msm_vidc_driver.h"
|
#include "msm_vidc_driver.h"
|
||||||
#include "msm_vidc_platform.h"
|
#include "msm_vidc_platform.h"
|
||||||
#include "msm_vidc_internal.h"
|
#include "msm_vidc_internal.h"
|
||||||
|
#include "msm_vidc_control.h"
|
||||||
#include "msm_vidc_memory.h"
|
#include "msm_vidc_memory.h"
|
||||||
#include "msm_vidc_debug.h"
|
#include "msm_vidc_debug.h"
|
||||||
#include "msm_vidc_power.h"
|
#include "msm_vidc_power.h"
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
#include "venus_hfi.h"
|
#include "venus_hfi.h"
|
||||||
#include "venus_hfi_response.h"
|
#include "venus_hfi_response.h"
|
||||||
#include "hfi_packet.h"
|
#include "hfi_packet.h"
|
||||||
|
extern struct msm_vidc_core *g_core;
|
||||||
|
|
||||||
#define COUNT_BITS(a, out) { \
|
#define COUNT_BITS(a, out) { \
|
||||||
while ((a) >= 1) { \
|
while ((a) >= 1) { \
|
||||||
@@ -1024,6 +1026,8 @@ bool msm_vidc_allow_streamoff(struct msm_vidc_inst *inst, u32 type)
|
|||||||
|
|
||||||
enum msm_vidc_allow msm_vidc_allow_qbuf(struct msm_vidc_inst *inst, u32 type)
|
enum msm_vidc_allow msm_vidc_allow_qbuf(struct msm_vidc_inst *inst, u32 type)
|
||||||
{
|
{
|
||||||
|
int port = 0;
|
||||||
|
|
||||||
if (!inst) {
|
if (!inst) {
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
return MSM_VIDC_DISALLOW;
|
return MSM_VIDC_DISALLOW;
|
||||||
@@ -1032,6 +1036,15 @@ enum msm_vidc_allow msm_vidc_allow_qbuf(struct msm_vidc_inst *inst, u32 type)
|
|||||||
i_vpr_e(inst, "%s: inst in error state\n", __func__);
|
i_vpr_e(inst, "%s: inst in error state\n", __func__);
|
||||||
return MSM_VIDC_DISALLOW;
|
return MSM_VIDC_DISALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
port = v4l2_type_to_driver_port(inst, type, __func__);
|
||||||
|
if (port < 0)
|
||||||
|
return MSM_VIDC_DISALLOW;
|
||||||
|
|
||||||
|
/* defer queuing if streamon not completed */
|
||||||
|
if (!inst->vb2q[port].streaming)
|
||||||
|
return MSM_VIDC_DEFER;
|
||||||
|
|
||||||
if (type == INPUT_META_PLANE || type == OUTPUT_META_PLANE)
|
if (type == INPUT_META_PLANE || type == OUTPUT_META_PLANE)
|
||||||
return MSM_VIDC_DEFER;
|
return MSM_VIDC_DEFER;
|
||||||
|
|
||||||
@@ -1679,6 +1692,9 @@ struct msm_vidc_buffer *msm_vidc_get_driver_buf(struct msm_vidc_inst *inst,
|
|||||||
buf->attr &= MSM_VIDC_ATTR_READ_ONLY;
|
buf->attr &= MSM_VIDC_ATTR_READ_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* treat every buffer as deferred buffer initially */
|
||||||
|
buf->attr |= MSM_VIDC_ATTR_DEFERRED;
|
||||||
|
|
||||||
rc = vb2_buffer_to_driver(vb2, buf);
|
rc = vb2_buffer_to_driver(vb2, buf);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -1736,7 +1752,7 @@ bool msm_vidc_is_super_buffer(struct msm_vidc_inst *inst)
|
|||||||
struct msm_vidc_inst_capability *capability = NULL;
|
struct msm_vidc_inst_capability *capability = NULL;
|
||||||
|
|
||||||
if (!inst || !inst->capabilities) {
|
if (!inst || !inst->capabilities) {
|
||||||
i_vpr_e(inst, "%s: Invalid params\n", __func__);
|
d_vpr_e("%s: Invalid params\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1745,49 +1761,98 @@ bool msm_vidc_is_super_buffer(struct msm_vidc_inst *inst)
|
|||||||
return !!capability->cap[SUPER_FRAME].value;
|
return !!capability->cap[SUPER_FRAME].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
|
static bool is_single_session(struct msm_vidc_inst *inst)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
struct msm_vidc_core *core;
|
||||||
struct msm_vidc_buffer *buf;
|
u32 count = 0;
|
||||||
struct msm_vidc_buffer *meta;
|
|
||||||
enum msm_vidc_allow allow;
|
|
||||||
int port;
|
|
||||||
|
|
||||||
if (!inst || !vb2) {
|
if (!inst) {
|
||||||
|
d_vpr_e("%s: Invalid params\n", __func__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
core = inst->core;
|
||||||
|
|
||||||
|
core_lock(core, __func__);
|
||||||
|
list_for_each_entry(inst, &core->instances, list)
|
||||||
|
count++;
|
||||||
|
core_unlock(core, __func__);
|
||||||
|
|
||||||
|
return count == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool msm_vidc_allow_decode_batch(struct msm_vidc_inst *inst)
|
||||||
|
{
|
||||||
|
struct msm_vidc_core *core;
|
||||||
|
bool allow = false;
|
||||||
|
|
||||||
|
if (!inst || !inst->core) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
core = inst->core;
|
||||||
|
|
||||||
|
allow = inst->decode_batch.enable;
|
||||||
|
if (!allow) {
|
||||||
|
i_vpr_h(inst, "%s: batching already disabled\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
allow = core->capabilities[DECODE_BATCH].value;
|
||||||
|
if (!allow) {
|
||||||
|
i_vpr_h(inst, "%s: core doesn't support batching\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
allow = is_single_session(inst);
|
||||||
|
if (!allow) {
|
||||||
|
i_vpr_h(inst, "%s: multiple sessions running\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
allow = is_decode_session(inst);
|
||||||
|
if (!allow) {
|
||||||
|
i_vpr_h(inst, "%s: not a decoder session\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
allow = !is_thumbnail_session(inst);
|
||||||
|
if (!allow) {
|
||||||
|
i_vpr_h(inst, "%s: thumbnail session\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
allow = is_realtime_session(inst);
|
||||||
|
if (!allow) {
|
||||||
|
i_vpr_h(inst, "%s: non-realtime session\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
allow = !is_lowlatency_session(inst);
|
||||||
|
if (!allow) {
|
||||||
|
i_vpr_h(inst, "%s: lowlatency session\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
i_vpr_h(inst, "%s: batching %s\n", __func__, allow ? "enabled" : "disabled");
|
||||||
|
|
||||||
|
return allow;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buf)
|
||||||
|
{
|
||||||
|
struct msm_vidc_buffer *meta;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!inst || !buf || !inst->capabilities) {
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = msm_vidc_get_driver_buf(inst, vb2);
|
if (is_decode_session(inst) && is_input_buffer(buf->type) &&
|
||||||
if (!buf)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* skip queuing if streamon not completed */
|
|
||||||
port = v4l2_type_to_driver_port(inst, vb2->type, __func__);
|
|
||||||
if (port < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
allow = msm_vidc_allow_qbuf(inst, vb2->type);
|
|
||||||
if (allow == MSM_VIDC_DISALLOW) {
|
|
||||||
i_vpr_e(inst, "%s: qbuf not allowed\n", __func__);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inst->vb2q[port].streaming || allow == MSM_VIDC_DEFER) {
|
|
||||||
buf->attr |= MSM_VIDC_ATTR_DEFERRED;
|
|
||||||
print_vidc_buffer(VIDC_HIGH, "high", "qbuf deferred", inst, buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_decode_session(inst) &&
|
|
||||||
inst->capabilities->cap[CODEC_CONFIG].value) {
|
inst->capabilities->cap[CODEC_CONFIG].value) {
|
||||||
buf->flags |= MSM_VIDC_BUF_FLAG_CODECCONFIG;
|
buf->flags |= MSM_VIDC_BUF_FLAG_CODECCONFIG;
|
||||||
inst->capabilities->cap[CODEC_CONFIG].value = 0;
|
msm_vidc_update_cap_value(inst, CODEC_CONFIG, 0, __func__);
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->type == MSM_VIDC_BUF_INPUT) {
|
|
||||||
inst->power.buffer_counter++;
|
|
||||||
msm_vidc_scale_power(inst, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print_vidc_buffer(VIDC_HIGH, "high", "qbuf", inst, buf);
|
print_vidc_buffer(VIDC_HIGH, "high", "qbuf", inst, buf);
|
||||||
@@ -1819,6 +1884,70 @@ int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
|
|||||||
else if (buf->type == MSM_VIDC_BUF_OUTPUT)
|
else if (buf->type == MSM_VIDC_BUF_OUTPUT)
|
||||||
msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FTB);
|
msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FTB);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msm_vidc_queue_buffer_batch(struct msm_vidc_inst *inst)
|
||||||
|
{
|
||||||
|
struct msm_vidc_buffers *buffers;
|
||||||
|
struct msm_vidc_buffer *buf;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!inst) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_OUTPUT, __func__);
|
||||||
|
if (!buffers)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
msm_vidc_scale_power(inst, true);
|
||||||
|
|
||||||
|
list_for_each_entry(buf, &buffers->list, list) {
|
||||||
|
if (!(buf->attr & MSM_VIDC_ATTR_DEFERRED))
|
||||||
|
continue;
|
||||||
|
rc = msm_vidc_queue_buffer(inst, buf);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msm_vidc_queue_buffer_single(struct msm_vidc_inst *inst, struct vb2_buffer *vb2)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct msm_vidc_buffer *buf;
|
||||||
|
enum msm_vidc_allow allow;
|
||||||
|
|
||||||
|
if (!inst || !vb2) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = msm_vidc_get_driver_buf(inst, vb2);
|
||||||
|
if (!buf)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
allow = msm_vidc_allow_qbuf(inst, vb2->type);
|
||||||
|
if (allow == MSM_VIDC_DISALLOW) {
|
||||||
|
i_vpr_e(inst, "%s: qbuf not allowed\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (allow == MSM_VIDC_DEFER) {
|
||||||
|
print_vidc_buffer(VIDC_HIGH, "high", "qbuf deferred", inst, buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->type == MSM_VIDC_BUF_INPUT) {
|
||||||
|
inst->power.buffer_counter++;
|
||||||
|
msm_vidc_scale_power(inst, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = msm_vidc_queue_buffer(inst, buf);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2558,6 +2687,9 @@ int msm_vidc_session_streamoff(struct msm_vidc_inst *inst,
|
|||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* flush deferred buffers */
|
||||||
|
msm_vidc_flush_buffers(inst, buffer_type);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@@ -3106,6 +3238,39 @@ void msm_vidc_fw_unload_handler(struct work_struct *work)
|
|||||||
|
|
||||||
void msm_vidc_batch_handler(struct work_struct *work)
|
void msm_vidc_batch_handler(struct work_struct *work)
|
||||||
{
|
{
|
||||||
|
struct msm_vidc_inst *inst;
|
||||||
|
enum msm_vidc_allow allow;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
inst = container_of(work, struct msm_vidc_inst, decode_batch.work.work);
|
||||||
|
inst = get_inst_ref(g_core, inst);
|
||||||
|
if (!inst) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
inst_lock(inst, __func__);
|
||||||
|
if (is_session_error(inst)) {
|
||||||
|
i_vpr_e(inst, "%s: failled. Session error\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
allow = msm_vidc_allow_qbuf(inst, OUTPUT_MPLANE);
|
||||||
|
if (allow != MSM_VIDC_ALLOW) {
|
||||||
|
i_vpr_e(inst, "%s: not allowed in state: %s\n", __func__, state_name(inst->state));
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
i_vpr_h(inst, "%s: queue pending batch buffers\n", __func__);
|
||||||
|
rc = msm_vidc_queue_buffer_batch(inst);
|
||||||
|
if (rc) {
|
||||||
|
i_vpr_e(inst, "%s: batch qbufs failed\n", __func__);
|
||||||
|
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
inst_unlock(inst, __func__);
|
||||||
|
put_inst(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
int msm_vidc_flush_buffers(struct msm_vidc_inst* inst,
|
int msm_vidc_flush_buffers(struct msm_vidc_inst* inst,
|
||||||
|
@@ -180,12 +180,19 @@ static int msm_vidc_deinitialize_core(struct msm_vidc_core *core)
|
|||||||
mutex_destroy(&core->lock);
|
mutex_destroy(&core->lock);
|
||||||
msm_vidc_change_core_state(core, MSM_VIDC_CORE_DEINIT, __func__);
|
msm_vidc_change_core_state(core, MSM_VIDC_CORE_DEINIT, __func__);
|
||||||
|
|
||||||
|
if (core->batch_workq)
|
||||||
|
destroy_workqueue(core->batch_workq);
|
||||||
|
|
||||||
if (core->pm_workq)
|
if (core->pm_workq)
|
||||||
destroy_workqueue(core->pm_workq);
|
destroy_workqueue(core->pm_workq);
|
||||||
|
|
||||||
if (core->device_workq)
|
if (core->device_workq)
|
||||||
destroy_workqueue(core->device_workq);
|
destroy_workqueue(core->device_workq);
|
||||||
|
|
||||||
|
core->batch_workq = NULL;
|
||||||
|
core->pm_workq = NULL;
|
||||||
|
core->device_workq = NULL;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +218,13 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
|
|||||||
core->pm_workq = create_singlethread_workqueue("pm_workq");
|
core->pm_workq = create_singlethread_workqueue("pm_workq");
|
||||||
if (!core->pm_workq) {
|
if (!core->pm_workq) {
|
||||||
d_vpr_e("%s: create pm workq failed\n", __func__);
|
d_vpr_e("%s: create pm workq failed\n", __func__);
|
||||||
destroy_workqueue(core->device_workq);
|
rc = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
core->batch_workq = create_singlethread_workqueue("batch_workq");
|
||||||
|
if (!core->batch_workq) {
|
||||||
|
d_vpr_e("%s: create batch workq failed\n", __func__);
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@@ -224,10 +237,20 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
|
|||||||
INIT_WORK(&core->smmu_fault_work, msm_vidc_smmu_fault_work_handler);
|
INIT_WORK(&core->smmu_fault_work, msm_vidc_smmu_fault_work_handler);
|
||||||
INIT_DELAYED_WORK(&core->pm_work, venus_hfi_pm_work_handler);
|
INIT_DELAYED_WORK(&core->pm_work, venus_hfi_pm_work_handler);
|
||||||
INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
|
INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
|
||||||
INIT_DELAYED_WORK(&core->batch_work, msm_vidc_batch_handler);
|
|
||||||
INIT_WORK(&core->ssr_work, msm_vidc_ssr_handler);
|
INIT_WORK(&core->ssr_work, msm_vidc_ssr_handler);
|
||||||
|
|
||||||
|
return 0;
|
||||||
exit:
|
exit:
|
||||||
|
if (core->batch_workq)
|
||||||
|
destroy_workqueue(core->batch_workq);
|
||||||
|
if (core->pm_workq)
|
||||||
|
destroy_workqueue(core->pm_workq);
|
||||||
|
if (core->device_workq)
|
||||||
|
destroy_workqueue(core->device_workq);
|
||||||
|
core->batch_workq = NULL;
|
||||||
|
core->pm_workq = NULL;
|
||||||
|
core->device_workq = NULL;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user