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

vdec_vp8_req_if.c (11738B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2021 MediaTek Inc.
      4 * Author: Yunfei Dong <yunfei.dong@mediatek.com>
      5 */
      6
      7#include <linux/slab.h>
      8#include <media/v4l2-mem2mem.h>
      9#include <media/videobuf2-dma-contig.h>
     10#include <uapi/linux/v4l2-controls.h>
     11
     12#include "../mtk_vcodec_util.h"
     13#include "../mtk_vcodec_dec.h"
     14#include "../mtk_vcodec_intr.h"
     15#include "../vdec_drv_base.h"
     16#include "../vdec_drv_if.h"
     17#include "../vdec_vpu_if.h"
     18
     19/* Decoding picture buffer size (3 reference frames plus current frame) */
     20#define VP8_DPB_SIZE 4
     21
     22/* HW working buffer size (bytes) */
     23#define VP8_SEG_ID_SZ   SZ_256K
     24#define VP8_PP_WRAPY_SZ SZ_64K
     25#define VP8_PP_WRAPC_SZ SZ_64K
     26#define VP8_VLD_PRED_SZ SZ_64K
     27
     28/**
     29 * struct vdec_vp8_slice_info - decode misc information
     30 *
     31 * @vld_wrapper_dma:	vld wrapper dma address
     32 * @seg_id_buf_dma:	seg id dma address
     33 * @wrap_y_dma:	wrap y dma address
     34 * @wrap_c_dma:	wrap y dma address
     35 * @cur_y_fb_dma:	current plane Y frame buffer dma address
     36 * @cur_c_fb_dma:	current plane C frame buffer dma address
     37 * @bs_dma:		bitstream dma address
     38 * @bs_sz:		bitstream size
     39 * @resolution_changed:resolution change flag 1 - changed,  0 - not change
     40 * @frame_header_type:	current frame header type
     41 * @wait_key_frame:	wait key frame coming
     42 * @crc:		used to check whether hardware's status is right
     43 * @reserved:		reserved, currently unused
     44 */
     45struct vdec_vp8_slice_info {
     46	u64 vld_wrapper_dma;
     47	u64 seg_id_buf_dma;
     48	u64 wrap_y_dma;
     49	u64 wrap_c_dma;
     50	u64 cur_y_fb_dma;
     51	u64 cur_c_fb_dma;
     52	u64 bs_dma;
     53	u32 bs_sz;
     54	u32 resolution_changed;
     55	u32 frame_header_type;
     56	u32 crc[8];
     57	u32 reserved;
     58};
     59
     60/**
     61 * struct vdec_vp8_slice_dpb_info  - vp8 reference information
     62 *
     63 * @y_dma_addr:	Y bitstream physical address
     64 * @c_dma_addr:	CbCr bitstream physical address
     65 * @reference_flag:	reference picture flag
     66 * @reserved:		64bit align
     67 */
     68struct vdec_vp8_slice_dpb_info {
     69	dma_addr_t y_dma_addr;
     70	dma_addr_t c_dma_addr;
     71	int reference_flag;
     72	int reserved;
     73};
     74
     75/**
     76 * struct vdec_vp8_slice_vsi - VPU shared information
     77 *
     78 * @dec:		decoding information
     79 * @pic:		picture information
     80 * @vp8_dpb_info:	reference buffer information
     81 */
     82struct vdec_vp8_slice_vsi {
     83	struct vdec_vp8_slice_info dec;
     84	struct vdec_pic_info pic;
     85	struct vdec_vp8_slice_dpb_info vp8_dpb_info[3];
     86};
     87
     88/**
     89 * struct vdec_vp8_slice_inst - VP8 decoder instance
     90 *
     91 * @seg_id_buf:	seg buffer
     92 * @wrap_y_buf:	wrapper y buffer
     93 * @wrap_c_buf:	wrapper c buffer
     94 * @vld_wrapper_buf:	vld wrapper buffer
     95 * @ctx:		V4L2 context
     96 * @vpu:		VPU instance for decoder
     97 * @vsi:		VPU share information
     98 */
     99struct vdec_vp8_slice_inst {
    100	struct mtk_vcodec_mem seg_id_buf;
    101	struct mtk_vcodec_mem wrap_y_buf;
    102	struct mtk_vcodec_mem wrap_c_buf;
    103	struct mtk_vcodec_mem vld_wrapper_buf;
    104	struct mtk_vcodec_ctx *ctx;
    105	struct vdec_vpu_inst vpu;
    106	struct vdec_vp8_slice_vsi *vsi;
    107};
    108
    109static void *vdec_vp8_slice_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
    110{
    111	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
    112
    113	if (!ctrl)
    114		return ERR_PTR(-EINVAL);
    115
    116	return ctrl->p_cur.p;
    117}
    118
    119static void vdec_vp8_slice_get_pic_info(struct vdec_vp8_slice_inst *inst)
    120{
    121	struct mtk_vcodec_ctx *ctx = inst->ctx;
    122	unsigned int data[3];
    123
    124	data[0] = ctx->picinfo.pic_w;
    125	data[1] = ctx->picinfo.pic_h;
    126	data[2] = ctx->capture_fourcc;
    127	vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO);
    128
    129	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
    130	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
    131	ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0];
    132	ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1];
    133
    134	inst->vsi->pic.pic_w = ctx->picinfo.pic_w;
    135	inst->vsi->pic.pic_h = ctx->picinfo.pic_h;
    136	inst->vsi->pic.buf_w = ctx->picinfo.buf_w;
    137	inst->vsi->pic.buf_h = ctx->picinfo.buf_h;
    138	inst->vsi->pic.fb_sz[0] = ctx->picinfo.fb_sz[0];
    139	inst->vsi->pic.fb_sz[1] = ctx->picinfo.fb_sz[1];
    140	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
    141			 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
    142			 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
    143	mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
    144			 ctx->picinfo.fb_sz[0], ctx->picinfo.fb_sz[1]);
    145}
    146
    147static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst)
    148{
    149	int err;
    150	struct mtk_vcodec_mem *mem;
    151
    152	mem = &inst->seg_id_buf;
    153	mem->size = VP8_SEG_ID_SZ;
    154	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
    155	if (err) {
    156		mtk_vcodec_err(inst, "Cannot allocate working buffer");
    157		return err;
    158	}
    159	inst->vsi->dec.seg_id_buf_dma = (u64)mem->dma_addr;
    160
    161	mem = &inst->wrap_y_buf;
    162	mem->size = VP8_PP_WRAPY_SZ;
    163	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
    164	if (err) {
    165		mtk_vcodec_err(inst, "cannot allocate WRAP Y buffer");
    166		return err;
    167	}
    168	inst->vsi->dec.wrap_y_dma = (u64)mem->dma_addr;
    169
    170	mem = &inst->wrap_c_buf;
    171	mem->size = VP8_PP_WRAPC_SZ;
    172	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
    173	if (err) {
    174		mtk_vcodec_err(inst, "cannot allocate WRAP C buffer");
    175		return err;
    176	}
    177	inst->vsi->dec.wrap_c_dma = (u64)mem->dma_addr;
    178
    179	mem = &inst->vld_wrapper_buf;
    180	mem->size = VP8_VLD_PRED_SZ;
    181	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
    182	if (err) {
    183		mtk_vcodec_err(inst, "cannot allocate vld wrapper buffer");
    184		return err;
    185	}
    186	inst->vsi->dec.vld_wrapper_dma = (u64)mem->dma_addr;
    187
    188	return 0;
    189}
    190
    191static void vdec_vp8_slice_free_working_buf(struct vdec_vp8_slice_inst *inst)
    192{
    193	struct mtk_vcodec_mem *mem;
    194
    195	mem = &inst->seg_id_buf;
    196	if (mem->va)
    197		mtk_vcodec_mem_free(inst->ctx, mem);
    198	inst->vsi->dec.seg_id_buf_dma = 0;
    199
    200	mem = &inst->wrap_y_buf;
    201	if (mem->va)
    202		mtk_vcodec_mem_free(inst->ctx, mem);
    203	inst->vsi->dec.wrap_y_dma = 0;
    204
    205	mem = &inst->wrap_c_buf;
    206	if (mem->va)
    207		mtk_vcodec_mem_free(inst->ctx, mem);
    208	inst->vsi->dec.wrap_c_dma = 0;
    209
    210	mem = &inst->vld_wrapper_buf;
    211	if (mem->va)
    212		mtk_vcodec_mem_free(inst->ctx, mem);
    213	inst->vsi->dec.vld_wrapper_dma = 0;
    214}
    215
    216static u64 vdec_vp8_slice_get_ref_by_ts(const struct v4l2_ctrl_vp8_frame *frame_header,
    217					int index)
    218{
    219	switch (index) {
    220	case 0:
    221		return frame_header->last_frame_ts;
    222	case 1:
    223		return frame_header->golden_frame_ts;
    224	case 2:
    225		return frame_header->alt_frame_ts;
    226	default:
    227		break;
    228	}
    229
    230	return -1;
    231}
    232
    233static int vdec_vp8_slice_get_decode_parameters(struct vdec_vp8_slice_inst *inst)
    234{
    235	const struct v4l2_ctrl_vp8_frame *frame_header;
    236	struct mtk_vcodec_ctx *ctx = inst->ctx;
    237	struct vb2_queue *vq;
    238	struct vb2_buffer *vb;
    239	u64 referenct_ts;
    240	int index, vb2_index;
    241
    242	frame_header = vdec_vp8_slice_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_VP8_FRAME);
    243	if (IS_ERR(frame_header))
    244		return PTR_ERR(frame_header);
    245
    246	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
    247	for (index = 0; index < 3; index++) {
    248		referenct_ts = vdec_vp8_slice_get_ref_by_ts(frame_header, index);
    249		vb2_index = vb2_find_timestamp(vq, referenct_ts, 0);
    250		if (vb2_index < 0) {
    251			if (!V4L2_VP8_FRAME_IS_KEY_FRAME(frame_header))
    252				mtk_vcodec_err(inst, "reference invalid: index(%d) ts(%lld)",
    253					       index, referenct_ts);
    254			inst->vsi->vp8_dpb_info[index].reference_flag = 0;
    255			continue;
    256		}
    257		inst->vsi->vp8_dpb_info[index].reference_flag = 1;
    258
    259		vb = vq->bufs[vb2_index];
    260		inst->vsi->vp8_dpb_info[index].y_dma_addr =
    261			vb2_dma_contig_plane_dma_addr(vb, 0);
    262		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
    263			inst->vsi->vp8_dpb_info[index].c_dma_addr =
    264				vb2_dma_contig_plane_dma_addr(vb, 1);
    265		else
    266			inst->vsi->vp8_dpb_info[index].c_dma_addr =
    267				inst->vsi->vp8_dpb_info[index].y_dma_addr +
    268				ctx->picinfo.fb_sz[0];
    269	}
    270
    271	inst->vsi->dec.frame_header_type = frame_header->flags >> 1;
    272
    273	return 0;
    274}
    275
    276static int vdec_vp8_slice_init(struct mtk_vcodec_ctx *ctx)
    277{
    278	struct vdec_vp8_slice_inst *inst;
    279	int err;
    280
    281	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
    282	if (!inst)
    283		return -ENOMEM;
    284
    285	inst->ctx = ctx;
    286
    287	inst->vpu.id = SCP_IPI_VDEC_LAT;
    288	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
    289	inst->vpu.ctx = ctx;
    290	inst->vpu.codec_type = ctx->current_codec;
    291	inst->vpu.capture_type = ctx->capture_fourcc;
    292
    293	err = vpu_dec_init(&inst->vpu);
    294	if (err) {
    295		mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err);
    296		goto error_free_inst;
    297	}
    298
    299	inst->vsi = inst->vpu.vsi;
    300	err = vdec_vp8_slice_alloc_working_buf(inst);
    301	if (err)
    302		goto error_deinit;
    303
    304	mtk_vcodec_debug(inst, "vp8 struct size = %d vsi: %d\n",
    305			 (int)sizeof(struct v4l2_ctrl_vp8_frame),
    306			 (int)sizeof(struct vdec_vp8_slice_vsi));
    307	mtk_vcodec_debug(inst, "vp8:%p, codec_type = 0x%x vsi: 0x%p",
    308			 inst, inst->vpu.codec_type, inst->vpu.vsi);
    309
    310	ctx->drv_handle = inst;
    311	return 0;
    312
    313error_deinit:
    314	vpu_dec_deinit(&inst->vpu);
    315error_free_inst:
    316	kfree(inst);
    317	return err;
    318}
    319
    320static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
    321				 struct vdec_fb *fb, bool *res_chg)
    322{
    323	struct vdec_vp8_slice_inst *inst = h_vdec;
    324	struct vdec_vpu_inst *vpu = &inst->vpu;
    325	struct mtk_video_dec_buf *src_buf_info, *dst_buf_info;
    326	unsigned int data;
    327	u64 y_fb_dma, c_fb_dma;
    328	int err, timeout;
    329
    330	/* Resolution changes are never initiated by us */
    331	*res_chg = false;
    332
    333	/* bs NULL means flush decoder */
    334	if (!bs)
    335		return vpu_dec_reset(vpu);
    336
    337	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
    338
    339	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
    340	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
    341
    342	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
    343	if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
    344		c_fb_dma = y_fb_dma +
    345			inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
    346	else
    347		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
    348
    349	inst->vsi->dec.bs_dma = (u64)bs->dma_addr;
    350	inst->vsi->dec.bs_sz = bs->size;
    351	inst->vsi->dec.cur_y_fb_dma = y_fb_dma;
    352	inst->vsi->dec.cur_c_fb_dma = c_fb_dma;
    353
    354	mtk_vcodec_debug(inst, "frame[%d] bs(%zu 0x%llx) y/c(0x%llx 0x%llx)",
    355			 inst->ctx->decoded_frame_cnt,
    356			 bs->size, (u64)bs->dma_addr,
    357			 y_fb_dma, c_fb_dma);
    358
    359	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
    360				   &dst_buf_info->m2m_buf.vb, true);
    361
    362	err = vdec_vp8_slice_get_decode_parameters(inst);
    363	if (err)
    364		goto error;
    365
    366	err = vpu_dec_start(vpu, &data, 1);
    367	if (err) {
    368		mtk_vcodec_debug(inst, "vp8 dec start err!");
    369		goto error;
    370	}
    371
    372	if (inst->vsi->dec.resolution_changed) {
    373		mtk_vcodec_debug(inst, "- resolution_changed -");
    374		*res_chg = true;
    375		return 0;
    376	}
    377
    378	/* wait decode done interrupt */
    379	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
    380					       50, MTK_VDEC_CORE);
    381
    382	err = vpu_dec_end(vpu);
    383	if (err || timeout)
    384		mtk_vcodec_debug(inst, "vp8 dec error timeout:%d err: %d pic_%d",
    385				 timeout, err, inst->ctx->decoded_frame_cnt);
    386
    387	mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
    388			 inst->ctx->decoded_frame_cnt,
    389			 inst->vsi->dec.crc[0], inst->vsi->dec.crc[1],
    390			 inst->vsi->dec.crc[2], inst->vsi->dec.crc[3],
    391			 inst->vsi->dec.crc[4], inst->vsi->dec.crc[5],
    392			 inst->vsi->dec.crc[6], inst->vsi->dec.crc[7]);
    393
    394	inst->ctx->decoded_frame_cnt++;
    395error:
    396	return err;
    397}
    398
    399static int vdec_vp8_slice_get_param(void *h_vdec, enum vdec_get_param_type type, void *out)
    400{
    401	struct vdec_vp8_slice_inst *inst = h_vdec;
    402
    403	switch (type) {
    404	case GET_PARAM_PIC_INFO:
    405		vdec_vp8_slice_get_pic_info(inst);
    406		break;
    407	case GET_PARAM_CROP_INFO:
    408		mtk_vcodec_debug(inst, "No need to get vp8 crop information.");
    409		break;
    410	case GET_PARAM_DPB_SIZE:
    411		*((unsigned int *)out) = VP8_DPB_SIZE;
    412		break;
    413	default:
    414		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
    415		return -EINVAL;
    416	}
    417
    418	return 0;
    419}
    420
    421static void vdec_vp8_slice_deinit(void *h_vdec)
    422{
    423	struct vdec_vp8_slice_inst *inst = h_vdec;
    424
    425	mtk_vcodec_debug_enter(inst);
    426
    427	vpu_dec_deinit(&inst->vpu);
    428	vdec_vp8_slice_free_working_buf(inst);
    429	kfree(inst);
    430}
    431
    432const struct vdec_common_if vdec_vp8_slice_if = {
    433	.init		= vdec_vp8_slice_init,
    434	.decode		= vdec_vp8_slice_decode,
    435	.get_param	= vdec_vp8_slice_get_param,
    436	.deinit		= vdec_vp8_slice_deinit,
    437};