summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/venus/vdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/venus/vdec.c')
-rw-r--r--drivers/media/platform/qcom/venus/vdec.c94
1 files changed, 66 insertions, 28 deletions
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 51a53bf82bd3..f5676440dd36 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -30,69 +30,87 @@
* - future firmware versions could add support for >1 planes
*/
static const struct venus_format vdec_formats[] = {
- {
+ [VENUS_FMT_NV12] = {
.pixfmt = V4L2_PIX_FMT_NV12,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
- }, {
+ },
+ [VENUS_FMT_QC08C] = {
.pixfmt = V4L2_PIX_FMT_QC08C,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
- }, {
+ },
+ [VENUS_FMT_QC10C] = {
.pixfmt = V4L2_PIX_FMT_QC10C,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
- }, {
- .pixfmt = V4L2_PIX_FMT_MPEG4,
+ },
+ [VENUS_FMT_P010] = {
+ .pixfmt = V4L2_PIX_FMT_P010,
+ .num_planes = 1,
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+ },
+ [VENUS_FMT_H264] = {
+ .pixfmt = V4L2_PIX_FMT_H264,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_MPEG2,
+ },
+ [VENUS_FMT_VP8] = {
+ .pixfmt = V4L2_PIX_FMT_VP8,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_H263,
+ },
+ [VENUS_FMT_VP9] = {
+ .pixfmt = V4L2_PIX_FMT_VP9,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
+ },
+ [VENUS_FMT_HEVC] = {
+ .pixfmt = V4L2_PIX_FMT_HEVC,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
+ },
+ [VENUS_FMT_VC1_ANNEX_G] = {
+ .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_H264,
+ },
+ [VENUS_FMT_VC1_ANNEX_L] = {
+ .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_VP8,
+ },
+ [VENUS_FMT_MPEG4] = {
+ .pixfmt = V4L2_PIX_FMT_MPEG4,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_VP9,
+ },
+ [VENUS_FMT_MPEG2] = {
+ .pixfmt = V4L2_PIX_FMT_MPEG2,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_XVID,
+ },
+ [VENUS_FMT_H263] = {
+ .pixfmt = V4L2_PIX_FMT_H263,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- }, {
- .pixfmt = V4L2_PIX_FMT_HEVC,
+ },
+ [VENUS_FMT_XVID] = {
+ .pixfmt = V4L2_PIX_FMT_XVID,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
},
+
};
static const struct venus_format *
@@ -551,7 +569,7 @@ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
fdata.buffer_type = HFI_BUFFER_INPUT;
fdata.flags |= HFI_BUFFERFLAG_EOS;
- if (IS_V6(inst->core))
+ if (IS_V6(inst->core) && is_fw_rev_or_older(inst->core, 1, 0, 87))
fdata.device_addr = 0;
else
fdata.device_addr = 0xdeadb000;
@@ -684,6 +702,14 @@ static int vdec_set_properties(struct venus_inst *inst)
return ret;
}
+ /* Enabling sufficient sequence change support for VP9 */
+ if (is_fw_rev_or_newer(inst->core, 5, 4, 51)) {
+ ptype = HFI_PROPERTY_PARAM_VDEC_ENABLE_SUFFICIENT_SEQCHANGE_EVENT;
+ ret = hfi_session_set_property(inst, ptype, &en);
+ if (ret)
+ return ret;
+ }
+
ptype = HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR;
conceal = ctr->conceal_color & 0xffff;
conceal |= ((ctr->conceal_color >> 16) & 0xffff) << 10;
@@ -710,6 +736,9 @@ static int vdec_set_work_route(struct venus_inst *inst)
}
#define is_ubwc_fmt(fmt) (!!((fmt) & HFI_COLOR_FORMAT_UBWC_BASE))
+#define is_10bit_ubwc_fmt(fmt) (!!((fmt) & HFI_COLOR_FORMAT_10_BIT_BASE & \
+ HFI_COLOR_FORMAT_UBWC_BASE))
+
static int vdec_output_conf(struct venus_inst *inst)
{
@@ -757,7 +786,7 @@ static int vdec_output_conf(struct venus_inst *inst)
inst->opb_fmt = out2_fmt;
inst->dpb_buftype = HFI_BUFFER_OUTPUT;
inst->dpb_fmt = out_fmt;
- } else if (is_ubwc_fmt(out2_fmt)) {
+ } else if (is_ubwc_fmt(out2_fmt) || is_10bit_ubwc_fmt(out_fmt)) {
inst->opb_buftype = HFI_BUFFER_OUTPUT;
inst->opb_fmt = out_fmt;
inst->dpb_buftype = HFI_BUFFER_OUTPUT2;
@@ -1474,8 +1503,13 @@ static void vdec_event_change(struct venus_inst *inst,
inst->out_width = ev_data->width;
inst->out_height = ev_data->height;
- if (inst->bit_depth != ev_data->bit_depth)
+ if (inst->bit_depth != ev_data->bit_depth) {
inst->bit_depth = ev_data->bit_depth;
+ if (inst->bit_depth == VIDC_BITDEPTH_10)
+ inst->fmt_cap = &vdec_formats[VENUS_FMT_P010];
+ else
+ inst->fmt_cap = &vdec_formats[VENUS_FMT_NV12];
+ }
if (inst->pic_struct != ev_data->pic_struct)
inst->pic_struct = ev_data->pic_struct;
@@ -1567,8 +1601,8 @@ static const struct hfi_inst_ops vdec_hfi_ops = {
static void vdec_inst_init(struct venus_inst *inst)
{
inst->hfi_codec = HFI_VIDEO_CODEC_H264;
- inst->fmt_out = &vdec_formats[8];
- inst->fmt_cap = &vdec_formats[0];
+ inst->fmt_out = &vdec_formats[VENUS_FMT_H264];
+ inst->fmt_cap = &vdec_formats[VENUS_FMT_NV12];
inst->width = frame_width_min(inst);
inst->height = ALIGN(frame_height_min(inst), 32);
inst->crop.left = 0;
@@ -1609,6 +1643,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq,
src_vq->allow_zero_bytesused = 1;
src_vq->min_buffers_needed = 0;
src_vq->dev = inst->core->dev;
+ src_vq->lock = &inst->ctx_q_lock;
ret = vb2_queue_init(src_vq);
if (ret)
return ret;
@@ -1623,6 +1658,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq,
dst_vq->allow_zero_bytesused = 1;
dst_vq->min_buffers_needed = 0;
dst_vq->dev = inst->core->dev;
+ dst_vq->lock = &inst->ctx_q_lock;
return vb2_queue_init(dst_vq);
}
@@ -1641,6 +1677,7 @@ static int vdec_open(struct file *file)
INIT_LIST_HEAD(&inst->internalbufs);
INIT_LIST_HEAD(&inst->list);
mutex_init(&inst->lock);
+ mutex_init(&inst->ctx_q_lock);
inst->core = core;
inst->session_type = VIDC_SESSION_TYPE_DEC;
@@ -1716,6 +1753,7 @@ static int vdec_close(struct file *file)
ida_destroy(&inst->dpb_ids);
hfi_session_destroy(inst);
mutex_destroy(&inst->lock);
+ mutex_destroy(&inst->ctx_q_lock);
v4l2_fh_del(&inst->fh);
v4l2_fh_exit(&inst->fh);