Merge remote-tracking branches 'asoc/fix/compress', 'asoc/fix/core', 'asoc/fix/dapm...
[sfrench/cifs-2.6.git] / drivers / media / platform / mtk-vcodec / venc / venc_h264_if.c
1 /*
2  * Copyright (c) 2016 MediaTek Inc.
3  * Author: Jungchang Tsao <jungchang.tsao@mediatek.com>
4  *         Daniel Hsiao <daniel.hsiao@mediatek.com>
5  *         PoChun Lin <pochun.lin@mediatek.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
20 #include <linux/slab.h>
21
22 #include "../mtk_vcodec_drv.h"
23 #include "../mtk_vcodec_util.h"
24 #include "../mtk_vcodec_intr.h"
25 #include "../mtk_vcodec_enc.h"
26 #include "../mtk_vcodec_enc_pm.h"
27 #include "../venc_drv_base.h"
28 #include "../venc_ipi_msg.h"
29 #include "../venc_vpu_if.h"
30 #include "mtk_vpu.h"
31
32 static const char h264_filler_marker[] = {0x0, 0x0, 0x0, 0x1, 0xc};
33
34 #define H264_FILLER_MARKER_SIZE ARRAY_SIZE(h264_filler_marker)
35 #define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
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_inst - h264 encoder AP driver instance
132  * @hw_base: h264 encoder hardware register base
133  * @work_bufs: working buffer
134  * @pps_buf: buffer to store the pps bitstream
135  * @work_buf_allocated: working buffer allocated flag
136  * @frm_cnt: encoded frame count
137  * @prepend_hdr: when the v4l2 layer send VENC_SET_PARAM_PREPEND_HEADER cmd
138  *  through h264_enc_set_param interface, it will set this flag and prepend the
139  *  sps/pps in h264_enc_encode function.
140  * @vpu_inst: VPU instance to exchange information between AP and VPU
141  * @vsi: driver structure allocated by VPU side and shared to AP side for
142  *       control and info share
143  * @ctx: context for v4l2 layer integration
144  */
145 struct venc_h264_inst {
146         void __iomem *hw_base;
147         struct mtk_vcodec_mem work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
148         struct mtk_vcodec_mem pps_buf;
149         bool work_buf_allocated;
150         unsigned int frm_cnt;
151         unsigned int prepend_hdr;
152         struct venc_vpu_inst vpu_inst;
153         struct venc_h264_vsi *vsi;
154         struct mtk_vcodec_ctx *ctx;
155 };
156
157 static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr)
158 {
159         return readl(inst->hw_base + addr);
160 }
161
162 static unsigned int h264_get_profile(struct venc_h264_inst *inst,
163                                      unsigned int profile)
164 {
165         switch (profile) {
166         case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
167                 return 66;
168         case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
169                 return 77;
170         case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
171                 return 100;
172         case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
173                 mtk_vcodec_err(inst, "unsupported CONSTRAINED_BASELINE");
174                 return 0;
175         case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
176                 mtk_vcodec_err(inst, "unsupported EXTENDED");
177                 return 0;
178         default:
179                 mtk_vcodec_debug(inst, "unsupported profile %d", profile);
180                 return 100;
181         }
182 }
183
184 static unsigned int h264_get_level(struct venc_h264_inst *inst,
185                                    unsigned int level)
186 {
187         switch (level) {
188         case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
189                 mtk_vcodec_err(inst, "unsupported 1B");
190                 return 0;
191         case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
192                 return 10;
193         case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
194                 return 11;
195         case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
196                 return 12;
197         case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
198                 return 13;
199         case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
200                 return 20;
201         case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
202                 return 21;
203         case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
204                 return 22;
205         case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
206                 return 30;
207         case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
208                 return 31;
209         case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
210                 return 32;
211         case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
212                 return 40;
213         case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
214                 return 41;
215         case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
216                 return 42;
217         default:
218                 mtk_vcodec_debug(inst, "unsupported level %d", level);
219                 return 31;
220         }
221 }
222
223 static void h264_enc_free_work_buf(struct venc_h264_inst *inst)
224 {
225         int i;
226
227         mtk_vcodec_debug_enter(inst);
228
229         /* Except the SKIP_FRAME buffers,
230          * other buffers need to be freed by AP.
231          */
232         for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
233                 if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME)
234                         mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
235         }
236
237         mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
238
239         mtk_vcodec_debug_leave(inst);
240 }
241
242 static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst)
243 {
244         int i;
245         int ret = 0;
246         struct venc_h264_vpu_buf *wb = inst->vsi->work_bufs;
247
248         mtk_vcodec_debug_enter(inst);
249
250         for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
251                 /*
252                  * This 'wb' structure is set by VPU side and shared to AP for
253                  * buffer allocation and IO virtual addr mapping. For most of
254                  * the buffers, AP will allocate the buffer according to 'size'
255                  * field and store the IO virtual addr in 'iova' field. There
256                  * are two exceptions:
257                  * (1) RC_CODE buffer, it's pre-allocated in the VPU side, and
258                  * save the VPU addr in the 'vpua' field. The AP will translate
259                  * the VPU addr to the corresponding IO virtual addr and store
260                  * in 'iova' field for reg setting in VPU side.
261                  * (2) SKIP_FRAME buffer, it's pre-allocated in the VPU side,
262                  * and save the VPU addr in the 'vpua' field. The AP will
263                  * translate the VPU addr to the corresponding AP side virtual
264                  * address and do some memcpy access to move to bitstream buffer
265                  * assigned by v4l2 layer.
266                  */
267                 inst->work_bufs[i].size = wb[i].size;
268                 if (i == VENC_H264_VPU_WORK_BUF_SKIP_FRAME) {
269                         inst->work_bufs[i].va = vpu_mapping_dm_addr(
270                                 inst->vpu_inst.dev, wb[i].vpua);
271                         inst->work_bufs[i].dma_addr = 0;
272                 } else {
273                         ret = mtk_vcodec_mem_alloc(inst->ctx,
274                                                    &inst->work_bufs[i]);
275                         if (ret) {
276                                 mtk_vcodec_err(inst,
277                                                "cannot allocate buf %d", i);
278                                 goto err_alloc;
279                         }
280                         /*
281                          * This RC_CODE is pre-allocated by VPU and saved in VPU
282                          * addr. So we need use memcpy to copy RC_CODE from VPU
283                          * addr into IO virtual addr in 'iova' field for reg
284                          * setting in VPU side.
285                          */
286                         if (i == VENC_H264_VPU_WORK_BUF_RC_CODE) {
287                                 void *tmp_va;
288
289                                 tmp_va = vpu_mapping_dm_addr(inst->vpu_inst.dev,
290                                                              wb[i].vpua);
291                                 memcpy(inst->work_bufs[i].va, tmp_va,
292                                        wb[i].size);
293                         }
294                 }
295                 wb[i].iova = inst->work_bufs[i].dma_addr;
296
297                 mtk_vcodec_debug(inst,
298                                  "work_buf[%d] va=0x%p iova=%pad size=%zu",
299                                  i, inst->work_bufs[i].va,
300                                  &inst->work_bufs[i].dma_addr,
301                                  inst->work_bufs[i].size);
302         }
303
304         /* the pps_buf is used by AP side only */
305         inst->pps_buf.size = 128;
306         ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->pps_buf);
307         if (ret) {
308                 mtk_vcodec_err(inst, "cannot allocate pps_buf");
309                 goto err_alloc;
310         }
311
312         mtk_vcodec_debug_leave(inst);
313
314         return ret;
315
316 err_alloc:
317         h264_enc_free_work_buf(inst);
318
319         return ret;
320 }
321
322 static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
323 {
324         unsigned int irq_status = 0;
325         struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
326
327         if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
328                                           WAIT_INTR_TIMEOUT_MS)) {
329                 irq_status = ctx->irq_status;
330                 mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
331         }
332         return irq_status;
333 }
334
335 static int h264_encode_sps(struct venc_h264_inst *inst,
336                            struct mtk_vcodec_mem *bs_buf,
337                            unsigned int *bs_size)
338 {
339         int ret = 0;
340         unsigned int irq_status;
341
342         mtk_vcodec_debug_enter(inst);
343
344         ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL,
345                              bs_buf, bs_size);
346         if (ret)
347                 return ret;
348
349         irq_status = h264_enc_wait_venc_done(inst);
350         if (irq_status != MTK_VENC_IRQ_STATUS_SPS) {
351                 mtk_vcodec_err(inst, "expect irq status %d",
352                                MTK_VENC_IRQ_STATUS_SPS);
353                 return -EINVAL;
354         }
355
356         *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
357         mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
358
359         return ret;
360 }
361
362 static int h264_encode_pps(struct venc_h264_inst *inst,
363                            struct mtk_vcodec_mem *bs_buf,
364                            unsigned int *bs_size)
365 {
366         int ret = 0;
367         unsigned int irq_status;
368
369         mtk_vcodec_debug_enter(inst);
370
371         ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL,
372                              bs_buf, bs_size);
373         if (ret)
374                 return ret;
375
376         irq_status = h264_enc_wait_venc_done(inst);
377         if (irq_status != MTK_VENC_IRQ_STATUS_PPS) {
378                 mtk_vcodec_err(inst, "expect irq status %d",
379                                MTK_VENC_IRQ_STATUS_PPS);
380                 return -EINVAL;
381         }
382
383         *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
384         mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
385
386         return ret;
387 }
388
389 static int h264_encode_header(struct venc_h264_inst *inst,
390                               struct mtk_vcodec_mem *bs_buf,
391                               unsigned int *bs_size)
392 {
393         int ret = 0;
394         unsigned int bs_size_sps;
395         unsigned int bs_size_pps;
396
397         ret = h264_encode_sps(inst, bs_buf, &bs_size_sps);
398         if (ret)
399                 return ret;
400
401         ret = h264_encode_pps(inst, &inst->pps_buf, &bs_size_pps);
402         if (ret)
403                 return ret;
404
405         memcpy(bs_buf->va + bs_size_sps, inst->pps_buf.va, bs_size_pps);
406         *bs_size = bs_size_sps + bs_size_pps;
407
408         return ret;
409 }
410
411 static int h264_encode_frame(struct venc_h264_inst *inst,
412                              struct venc_frm_buf *frm_buf,
413                              struct mtk_vcodec_mem *bs_buf,
414                              unsigned int *bs_size)
415 {
416         int ret = 0;
417         unsigned int irq_status;
418
419         mtk_vcodec_debug_enter(inst);
420
421         ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf,
422                              bs_buf, bs_size);
423         if (ret)
424                 return ret;
425
426         /*
427          * skip frame case: The skip frame buffer is composed by vpu side only,
428          * it does not trigger the hw, so skip the wait interrupt operation.
429          */
430         if (inst->vpu_inst.state == VEN_IPI_MSG_ENC_STATE_SKIP) {
431                 *bs_size = inst->vpu_inst.bs_size;
432                 memcpy(bs_buf->va,
433                        inst->work_bufs[VENC_H264_VPU_WORK_BUF_SKIP_FRAME].va,
434                        *bs_size);
435                 ++inst->frm_cnt;
436                 return ret;
437         }
438
439         irq_status = h264_enc_wait_venc_done(inst);
440         if (irq_status != MTK_VENC_IRQ_STATUS_FRM) {
441                 mtk_vcodec_err(inst, "irq_status=%d failed", irq_status);
442                 return -EIO;
443         }
444
445         *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
446
447         ++inst->frm_cnt;
448         mtk_vcodec_debug(inst, "frm %d bs_size %d key_frm %d <-",
449                          inst->frm_cnt, *bs_size, inst->vpu_inst.is_key_frm);
450
451         return ret;
452 }
453
454 static void h264_encode_filler(struct venc_h264_inst *inst, void *buf,
455                                int size)
456 {
457         unsigned char *p = buf;
458
459         if (size < H264_FILLER_MARKER_SIZE) {
460                 mtk_vcodec_err(inst, "filler size too small %d", size);
461                 return;
462         }
463
464         memcpy(p, h264_filler_marker, ARRAY_SIZE(h264_filler_marker));
465         size -= H264_FILLER_MARKER_SIZE;
466         p += H264_FILLER_MARKER_SIZE;
467         memset(p, 0xff, size);
468 }
469
470 static int h264_enc_init(struct mtk_vcodec_ctx *ctx, unsigned long *handle)
471 {
472         int ret = 0;
473         struct venc_h264_inst *inst;
474
475         inst = kzalloc(sizeof(*inst), GFP_KERNEL);
476         if (!inst)
477                 return -ENOMEM;
478
479         inst->ctx = ctx;
480         inst->vpu_inst.ctx = ctx;
481         inst->vpu_inst.dev = ctx->dev->vpu_plat_dev;
482         inst->vpu_inst.id = IPI_VENC_H264;
483         inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS);
484
485         mtk_vcodec_debug_enter(inst);
486
487         ret = vpu_enc_init(&inst->vpu_inst);
488
489         inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
490
491         mtk_vcodec_debug_leave(inst);
492
493         if (ret)
494                 kfree(inst);
495         else
496                 (*handle) = (unsigned long)inst;
497
498         return ret;
499 }
500
501 static int h264_enc_encode(unsigned long handle,
502                            enum venc_start_opt opt,
503                            struct venc_frm_buf *frm_buf,
504                            struct mtk_vcodec_mem *bs_buf,
505                            struct venc_done_result *result)
506 {
507         int ret = 0;
508         struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
509         struct mtk_vcodec_ctx *ctx = inst->ctx;
510
511         mtk_vcodec_debug(inst, "opt %d ->", opt);
512
513         enable_irq(ctx->dev->enc_irq);
514
515         switch (opt) {
516         case VENC_START_OPT_ENCODE_SEQUENCE_HEADER: {
517                 unsigned int bs_size_hdr;
518
519                 ret = h264_encode_header(inst, bs_buf, &bs_size_hdr);
520                 if (ret)
521                         goto encode_err;
522
523                 result->bs_size = bs_size_hdr;
524                 result->is_key_frm = false;
525                 break;
526         }
527
528         case VENC_START_OPT_ENCODE_FRAME: {
529                 int hdr_sz;
530                 int hdr_sz_ext;
531                 int filler_sz = 0;
532                 const int bs_alignment = 128;
533                 struct mtk_vcodec_mem tmp_bs_buf;
534                 unsigned int bs_size_hdr;
535                 unsigned int bs_size_frm;
536
537                 if (!inst->prepend_hdr) {
538                         ret = h264_encode_frame(inst, frm_buf, bs_buf,
539                                                 &result->bs_size);
540                         if (ret)
541                                 goto encode_err;
542                         result->is_key_frm = inst->vpu_inst.is_key_frm;
543                         break;
544                 }
545
546                 mtk_vcodec_debug(inst, "h264_encode_frame prepend SPS/PPS");
547
548                 ret = h264_encode_header(inst, bs_buf, &bs_size_hdr);
549                 if (ret)
550                         goto encode_err;
551
552                 hdr_sz = bs_size_hdr;
553                 hdr_sz_ext = (hdr_sz & (bs_alignment - 1));
554                 if (hdr_sz_ext) {
555                         filler_sz = bs_alignment - hdr_sz_ext;
556                         if (hdr_sz_ext + H264_FILLER_MARKER_SIZE > bs_alignment)
557                                 filler_sz += bs_alignment;
558                         h264_encode_filler(inst, bs_buf->va + hdr_sz,
559                                            filler_sz);
560                 }
561
562                 tmp_bs_buf.va = bs_buf->va + hdr_sz + filler_sz;
563                 tmp_bs_buf.dma_addr = bs_buf->dma_addr + hdr_sz + filler_sz;
564                 tmp_bs_buf.size = bs_buf->size - (hdr_sz + filler_sz);
565
566                 ret = h264_encode_frame(inst, frm_buf, &tmp_bs_buf,
567                                         &bs_size_frm);
568                 if (ret)
569                         goto encode_err;
570
571                 result->bs_size = hdr_sz + filler_sz + bs_size_frm;
572
573                 mtk_vcodec_debug(inst, "hdr %d filler %d frame %d bs %d",
574                                  hdr_sz, filler_sz, bs_size_frm,
575                                  result->bs_size);
576
577                 inst->prepend_hdr = 0;
578                 result->is_key_frm = inst->vpu_inst.is_key_frm;
579                 break;
580         }
581
582         default:
583                 mtk_vcodec_err(inst, "venc_start_opt %d not supported", opt);
584                 ret = -EINVAL;
585                 break;
586         }
587
588 encode_err:
589
590         disable_irq(ctx->dev->enc_irq);
591         mtk_vcodec_debug(inst, "opt %d <-", opt);
592
593         return ret;
594 }
595
596 static int h264_enc_set_param(unsigned long handle,
597                               enum venc_set_param_type type,
598                               struct venc_enc_param *enc_prm)
599 {
600         int ret = 0;
601         struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
602
603         mtk_vcodec_debug(inst, "->type=%d", type);
604
605         switch (type) {
606         case VENC_SET_PARAM_ENC:
607                 inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
608                 inst->vsi->config.bitrate = enc_prm->bitrate;
609                 inst->vsi->config.pic_w = enc_prm->width;
610                 inst->vsi->config.pic_h = enc_prm->height;
611                 inst->vsi->config.buf_w = enc_prm->buf_width;
612                 inst->vsi->config.buf_h = enc_prm->buf_height;
613                 inst->vsi->config.gop_size = enc_prm->gop_size;
614                 inst->vsi->config.framerate = enc_prm->frm_rate;
615                 inst->vsi->config.intra_period = enc_prm->intra_period;
616                 inst->vsi->config.profile =
617                         h264_get_profile(inst, enc_prm->h264_profile);
618                 inst->vsi->config.level =
619                         h264_get_level(inst, enc_prm->h264_level);
620                 inst->vsi->config.wfd = 0;
621                 ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
622                 if (ret)
623                         break;
624                 if (inst->work_buf_allocated) {
625                         h264_enc_free_work_buf(inst);
626                         inst->work_buf_allocated = false;
627                 }
628                 ret = h264_enc_alloc_work_buf(inst);
629                 if (ret)
630                         break;
631                 inst->work_buf_allocated = true;
632                 break;
633
634         case VENC_SET_PARAM_PREPEND_HEADER:
635                 inst->prepend_hdr = 1;
636                 mtk_vcodec_debug(inst, "set prepend header mode");
637                 break;
638
639         default:
640                 ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
641                 break;
642         }
643
644         mtk_vcodec_debug_leave(inst);
645
646         return ret;
647 }
648
649 static int h264_enc_deinit(unsigned long handle)
650 {
651         int ret = 0;
652         struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
653
654         mtk_vcodec_debug_enter(inst);
655
656         ret = vpu_enc_deinit(&inst->vpu_inst);
657
658         if (inst->work_buf_allocated)
659                 h264_enc_free_work_buf(inst);
660
661         mtk_vcodec_debug_leave(inst);
662         kfree(inst);
663
664         return ret;
665 }
666
667 static const struct venc_common_if venc_h264_if = {
668         .init = h264_enc_init,
669         .encode = h264_enc_encode,
670         .set_param = h264_enc_set_param,
671         .deinit = h264_enc_deinit,
672 };
673
674 const struct venc_common_if *get_h264_enc_comm_if(void);
675
676 const struct venc_common_if *get_h264_enc_comm_if(void)
677 {
678         return &venc_h264_if;
679 }