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