vdec_h264_req_if.c (13497B)
1// SPDX-License-Identifier: GPL-2.0 2 3#include <linux/module.h> 4#include <linux/slab.h> 5#include <media/v4l2-mem2mem.h> 6#include <media/v4l2-h264.h> 7#include <media/videobuf2-dma-contig.h> 8 9#include "../mtk_vcodec_util.h" 10#include "../mtk_vcodec_dec.h" 11#include "../mtk_vcodec_intr.h" 12#include "../vdec_drv_base.h" 13#include "../vdec_drv_if.h" 14#include "../vdec_vpu_if.h" 15#include "vdec_h264_req_common.h" 16 17/* 18 * struct mtk_h264_dec_slice_param - parameters for decode current frame 19 */ 20struct mtk_h264_dec_slice_param { 21 struct mtk_h264_sps_param sps; 22 struct mtk_h264_pps_param pps; 23 struct slice_api_h264_scaling_matrix scaling_matrix; 24 struct slice_api_h264_decode_param decode_params; 25 struct mtk_h264_dpb_info h264_dpb_info[16]; 26}; 27 28/** 29 * struct vdec_h264_dec_info - decode information 30 * @dpb_sz : decoding picture buffer size 31 * @resolution_changed : resoltion change happen 32 * @realloc_mv_buf : flag to notify driver to re-allocate mv buffer 33 * @cap_num_planes : number planes of capture buffer 34 * @bs_dma : Input bit-stream buffer dma address 35 * @y_fb_dma : Y frame buffer dma address 36 * @c_fb_dma : C frame buffer dma address 37 * @vdec_fb_va : VDEC frame buffer struct virtual address 38 */ 39struct vdec_h264_dec_info { 40 u32 dpb_sz; 41 u32 resolution_changed; 42 u32 realloc_mv_buf; 43 u32 cap_num_planes; 44 u64 bs_dma; 45 u64 y_fb_dma; 46 u64 c_fb_dma; 47 u64 vdec_fb_va; 48}; 49 50/** 51 * struct vdec_h264_vsi - shared memory for decode information exchange 52 * between VPU and Host. 53 * The memory is allocated by VPU then mapping to Host 54 * in vpu_dec_init() and freed in vpu_dec_deinit() 55 * by VPU. 56 * AP-W/R : AP is writer/reader on this item 57 * VPU-W/R: VPU is write/reader on this item 58 * @pred_buf_dma : HW working predication buffer dma address (AP-W, VPU-R) 59 * @mv_buf_dma : HW working motion vector buffer dma address (AP-W, VPU-R) 60 * @dec : decode information (AP-R, VPU-W) 61 * @pic : picture information (AP-R, VPU-W) 62 * @crop : crop information (AP-R, VPU-W) 63 * @h264_slice_params : the parameters that hardware use to decode 64 */ 65struct vdec_h264_vsi { 66 u64 pred_buf_dma; 67 u64 mv_buf_dma[H264_MAX_MV_NUM]; 68 struct vdec_h264_dec_info dec; 69 struct vdec_pic_info pic; 70 struct v4l2_rect crop; 71 struct mtk_h264_dec_slice_param h264_slice_params; 72}; 73 74/** 75 * struct vdec_h264_slice_inst - h264 decoder instance 76 * @num_nalu : how many nalus be decoded 77 * @ctx : point to mtk_vcodec_ctx 78 * @pred_buf : HW working predication buffer 79 * @mv_buf : HW working motion vector buffer 80 * @vpu : VPU instance 81 * @vsi_ctx : Local VSI data for this decoding context 82 * @h264_slice_param : the parameters that hardware use to decode 83 * @dpb : decoded picture buffer used to store reference buffer information 84 */ 85struct vdec_h264_slice_inst { 86 unsigned int num_nalu; 87 struct mtk_vcodec_ctx *ctx; 88 struct mtk_vcodec_mem pred_buf; 89 struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM]; 90 struct vdec_vpu_inst vpu; 91 struct vdec_h264_vsi vsi_ctx; 92 struct mtk_h264_dec_slice_param h264_slice_param; 93 94 struct v4l2_h264_dpb_entry dpb[16]; 95}; 96 97static int get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst) 98{ 99 const struct v4l2_ctrl_h264_decode_params *dec_params; 100 const struct v4l2_ctrl_h264_sps *sps; 101 const struct v4l2_ctrl_h264_pps *pps; 102 const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix; 103 struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param; 104 struct v4l2_h264_reflist_builder reflist_builder; 105 struct v4l2_h264_reference v4l2_p0_reflist[V4L2_H264_REF_LIST_LEN]; 106 struct v4l2_h264_reference v4l2_b0_reflist[V4L2_H264_REF_LIST_LEN]; 107 struct v4l2_h264_reference v4l2_b1_reflist[V4L2_H264_REF_LIST_LEN]; 108 u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0; 109 u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0; 110 u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1; 111 112 dec_params = 113 mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS); 114 if (IS_ERR(dec_params)) 115 return PTR_ERR(dec_params); 116 117 sps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS); 118 if (IS_ERR(sps)) 119 return PTR_ERR(sps); 120 121 pps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS); 122 if (IS_ERR(pps)) 123 return PTR_ERR(pps); 124 125 scaling_matrix = 126 mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX); 127 if (IS_ERR(scaling_matrix)) 128 return PTR_ERR(scaling_matrix); 129 130 mtk_vdec_h264_update_dpb(dec_params, inst->dpb); 131 132 mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps); 133 mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps); 134 mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix); 135 mtk_vdec_h264_copy_decode_params(&slice_param->decode_params, 136 dec_params, inst->dpb); 137 mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params, 138 slice_param->h264_dpb_info); 139 140 /* Build the reference lists */ 141 v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps, 142 inst->dpb); 143 v4l2_h264_build_p_ref_list(&reflist_builder, v4l2_p0_reflist); 144 v4l2_h264_build_b_ref_lists(&reflist_builder, v4l2_b0_reflist, 145 v4l2_b1_reflist); 146 147 /* Adapt the built lists to the firmware's expectations */ 148 mtk_vdec_h264_get_ref_list(p0_reflist, v4l2_p0_reflist, reflist_builder.num_valid); 149 mtk_vdec_h264_get_ref_list(b0_reflist, v4l2_b0_reflist, reflist_builder.num_valid); 150 mtk_vdec_h264_get_ref_list(b1_reflist, v4l2_b1_reflist, reflist_builder.num_valid); 151 152 memcpy(&inst->vsi_ctx.h264_slice_params, slice_param, 153 sizeof(inst->vsi_ctx.h264_slice_params)); 154 155 return 0; 156} 157 158static int allocate_predication_buf(struct vdec_h264_slice_inst *inst) 159{ 160 int err; 161 162 inst->pred_buf.size = BUF_PREDICTION_SZ; 163 err = mtk_vcodec_mem_alloc(inst->ctx, &inst->pred_buf); 164 if (err) { 165 mtk_vcodec_err(inst, "failed to allocate ppl buf"); 166 return err; 167 } 168 169 inst->vsi_ctx.pred_buf_dma = inst->pred_buf.dma_addr; 170 return 0; 171} 172 173static void free_predication_buf(struct vdec_h264_slice_inst *inst) 174{ 175 struct mtk_vcodec_mem *mem = &inst->pred_buf; 176 177 mtk_vcodec_debug_enter(inst); 178 179 inst->vsi_ctx.pred_buf_dma = 0; 180 if (mem->va) 181 mtk_vcodec_mem_free(inst->ctx, mem); 182} 183 184static int alloc_mv_buf(struct vdec_h264_slice_inst *inst, 185 struct vdec_pic_info *pic) 186{ 187 int i; 188 int err; 189 struct mtk_vcodec_mem *mem = NULL; 190 unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h); 191 192 mtk_v4l2_debug(3, "size = 0x%x", buf_sz); 193 for (i = 0; i < H264_MAX_MV_NUM; i++) { 194 mem = &inst->mv_buf[i]; 195 if (mem->va) 196 mtk_vcodec_mem_free(inst->ctx, mem); 197 mem->size = buf_sz; 198 err = mtk_vcodec_mem_alloc(inst->ctx, mem); 199 if (err) { 200 mtk_vcodec_err(inst, "failed to allocate mv buf"); 201 return err; 202 } 203 inst->vsi_ctx.mv_buf_dma[i] = mem->dma_addr; 204 } 205 206 return 0; 207} 208 209static void free_mv_buf(struct vdec_h264_slice_inst *inst) 210{ 211 int i; 212 struct mtk_vcodec_mem *mem; 213 214 for (i = 0; i < H264_MAX_MV_NUM; i++) { 215 inst->vsi_ctx.mv_buf_dma[i] = 0; 216 mem = &inst->mv_buf[i]; 217 if (mem->va) 218 mtk_vcodec_mem_free(inst->ctx, mem); 219 } 220} 221 222static void get_pic_info(struct vdec_h264_slice_inst *inst, 223 struct vdec_pic_info *pic) 224{ 225 struct mtk_vcodec_ctx *ctx = inst->ctx; 226 227 ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, VCODEC_DEC_ALIGNED_64); 228 ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, VCODEC_DEC_ALIGNED_64); 229 ctx->picinfo.fb_sz[0] = ctx->picinfo.buf_w * ctx->picinfo.buf_h; 230 ctx->picinfo.fb_sz[1] = ctx->picinfo.fb_sz[0] >> 1; 231 inst->vsi_ctx.dec.cap_num_planes = 232 ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes; 233 234 *pic = ctx->picinfo; 235 mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", 236 ctx->picinfo.pic_w, ctx->picinfo.pic_h, 237 ctx->picinfo.buf_w, ctx->picinfo.buf_h); 238 mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0], 239 ctx->picinfo.fb_sz[1]); 240 241 if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w || 242 ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) { 243 inst->vsi_ctx.dec.resolution_changed = true; 244 if (ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w || 245 ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h) 246 inst->vsi_ctx.dec.realloc_mv_buf = true; 247 248 mtk_v4l2_debug(1, "ResChg: (%d %d) : old(%d, %d) -> new(%d, %d)", 249 inst->vsi_ctx.dec.resolution_changed, 250 inst->vsi_ctx.dec.realloc_mv_buf, 251 ctx->last_decoded_picinfo.pic_w, 252 ctx->last_decoded_picinfo.pic_h, 253 ctx->picinfo.pic_w, ctx->picinfo.pic_h); 254 } 255} 256 257static void get_crop_info(struct vdec_h264_slice_inst *inst, struct v4l2_rect *cr) 258{ 259 cr->left = inst->vsi_ctx.crop.left; 260 cr->top = inst->vsi_ctx.crop.top; 261 cr->width = inst->vsi_ctx.crop.width; 262 cr->height = inst->vsi_ctx.crop.height; 263 264 mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d", 265 cr->left, cr->top, cr->width, cr->height); 266} 267 268static void get_dpb_size(struct vdec_h264_slice_inst *inst, unsigned int *dpb_sz) 269{ 270 *dpb_sz = inst->vsi_ctx.dec.dpb_sz; 271 mtk_vcodec_debug(inst, "sz=%d", *dpb_sz); 272} 273 274static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx) 275{ 276 struct vdec_h264_slice_inst *inst; 277 int err; 278 279 inst = kzalloc(sizeof(*inst), GFP_KERNEL); 280 if (!inst) 281 return -ENOMEM; 282 283 inst->ctx = ctx; 284 285 inst->vpu.id = SCP_IPI_VDEC_H264; 286 inst->vpu.ctx = ctx; 287 288 err = vpu_dec_init(&inst->vpu); 289 if (err) { 290 mtk_vcodec_err(inst, "vdec_h264 init err=%d", err); 291 goto error_free_inst; 292 } 293 294 memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx)); 295 inst->vsi_ctx.dec.resolution_changed = true; 296 inst->vsi_ctx.dec.realloc_mv_buf = true; 297 298 err = allocate_predication_buf(inst); 299 if (err) 300 goto error_deinit; 301 302 mtk_vcodec_debug(inst, "struct size = %zu,%zu,%zu,%zu\n", 303 sizeof(struct mtk_h264_sps_param), 304 sizeof(struct mtk_h264_pps_param), 305 sizeof(struct mtk_h264_dec_slice_param), 306 sizeof(struct mtk_h264_dpb_info)); 307 308 mtk_vcodec_debug(inst, "H264 Instance >> %p", inst); 309 310 ctx->drv_handle = inst; 311 return 0; 312 313error_deinit: 314 vpu_dec_deinit(&inst->vpu); 315 316error_free_inst: 317 kfree(inst); 318 return err; 319} 320 321static void vdec_h264_slice_deinit(void *h_vdec) 322{ 323 struct vdec_h264_slice_inst *inst = h_vdec; 324 325 mtk_vcodec_debug_enter(inst); 326 327 vpu_dec_deinit(&inst->vpu); 328 free_predication_buf(inst); 329 free_mv_buf(inst); 330 331 kfree(inst); 332} 333 334static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, 335 struct vdec_fb *unused, bool *res_chg) 336{ 337 struct vdec_h264_slice_inst *inst = h_vdec; 338 const struct v4l2_ctrl_h264_decode_params *dec_params = 339 mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS); 340 struct vdec_vpu_inst *vpu = &inst->vpu; 341 struct mtk_video_dec_buf *src_buf_info; 342 struct mtk_video_dec_buf *dst_buf_info; 343 struct vdec_fb *fb; 344 u32 data[2]; 345 u64 y_fb_dma; 346 u64 c_fb_dma; 347 int err; 348 349 inst->num_nalu++; 350 /* bs NULL means flush decoder */ 351 if (!bs) 352 return vpu_dec_reset(vpu); 353 354 fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx); 355 src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); 356 dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); 357 358 y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; 359 c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; 360 361 mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p", 362 inst->num_nalu, y_fb_dma, c_fb_dma, fb); 363 364 inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr; 365 inst->vsi_ctx.dec.y_fb_dma = y_fb_dma; 366 inst->vsi_ctx.dec.c_fb_dma = c_fb_dma; 367 inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb; 368 369 v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, 370 &dst_buf_info->m2m_buf.vb, true); 371 err = get_vdec_decode_parameters(inst); 372 if (err) 373 goto err_free_fb_out; 374 375 data[0] = bs->size; 376 /* 377 * Reconstruct the first byte of the NAL unit, as the firmware requests 378 * that information to be passed even though it is present in the stream 379 * itself... 380 */ 381 data[1] = (dec_params->nal_ref_idc << 5) | 382 ((dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) 383 ? 0x5 : 0x1); 384 385 *res_chg = inst->vsi_ctx.dec.resolution_changed; 386 if (*res_chg) { 387 mtk_vcodec_debug(inst, "- resolution changed -"); 388 if (inst->vsi_ctx.dec.realloc_mv_buf) { 389 err = alloc_mv_buf(inst, &inst->ctx->picinfo); 390 inst->vsi_ctx.dec.realloc_mv_buf = false; 391 if (err) 392 goto err_free_fb_out; 393 } 394 *res_chg = false; 395 } 396 397 memcpy(inst->vpu.vsi, &inst->vsi_ctx, sizeof(inst->vsi_ctx)); 398 err = vpu_dec_start(vpu, data, 2); 399 if (err) 400 goto err_free_fb_out; 401 402 /* wait decoder done interrupt */ 403 err = mtk_vcodec_wait_for_done_ctx(inst->ctx, 404 MTK_INST_IRQ_RECEIVED, 405 WAIT_INTR_TIMEOUT_MS, 0); 406 if (err) 407 goto err_free_fb_out; 408 vpu_dec_end(vpu); 409 410 memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx)); 411 mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu); 412 return 0; 413 414err_free_fb_out: 415 mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err); 416 return err; 417} 418 419static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type, void *out) 420{ 421 struct vdec_h264_slice_inst *inst = h_vdec; 422 423 switch (type) { 424 case GET_PARAM_PIC_INFO: 425 get_pic_info(inst, out); 426 break; 427 428 case GET_PARAM_DPB_SIZE: 429 get_dpb_size(inst, out); 430 break; 431 432 case GET_PARAM_CROP_INFO: 433 get_crop_info(inst, out); 434 break; 435 436 default: 437 mtk_vcodec_err(inst, "invalid get parameter type=%d", type); 438 return -EINVAL; 439 } 440 441 return 0; 442} 443 444const struct vdec_common_if vdec_h264_slice_if = { 445 .init = vdec_h264_slice_init, 446 .decode = vdec_h264_slice_decode, 447 .get_param = vdec_h264_slice_get_param, 448 .deinit = vdec_h264_slice_deinit, 449};