cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mtk_vcodec_dec.c (27108B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2016 MediaTek Inc.
      4 * Author: PC Chen <pc.chen@mediatek.com>
      5 *         Tiffany Lin <tiffany.lin@mediatek.com>
      6 */
      7
      8#include <media/v4l2-event.h>
      9#include <media/v4l2-mem2mem.h>
     10#include <media/videobuf2-dma-contig.h>
     11
     12#include "mtk_vcodec_drv.h"
     13#include "mtk_vcodec_dec.h"
     14#include "mtk_vcodec_intr.h"
     15#include "mtk_vcodec_util.h"
     16#include "vdec_drv_if.h"
     17#include "mtk_vcodec_dec_pm.h"
     18
     19#define DFT_CFG_WIDTH	MTK_VDEC_MIN_W
     20#define DFT_CFG_HEIGHT	MTK_VDEC_MIN_H
     21
     22static const struct mtk_video_fmt *
     23mtk_vdec_find_format(struct v4l2_format *f,
     24		     const struct mtk_vcodec_dec_pdata *dec_pdata)
     25{
     26	const struct mtk_video_fmt *fmt;
     27	unsigned int k;
     28
     29	for (k = 0; k < *dec_pdata->num_formats; k++) {
     30		fmt = &dec_pdata->vdec_formats[k];
     31		if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
     32			return fmt;
     33	}
     34
     35	return NULL;
     36}
     37
     38static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
     39					      enum v4l2_buf_type type)
     40{
     41	if (V4L2_TYPE_IS_OUTPUT(type))
     42		return &ctx->q_data[MTK_Q_DATA_SRC];
     43
     44	return &ctx->q_data[MTK_Q_DATA_DST];
     45}
     46
     47static int vidioc_try_decoder_cmd(struct file *file, void *priv,
     48				struct v4l2_decoder_cmd *cmd)
     49{
     50	return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd);
     51}
     52
     53
     54static int vidioc_decoder_cmd(struct file *file, void *priv,
     55				struct v4l2_decoder_cmd *cmd)
     56{
     57	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
     58	struct vb2_queue *src_vq, *dst_vq;
     59	int ret;
     60
     61	ret = vidioc_try_decoder_cmd(file, priv, cmd);
     62	if (ret)
     63		return ret;
     64
     65	mtk_v4l2_debug(1, "decoder cmd=%u", cmd->cmd);
     66	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
     67				V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
     68	switch (cmd->cmd) {
     69	case V4L2_DEC_CMD_STOP:
     70		src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
     71				V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
     72		if (!vb2_is_streaming(src_vq)) {
     73			mtk_v4l2_debug(1, "Output stream is off. No need to flush.");
     74			return 0;
     75		}
     76		if (!vb2_is_streaming(dst_vq)) {
     77			mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
     78			return 0;
     79		}
     80		v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
     81		v4l2_m2m_try_schedule(ctx->m2m_ctx);
     82		break;
     83
     84	case V4L2_DEC_CMD_START:
     85		vb2_clear_last_buffer_dequeued(dst_vq);
     86		break;
     87
     88	default:
     89		return -EINVAL;
     90	}
     91
     92	return 0;
     93}
     94
     95void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
     96{
     97	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
     98}
     99
    100void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
    101{
    102	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
    103}
    104
    105void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
    106{
    107	vdec_if_deinit(ctx);
    108	ctx->state = MTK_STATE_FREE;
    109}
    110
    111void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
    112{
    113	struct mtk_q_data *q_data;
    114
    115	ctx->dev->vdec_pdata->init_vdec_params(ctx);
    116
    117	ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
    118	ctx->fh.m2m_ctx = ctx->m2m_ctx;
    119	ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
    120	INIT_WORK(&ctx->decode_work, ctx->dev->vdec_pdata->worker);
    121	ctx->colorspace = V4L2_COLORSPACE_REC709;
    122	ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
    123	ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
    124	ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
    125
    126	q_data = &ctx->q_data[MTK_Q_DATA_SRC];
    127	memset(q_data, 0, sizeof(struct mtk_q_data));
    128	q_data->visible_width = DFT_CFG_WIDTH;
    129	q_data->visible_height = DFT_CFG_HEIGHT;
    130	q_data->fmt = ctx->dev->vdec_pdata->default_out_fmt;
    131	q_data->field = V4L2_FIELD_NONE;
    132
    133	q_data->sizeimage[0] = DFT_CFG_WIDTH * DFT_CFG_HEIGHT;
    134	q_data->bytesperline[0] = 0;
    135
    136	q_data = &ctx->q_data[MTK_Q_DATA_DST];
    137	memset(q_data, 0, sizeof(struct mtk_q_data));
    138	q_data->visible_width = DFT_CFG_WIDTH;
    139	q_data->visible_height = DFT_CFG_HEIGHT;
    140	q_data->coded_width = DFT_CFG_WIDTH;
    141	q_data->coded_height = DFT_CFG_HEIGHT;
    142	q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
    143	q_data->field = V4L2_FIELD_NONE;
    144	ctx->max_width = MTK_VDEC_MAX_W;
    145	ctx->max_height = MTK_VDEC_MAX_H;
    146
    147	v4l_bound_align_image(&q_data->coded_width,
    148				MTK_VDEC_MIN_W,
    149				ctx->max_width, 4,
    150				&q_data->coded_height,
    151				MTK_VDEC_MIN_H,
    152				ctx->max_height, 5, 6);
    153
    154	q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
    155	q_data->bytesperline[0] = q_data->coded_width;
    156	q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
    157	q_data->bytesperline[1] = q_data->coded_width;
    158}
    159
    160static int vidioc_vdec_qbuf(struct file *file, void *priv,
    161			    struct v4l2_buffer *buf)
    162{
    163	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    164
    165	if (ctx->state == MTK_STATE_ABORT) {
    166		mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
    167				ctx->id);
    168		return -EIO;
    169	}
    170
    171	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
    172}
    173
    174static int vidioc_vdec_dqbuf(struct file *file, void *priv,
    175			     struct v4l2_buffer *buf)
    176{
    177	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    178
    179	if (ctx->state == MTK_STATE_ABORT) {
    180		mtk_v4l2_err("[%d] Call on DQBUF after unrecoverable error",
    181				ctx->id);
    182		return -EIO;
    183	}
    184
    185	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
    186}
    187
    188static int vidioc_vdec_querycap(struct file *file, void *priv,
    189				struct v4l2_capability *cap)
    190{
    191	strscpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver));
    192	strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info));
    193	strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card));
    194
    195	return 0;
    196}
    197
    198static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
    199				     const struct v4l2_event_subscription *sub)
    200{
    201	switch (sub->type) {
    202	case V4L2_EVENT_EOS:
    203		return v4l2_event_subscribe(fh, sub, 2, NULL);
    204	case V4L2_EVENT_SOURCE_CHANGE:
    205		return v4l2_src_change_event_subscribe(fh, sub);
    206	default:
    207		return v4l2_ctrl_subscribe_event(fh, sub);
    208	}
    209}
    210
    211static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
    212			  const struct mtk_video_fmt *fmt)
    213{
    214	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
    215
    216	pix_fmt_mp->field = V4L2_FIELD_NONE;
    217
    218	pix_fmt_mp->width =
    219		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, ctx->max_width);
    220	pix_fmt_mp->height =
    221		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, ctx->max_height);
    222
    223	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
    224		pix_fmt_mp->num_planes = 1;
    225		pix_fmt_mp->plane_fmt[0].bytesperline = 0;
    226	} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
    227		int tmp_w, tmp_h;
    228
    229		/*
    230		 * Find next closer width align 64, heign align 64, size align
    231		 * 64 rectangle
    232		 * Note: This only get default value, the real HW needed value
    233		 *       only available when ctx in MTK_STATE_HEADER state
    234		 */
    235		tmp_w = pix_fmt_mp->width;
    236		tmp_h = pix_fmt_mp->height;
    237		v4l_bound_align_image(&pix_fmt_mp->width,
    238					MTK_VDEC_MIN_W,
    239					ctx->max_width, 6,
    240					&pix_fmt_mp->height,
    241					MTK_VDEC_MIN_H,
    242					ctx->max_height, 6, 9);
    243
    244		if (pix_fmt_mp->width < tmp_w &&
    245			(pix_fmt_mp->width + 64) <= ctx->max_width)
    246			pix_fmt_mp->width += 64;
    247		if (pix_fmt_mp->height < tmp_h &&
    248			(pix_fmt_mp->height + 64) <= ctx->max_height)
    249			pix_fmt_mp->height += 64;
    250
    251		mtk_v4l2_debug(0,
    252			"before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d",
    253			tmp_w, tmp_h, pix_fmt_mp->width,
    254			pix_fmt_mp->height,
    255			pix_fmt_mp->width * pix_fmt_mp->height);
    256
    257		pix_fmt_mp->num_planes = fmt->num_planes;
    258		pix_fmt_mp->plane_fmt[0].sizeimage =
    259				pix_fmt_mp->width * pix_fmt_mp->height;
    260		pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
    261
    262		if (pix_fmt_mp->num_planes == 2) {
    263			pix_fmt_mp->plane_fmt[1].sizeimage =
    264				(pix_fmt_mp->width * pix_fmt_mp->height) / 2;
    265			pix_fmt_mp->plane_fmt[1].bytesperline =
    266				pix_fmt_mp->width;
    267		}
    268	}
    269
    270	pix_fmt_mp->flags = 0;
    271	return 0;
    272}
    273
    274static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
    275				struct v4l2_format *f)
    276{
    277	const struct mtk_video_fmt *fmt;
    278	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    279	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
    280
    281	fmt = mtk_vdec_find_format(f, dec_pdata);
    282	if (!fmt) {
    283		f->fmt.pix.pixelformat =
    284			ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc;
    285		fmt = mtk_vdec_find_format(f, dec_pdata);
    286	}
    287
    288	return vidioc_try_fmt(ctx, f, fmt);
    289}
    290
    291static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
    292				struct v4l2_format *f)
    293{
    294	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
    295	const struct mtk_video_fmt *fmt;
    296	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    297	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
    298
    299	fmt = mtk_vdec_find_format(f, dec_pdata);
    300	if (!fmt) {
    301		f->fmt.pix.pixelformat =
    302			ctx->q_data[MTK_Q_DATA_SRC].fmt->fourcc;
    303		fmt = mtk_vdec_find_format(f, dec_pdata);
    304	}
    305
    306	if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
    307		mtk_v4l2_err("sizeimage of output format must be given");
    308		return -EINVAL;
    309	}
    310
    311	return vidioc_try_fmt(ctx, f, fmt);
    312}
    313
    314static int vidioc_vdec_g_selection(struct file *file, void *priv,
    315			struct v4l2_selection *s)
    316{
    317	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    318	struct mtk_q_data *q_data;
    319
    320	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
    321		return -EINVAL;
    322
    323	q_data = &ctx->q_data[MTK_Q_DATA_DST];
    324
    325	switch (s->target) {
    326	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
    327		s->r.left = 0;
    328		s->r.top = 0;
    329		s->r.width = ctx->picinfo.pic_w;
    330		s->r.height = ctx->picinfo.pic_h;
    331		break;
    332	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
    333		s->r.left = 0;
    334		s->r.top = 0;
    335		s->r.width = ctx->picinfo.buf_w;
    336		s->r.height = ctx->picinfo.buf_h;
    337		break;
    338	case V4L2_SEL_TGT_COMPOSE:
    339		if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) {
    340			/* set to default value if header info not ready yet*/
    341			s->r.left = 0;
    342			s->r.top = 0;
    343			s->r.width = q_data->visible_width;
    344			s->r.height = q_data->visible_height;
    345		}
    346		break;
    347	default:
    348		return -EINVAL;
    349	}
    350
    351	if (ctx->state < MTK_STATE_HEADER) {
    352		/* set to default value if header info not ready yet*/
    353		s->r.left = 0;
    354		s->r.top = 0;
    355		s->r.width = q_data->visible_width;
    356		s->r.height = q_data->visible_height;
    357		return 0;
    358	}
    359
    360	return 0;
    361}
    362
    363static int vidioc_vdec_s_selection(struct file *file, void *priv,
    364				struct v4l2_selection *s)
    365{
    366	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    367
    368	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
    369		return -EINVAL;
    370
    371	switch (s->target) {
    372	case V4L2_SEL_TGT_COMPOSE:
    373		s->r.left = 0;
    374		s->r.top = 0;
    375		s->r.width = ctx->picinfo.pic_w;
    376		s->r.height = ctx->picinfo.pic_h;
    377		break;
    378	default:
    379		return -EINVAL;
    380	}
    381
    382	return 0;
    383}
    384
    385static int vidioc_vdec_s_fmt(struct file *file, void *priv,
    386			     struct v4l2_format *f)
    387{
    388	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    389	struct v4l2_pix_format_mplane *pix_mp;
    390	struct mtk_q_data *q_data;
    391	int ret = 0;
    392	const struct mtk_video_fmt *fmt;
    393	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
    394
    395	mtk_v4l2_debug(3, "[%d]", ctx->id);
    396
    397	q_data = mtk_vdec_get_q_data(ctx, f->type);
    398	if (!q_data)
    399		return -EINVAL;
    400
    401	pix_mp = &f->fmt.pix_mp;
    402	/*
    403	 * Setting OUTPUT format after OUTPUT buffers are allocated is invalid
    404	 * if using the stateful API.
    405	 */
    406	if (!dec_pdata->uses_stateless_api &&
    407	    f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
    408	    vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
    409		mtk_v4l2_err("out_q_ctx buffers already requested");
    410		ret = -EBUSY;
    411	}
    412
    413	/*
    414	 * Setting CAPTURE format after CAPTURE buffers are allocated is
    415	 * invalid.
    416	 */
    417	if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
    418	    vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
    419		mtk_v4l2_err("cap_q_ctx buffers already requested");
    420		ret = -EBUSY;
    421	}
    422
    423	fmt = mtk_vdec_find_format(f, dec_pdata);
    424	if (fmt == NULL) {
    425		if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
    426			f->fmt.pix.pixelformat =
    427				dec_pdata->default_out_fmt->fourcc;
    428			fmt = mtk_vdec_find_format(f, dec_pdata);
    429		} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
    430			f->fmt.pix.pixelformat =
    431				dec_pdata->default_cap_fmt->fourcc;
    432			fmt = mtk_vdec_find_format(f, dec_pdata);
    433		}
    434	}
    435	if (fmt == NULL)
    436		return -EINVAL;
    437
    438	if (!(ctx->dev->dec_capability & VCODEC_CAPABILITY_4K_DISABLED) &&
    439	    fmt->fourcc != V4L2_PIX_FMT_VP8_FRAME) {
    440		mtk_v4l2_debug(3, "4K is enabled");
    441		ctx->max_width = VCODEC_DEC_4K_CODED_WIDTH;
    442		ctx->max_height = VCODEC_DEC_4K_CODED_HEIGHT;
    443	}
    444
    445	q_data->fmt = fmt;
    446	vidioc_try_fmt(ctx, f, q_data->fmt);
    447	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
    448		q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
    449		q_data->coded_width = pix_mp->width;
    450		q_data->coded_height = pix_mp->height;
    451
    452		ctx->colorspace = pix_mp->colorspace;
    453		ctx->ycbcr_enc = pix_mp->ycbcr_enc;
    454		ctx->quantization = pix_mp->quantization;
    455		ctx->xfer_func = pix_mp->xfer_func;
    456
    457		ctx->current_codec = fmt->fourcc;
    458		if (ctx->state == MTK_STATE_FREE) {
    459			ret = vdec_if_init(ctx, q_data->fmt->fourcc);
    460			if (ret) {
    461				mtk_v4l2_err("[%d]: vdec_if_init() fail ret=%d",
    462					ctx->id, ret);
    463				return -EINVAL;
    464			}
    465			ctx->state = MTK_STATE_INIT;
    466		}
    467	} else {
    468		ctx->capture_fourcc = fmt->fourcc;
    469	}
    470
    471	/*
    472	 * If using the stateless API, S_FMT should have the effect of setting
    473	 * the CAPTURE queue resolution no matter which queue it was called on.
    474	 */
    475	if (dec_pdata->uses_stateless_api) {
    476		ctx->picinfo.pic_w = pix_mp->width;
    477		ctx->picinfo.pic_h = pix_mp->height;
    478
    479		/*
    480		 * If get pic info fail, need to use the default pic info params, or
    481		 * v4l2-compliance will fail
    482		 */
    483		ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
    484		if (ret) {
    485			mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
    486				     ctx->id);
    487		}
    488
    489		ctx->last_decoded_picinfo = ctx->picinfo;
    490
    491		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) {
    492			ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
    493				ctx->picinfo.fb_sz[0] +
    494				ctx->picinfo.fb_sz[1];
    495			ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
    496				ctx->picinfo.buf_w;
    497		} else {
    498			ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
    499				ctx->picinfo.fb_sz[0];
    500			ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
    501				ctx->picinfo.buf_w;
    502			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] =
    503				ctx->picinfo.fb_sz[1];
    504			ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] =
    505				ctx->picinfo.buf_w;
    506		}
    507
    508		ctx->q_data[MTK_Q_DATA_DST].coded_width = ctx->picinfo.buf_w;
    509		ctx->q_data[MTK_Q_DATA_DST].coded_height = ctx->picinfo.buf_h;
    510		mtk_v4l2_debug(2, "[%d] vdec_if_init() num_plane = %d wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
    511			       ctx->id, pix_mp->num_planes, ctx->picinfo.buf_w, ctx->picinfo.buf_h,
    512			       ctx->picinfo.pic_w, ctx->picinfo.pic_h,
    513			       ctx->q_data[MTK_Q_DATA_DST].sizeimage[0],
    514			       ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]);
    515	}
    516	return 0;
    517}
    518
    519static int vidioc_enum_framesizes(struct file *file, void *priv,
    520				struct v4l2_frmsizeenum *fsize)
    521{
    522	int i = 0;
    523	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    524	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
    525
    526	if (fsize->index != 0)
    527		return -EINVAL;
    528
    529	for (i = 0; i < *dec_pdata->num_framesizes; ++i) {
    530		if (fsize->pixel_format != dec_pdata->vdec_framesizes[i].fourcc)
    531			continue;
    532
    533		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
    534		fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise;
    535
    536		fsize->stepwise.max_width = ctx->max_width;
    537		fsize->stepwise.max_height = ctx->max_height;
    538		mtk_v4l2_debug(1, "%x, %d %d %d %d %d %d",
    539				ctx->dev->dec_capability,
    540				fsize->stepwise.min_width,
    541				fsize->stepwise.max_width,
    542				fsize->stepwise.step_width,
    543				fsize->stepwise.min_height,
    544				fsize->stepwise.max_height,
    545				fsize->stepwise.step_height);
    546
    547		return 0;
    548	}
    549
    550	return -EINVAL;
    551}
    552
    553static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
    554			   bool output_queue)
    555{
    556	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    557	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
    558	const struct mtk_video_fmt *fmt;
    559	int i, j = 0;
    560
    561	for (i = 0; i < *dec_pdata->num_formats; i++) {
    562		if (output_queue &&
    563		    dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
    564			continue;
    565		if (!output_queue &&
    566		    dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
    567			continue;
    568
    569		if (j == f->index)
    570			break;
    571		++j;
    572	}
    573
    574	if (i == *dec_pdata->num_formats)
    575		return -EINVAL;
    576
    577	fmt = &dec_pdata->vdec_formats[i];
    578	f->pixelformat = fmt->fourcc;
    579	f->flags = fmt->flags;
    580
    581	return 0;
    582}
    583
    584static int vidioc_vdec_enum_fmt_vid_cap(struct file *file, void *priv,
    585					struct v4l2_fmtdesc *f)
    586{
    587	return vidioc_enum_fmt(f, priv, false);
    588}
    589
    590static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv,
    591					struct v4l2_fmtdesc *f)
    592{
    593	return vidioc_enum_fmt(f, priv, true);
    594}
    595
    596static int vidioc_vdec_g_fmt(struct file *file, void *priv,
    597			     struct v4l2_format *f)
    598{
    599	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
    600	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
    601	struct vb2_queue *vq;
    602	struct mtk_q_data *q_data;
    603
    604	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
    605	if (!vq) {
    606		mtk_v4l2_err("no vb2 queue for type=%d", f->type);
    607		return -EINVAL;
    608	}
    609
    610	q_data = mtk_vdec_get_q_data(ctx, f->type);
    611
    612	pix_mp->field = V4L2_FIELD_NONE;
    613	pix_mp->colorspace = ctx->colorspace;
    614	pix_mp->ycbcr_enc = ctx->ycbcr_enc;
    615	pix_mp->quantization = ctx->quantization;
    616	pix_mp->xfer_func = ctx->xfer_func;
    617
    618	if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
    619	    (ctx->state >= MTK_STATE_HEADER)) {
    620		/* Until STREAMOFF is called on the CAPTURE queue
    621		 * (acknowledging the event), the driver operates as if
    622		 * the resolution hasn't changed yet.
    623		 * So we just return picinfo yet, and update picinfo in
    624		 * stop_streaming hook function
    625		 */
    626		q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
    627		q_data->sizeimage[1] = ctx->picinfo.fb_sz[1];
    628		q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w;
    629		q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w;
    630		q_data->coded_width = ctx->picinfo.buf_w;
    631		q_data->coded_height = ctx->picinfo.buf_h;
    632		ctx->last_decoded_picinfo.cap_fourcc = q_data->fmt->fourcc;
    633
    634		/*
    635		 * Width and height are set to the dimensions
    636		 * of the movie, the buffer is bigger and
    637		 * further processing stages should crop to this
    638		 * rectangle.
    639		 */
    640		pix_mp->width = q_data->coded_width;
    641		pix_mp->height = q_data->coded_height;
    642
    643		/*
    644		 * Set pixelformat to the format in which mt vcodec
    645		 * outputs the decoded frame
    646		 */
    647		pix_mp->num_planes = q_data->fmt->num_planes;
    648		pix_mp->pixelformat = q_data->fmt->fourcc;
    649		pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
    650		pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
    651		pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
    652		pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
    653
    654	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
    655		/*
    656		 * This is run on OUTPUT
    657		 * The buffer contains compressed image
    658		 * so width and height have no meaning.
    659		 * Assign value here to pass v4l2-compliance test
    660		 */
    661		pix_mp->width = q_data->visible_width;
    662		pix_mp->height = q_data->visible_height;
    663		pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
    664		pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
    665		pix_mp->pixelformat = q_data->fmt->fourcc;
    666		pix_mp->num_planes = q_data->fmt->num_planes;
    667	} else {
    668		pix_mp->width = q_data->coded_width;
    669		pix_mp->height = q_data->coded_height;
    670		pix_mp->num_planes = q_data->fmt->num_planes;
    671		pix_mp->pixelformat = q_data->fmt->fourcc;
    672		pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
    673		pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
    674		pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
    675		pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
    676
    677		mtk_v4l2_debug(1, "[%d] type=%d state=%d Format information could not be read, not ready yet!",
    678				ctx->id, f->type, ctx->state);
    679	}
    680
    681	return 0;
    682}
    683
    684int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
    685			    unsigned int *nplanes, unsigned int sizes[],
    686			    struct device *alloc_devs[])
    687{
    688	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
    689	struct mtk_q_data *q_data;
    690	unsigned int i;
    691
    692	q_data = mtk_vdec_get_q_data(ctx, vq->type);
    693
    694	if (q_data == NULL) {
    695		mtk_v4l2_err("vq->type=%d err\n", vq->type);
    696		return -EINVAL;
    697	}
    698
    699	if (*nplanes) {
    700		for (i = 0; i < *nplanes; i++) {
    701			if (sizes[i] < q_data->sizeimage[i])
    702				return -EINVAL;
    703		}
    704	} else {
    705		if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
    706			*nplanes = q_data->fmt->num_planes;
    707		else
    708			*nplanes = 1;
    709
    710		for (i = 0; i < *nplanes; i++)
    711			sizes[i] = q_data->sizeimage[i];
    712	}
    713
    714	mtk_v4l2_debug(1,
    715			"[%d]\t type = %d, get %d plane(s), %d buffer(s) of size 0x%x 0x%x ",
    716			ctx->id, vq->type, *nplanes, *nbuffers,
    717			sizes[0], sizes[1]);
    718
    719	return 0;
    720}
    721
    722int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
    723{
    724	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
    725	struct mtk_q_data *q_data;
    726	int i;
    727
    728	mtk_v4l2_debug(3, "[%d] (%d) id=%d",
    729			ctx->id, vb->vb2_queue->type, vb->index);
    730
    731	q_data = mtk_vdec_get_q_data(ctx, vb->vb2_queue->type);
    732
    733	for (i = 0; i < q_data->fmt->num_planes; i++) {
    734		if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
    735			mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
    736				i, vb2_plane_size(vb, i),
    737				q_data->sizeimage[i]);
    738		}
    739		if (!V4L2_TYPE_IS_OUTPUT(vb->type))
    740			vb2_set_plane_payload(vb, i, q_data->sizeimage[i]);
    741	}
    742
    743	return 0;
    744}
    745
    746void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
    747{
    748	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
    749	struct vb2_v4l2_buffer *vb2_v4l2;
    750	struct mtk_video_dec_buf *buf;
    751	bool buf_error;
    752
    753	vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
    754	buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
    755	mutex_lock(&ctx->lock);
    756	if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
    757		buf->queued_in_v4l2 = false;
    758		buf->queued_in_vb2 = false;
    759	}
    760	buf_error = buf->error;
    761	mutex_unlock(&ctx->lock);
    762
    763	if (buf_error) {
    764		mtk_v4l2_err("Unrecoverable error on buffer.");
    765		ctx->state = MTK_STATE_ABORT;
    766	}
    767}
    768
    769int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
    770{
    771	struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
    772					struct vb2_v4l2_buffer, vb2_buf);
    773	struct mtk_video_dec_buf *buf = container_of(vb2_v4l2,
    774					struct mtk_video_dec_buf, m2m_buf.vb);
    775
    776	if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
    777		buf->used = false;
    778		buf->queued_in_v4l2 = false;
    779	}
    780
    781	return 0;
    782}
    783
    784int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
    785{
    786	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
    787
    788	if (ctx->state == MTK_STATE_FLUSH)
    789		ctx->state = MTK_STATE_HEADER;
    790
    791	return 0;
    792}
    793
    794void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
    795{
    796	struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL;
    797	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
    798	int ret;
    799
    800	mtk_v4l2_debug(3, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d",
    801			ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt);
    802
    803	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
    804		while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
    805			if (src_buf != &ctx->empty_flush_buf.vb) {
    806				struct media_request *req =
    807					src_buf->vb2_buf.req_obj.req;
    808				v4l2_m2m_buf_done(src_buf,
    809						VB2_BUF_STATE_ERROR);
    810				if (req)
    811					v4l2_ctrl_request_complete(req, &ctx->ctrl_hdl);
    812			}
    813		}
    814		return;
    815	}
    816
    817	if (ctx->state >= MTK_STATE_HEADER) {
    818
    819		/* Until STREAMOFF is called on the CAPTURE queue
    820		 * (acknowledging the event), the driver operates
    821		 * as if the resolution hasn't changed yet, i.e.
    822		 * VIDIOC_G_FMT< etc. return previous resolution.
    823		 * So we update picinfo here
    824		 */
    825		ctx->picinfo = ctx->last_decoded_picinfo;
    826
    827		mtk_v4l2_debug(2,
    828				"[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)",
    829				ctx->id, ctx->last_decoded_picinfo.pic_w,
    830				ctx->last_decoded_picinfo.pic_h,
    831				ctx->picinfo.pic_w, ctx->picinfo.pic_h,
    832				ctx->last_decoded_picinfo.buf_w,
    833				ctx->last_decoded_picinfo.buf_h);
    834
    835		ret = ctx->dev->vdec_pdata->flush_decoder(ctx);
    836		if (ret)
    837			mtk_v4l2_err("DecodeFinal failed, ret=%d", ret);
    838	}
    839	ctx->state = MTK_STATE_FLUSH;
    840
    841	while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
    842		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
    843		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
    844			vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
    845		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
    846	}
    847
    848}
    849
    850static void m2mops_vdec_device_run(void *priv)
    851{
    852	struct mtk_vcodec_ctx *ctx = priv;
    853	struct mtk_vcodec_dev *dev = ctx->dev;
    854
    855	queue_work(dev->decode_workqueue, &ctx->decode_work);
    856}
    857
    858static int m2mops_vdec_job_ready(void *m2m_priv)
    859{
    860	struct mtk_vcodec_ctx *ctx = m2m_priv;
    861
    862	mtk_v4l2_debug(3, "[%d]", ctx->id);
    863
    864	if (ctx->state == MTK_STATE_ABORT)
    865		return 0;
    866
    867	if ((ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w) ||
    868	    (ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h))
    869		return 0;
    870
    871	if (ctx->state != MTK_STATE_HEADER)
    872		return 0;
    873
    874	return 1;
    875}
    876
    877static void m2mops_vdec_job_abort(void *priv)
    878{
    879	struct mtk_vcodec_ctx *ctx = priv;
    880
    881	ctx->state = MTK_STATE_ABORT;
    882}
    883
    884const struct v4l2_m2m_ops mtk_vdec_m2m_ops = {
    885	.device_run	= m2mops_vdec_device_run,
    886	.job_ready	= m2mops_vdec_job_ready,
    887	.job_abort	= m2mops_vdec_job_abort,
    888};
    889
    890const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = {
    891	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
    892	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
    893	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
    894	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
    895	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
    896
    897	.vidioc_qbuf		= vidioc_vdec_qbuf,
    898	.vidioc_dqbuf		= vidioc_vdec_dqbuf,
    899
    900	.vidioc_try_fmt_vid_cap_mplane	= vidioc_try_fmt_vid_cap_mplane,
    901	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_out_mplane,
    902
    903	.vidioc_s_fmt_vid_cap_mplane	= vidioc_vdec_s_fmt,
    904	.vidioc_s_fmt_vid_out_mplane	= vidioc_vdec_s_fmt,
    905	.vidioc_g_fmt_vid_cap_mplane	= vidioc_vdec_g_fmt,
    906	.vidioc_g_fmt_vid_out_mplane	= vidioc_vdec_g_fmt,
    907
    908	.vidioc_create_bufs		= v4l2_m2m_ioctl_create_bufs,
    909
    910	.vidioc_enum_fmt_vid_cap	= vidioc_vdec_enum_fmt_vid_cap,
    911	.vidioc_enum_fmt_vid_out	= vidioc_vdec_enum_fmt_vid_out,
    912	.vidioc_enum_framesizes	= vidioc_enum_framesizes,
    913
    914	.vidioc_querycap		= vidioc_vdec_querycap,
    915	.vidioc_subscribe_event		= vidioc_vdec_subscribe_evt,
    916	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
    917	.vidioc_g_selection             = vidioc_vdec_g_selection,
    918	.vidioc_s_selection             = vidioc_vdec_s_selection,
    919
    920	.vidioc_decoder_cmd = vidioc_decoder_cmd,
    921	.vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
    922};
    923
    924int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
    925			   struct vb2_queue *dst_vq)
    926{
    927	struct mtk_vcodec_ctx *ctx = priv;
    928	int ret = 0;
    929
    930	mtk_v4l2_debug(3, "[%d]", ctx->id);
    931
    932	src_vq->type		= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    933	src_vq->io_modes	= VB2_DMABUF | VB2_MMAP;
    934	src_vq->drv_priv	= ctx;
    935	src_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
    936	src_vq->ops		= ctx->dev->vdec_pdata->vdec_vb2_ops;
    937	src_vq->mem_ops		= &vb2_dma_contig_memops;
    938	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
    939	src_vq->lock		= &ctx->dev->dev_mutex;
    940	src_vq->dev             = &ctx->dev->plat_dev->dev;
    941
    942	ret = vb2_queue_init(src_vq);
    943	if (ret) {
    944		mtk_v4l2_err("Failed to initialize videobuf2 queue(output)");
    945		return ret;
    946	}
    947	dst_vq->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    948	dst_vq->io_modes	= VB2_DMABUF | VB2_MMAP;
    949	dst_vq->drv_priv	= ctx;
    950	dst_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
    951	dst_vq->ops		= ctx->dev->vdec_pdata->vdec_vb2_ops;
    952	dst_vq->mem_ops		= &vb2_dma_contig_memops;
    953	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
    954	dst_vq->lock		= &ctx->dev->dev_mutex;
    955	dst_vq->dev             = &ctx->dev->plat_dev->dev;
    956
    957	ret = vb2_queue_init(dst_vq);
    958	if (ret)
    959		mtk_v4l2_err("Failed to initialize videobuf2 queue(capture)");
    960
    961	return ret;
    962}