gfs2: Initialize atime of I_NEW inodes
[cascardo/linux.git] / drivers / media / platform / mtk-vcodec / venc / venc_vp8_if.c
1 /*
2  * Copyright (c) 2016 MediaTek Inc.
3  * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
4  *         PoChun Lin <pochun.lin@mediatek.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include <linux/interrupt.h>
18 #include <linux/kernel.h>
19 #include <linux/slab.h>
20
21 #include "../mtk_vcodec_drv.h"
22 #include "../mtk_vcodec_util.h"
23 #include "../mtk_vcodec_intr.h"
24 #include "../mtk_vcodec_enc.h"
25 #include "../mtk_vcodec_enc_pm.h"
26 #include "../venc_drv_base.h"
27 #include "../venc_ipi_msg.h"
28 #include "../venc_vpu_if.h"
29 #include "mtk_vpu.h"
30
31 #define VENC_BITSTREAM_FRAME_SIZE 0x0098
32 #define VENC_BITSTREAM_HEADER_LEN 0x00e8
33
34 /* This ac_tag is vp8 frame tag. */
35 #define MAX_AC_TAG_SIZE 10
36
37 /**
38  * enum venc_vp8_vpu_work_buf - vp8 encoder buffer index
39  */
40 enum venc_vp8_vpu_work_buf {
41         VENC_VP8_VPU_WORK_BUF_LUMA,
42         VENC_VP8_VPU_WORK_BUF_LUMA2,
43         VENC_VP8_VPU_WORK_BUF_LUMA3,
44         VENC_VP8_VPU_WORK_BUF_CHROMA,
45         VENC_VP8_VPU_WORK_BUF_CHROMA2,
46         VENC_VP8_VPU_WORK_BUF_CHROMA3,
47         VENC_VP8_VPU_WORK_BUF_MV_INFO,
48         VENC_VP8_VPU_WORK_BUF_BS_HEADER,
49         VENC_VP8_VPU_WORK_BUF_PROB_BUF,
50         VENC_VP8_VPU_WORK_BUF_RC_INFO,
51         VENC_VP8_VPU_WORK_BUF_RC_CODE,
52         VENC_VP8_VPU_WORK_BUF_RC_CODE2,
53         VENC_VP8_VPU_WORK_BUF_RC_CODE3,
54         VENC_VP8_VPU_WORK_BUF_MAX,
55 };
56
57 /*
58  * struct venc_vp8_vpu_config - Structure for vp8 encoder configuration
59  * @input_fourcc: input fourcc
60  * @bitrate: target bitrate (in bps)
61  * @pic_w: picture width. Picture size is visible stream resolution, in pixels,
62  *         to be used for display purposes; must be smaller or equal to buffer
63  *         size.
64  * @pic_h: picture height
65  * @buf_w: buffer width (with 16 alignment). Buffer size is stream resolution
66  *         in pixels aligned to hardware requirements.
67  * @buf_h: buffer height (with 16 alignment)
68  * @gop_size: group of picture size (key frame)
69  * @framerate: frame rate in fps
70  * @ts_mode: temporal scalability mode (0: disable, 1: enable)
71  *           support three temporal layers - 0: 7.5fps 1: 7.5fps 2: 15fps.
72  */
73 struct venc_vp8_vpu_config {
74         u32 input_fourcc;
75         u32 bitrate;
76         u32 pic_w;
77         u32 pic_h;
78         u32 buf_w;
79         u32 buf_h;
80         u32 gop_size;
81         u32 framerate;
82         u32 ts_mode;
83 };
84
85 /*
86  * struct venc_vp8_vpu_buf -Structure for buffer information
87  * @align: buffer alignment (in bytes)
88  * @iova: IO virtual address
89  * @vpua: VPU side memory addr which is used by RC_CODE
90  * @size: buffer size (in bytes)
91  */
92 struct venc_vp8_vpu_buf {
93         u32 align;
94         u32 iova;
95         u32 vpua;
96         u32 size;
97 };
98
99 /*
100  * struct venc_vp8_vsi - Structure for VPU driver control and info share
101  * This structure is allocated in VPU side and shared to AP side.
102  * @config: vp8 encoder configuration
103  * @work_bufs: working buffer information in VPU side
104  * The work_bufs here is for storing the 'size' info shared to AP side.
105  * The similar item in struct venc_vp8_inst is for memory allocation
106  * in AP side. The AP driver will copy the 'size' from here to the one in
107  * struct mtk_vcodec_mem, then invoke mtk_vcodec_mem_alloc to allocate
108  * the buffer. After that, bypass the 'dma_addr' to the 'iova' field here for
109  * register setting in VPU side.
110  */
111 struct venc_vp8_vsi {
112         struct venc_vp8_vpu_config config;
113         struct venc_vp8_vpu_buf work_bufs[VENC_VP8_VPU_WORK_BUF_MAX];
114 };
115
116 /*
117  * struct venc_vp8_inst - vp8 encoder AP driver instance
118  * @hw_base: vp8 encoder hardware register base
119  * @work_bufs: working buffer
120  * @work_buf_allocated: working buffer allocated flag
121  * @frm_cnt: encoded frame count, it's used for I-frame judgement and
122  *           reset when force intra cmd received.
123  * @ts_mode: temporal scalability mode (0: disable, 1: enable)
124  *           support three temporal layers - 0: 7.5fps 1: 7.5fps 2: 15fps.
125  * @vpu_inst: VPU instance to exchange information between AP and VPU
126  * @vsi: driver structure allocated by VPU side and shared to AP side for
127  *       control and info share
128  * @ctx: context for v4l2 layer integration
129  */
130 struct venc_vp8_inst {
131         void __iomem *hw_base;
132         struct mtk_vcodec_mem work_bufs[VENC_VP8_VPU_WORK_BUF_MAX];
133         bool work_buf_allocated;
134         unsigned int frm_cnt;
135         unsigned int ts_mode;
136         struct venc_vpu_inst vpu_inst;
137         struct venc_vp8_vsi *vsi;
138         struct mtk_vcodec_ctx *ctx;
139 };
140
141 static inline void vp8_enc_write_reg(struct venc_vp8_inst *inst, u32 addr,
142                                      u32 val)
143 {
144         writel(val, inst->hw_base + addr);
145 }
146
147 static inline u32 vp8_enc_read_reg(struct venc_vp8_inst *inst, u32 addr)
148 {
149         return readl(inst->hw_base + addr);
150 }
151
152 static void vp8_enc_free_work_buf(struct venc_vp8_inst *inst)
153 {
154         int i;
155
156         mtk_vcodec_debug_enter(inst);
157
158         /* Buffers need to be freed by AP. */
159         for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) {
160                 if ((inst->work_bufs[i].size == 0))
161                         continue;
162                 mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
163         }
164
165         mtk_vcodec_debug_leave(inst);
166 }
167
168 static int vp8_enc_alloc_work_buf(struct venc_vp8_inst *inst)
169 {
170         int i;
171         int ret = 0;
172         struct venc_vp8_vpu_buf *wb = inst->vsi->work_bufs;
173
174         mtk_vcodec_debug_enter(inst);
175
176         for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) {
177                 if ((wb[i].size == 0))
178                         continue;
179                 /*
180                  * This 'wb' structure is set by VPU side and shared to AP for
181                  * buffer allocation and IO virtual addr mapping. For most of
182                  * the buffers, AP will allocate the buffer according to 'size'
183                  * field and store the IO virtual addr in 'iova' field. For the
184                  * RC_CODEx buffers, they are pre-allocated in the VPU side
185                  * because they are inside VPU SRAM, and save the VPU addr in
186                  * the 'vpua' field. The AP will translate the VPU addr to the
187                  * corresponding IO virtual addr and store in 'iova' field.
188                  */
189                 inst->work_bufs[i].size = wb[i].size;
190                 ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->work_bufs[i]);
191                 if (ret) {
192                         mtk_vcodec_err(inst,
193                                        "cannot alloc work_bufs[%d]", i);
194                         goto err_alloc;
195                 }
196                 /*
197                  * This RC_CODEx is pre-allocated by VPU and saved in VPU addr.
198                  * So we need use memcpy to copy RC_CODEx from VPU addr into IO
199                  * virtual addr in 'iova' field for reg setting in VPU side.
200                  */
201                 if (i == VENC_VP8_VPU_WORK_BUF_RC_CODE ||
202                     i == VENC_VP8_VPU_WORK_BUF_RC_CODE2 ||
203                     i == VENC_VP8_VPU_WORK_BUF_RC_CODE3) {
204                         void *tmp_va;
205
206                         tmp_va = vpu_mapping_dm_addr(inst->vpu_inst.dev,
207                                                      wb[i].vpua);
208                         memcpy(inst->work_bufs[i].va, tmp_va, wb[i].size);
209                 }
210                 wb[i].iova = inst->work_bufs[i].dma_addr;
211
212                 mtk_vcodec_debug(inst,
213                                  "work_bufs[%d] va=0x%p,iova=%pad,size=%zu",
214                                  i, inst->work_bufs[i].va,
215                                  &inst->work_bufs[i].dma_addr,
216                                  inst->work_bufs[i].size);
217         }
218
219         mtk_vcodec_debug_leave(inst);
220
221         return ret;
222
223 err_alloc:
224         vp8_enc_free_work_buf(inst);
225
226         return ret;
227 }
228
229 static unsigned int vp8_enc_wait_venc_done(struct venc_vp8_inst *inst)
230 {
231         unsigned int irq_status = 0;
232         struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
233
234         if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
235                                           WAIT_INTR_TIMEOUT_MS)) {
236                 irq_status = ctx->irq_status;
237                 mtk_vcodec_debug(inst, "isr return %x", irq_status);
238         }
239         return irq_status;
240 }
241
242 /*
243  * Compose ac_tag, bitstream header and bitstream payload into
244  * one bitstream buffer.
245  */
246 static int vp8_enc_compose_one_frame(struct venc_vp8_inst *inst,
247                                      struct mtk_vcodec_mem *bs_buf,
248                                      unsigned int *bs_size)
249 {
250         unsigned int not_key;
251         u32 bs_frm_size;
252         u32 bs_hdr_len;
253         unsigned int ac_tag_size;
254         u8 ac_tag[MAX_AC_TAG_SIZE];
255         u32 tag;
256
257         bs_frm_size = vp8_enc_read_reg(inst, VENC_BITSTREAM_FRAME_SIZE);
258         bs_hdr_len = vp8_enc_read_reg(inst, VENC_BITSTREAM_HEADER_LEN);
259
260         /* if a frame is key frame, not_key is 0 */
261         not_key = !inst->vpu_inst.is_key_frm;
262         tag = (bs_hdr_len << 5) | 0x10 | not_key;
263         ac_tag[0] = tag & 0xff;
264         ac_tag[1] = (tag >> 8) & 0xff;
265         ac_tag[2] = (tag >> 16) & 0xff;
266
267         /* key frame */
268         if (not_key == 0) {
269                 ac_tag_size = MAX_AC_TAG_SIZE;
270                 ac_tag[3] = 0x9d;
271                 ac_tag[4] = 0x01;
272                 ac_tag[5] = 0x2a;
273                 ac_tag[6] = inst->vsi->config.pic_w;
274                 ac_tag[7] = inst->vsi->config.pic_w >> 8;
275                 ac_tag[8] = inst->vsi->config.pic_h;
276                 ac_tag[9] = inst->vsi->config.pic_h >> 8;
277         } else {
278                 ac_tag_size = 3;
279         }
280
281         if (bs_buf->size < bs_hdr_len + bs_frm_size + ac_tag_size) {
282                 mtk_vcodec_err(inst, "bitstream buf size is too small(%zu)",
283                                bs_buf->size);
284                 return -EINVAL;
285         }
286
287         /*
288         * (1) The vp8 bitstream header and body are generated by the HW vp8
289         * encoder separately at the same time. We cannot know the bitstream
290         * header length in advance.
291         * (2) From the vp8 spec, there is no stuffing byte allowed between the
292         * ac tag, bitstream header and bitstream body.
293         */
294         memmove(bs_buf->va + bs_hdr_len + ac_tag_size,
295                 bs_buf->va, bs_frm_size);
296         memcpy(bs_buf->va + ac_tag_size,
297                inst->work_bufs[VENC_VP8_VPU_WORK_BUF_BS_HEADER].va,
298                bs_hdr_len);
299         memcpy(bs_buf->va, ac_tag, ac_tag_size);
300         *bs_size = bs_frm_size + bs_hdr_len + ac_tag_size;
301
302         return 0;
303 }
304
305 static int vp8_enc_encode_frame(struct venc_vp8_inst *inst,
306                                 struct venc_frm_buf *frm_buf,
307                                 struct mtk_vcodec_mem *bs_buf,
308                                 unsigned int *bs_size)
309 {
310         int ret = 0;
311         unsigned int irq_status;
312
313         mtk_vcodec_debug(inst, "->frm_cnt=%d", inst->frm_cnt);
314
315         ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf, bs_size);
316         if (ret)
317                 return ret;
318
319         irq_status = vp8_enc_wait_venc_done(inst);
320         if (irq_status != MTK_VENC_IRQ_STATUS_FRM) {
321                 mtk_vcodec_err(inst, "irq_status=%d failed", irq_status);
322                 return -EIO;
323         }
324
325         if (vp8_enc_compose_one_frame(inst, bs_buf, bs_size)) {
326                 mtk_vcodec_err(inst, "vp8_enc_compose_one_frame failed");
327                 return -EINVAL;
328         }
329
330         inst->frm_cnt++;
331         mtk_vcodec_debug(inst, "<-size=%d key_frm=%d", *bs_size,
332                          inst->vpu_inst.is_key_frm);
333
334         return ret;
335 }
336
337 static int vp8_enc_init(struct mtk_vcodec_ctx *ctx, unsigned long *handle)
338 {
339         int ret = 0;
340         struct venc_vp8_inst *inst;
341
342         inst = kzalloc(sizeof(*inst), GFP_KERNEL);
343         if (!inst)
344                 return -ENOMEM;
345
346         inst->ctx = ctx;
347         inst->vpu_inst.ctx = ctx;
348         inst->vpu_inst.dev = ctx->dev->vpu_plat_dev;
349         inst->vpu_inst.id = IPI_VENC_VP8;
350         inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_LT_SYS);
351
352         mtk_vcodec_debug_enter(inst);
353
354         ret = vpu_enc_init(&inst->vpu_inst);
355
356         inst->vsi = (struct venc_vp8_vsi *)inst->vpu_inst.vsi;
357
358         mtk_vcodec_debug_leave(inst);
359
360         if (ret)
361                 kfree(inst);
362         else
363                 (*handle) = (unsigned long)inst;
364
365         return ret;
366 }
367
368 static int vp8_enc_encode(unsigned long handle,
369                           enum venc_start_opt opt,
370                           struct venc_frm_buf *frm_buf,
371                           struct mtk_vcodec_mem *bs_buf,
372                           struct venc_done_result *result)
373 {
374         int ret = 0;
375         struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle;
376         struct mtk_vcodec_ctx *ctx = inst->ctx;
377
378         mtk_vcodec_debug_enter(inst);
379
380         enable_irq(ctx->dev->enc_lt_irq);
381
382         switch (opt) {
383         case VENC_START_OPT_ENCODE_FRAME:
384                 ret = vp8_enc_encode_frame(inst, frm_buf, bs_buf,
385                                            &result->bs_size);
386                 if (ret)
387                         goto encode_err;
388                 result->is_key_frm = inst->vpu_inst.is_key_frm;
389                 break;
390
391         default:
392                 mtk_vcodec_err(inst, "opt not support:%d", opt);
393                 ret = -EINVAL;
394                 break;
395         }
396
397 encode_err:
398
399         disable_irq(ctx->dev->enc_lt_irq);
400         mtk_vcodec_debug_leave(inst);
401
402         return ret;
403 }
404
405 static int vp8_enc_set_param(unsigned long handle,
406                              enum venc_set_param_type type,
407                              struct venc_enc_param *enc_prm)
408 {
409         int ret = 0;
410         struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle;
411
412         mtk_vcodec_debug(inst, "->type=%d", type);
413
414         switch (type) {
415         case VENC_SET_PARAM_ENC:
416                 inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
417                 inst->vsi->config.bitrate = enc_prm->bitrate;
418                 inst->vsi->config.pic_w = enc_prm->width;
419                 inst->vsi->config.pic_h = enc_prm->height;
420                 inst->vsi->config.buf_w = enc_prm->buf_width;
421                 inst->vsi->config.buf_h = enc_prm->buf_height;
422                 inst->vsi->config.gop_size = enc_prm->gop_size;
423                 inst->vsi->config.framerate = enc_prm->frm_rate;
424                 inst->vsi->config.ts_mode = inst->ts_mode;
425                 ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
426                 if (ret)
427                         break;
428                 if (inst->work_buf_allocated) {
429                         vp8_enc_free_work_buf(inst);
430                         inst->work_buf_allocated = false;
431                 }
432                 ret = vp8_enc_alloc_work_buf(inst);
433                 if (ret)
434                         break;
435                 inst->work_buf_allocated = true;
436                 break;
437
438         /*
439          * VENC_SET_PARAM_TS_MODE must be called before VENC_SET_PARAM_ENC
440          */
441         case VENC_SET_PARAM_TS_MODE:
442                 inst->ts_mode = 1;
443                 mtk_vcodec_debug(inst, "set ts_mode");
444                 break;
445
446         default:
447                 ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
448                 break;
449         }
450
451         mtk_vcodec_debug_leave(inst);
452
453         return ret;
454 }
455
456 static int vp8_enc_deinit(unsigned long handle)
457 {
458         int ret = 0;
459         struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle;
460
461         mtk_vcodec_debug_enter(inst);
462
463         ret = vpu_enc_deinit(&inst->vpu_inst);
464
465         if (inst->work_buf_allocated)
466                 vp8_enc_free_work_buf(inst);
467
468         mtk_vcodec_debug_leave(inst);
469         kfree(inst);
470
471         return ret;
472 }
473
474 static struct venc_common_if venc_vp8_if = {
475         vp8_enc_init,
476         vp8_enc_encode,
477         vp8_enc_set_param,
478         vp8_enc_deinit,
479 };
480
481 struct venc_common_if *get_vp8_enc_comm_if(void);
482
483 struct venc_common_if *get_vp8_enc_comm_if(void)
484 {
485         return &venc_vp8_if;
486 }