Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: mediatek: vcodec: support stateless H.264 decoding for mt8192

Adds h264 lat and core architecture driver for mt8192,
and the decode mode is frame based for stateless decoder.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Yunfei Dong and committed by
Mauro Carvalho Chehab
59fba9ee 024b1f4f

+640 -1
+1
drivers/media/platform/mediatek/vcodec/Makefile
··· 10 10 vdec/vdec_vp9_if.o \ 11 11 vdec/vdec_h264_req_if.o \ 12 12 vdec/vdec_h264_req_common.o \ 13 + vdec/vdec_h264_req_multi_if.o \ 13 14 mtk_vcodec_dec_drv.o \ 14 15 vdec_drv_if.o \ 15 16 vdec_vpu_if.o \
+626
drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2022 MediaTek Inc. 4 + * Author: Yunfei Dong <yunfei.dong@mediatek.com> 5 + */ 6 + 7 + #include <linux/module.h> 8 + #include <linux/slab.h> 9 + #include <media/v4l2-h264.h> 10 + #include <media/v4l2-mem2mem.h> 11 + #include <media/videobuf2-dma-contig.h> 12 + 13 + #include "../mtk_vcodec_util.h" 14 + #include "../mtk_vcodec_dec.h" 15 + #include "../mtk_vcodec_intr.h" 16 + #include "../vdec_drv_base.h" 17 + #include "../vdec_drv_if.h" 18 + #include "../vdec_vpu_if.h" 19 + #include "vdec_h264_req_common.h" 20 + 21 + /** 22 + * enum vdec_h264_core_dec_err_type - core decode error type 23 + * 24 + * @TRANS_BUFFER_FULL: trans buffer is full 25 + * @SLICE_HEADER_FULL: slice header buffer is full 26 + */ 27 + enum vdec_h264_core_dec_err_type { 28 + TRANS_BUFFER_FULL = 1, 29 + SLICE_HEADER_FULL, 30 + }; 31 + 32 + /** 33 + * struct vdec_h264_slice_lat_dec_param - parameters for decode current frame 34 + * 35 + * @sps: h264 sps syntax parameters 36 + * @pps: h264 pps syntax parameters 37 + * @slice_header: h264 slice header syntax parameters 38 + * @scaling_matrix: h264 scaling list parameters 39 + * @decode_params: decoder parameters of each frame used for hardware decode 40 + * @h264_dpb_info: dpb reference list 41 + */ 42 + struct vdec_h264_slice_lat_dec_param { 43 + struct mtk_h264_sps_param sps; 44 + struct mtk_h264_pps_param pps; 45 + struct mtk_h264_slice_hd_param slice_header; 46 + struct slice_api_h264_scaling_matrix scaling_matrix; 47 + struct slice_api_h264_decode_param decode_params; 48 + struct mtk_h264_dpb_info h264_dpb_info[V4L2_H264_NUM_DPB_ENTRIES]; 49 + }; 50 + 51 + /** 52 + * struct vdec_h264_slice_info - decode information 53 + * 54 + * @nal_info: nal info of current picture 55 + * @timeout: Decode timeout: 1 timeout, 0 no timeount 56 + * @bs_buf_size: bitstream size 57 + * @bs_buf_addr: bitstream buffer dma address 58 + * @y_fb_dma: Y frame buffer dma address 59 + * @c_fb_dma: C frame buffer dma address 60 + * @vdec_fb_va: VDEC frame buffer struct virtual address 61 + * @crc: Used to check whether hardware's status is right 62 + */ 63 + struct vdec_h264_slice_info { 64 + u16 nal_info; 65 + u16 timeout; 66 + u32 bs_buf_size; 67 + u64 bs_buf_addr; 68 + u64 y_fb_dma; 69 + u64 c_fb_dma; 70 + u64 vdec_fb_va; 71 + u32 crc[8]; 72 + }; 73 + 74 + /** 75 + * struct vdec_h264_slice_vsi - shared memory for decode information exchange 76 + * between SCP and Host. 77 + * 78 + * @wdma_err_addr: wdma error dma address 79 + * @wdma_start_addr: wdma start dma address 80 + * @wdma_end_addr: wdma end dma address 81 + * @slice_bc_start_addr: slice bc start dma address 82 + * @slice_bc_end_addr: slice bc end dma address 83 + * @row_info_start_addr: row info start dma address 84 + * @row_info_end_addr: row info end dma address 85 + * @trans_start: trans start dma address 86 + * @trans_end: trans end dma address 87 + * @wdma_end_addr_offset: wdma end address offset 88 + * 89 + * @mv_buf_dma: HW working motion vector buffer 90 + * dma address (AP-W, VPU-R) 91 + * @dec: decode information (AP-R, VPU-W) 92 + * @h264_slice_params: decode parameters for hw used 93 + */ 94 + struct vdec_h264_slice_vsi { 95 + /* LAT dec addr */ 96 + u64 wdma_err_addr; 97 + u64 wdma_start_addr; 98 + u64 wdma_end_addr; 99 + u64 slice_bc_start_addr; 100 + u64 slice_bc_end_addr; 101 + u64 row_info_start_addr; 102 + u64 row_info_end_addr; 103 + u64 trans_start; 104 + u64 trans_end; 105 + u64 wdma_end_addr_offset; 106 + 107 + u64 mv_buf_dma[H264_MAX_MV_NUM]; 108 + struct vdec_h264_slice_info dec; 109 + struct vdec_h264_slice_lat_dec_param h264_slice_params; 110 + }; 111 + 112 + /** 113 + * struct vdec_h264_slice_share_info - shared information used to exchange 114 + * message between lat and core 115 + * 116 + * @sps: sequence header information from user space 117 + * @dec_params: decoder params from user space 118 + * @h264_slice_params: decoder params used for hardware 119 + * @trans_start: trans start dma address 120 + * @trans_end: trans end dma address 121 + * @nal_info: nal info of current picture 122 + */ 123 + struct vdec_h264_slice_share_info { 124 + struct v4l2_ctrl_h264_sps sps; 125 + struct v4l2_ctrl_h264_decode_params dec_params; 126 + struct vdec_h264_slice_lat_dec_param h264_slice_params; 127 + u64 trans_start; 128 + u64 trans_end; 129 + u16 nal_info; 130 + }; 131 + 132 + /** 133 + * struct vdec_h264_slice_inst - h264 decoder instance 134 + * 135 + * @slice_dec_num: how many picture be decoded 136 + * @ctx: point to mtk_vcodec_ctx 137 + * @pred_buf: HW working predication buffer 138 + * @mv_buf: HW working motion vector buffer 139 + * @vpu: VPU instance 140 + * @vsi: vsi used for lat 141 + * @vsi_core: vsi used for core 142 + * 143 + * @resolution_changed:resolution changed 144 + * @realloc_mv_buf: reallocate mv buffer 145 + * @cap_num_planes: number of capture queue plane 146 + * 147 + * @dpb: decoded picture buffer used to store reference 148 + * buffer information 149 + *@is_field_bitstream: is field bitstream 150 + */ 151 + struct vdec_h264_slice_inst { 152 + unsigned int slice_dec_num; 153 + struct mtk_vcodec_ctx *ctx; 154 + struct mtk_vcodec_mem pred_buf; 155 + struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM]; 156 + struct vdec_vpu_inst vpu; 157 + struct vdec_h264_slice_vsi *vsi; 158 + struct vdec_h264_slice_vsi *vsi_core; 159 + 160 + unsigned int resolution_changed; 161 + unsigned int realloc_mv_buf; 162 + unsigned int cap_num_planes; 163 + 164 + struct v4l2_h264_dpb_entry dpb[16]; 165 + bool is_field_bitstream; 166 + }; 167 + 168 + static int vdec_h264_slice_fill_decode_parameters(struct vdec_h264_slice_inst *inst, 169 + struct vdec_h264_slice_share_info *share_info) 170 + { 171 + struct vdec_h264_slice_lat_dec_param *slice_param = &inst->vsi->h264_slice_params; 172 + const struct v4l2_ctrl_h264_decode_params *dec_params; 173 + const struct v4l2_ctrl_h264_scaling_matrix *src_matrix; 174 + const struct v4l2_ctrl_h264_sps *sps; 175 + const struct v4l2_ctrl_h264_pps *pps; 176 + 177 + dec_params = 178 + mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS); 179 + if (IS_ERR(dec_params)) 180 + return PTR_ERR(dec_params); 181 + 182 + src_matrix = 183 + mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX); 184 + if (IS_ERR(src_matrix)) 185 + return PTR_ERR(src_matrix); 186 + 187 + sps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS); 188 + if (IS_ERR(sps)) 189 + return PTR_ERR(sps); 190 + 191 + pps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS); 192 + if (IS_ERR(pps)) 193 + return PTR_ERR(pps); 194 + 195 + if (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) { 196 + mtk_vcodec_err(inst, "No support for H.264 field decoding."); 197 + inst->is_field_bitstream = true; 198 + return -EINVAL; 199 + } 200 + 201 + mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps); 202 + mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps); 203 + mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix, src_matrix); 204 + 205 + memcpy(&share_info->sps, sps, sizeof(*sps)); 206 + memcpy(&share_info->dec_params, dec_params, sizeof(*dec_params)); 207 + 208 + return 0; 209 + } 210 + 211 + static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *inst, 212 + struct vdec_h264_slice_lat_dec_param *slice_param, 213 + struct vdec_h264_slice_share_info *share_info) 214 + { 215 + struct v4l2_ctrl_h264_decode_params *dec_params = &share_info->dec_params; 216 + struct v4l2_ctrl_h264_sps *sps = &share_info->sps; 217 + struct v4l2_h264_reflist_builder reflist_builder; 218 + u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0; 219 + u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0; 220 + u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1; 221 + 222 + mtk_vdec_h264_update_dpb(dec_params, inst->dpb); 223 + 224 + mtk_vdec_h264_copy_decode_params(&slice_param->decode_params, dec_params, 225 + inst->dpb); 226 + mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params, 227 + slice_param->h264_dpb_info); 228 + 229 + mtk_v4l2_debug(3, "cur poc = %d\n", dec_params->bottom_field_order_cnt); 230 + /* Build the reference lists */ 231 + v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps, 232 + inst->dpb); 233 + v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist); 234 + v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist); 235 + 236 + /* Adapt the built lists to the firmware's expectations */ 237 + mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid); 238 + mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid); 239 + mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid); 240 + } 241 + 242 + static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst, 243 + struct vdec_pic_info *pic) 244 + { 245 + unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h); 246 + struct mtk_vcodec_mem *mem; 247 + int i, err; 248 + 249 + mtk_v4l2_debug(3, "size = 0x%x", buf_sz); 250 + for (i = 0; i < H264_MAX_MV_NUM; i++) { 251 + mem = &inst->mv_buf[i]; 252 + if (mem->va) 253 + mtk_vcodec_mem_free(inst->ctx, mem); 254 + mem->size = buf_sz; 255 + err = mtk_vcodec_mem_alloc(inst->ctx, mem); 256 + if (err) { 257 + mtk_vcodec_err(inst, "failed to allocate mv buf"); 258 + return err; 259 + } 260 + } 261 + 262 + return 0; 263 + } 264 + 265 + static void vdec_h264_slice_free_mv_buf(struct vdec_h264_slice_inst *inst) 266 + { 267 + int i; 268 + struct mtk_vcodec_mem *mem; 269 + 270 + for (i = 0; i < H264_MAX_MV_NUM; i++) { 271 + mem = &inst->mv_buf[i]; 272 + if (mem->va) 273 + mtk_vcodec_mem_free(inst->ctx, mem); 274 + } 275 + } 276 + 277 + static void vdec_h264_slice_get_pic_info(struct vdec_h264_slice_inst *inst) 278 + { 279 + struct mtk_vcodec_ctx *ctx = inst->ctx; 280 + u32 data[3]; 281 + 282 + data[0] = ctx->picinfo.pic_w; 283 + data[1] = ctx->picinfo.pic_h; 284 + data[2] = ctx->capture_fourcc; 285 + vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO); 286 + 287 + ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, VCODEC_DEC_ALIGNED_64); 288 + ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, VCODEC_DEC_ALIGNED_64); 289 + ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0]; 290 + ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1]; 291 + inst->cap_num_planes = 292 + ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes; 293 + 294 + mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", 295 + ctx->picinfo.pic_w, ctx->picinfo.pic_h, 296 + ctx->picinfo.buf_w, ctx->picinfo.buf_h); 297 + mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], 298 + ctx->picinfo.fb_sz[1]); 299 + 300 + if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w || 301 + ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) { 302 + inst->resolution_changed = true; 303 + if (ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w || 304 + ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h) 305 + inst->realloc_mv_buf = true; 306 + 307 + mtk_v4l2_debug(1, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)", 308 + inst->resolution_changed, 309 + inst->realloc_mv_buf, 310 + ctx->last_decoded_picinfo.pic_w, 311 + ctx->last_decoded_picinfo.pic_h, 312 + ctx->picinfo.pic_w, ctx->picinfo.pic_h); 313 + } 314 + } 315 + 316 + static void vdec_h264_slice_get_crop_info(struct vdec_h264_slice_inst *inst, 317 + struct v4l2_rect *cr) 318 + { 319 + cr->left = 0; 320 + cr->top = 0; 321 + cr->width = inst->ctx->picinfo.pic_w; 322 + cr->height = inst->ctx->picinfo.pic_h; 323 + 324 + mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", 325 + cr->left, cr->top, cr->width, cr->height); 326 + } 327 + 328 + static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx) 329 + { 330 + struct vdec_h264_slice_inst *inst; 331 + int err, vsi_size; 332 + 333 + inst = kzalloc(sizeof(*inst), GFP_KERNEL); 334 + if (!inst) 335 + return -ENOMEM; 336 + 337 + inst->ctx = ctx; 338 + 339 + inst->vpu.id = SCP_IPI_VDEC_LAT; 340 + inst->vpu.core_id = SCP_IPI_VDEC_CORE; 341 + inst->vpu.ctx = ctx; 342 + inst->vpu.codec_type = ctx->current_codec; 343 + inst->vpu.capture_type = ctx->capture_fourcc; 344 + 345 + err = vpu_dec_init(&inst->vpu); 346 + if (err) { 347 + mtk_vcodec_err(inst, "vdec_h264 init err=%d", err); 348 + goto error_free_inst; 349 + } 350 + 351 + vsi_size = round_up(sizeof(struct vdec_h264_slice_vsi), VCODEC_DEC_ALIGNED_64); 352 + inst->vsi = inst->vpu.vsi; 353 + inst->vsi_core = 354 + (struct vdec_h264_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size); 355 + inst->resolution_changed = true; 356 + inst->realloc_mv_buf = true; 357 + 358 + mtk_vcodec_debug(inst, "lat struct size = %d,%d,%d,%d vsi: %d\n", 359 + (int)sizeof(struct mtk_h264_sps_param), 360 + (int)sizeof(struct mtk_h264_pps_param), 361 + (int)sizeof(struct vdec_h264_slice_lat_dec_param), 362 + (int)sizeof(struct mtk_h264_dpb_info), 363 + vsi_size); 364 + mtk_vcodec_debug(inst, "lat H264 instance >> %p, codec_type = 0x%x", 365 + inst, inst->vpu.codec_type); 366 + 367 + ctx->drv_handle = inst; 368 + return 0; 369 + 370 + error_free_inst: 371 + kfree(inst); 372 + return err; 373 + } 374 + 375 + static void vdec_h264_slice_deinit(void *h_vdec) 376 + { 377 + struct vdec_h264_slice_inst *inst = h_vdec; 378 + 379 + mtk_vcodec_debug_enter(inst); 380 + 381 + vpu_dec_deinit(&inst->vpu); 382 + vdec_h264_slice_free_mv_buf(inst); 383 + vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx); 384 + 385 + kfree(inst); 386 + } 387 + 388 + static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf) 389 + { 390 + struct vdec_fb *fb; 391 + u64 vdec_fb_va; 392 + u64 y_fb_dma, c_fb_dma; 393 + int err, timeout, i; 394 + struct mtk_vcodec_ctx *ctx = lat_buf->ctx; 395 + struct vdec_h264_slice_inst *inst = ctx->drv_handle; 396 + struct vb2_v4l2_buffer *vb2_v4l2; 397 + struct vdec_h264_slice_share_info *share_info = lat_buf->private_data; 398 + struct mtk_vcodec_mem *mem; 399 + struct vdec_vpu_inst *vpu = &inst->vpu; 400 + 401 + mtk_vcodec_debug(inst, "[h264-core] vdec_h264 core decode"); 402 + memcpy(&inst->vsi_core->h264_slice_params, &share_info->h264_slice_params, 403 + sizeof(share_info->h264_slice_params)); 404 + 405 + fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx); 406 + y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; 407 + vdec_fb_va = (unsigned long)fb; 408 + 409 + if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) 410 + c_fb_dma = 411 + y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h; 412 + else 413 + c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; 414 + 415 + mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma, 416 + c_fb_dma); 417 + 418 + inst->vsi_core->dec.y_fb_dma = y_fb_dma; 419 + inst->vsi_core->dec.c_fb_dma = c_fb_dma; 420 + inst->vsi_core->dec.vdec_fb_va = vdec_fb_va; 421 + inst->vsi_core->dec.nal_info = share_info->nal_info; 422 + inst->vsi_core->wdma_start_addr = 423 + lat_buf->ctx->msg_queue.wdma_addr.dma_addr; 424 + inst->vsi_core->wdma_end_addr = 425 + lat_buf->ctx->msg_queue.wdma_addr.dma_addr + 426 + lat_buf->ctx->msg_queue.wdma_addr.size; 427 + inst->vsi_core->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr; 428 + inst->vsi_core->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr; 429 + inst->vsi_core->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr + 430 + lat_buf->slice_bc_addr.size; 431 + inst->vsi_core->trans_start = share_info->trans_start; 432 + inst->vsi_core->trans_end = share_info->trans_end; 433 + for (i = 0; i < H264_MAX_MV_NUM; i++) { 434 + mem = &inst->mv_buf[i]; 435 + inst->vsi_core->mv_buf_dma[i] = mem->dma_addr; 436 + } 437 + 438 + vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 439 + v4l2_m2m_buf_copy_metadata(&lat_buf->ts_info, vb2_v4l2, true); 440 + 441 + vdec_h264_slice_fill_decode_reflist(inst, &inst->vsi_core->h264_slice_params, 442 + share_info); 443 + 444 + err = vpu_dec_core(vpu); 445 + if (err) { 446 + mtk_vcodec_err(inst, "core decode err=%d", err); 447 + goto vdec_dec_end; 448 + } 449 + 450 + /* wait decoder done interrupt */ 451 + timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, 452 + WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); 453 + if (timeout) 454 + mtk_vcodec_err(inst, "core decode timeout: pic_%d", 455 + ctx->decoded_frame_cnt); 456 + inst->vsi_core->dec.timeout = !!timeout; 457 + 458 + vpu_dec_core_end(vpu); 459 + mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", 460 + ctx->decoded_frame_cnt, 461 + inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1], 462 + inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3], 463 + inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5], 464 + inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]); 465 + 466 + vdec_dec_end: 467 + vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue, share_info->trans_end); 468 + ctx->dev->vdec_pdata->cap_to_disp(ctx, !!err, lat_buf->src_buf_req); 469 + mtk_vcodec_debug(inst, "core decode done err=%d", err); 470 + ctx->decoded_frame_cnt++; 471 + return 0; 472 + } 473 + 474 + static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, 475 + struct vdec_fb *fb, bool *res_chg) 476 + { 477 + struct vdec_h264_slice_inst *inst = h_vdec; 478 + struct vdec_vpu_inst *vpu = &inst->vpu; 479 + struct mtk_video_dec_buf *src_buf_info; 480 + int nal_start_idx, err, timeout = 0, i; 481 + unsigned int data[2]; 482 + struct vdec_lat_buf *lat_buf; 483 + struct vdec_h264_slice_share_info *share_info; 484 + unsigned char *buf; 485 + struct mtk_vcodec_mem *mem; 486 + 487 + if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx, 488 + vdec_h264_slice_core_decode, 489 + sizeof(*share_info))) 490 + return -ENOMEM; 491 + 492 + /* bs NULL means flush decoder */ 493 + if (!bs) { 494 + vdec_msg_queue_wait_lat_buf_full(&inst->ctx->msg_queue); 495 + return vpu_dec_reset(vpu); 496 + } 497 + 498 + if (inst->is_field_bitstream) 499 + return -EINVAL; 500 + 501 + lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx); 502 + if (!lat_buf) { 503 + mtk_vcodec_err(inst, "failed to get lat buffer"); 504 + return -EINVAL; 505 + } 506 + share_info = lat_buf->private_data; 507 + src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); 508 + 509 + buf = (unsigned char *)bs->va; 510 + nal_start_idx = mtk_vdec_h264_find_start_code(buf, bs->size); 511 + if (nal_start_idx < 0) { 512 + err = -EINVAL; 513 + goto err_free_fb_out; 514 + } 515 + 516 + inst->vsi->dec.nal_info = buf[nal_start_idx]; 517 + inst->vsi->dec.bs_buf_addr = (u64)bs->dma_addr; 518 + inst->vsi->dec.bs_buf_size = bs->size; 519 + 520 + lat_buf->src_buf_req = src_buf_info->m2m_buf.vb.vb2_buf.req_obj.req; 521 + v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, &lat_buf->ts_info, true); 522 + 523 + err = vdec_h264_slice_fill_decode_parameters(inst, share_info); 524 + if (err) 525 + goto err_free_fb_out; 526 + 527 + *res_chg = inst->resolution_changed; 528 + if (inst->resolution_changed) { 529 + mtk_vcodec_debug(inst, "- resolution changed -"); 530 + if (inst->realloc_mv_buf) { 531 + err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo); 532 + inst->realloc_mv_buf = false; 533 + if (err) 534 + goto err_free_fb_out; 535 + } 536 + inst->resolution_changed = false; 537 + } 538 + for (i = 0; i < H264_MAX_MV_NUM; i++) { 539 + mem = &inst->mv_buf[i]; 540 + inst->vsi->mv_buf_dma[i] = mem->dma_addr; 541 + } 542 + inst->vsi->wdma_start_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr; 543 + inst->vsi->wdma_end_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr + 544 + lat_buf->ctx->msg_queue.wdma_addr.size; 545 + inst->vsi->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr; 546 + inst->vsi->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr; 547 + inst->vsi->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr + 548 + lat_buf->slice_bc_addr.size; 549 + 550 + inst->vsi->trans_end = inst->ctx->msg_queue.wdma_rptr_addr; 551 + inst->vsi->trans_start = inst->ctx->msg_queue.wdma_wptr_addr; 552 + mtk_vcodec_debug(inst, "lat:trans(0x%llx 0x%llx) err:0x%llx", 553 + inst->vsi->wdma_start_addr, 554 + inst->vsi->wdma_end_addr, 555 + inst->vsi->wdma_err_addr); 556 + 557 + mtk_vcodec_debug(inst, "slice(0x%llx 0x%llx) rprt((0x%llx 0x%llx))", 558 + inst->vsi->slice_bc_start_addr, 559 + inst->vsi->slice_bc_end_addr, 560 + inst->vsi->trans_start, 561 + inst->vsi->trans_end); 562 + err = vpu_dec_start(vpu, data, 2); 563 + if (err) { 564 + mtk_vcodec_debug(inst, "lat decode err: %d", err); 565 + goto err_scp_decode; 566 + } 567 + 568 + /* wait decoder done interrupt */ 569 + timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, 570 + WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0); 571 + inst->vsi->dec.timeout = !!timeout; 572 + 573 + err = vpu_dec_end(vpu); 574 + if (err == SLICE_HEADER_FULL || timeout || err == TRANS_BUFFER_FULL) { 575 + err = -EINVAL; 576 + goto err_scp_decode; 577 + } 578 + 579 + share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr + 580 + inst->vsi->wdma_end_addr_offset; 581 + share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr; 582 + share_info->nal_info = inst->vsi->dec.nal_info; 583 + vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue, share_info->trans_end); 584 + 585 + memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params, 586 + sizeof(share_info->h264_slice_params)); 587 + vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf); 588 + 589 + inst->slice_dec_num++; 590 + return 0; 591 + 592 + err_scp_decode: 593 + err_free_fb_out: 594 + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); 595 + mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err); 596 + return err; 597 + } 598 + 599 + static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type, 600 + void *out) 601 + { 602 + struct vdec_h264_slice_inst *inst = h_vdec; 603 + 604 + switch (type) { 605 + case GET_PARAM_PIC_INFO: 606 + vdec_h264_slice_get_pic_info(inst); 607 + break; 608 + case GET_PARAM_DPB_SIZE: 609 + *(unsigned int *)out = 6; 610 + break; 611 + case GET_PARAM_CROP_INFO: 612 + vdec_h264_slice_get_crop_info(inst, out); 613 + break; 614 + default: 615 + mtk_vcodec_err(inst, "invalid get parameter type=%d", type); 616 + return -EINVAL; 617 + } 618 + return 0; 619 + } 620 + 621 + const struct vdec_common_if vdec_h264_slice_multi_if = { 622 + .init = vdec_h264_slice_init, 623 + .decode = vdec_h264_slice_lat_decode, 624 + .get_param = vdec_h264_slice_get_param, 625 + .deinit = vdec_h264_slice_deinit, 626 + };
+8 -1
drivers/media/platform/mediatek/vcodec/vdec_drv_if.c
··· 16 16 17 17 int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) 18 18 { 19 + enum mtk_vdec_hw_arch hw_arch = ctx->dev->vdec_pdata->hw_arch; 19 20 int ret = 0; 20 21 21 22 switch (fourcc) { 22 23 case V4L2_PIX_FMT_H264_SLICE: 23 - ctx->dec_if = &vdec_h264_slice_if; 24 + if (!ctx->dev->vdec_pdata->is_subdev_supported) { 25 + ctx->dec_if = &vdec_h264_slice_if; 26 + ctx->hw_id = MTK_VDEC_CORE; 27 + } else { 28 + ctx->dec_if = &vdec_h264_slice_multi_if; 29 + ctx->hw_id = IS_VDEC_LAT_ARCH(hw_arch) ? MTK_VDEC_LAT0 : MTK_VDEC_CORE; 30 + } 24 31 break; 25 32 case V4L2_PIX_FMT_H264: 26 33 ctx->dec_if = &vdec_h264_if;
+1
drivers/media/platform/mediatek/vcodec/vdec_drv_if.h
··· 56 56 57 57 extern const struct vdec_common_if vdec_h264_if; 58 58 extern const struct vdec_common_if vdec_h264_slice_if; 59 + extern const struct vdec_common_if vdec_h264_slice_multi_if; 59 60 extern const struct vdec_common_if vdec_vp8_if; 60 61 extern const struct vdec_common_if vdec_vp9_if; 61 62
+2
drivers/media/platform/mediatek/vcodec/vdec_vpu_if.h
··· 28 28 * @wq : wait queue to wait VPU message ack 29 29 * @handler : ipi handler for each decoder 30 30 * @codec_type : use codec type to separate different codecs 31 + * @capture_type: used capture type to separate different capture format 31 32 * @fb_sz : frame buffer size of each plane 32 33 */ 33 34 struct vdec_vpu_inst { ··· 44 43 wait_queue_head_t wq; 45 44 mtk_vcodec_ipi_handler handler; 46 45 unsigned int codec_type; 46 + unsigned int capture_type; 47 47 unsigned int fb_sz[2]; 48 48 }; 49 49
+2
include/linux/remoteproc/mtk_scp.h
··· 41 41 SCP_IPI_ISP_FRAME, 42 42 SCP_IPI_FD_CMD, 43 43 SCP_IPI_CROS_HOST_CMD, 44 + SCP_IPI_VDEC_LAT, 45 + SCP_IPI_VDEC_CORE, 44 46 SCP_IPI_NS_SERVICE = 0xFF, 45 47 SCP_IPI_MAX = 0x100, 46 48 };