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