1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2016 MediaTek Inc. 4 * Author: Jungchang Tsao <jungchang.tsao@mediatek.com> 5 * Daniel Hsiao <daniel.hsiao@mediatek.com> 6 * PoChun Lin <pochun.lin@mediatek.com> 7 */ 8 9#include <linux/interrupt.h> 10#include <linux/kernel.h> 11#include <linux/slab.h> 12 13#include "../mtk_vcodec_enc_drv.h" 14#include "../../common/mtk_vcodec_intr.h" 15#include "../mtk_vcodec_enc.h" 16#include "../mtk_vcodec_enc_pm.h" 17#include "../venc_drv_base.h" 18#include "../venc_ipi_msg.h" 19#include "../venc_vpu_if.h" 20 21static const char h264_filler_marker[] = {0x0, 0x0, 0x0, 0x1, 0xc}; 22 23#define H264_FILLER_MARKER_SIZE ARRAY_SIZE(h264_filler_marker) 24#define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098 25 26/* 27 * enum venc_h264_frame_type - h264 encoder output bitstream frame type 28 */ 29enum venc_h264_frame_type { 30 VENC_H264_IDR_FRM, 31 VENC_H264_I_FRM, 32 VENC_H264_P_FRM, 33 VENC_H264_B_FRM, 34}; 35 36/* 37 * enum venc_h264_vpu_work_buf - h264 encoder buffer index 38 */ 39enum venc_h264_vpu_work_buf { 40 VENC_H264_VPU_WORK_BUF_RC_INFO, 41 VENC_H264_VPU_WORK_BUF_RC_CODE, 42 VENC_H264_VPU_WORK_BUF_REC_LUMA, 43 VENC_H264_VPU_WORK_BUF_REC_CHROMA, 44 VENC_H264_VPU_WORK_BUF_REF_LUMA, 45 VENC_H264_VPU_WORK_BUF_REF_CHROMA, 46 VENC_H264_VPU_WORK_BUF_MV_INFO_1, 47 VENC_H264_VPU_WORK_BUF_MV_INFO_2, 48 VENC_H264_VPU_WORK_BUF_SKIP_FRAME, 49 VENC_H264_VPU_WORK_BUF_MAX, 50}; 51 52/* 53 * enum venc_h264_bs_mode - for bs_mode argument in h264_enc_vpu_encode 54 */ 55enum venc_h264_bs_mode { 56 H264_BS_MODE_SPS, 57 H264_BS_MODE_PPS, 58 H264_BS_MODE_FRAME, 59}; 60 61/* 62 * struct venc_h264_vpu_config - Structure for h264 encoder configuration 63 * AP-W/R : AP is writer/reader on this item 64 * VPU-W/R: VPU is write/reader on this item 65 * @input_fourcc: input fourcc 66 * @bitrate: target bitrate (in bps) 67 * @pic_w: picture width. Picture size is visible stream resolution, in pixels, 68 * to be used for display purposes; must be smaller or equal to buffer 69 * size. 70 * @pic_h: picture height 71 * @buf_w: buffer width. Buffer size is stream resolution in pixels aligned to 72 * hardware requirements. 73 * @buf_h: buffer height 74 * @gop_size: group of picture size (idr frame) 75 * @intra_period: intra frame period 76 * @framerate: frame rate in fps 77 * @profile: as specified in standard 78 * @level: as specified in standard 79 * @wfd: WFD mode 1:on, 0:off 80 */ 81struct venc_h264_vpu_config { 82 u32 input_fourcc; 83 u32 bitrate; 84 u32 pic_w; 85 u32 pic_h; 86 u32 buf_w; 87 u32 buf_h; 88 u32 gop_size; 89 u32 intra_period; 90 u32 framerate; 91 u32 profile; 92 u32 level; 93 u32 wfd; 94}; 95 96/* 97 * struct venc_h264_vpu_buf - Structure for buffer information 98 * AP-W/R : AP is writer/reader on this item 99 * VPU-W/R: VPU is write/reader on this item 100 * @iova: IO virtual address 101 * @vpua: VPU side memory addr which is used by RC_CODE 102 * @size: buffer size (in bytes) 103 */ 104struct venc_h264_vpu_buf { 105 u32 iova; 106 u32 vpua; 107 u32 size; 108}; 109 110/* 111 * struct venc_h264_vsi - Structure for VPU driver control and info share 112 * AP-W/R : AP is writer/reader on this item 113 * VPU-W/R: VPU is write/reader on this item 114 * This structure is allocated in VPU side and shared to AP side. 115 * @config: h264 encoder configuration 116 * @work_bufs: working buffer information in VPU side 117 * The work_bufs here is for storing the 'size' info shared to AP side. 118 * The similar item in struct venc_h264_inst is for memory allocation 119 * in AP side. The AP driver will copy the 'size' from here to the one in 120 * struct mtk_vcodec_mem, then invoke mtk_vcodec_mem_alloc to allocate 121 * the buffer. After that, bypass the 'dma_addr' to the 'iova' field here for 122 * register setting in VPU side. 123 */ 124struct venc_h264_vsi { 125 struct venc_h264_vpu_config config; 126 struct venc_h264_vpu_buf work_bufs[VENC_H264_VPU_WORK_BUF_MAX]; 127}; 128 129/** 130 * struct venc_h264_vpu_config_ext - Structure for h264 encoder configuration 131 * AP-W/R : AP is writer/reader on this item 132 * VPU-W/R: VPU is write/reader on this item 133 * @input_fourcc: input fourcc 134 * @bitrate: target bitrate (in bps) 135 * @pic_w: picture width. Picture size is visible stream resolution, in pixels, 136 * to be used for display purposes; must be smaller or equal to buffer 137 * size. 138 * @pic_h: picture height 139 * @buf_w: buffer width. Buffer size is stream resolution in pixels aligned to 140 * hardware requirements. 141 * @buf_h: buffer height 142 * @gop_size: group of picture size (idr frame) 143 * @intra_period: intra frame period 144 * @framerate: frame rate in fps 145 * @profile: as specified in standard 146 * @level: as specified in standard 147 * @wfd: WFD mode 1:on, 0:off 148 * @max_qp: max quant parameter 149 * @min_qp: min quant parameter 150 * @reserved: reserved configs 151 */ 152struct venc_h264_vpu_config_ext { 153 u32 input_fourcc; 154 u32 bitrate; 155 u32 pic_w; 156 u32 pic_h; 157 u32 buf_w; 158 u32 buf_h; 159 u32 gop_size; 160 u32 intra_period; 161 u32 framerate; 162 u32 profile; 163 u32 level; 164 u32 wfd; 165 u32 max_qp; 166 u32 min_qp; 167 u32 reserved[8]; 168}; 169 170/** 171 * struct venc_h264_vpu_buf_34 - Structure for 34-bit buffer information 172 * AP-W/R : AP is writer/reader on this item 173 * VPU-W/R: VPU is write/reader on this item 174 * @iova: 34-bit IO virtual address 175 * @vpua: VPU side memory addr which is used by RC_CODE 176 * @size: buffer size (in bytes) 177 */ 178struct venc_h264_vpu_buf_34 { 179 u64 iova; 180 u32 vpua; 181 u32 size; 182}; 183 184/** 185 * struct venc_h264_vsi_34 - Structure for VPU driver control and info share 186 * Used for 34-bit iova sharing 187 * @config: h264 encoder configuration 188 * @work_bufs: working buffer information in VPU side 189 */ 190struct venc_h264_vsi_34 { 191 struct venc_h264_vpu_config_ext config; 192 struct venc_h264_vpu_buf_34 work_bufs[VENC_H264_VPU_WORK_BUF_MAX]; 193}; 194 195/* 196 * struct venc_h264_inst - h264 encoder AP driver instance 197 * @hw_base: h264 encoder hardware register base 198 * @work_bufs: working buffer 199 * @pps_buf: buffer to store the pps bitstream 200 * @work_buf_allocated: working buffer allocated flag 201 * @frm_cnt: encoded frame count 202 * @prepend_hdr: when the v4l2 layer send VENC_SET_PARAM_PREPEND_HEADER cmd 203 * through h264_enc_set_param interface, it will set this flag and prepend the 204 * sps/pps in h264_enc_encode function. 205 * @vpu_inst: VPU instance to exchange information between AP and VPU 206 * @vsi: driver structure allocated by VPU side and shared to AP side for 207 * control and info share 208 * @vsi_34: driver structure allocated by VPU side and shared to AP side for 209 * control and info share, used for 34-bit iova sharing. 210 * @ctx: context for v4l2 layer integration 211 */ 212struct venc_h264_inst { 213 void __iomem *hw_base; 214 struct mtk_vcodec_mem work_bufs[VENC_H264_VPU_WORK_BUF_MAX]; 215 struct mtk_vcodec_mem pps_buf; 216 bool work_buf_allocated; 217 unsigned int frm_cnt; 218 unsigned int skip_frm_cnt; 219 unsigned int prepend_hdr; 220 struct venc_vpu_inst vpu_inst; 221 struct venc_h264_vsi *vsi; 222 struct venc_h264_vsi_34 *vsi_34; 223 struct mtk_vcodec_enc_ctx *ctx; 224}; 225 226static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr) 227{ 228 return readl(inst->hw_base + addr); 229} 230 231static unsigned int h264_get_profile(struct venc_h264_inst *inst, 232 unsigned int profile) 233{ 234 switch (profile) { 235 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 236 return 66; 237 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 238 return 77; 239 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 240 return 100; 241 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 242 mtk_venc_err(inst->ctx, "unsupported CONSTRAINED_BASELINE"); 243 return 0; 244 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: 245 mtk_venc_err(inst->ctx, "unsupported EXTENDED"); 246 return 0; 247 default: 248 mtk_venc_debug(inst->ctx, "unsupported profile %d", profile); 249 return 100; 250 } 251} 252 253static unsigned int h264_get_level(struct venc_h264_inst *inst, 254 unsigned int level) 255{ 256 switch (level) { 257 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 258 mtk_venc_err(inst->ctx, "unsupported 1B"); 259 return 0; 260 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 261 return 10; 262 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 263 return 11; 264 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 265 return 12; 266 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 267 return 13; 268 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 269 return 20; 270 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 271 return 21; 272 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 273 return 22; 274 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 275 return 30; 276 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 277 return 31; 278 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 279 return 32; 280 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 281 return 40; 282 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 283 return 41; 284 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 285 return 42; 286 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 287 return 50; 288 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 289 return 51; 290 default: 291 mtk_venc_debug(inst->ctx, "unsupported level %d", level); 292 return 31; 293 } 294} 295 296static void h264_enc_free_work_buf(struct venc_h264_inst *inst) 297{ 298 int i; 299 300 /* Except the SKIP_FRAME buffers, 301 * other buffers need to be freed by AP. 302 */ 303 for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) { 304 if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME) 305 mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]); 306 } 307 308 mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf); 309} 310 311static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit) 312{ 313 struct venc_h264_vpu_buf *wb = NULL; 314 struct venc_h264_vpu_buf_34 *wb_34 = NULL; 315 int i; 316 u32 vpua, wb_size; 317 int ret = 0; 318 319 if (is_34bit) 320 wb_34 = inst->vsi_34->work_bufs; 321 else 322 wb = inst->vsi->work_bufs; 323 324 for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) { 325 /* 326 * This 'wb' structure is set by VPU side and shared to AP for 327 * buffer allocation and IO virtual addr mapping. For most of 328 * the buffers, AP will allocate the buffer according to 'size' 329 * field and store the IO virtual addr in 'iova' field. There 330 * are two exceptions: 331 * (1) RC_CODE buffer, it's pre-allocated in the VPU side, and 332 * save the VPU addr in the 'vpua' field. The AP will translate 333 * the VPU addr to the corresponding IO virtual addr and store 334 * in 'iova' field for reg setting in VPU side. 335 * (2) SKIP_FRAME buffer, it's pre-allocated in the VPU side, 336 * and save the VPU addr in the 'vpua' field. The AP will 337 * translate the VPU addr to the corresponding AP side virtual 338 * address and do some memcpy access to move to bitstream buffer 339 * assigned by v4l2 layer. 340 */ 341 if (is_34bit) { 342 inst->work_bufs[i].size = wb_34[i].size; 343 vpua = wb_34[i].vpua; 344 wb_size = wb_34[i].size; 345 } else { 346 inst->work_bufs[i].size = wb[i].size; 347 vpua = wb[i].vpua; 348 wb_size = wb[i].size; 349 } 350 351 if (i == VENC_H264_VPU_WORK_BUF_SKIP_FRAME) { 352 struct mtk_vcodec_fw *handler; 353 354 handler = inst->vpu_inst.ctx->dev->fw_handler; 355 inst->work_bufs[i].va = 356 mtk_vcodec_fw_map_dm_addr(handler, vpua); 357 inst->work_bufs[i].dma_addr = 0; 358 } else { 359 ret = mtk_vcodec_mem_alloc(inst->ctx, 360 &inst->work_bufs[i]); 361 if (ret) { 362 mtk_venc_err(inst->ctx, "cannot allocate buf %d", i); 363 goto err_alloc; 364 } 365 /* 366 * This RC_CODE is pre-allocated by VPU and saved in VPU 367 * addr. So we need use memcpy to copy RC_CODE from VPU 368 * addr into IO virtual addr in 'iova' field for reg 369 * setting in VPU side. 370 */ 371 if (i == VENC_H264_VPU_WORK_BUF_RC_CODE) { 372 struct mtk_vcodec_fw *handler; 373 void *tmp_va; 374 375 handler = inst->vpu_inst.ctx->dev->fw_handler; 376 tmp_va = mtk_vcodec_fw_map_dm_addr(handler, 377 vpua); 378 memcpy(inst->work_bufs[i].va, tmp_va, wb_size); 379 } 380 } 381 if (is_34bit) 382 wb_34[i].iova = inst->work_bufs[i].dma_addr; 383 else 384 wb[i].iova = inst->work_bufs[i].dma_addr; 385 386 mtk_venc_debug(inst->ctx, "work_buf[%d] va=0x%p iova=%pad size=%zu", 387 i, inst->work_bufs[i].va, 388 &inst->work_bufs[i].dma_addr, 389 inst->work_bufs[i].size); 390 } 391 392 /* the pps_buf is used by AP side only */ 393 inst->pps_buf.size = 128; 394 ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->pps_buf); 395 if (ret) { 396 mtk_venc_err(inst->ctx, "cannot allocate pps_buf"); 397 goto err_alloc; 398 } 399 400 return ret; 401 402err_alloc: 403 h264_enc_free_work_buf(inst); 404 405 return ret; 406} 407 408static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst) 409{ 410 unsigned int irq_status = 0; 411 struct mtk_vcodec_enc_ctx *ctx = (struct mtk_vcodec_enc_ctx *)inst->ctx; 412 413 if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED, 414 WAIT_INTR_TIMEOUT_MS, 0)) { 415 irq_status = ctx->irq_status; 416 mtk_venc_debug(ctx, "irq_status %x <-", irq_status); 417 } 418 return irq_status; 419} 420 421static int h264_frame_type(unsigned int frm_cnt, unsigned int gop_size, 422 unsigned int intra_period) 423{ 424 if ((gop_size != 0 && (frm_cnt % gop_size) == 0) || 425 (frm_cnt == 0 && gop_size == 0)) { 426 /* IDR frame */ 427 return VENC_H264_IDR_FRM; 428 } else if ((intra_period != 0 && (frm_cnt % intra_period) == 0) || 429 (frm_cnt == 0 && intra_period == 0)) { 430 /* I frame */ 431 return VENC_H264_I_FRM; 432 } else { 433 return VENC_H264_P_FRM; /* Note: B frames are not supported */ 434 } 435} 436 437static int h264_encode_sps(struct venc_h264_inst *inst, 438 struct mtk_vcodec_mem *bs_buf, 439 unsigned int *bs_size) 440{ 441 int ret = 0; 442 unsigned int irq_status; 443 444 ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL, bs_buf, NULL); 445 if (ret) 446 return ret; 447 448 irq_status = h264_enc_wait_venc_done(inst); 449 if (irq_status != MTK_VENC_IRQ_STATUS_SPS) { 450 mtk_venc_err(inst->ctx, "expect irq status %d", MTK_VENC_IRQ_STATUS_SPS); 451 return -EINVAL; 452 } 453 454 *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT); 455 mtk_venc_debug(inst->ctx, "bs size %d <-", *bs_size); 456 457 return ret; 458} 459 460static int h264_encode_pps(struct venc_h264_inst *inst, 461 struct mtk_vcodec_mem *bs_buf, 462 unsigned int *bs_size) 463{ 464 int ret = 0; 465 unsigned int irq_status; 466 467 ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL, bs_buf, NULL); 468 if (ret) 469 return ret; 470 471 irq_status = h264_enc_wait_venc_done(inst); 472 if (irq_status != MTK_VENC_IRQ_STATUS_PPS) { 473 mtk_venc_err(inst->ctx, "expect irq status %d", MTK_VENC_IRQ_STATUS_PPS); 474 return -EINVAL; 475 } 476 477 *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT); 478 mtk_venc_debug(inst->ctx, "bs size %d <-", *bs_size); 479 480 return ret; 481} 482 483static int h264_encode_header(struct venc_h264_inst *inst, 484 struct mtk_vcodec_mem *bs_buf, 485 unsigned int *bs_size) 486{ 487 int ret = 0; 488 unsigned int bs_size_sps; 489 unsigned int bs_size_pps; 490 491 ret = h264_encode_sps(inst, bs_buf, &bs_size_sps); 492 if (ret) 493 return ret; 494 495 ret = h264_encode_pps(inst, &inst->pps_buf, &bs_size_pps); 496 if (ret) 497 return ret; 498 499 memcpy(bs_buf->va + bs_size_sps, inst->pps_buf.va, bs_size_pps); 500 *bs_size = bs_size_sps + bs_size_pps; 501 502 return ret; 503} 504 505static int h264_encode_frame(struct venc_h264_inst *inst, 506 struct venc_frm_buf *frm_buf, 507 struct mtk_vcodec_mem *bs_buf, 508 unsigned int *bs_size) 509{ 510 int ret = 0; 511 unsigned int gop_size; 512 unsigned int intra_period; 513 unsigned int irq_status; 514 struct venc_frame_info frame_info; 515 struct mtk_vcodec_enc_ctx *ctx = inst->ctx; 516 517 mtk_venc_debug(ctx, "frm_cnt = %d\n ", inst->frm_cnt); 518 519 if (MTK_ENC_IOVA_IS_34BIT(ctx)) { 520 gop_size = inst->vsi_34->config.gop_size; 521 intra_period = inst->vsi_34->config.intra_period; 522 } else { 523 gop_size = inst->vsi->config.gop_size; 524 intra_period = inst->vsi->config.intra_period; 525 } 526 frame_info.frm_count = inst->frm_cnt; 527 frame_info.skip_frm_count = inst->skip_frm_cnt; 528 frame_info.frm_type = h264_frame_type(inst->frm_cnt, gop_size, 529 intra_period); 530 mtk_venc_debug(ctx, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n", 531 frame_info.frm_count, frame_info.skip_frm_count, 532 frame_info.frm_type); 533 534 ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, 535 frm_buf, bs_buf, &frame_info); 536 if (ret) 537 return ret; 538 539 /* 540 * skip frame case: The skip frame buffer is composed by vpu side only, 541 * it does not trigger the hw, so skip the wait interrupt operation. 542 */ 543 if (inst->vpu_inst.state == VEN_IPI_MSG_ENC_STATE_SKIP) { 544 *bs_size = inst->vpu_inst.bs_size; 545 memcpy(bs_buf->va, 546 inst->work_bufs[VENC_H264_VPU_WORK_BUF_SKIP_FRAME].va, 547 *bs_size); 548 ++inst->frm_cnt; 549 ++inst->skip_frm_cnt; 550 return 0; 551 } 552 553 irq_status = h264_enc_wait_venc_done(inst); 554 if (irq_status != MTK_VENC_IRQ_STATUS_FRM) { 555 mtk_venc_err(ctx, "irq_status=%d failed", irq_status); 556 return -EIO; 557 } 558 559 *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT); 560 561 ++inst->frm_cnt; 562 mtk_venc_debug(ctx, "frm %d bs_size %d key_frm %d <-", 563 inst->frm_cnt, *bs_size, inst->vpu_inst.is_key_frm); 564 565 return 0; 566} 567 568static void h264_encode_filler(struct venc_h264_inst *inst, void *buf, 569 int size) 570{ 571 unsigned char *p = buf; 572 573 if (size < H264_FILLER_MARKER_SIZE) { 574 mtk_venc_err(inst->ctx, "filler size too small %d", size); 575 return; 576 } 577 578 memcpy(p, h264_filler_marker, ARRAY_SIZE(h264_filler_marker)); 579 size -= H264_FILLER_MARKER_SIZE; 580 p += H264_FILLER_MARKER_SIZE; 581 memset(p, 0xff, size); 582} 583 584static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx) 585{ 586 const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx); 587 int ret = 0; 588 struct venc_h264_inst *inst; 589 590 inst = kzalloc(sizeof(*inst), GFP_KERNEL); 591 if (!inst) 592 return -ENOMEM; 593 594 inst->ctx = ctx; 595 inst->vpu_inst.ctx = ctx; 596 inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264; 597 inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx->dev->reg_base, VENC_SYS); 598 599 ret = vpu_enc_init(&inst->vpu_inst); 600 601 if (MTK_ENC_IOVA_IS_34BIT(ctx)) 602 inst->vsi_34 = (struct venc_h264_vsi_34 *)inst->vpu_inst.vsi; 603 else 604 inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi; 605 606 if (ret) 607 kfree(inst); 608 else 609 ctx->drv_handle = inst; 610 611 return ret; 612} 613 614static int h264_enc_encode(void *handle, 615 enum venc_start_opt opt, 616 struct venc_frm_buf *frm_buf, 617 struct mtk_vcodec_mem *bs_buf, 618 struct venc_done_result *result) 619{ 620 int ret = 0; 621 struct venc_h264_inst *inst = (struct venc_h264_inst *)handle; 622 struct mtk_vcodec_enc_ctx *ctx = inst->ctx; 623 624 mtk_venc_debug(ctx, "opt %d ->", opt); 625 626 enable_irq(ctx->dev->enc_irq); 627 628 switch (opt) { 629 case VENC_START_OPT_ENCODE_SEQUENCE_HEADER: { 630 unsigned int bs_size_hdr; 631 632 ret = h264_encode_header(inst, bs_buf, &bs_size_hdr); 633 if (ret) 634 goto encode_err; 635 636 result->bs_size = bs_size_hdr; 637 result->is_key_frm = false; 638 break; 639 } 640 641 case VENC_START_OPT_ENCODE_FRAME: { 642 int hdr_sz; 643 int hdr_sz_ext; 644 int filler_sz = 0; 645 const int bs_alignment = 128; 646 struct mtk_vcodec_mem tmp_bs_buf; 647 unsigned int bs_size_hdr; 648 unsigned int bs_size_frm; 649 650 if (!inst->prepend_hdr) { 651 ret = h264_encode_frame(inst, frm_buf, bs_buf, 652 &result->bs_size); 653 if (ret) 654 goto encode_err; 655 result->is_key_frm = inst->vpu_inst.is_key_frm; 656 break; 657 } 658 659 mtk_venc_debug(ctx, "h264_encode_frame prepend SPS/PPS"); 660 661 ret = h264_encode_header(inst, bs_buf, &bs_size_hdr); 662 if (ret) 663 goto encode_err; 664 665 hdr_sz = bs_size_hdr; 666 hdr_sz_ext = (hdr_sz & (bs_alignment - 1)); 667 if (hdr_sz_ext) { 668 filler_sz = bs_alignment - hdr_sz_ext; 669 if (hdr_sz_ext + H264_FILLER_MARKER_SIZE > bs_alignment) 670 filler_sz += bs_alignment; 671 h264_encode_filler(inst, bs_buf->va + hdr_sz, 672 filler_sz); 673 } 674 675 tmp_bs_buf.va = bs_buf->va + hdr_sz + filler_sz; 676 tmp_bs_buf.dma_addr = bs_buf->dma_addr + hdr_sz + filler_sz; 677 tmp_bs_buf.size = bs_buf->size - (hdr_sz + filler_sz); 678 679 ret = h264_encode_frame(inst, frm_buf, &tmp_bs_buf, 680 &bs_size_frm); 681 if (ret) 682 goto encode_err; 683 684 result->bs_size = hdr_sz + filler_sz + bs_size_frm; 685 686 mtk_venc_debug(ctx, "hdr %d filler %d frame %d bs %d", 687 hdr_sz, filler_sz, bs_size_frm, result->bs_size); 688 689 inst->prepend_hdr = 0; 690 result->is_key_frm = inst->vpu_inst.is_key_frm; 691 break; 692 } 693 694 default: 695 mtk_venc_err(ctx, "venc_start_opt %d not supported", opt); 696 ret = -EINVAL; 697 break; 698 } 699 700encode_err: 701 702 disable_irq(ctx->dev->enc_irq); 703 mtk_venc_debug(ctx, "opt %d <-", opt); 704 705 return ret; 706} 707 708static void h264_enc_set_vsi_configs(struct venc_h264_inst *inst, 709 struct venc_enc_param *enc_prm) 710{ 711 inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt; 712 inst->vsi->config.bitrate = enc_prm->bitrate; 713 inst->vsi->config.pic_w = enc_prm->width; 714 inst->vsi->config.pic_h = enc_prm->height; 715 inst->vsi->config.buf_w = enc_prm->buf_width; 716 inst->vsi->config.buf_h = enc_prm->buf_height; 717 inst->vsi->config.gop_size = enc_prm->gop_size; 718 inst->vsi->config.framerate = enc_prm->frm_rate; 719 inst->vsi->config.intra_period = enc_prm->intra_period; 720 inst->vsi->config.profile = 721 h264_get_profile(inst, enc_prm->h264_profile); 722 inst->vsi->config.level = 723 h264_get_level(inst, enc_prm->h264_level); 724 inst->vsi->config.wfd = 0; 725} 726 727static void h264_enc_set_vsi_34_configs(struct venc_h264_inst *inst, 728 struct venc_enc_param *enc_prm) 729{ 730 inst->vsi_34->config.input_fourcc = enc_prm->input_yuv_fmt; 731 inst->vsi_34->config.bitrate = enc_prm->bitrate; 732 inst->vsi_34->config.pic_w = enc_prm->width; 733 inst->vsi_34->config.pic_h = enc_prm->height; 734 inst->vsi_34->config.buf_w = enc_prm->buf_width; 735 inst->vsi_34->config.buf_h = enc_prm->buf_height; 736 inst->vsi_34->config.gop_size = enc_prm->gop_size; 737 inst->vsi_34->config.framerate = enc_prm->frm_rate; 738 inst->vsi_34->config.intra_period = enc_prm->intra_period; 739 inst->vsi_34->config.profile = 740 h264_get_profile(inst, enc_prm->h264_profile); 741 inst->vsi_34->config.level = 742 h264_get_level(inst, enc_prm->h264_level); 743 inst->vsi_34->config.wfd = 0; 744} 745 746static int h264_enc_set_param(void *handle, 747 enum venc_set_param_type type, 748 struct venc_enc_param *enc_prm) 749{ 750 int ret = 0; 751 struct venc_h264_inst *inst = (struct venc_h264_inst *)handle; 752 struct mtk_vcodec_enc_ctx *ctx = inst->ctx; 753 const bool is_34bit = MTK_ENC_IOVA_IS_34BIT(ctx); 754 755 mtk_venc_debug(ctx, "->type=%d", type); 756 757 switch (type) { 758 case VENC_SET_PARAM_ENC: 759 if (is_34bit) 760 h264_enc_set_vsi_34_configs(inst, enc_prm); 761 else 762 h264_enc_set_vsi_configs(inst, enc_prm); 763 ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm); 764 if (ret) 765 break; 766 if (inst->work_buf_allocated) { 767 h264_enc_free_work_buf(inst); 768 inst->work_buf_allocated = false; 769 } 770 ret = h264_enc_alloc_work_buf(inst, is_34bit); 771 if (ret) 772 break; 773 inst->work_buf_allocated = true; 774 break; 775 776 case VENC_SET_PARAM_PREPEND_HEADER: 777 inst->prepend_hdr = 1; 778 mtk_venc_debug(ctx, "set prepend header mode"); 779 break; 780 case VENC_SET_PARAM_FORCE_INTRA: 781 case VENC_SET_PARAM_GOP_SIZE: 782 case VENC_SET_PARAM_INTRA_PERIOD: 783 inst->frm_cnt = 0; 784 inst->skip_frm_cnt = 0; 785 fallthrough; 786 default: 787 ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm); 788 break; 789 } 790 791 return ret; 792} 793 794static int h264_enc_deinit(void *handle) 795{ 796 int ret = 0; 797 struct venc_h264_inst *inst = (struct venc_h264_inst *)handle; 798 799 ret = vpu_enc_deinit(&inst->vpu_inst); 800 801 if (inst->work_buf_allocated) 802 h264_enc_free_work_buf(inst); 803 804 kfree(inst); 805 806 return ret; 807} 808 809const struct venc_common_if venc_h264_if = { 810 .init = h264_enc_init, 811 .encode = h264_enc_encode, 812 .set_param = h264_enc_set_param, 813 .deinit = h264_enc_deinit, 814}; 815