GNU Linux-libre 4.14.294-gnu1
[releases.git] / drivers / media / platform / mtk-vcodec / vdec / vdec_vp9_if.c
1 /*
2  * Copyright (c) 2016 MediaTek Inc.
3  * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
4  *      Kai-Sean Yang <kai-sean.yang@mediatek.com>
5  *      Tiffany Lin <tiffany.lin@mediatek.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as 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/fs.h>
18 #include <linux/slab.h>
19 #include <linux/syscalls.h>
20 #include <linux/delay.h>
21 #include <linux/time.h>
22
23 #include "../mtk_vcodec_intr.h"
24 #include "../vdec_drv_base.h"
25 #include "../vdec_vpu_if.h"
26
27 #define VP9_SUPER_FRAME_BS_SZ 64
28 #define MAX_VP9_DPB_SIZE        9
29
30 #define REFS_PER_FRAME 3
31 #define MAX_NUM_REF_FRAMES 8
32 #define VP9_MAX_FRM_BUF_NUM 9
33 #define VP9_MAX_FRM_BUF_NODE_NUM (VP9_MAX_FRM_BUF_NUM * 2)
34 #define VP9_SEG_ID_SZ 0x12000
35
36 /**
37  * struct vp9_dram_buf - contains buffer info for vpu
38  * @va : cpu address
39  * @pa : iova address
40  * @sz : buffer size
41  * @padding : for 64 bytes alignment
42  */
43 struct vp9_dram_buf {
44         unsigned long va;
45         unsigned long pa;
46         unsigned int sz;
47         unsigned int padding;
48 };
49
50 /**
51  * struct vp9_fb_info - contains frame buffer info
52  * @fb : frmae buffer
53  * @reserved : reserved field used by vpu
54  */
55 struct vp9_fb_info {
56         struct vdec_fb *fb;
57         unsigned int reserved[32];
58 };
59
60 /**
61  * struct vp9_ref_cnt_buf - contains reference buffer information
62  * @buf : referenced frame buffer
63  * @ref_cnt : referenced frame buffer's reference count.
64  *      When reference count=0, remove it from reference list
65  */
66 struct vp9_ref_cnt_buf {
67         struct vp9_fb_info buf;
68         unsigned int ref_cnt;
69 };
70
71 /**
72  * struct vp9_fb_info - contains current frame's reference buffer information
73  * @buf : reference buffer
74  * @idx : reference buffer index to frm_bufs
75  * @reserved : reserved field used by vpu
76  */
77 struct vp9_ref_buf {
78         struct vp9_fb_info *buf;
79         unsigned int idx;
80         unsigned int reserved[6];
81 };
82
83 /**
84  * struct vp9_fb_info - contains frame buffer info
85  * @fb : super frame reference frame buffer
86  * @used : this reference frame info entry is used
87  * @padding : for 64 bytes size align
88  */
89 struct vp9_sf_ref_fb {
90         struct vdec_fb fb;
91         int used;
92         int padding;
93 };
94
95 /*
96  * struct vdec_vp9_vsi - shared buffer between host and VPU firmware
97  *      AP-W/R : AP is writer/reader on this item
98  *      VPU-W/R: VPU is write/reader on this item
99  * @sf_bs_buf : super frame backup buffer (AP-W, VPU-R)
100  * @sf_ref_fb : record supoer frame reference buffer information
101  *      (AP-R/W, VPU-R/W)
102  * @sf_next_ref_fb_idx : next available super frame (AP-W, VPU-R)
103  * @sf_frm_cnt : super frame count, filled by vpu (AP-R, VPU-W)
104  * @sf_frm_offset : super frame offset, filled by vpu (AP-R, VPU-W)
105  * @sf_frm_sz : super frame size, filled by vpu (AP-R, VPU-W)
106  * @sf_frm_idx : current super frame (AP-R, VPU-W)
107  * @sf_init : inform super frame info already parsed by vpu (AP-R, VPU-W)
108  * @fb : capture buffer (AP-W, VPU-R)
109  * @bs : bs buffer (AP-W, VPU-R)
110  * @cur_fb : current show capture buffer (AP-R/W, VPU-R/W)
111  * @pic_w : picture width (AP-R, VPU-W)
112  * @pic_h : picture height (AP-R, VPU-W)
113  * @buf_w : codec width (AP-R, VPU-W)
114  * @buf_h : coded height (AP-R, VPU-W)
115  * @buf_sz_y_bs : ufo compressed y plane size (AP-R, VPU-W)
116  * @buf_sz_c_bs : ufo compressed cbcr plane size (AP-R, VPU-W)
117  * @buf_len_sz_y : size used to store y plane ufo info (AP-R, VPU-W)
118  * @buf_len_sz_c : size used to store cbcr plane ufo info (AP-R, VPU-W)
119
120  * @profile : profile sparsed from vpu (AP-R, VPU-W)
121  * @show_frame : display this frame or not (AP-R, VPU-W)
122  * @show_existing_frame : inform this frame is show existing frame
123  *      (AP-R, VPU-W)
124  * @frm_to_show_idx : index to show frame (AP-R, VPU-W)
125
126  * @refresh_frm_flags : indicate when frame need to refine reference count
127  *      (AP-R, VPU-W)
128  * @resolution_changed : resolution change in this frame (AP-R, VPU-W)
129
130  * @frm_bufs : maintain reference buffer info (AP-R/W, VPU-R/W)
131  * @ref_frm_map : maintain reference buffer map info (AP-R/W, VPU-R/W)
132  * @new_fb_idx : index to frm_bufs array (AP-R, VPU-W)
133  * @frm_num : decoded frame number, include sub-frame count (AP-R, VPU-W)
134  * @mv_buf : motion vector working buffer (AP-W, VPU-R)
135  * @frm_refs : maintain three reference buffer info (AP-R/W, VPU-R/W)
136  * @seg_id_buf : segmentation map working buffer (AP-W, VPU-R)
137  */
138 struct vdec_vp9_vsi {
139         unsigned char sf_bs_buf[VP9_SUPER_FRAME_BS_SZ];
140         struct vp9_sf_ref_fb sf_ref_fb[VP9_MAX_FRM_BUF_NUM-1];
141         int sf_next_ref_fb_idx;
142         unsigned int sf_frm_cnt;
143         unsigned int sf_frm_offset[VP9_MAX_FRM_BUF_NUM-1];
144         unsigned int sf_frm_sz[VP9_MAX_FRM_BUF_NUM-1];
145         unsigned int sf_frm_idx;
146         unsigned int sf_init;
147         struct vdec_fb fb;
148         struct mtk_vcodec_mem bs;
149         struct vdec_fb cur_fb;
150         unsigned int pic_w;
151         unsigned int pic_h;
152         unsigned int buf_w;
153         unsigned int buf_h;
154         unsigned int buf_sz_y_bs;
155         unsigned int buf_sz_c_bs;
156         unsigned int buf_len_sz_y;
157         unsigned int buf_len_sz_c;
158         unsigned int profile;
159         unsigned int show_frame;
160         unsigned int show_existing_frame;
161         unsigned int frm_to_show_idx;
162         unsigned int refresh_frm_flags;
163         unsigned int resolution_changed;
164
165         struct vp9_ref_cnt_buf frm_bufs[VP9_MAX_FRM_BUF_NUM];
166         int ref_frm_map[MAX_NUM_REF_FRAMES];
167         unsigned int new_fb_idx;
168         unsigned int frm_num;
169         struct vp9_dram_buf mv_buf;
170
171         struct vp9_ref_buf frm_refs[REFS_PER_FRAME];
172         struct vp9_dram_buf seg_id_buf;
173
174 };
175
176 /*
177  * struct vdec_vp9_inst - vp9 decode instance
178  * @mv_buf : working buffer for mv
179  * @seg_id_buf : working buffer for segmentation map
180  * @dec_fb : vdec_fb node to link fb to different fb_xxx_list
181  * @available_fb_node_list : current available vdec_fb node
182  * @fb_use_list : current used or referenced vdec_fb
183  * @fb_free_list : current available to free vdec_fb
184  * @fb_disp_list : current available to display vdec_fb
185  * @cur_fb : current frame buffer
186  * @ctx : current decode context
187  * @vpu : vpu instance information
188  * @vsi : shared buffer between host and VPU firmware
189  * @total_frm_cnt : total frame count, it do not include sub-frames in super
190  *          frame
191  * @mem : instance memory information
192  */
193 struct vdec_vp9_inst {
194         struct mtk_vcodec_mem mv_buf;
195         struct mtk_vcodec_mem seg_id_buf;
196
197         struct vdec_fb_node dec_fb[VP9_MAX_FRM_BUF_NODE_NUM];
198         struct list_head available_fb_node_list;
199         struct list_head fb_use_list;
200         struct list_head fb_free_list;
201         struct list_head fb_disp_list;
202         struct vdec_fb *cur_fb;
203         struct mtk_vcodec_ctx *ctx;
204         struct vdec_vpu_inst vpu;
205         struct vdec_vp9_vsi *vsi;
206         unsigned int total_frm_cnt;
207         struct mtk_vcodec_mem mem;
208 };
209
210 static bool vp9_is_sf_ref_fb(struct vdec_vp9_inst *inst, struct vdec_fb *fb)
211 {
212         int i;
213         struct vdec_vp9_vsi *vsi = inst->vsi;
214
215         for (i = 0; i < ARRAY_SIZE(vsi->sf_ref_fb); i++) {
216                 if (fb == &vsi->sf_ref_fb[i].fb)
217                         return true;
218         }
219         return false;
220 }
221
222 static struct vdec_fb *vp9_rm_from_fb_use_list(struct vdec_vp9_inst
223                                         *inst, void *addr)
224 {
225         struct vdec_fb *fb = NULL;
226         struct vdec_fb_node *node;
227
228         list_for_each_entry(node, &inst->fb_use_list, list) {
229                 fb = (struct vdec_fb *)node->fb;
230                 if (fb->base_y.va == addr) {
231                         list_move_tail(&node->list,
232                                        &inst->available_fb_node_list);
233                         break;
234                 }
235         }
236         return fb;
237 }
238
239 static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst,
240                              struct vdec_fb *fb)
241 {
242         struct vdec_fb_node *node;
243
244         if (fb) {
245                 node = list_first_entry_or_null(&inst->available_fb_node_list,
246                                         struct vdec_fb_node, list);
247
248                 if (node) {
249                         node->fb = fb;
250                         list_move_tail(&node->list, &inst->fb_free_list);
251                 }
252         } else {
253                 mtk_vcodec_debug(inst, "No free fb node");
254         }
255 }
256
257 static void vp9_free_sf_ref_fb(struct vdec_fb *fb)
258 {
259         struct vp9_sf_ref_fb *sf_ref_fb =
260                 container_of(fb, struct vp9_sf_ref_fb, fb);
261
262         sf_ref_fb->used = 0;
263 }
264
265 static void vp9_ref_cnt_fb(struct vdec_vp9_inst *inst, int *idx,
266                            int new_idx)
267 {
268         struct vdec_vp9_vsi *vsi = inst->vsi;
269         int ref_idx = *idx;
270
271         if (ref_idx >= 0 && vsi->frm_bufs[ref_idx].ref_cnt > 0) {
272                 vsi->frm_bufs[ref_idx].ref_cnt--;
273
274                 if (vsi->frm_bufs[ref_idx].ref_cnt == 0) {
275                         if (!vp9_is_sf_ref_fb(inst,
276                                               vsi->frm_bufs[ref_idx].buf.fb)) {
277                                 struct vdec_fb *fb;
278
279                                 fb = vp9_rm_from_fb_use_list(inst,
280                                      vsi->frm_bufs[ref_idx].buf.fb->base_y.va);
281                                 vp9_add_to_fb_free_list(inst, fb);
282                         } else
283                                 vp9_free_sf_ref_fb(
284                                         vsi->frm_bufs[ref_idx].buf.fb);
285                 }
286         }
287
288         *idx = new_idx;
289         vsi->frm_bufs[new_idx].ref_cnt++;
290 }
291
292 static void vp9_free_all_sf_ref_fb(struct vdec_vp9_inst *inst)
293 {
294         int i;
295         struct vdec_vp9_vsi *vsi = inst->vsi;
296
297         for (i = 0; i < ARRAY_SIZE(vsi->sf_ref_fb); i++) {
298                 if (vsi->sf_ref_fb[i].fb.base_y.va) {
299                         mtk_vcodec_mem_free(inst->ctx,
300                                 &vsi->sf_ref_fb[i].fb.base_y);
301                         mtk_vcodec_mem_free(inst->ctx,
302                                 &vsi->sf_ref_fb[i].fb.base_c);
303                         vsi->sf_ref_fb[i].used = 0;
304                 }
305         }
306 }
307
308 /* For each sub-frame except the last one, the driver will dynamically
309  * allocate reference buffer by calling vp9_get_sf_ref_fb()
310  * The last sub-frame will use the original fb provided by the
311  * vp9_dec_decode() interface
312  */
313 static int vp9_get_sf_ref_fb(struct vdec_vp9_inst *inst)
314 {
315         int idx;
316         struct mtk_vcodec_mem *mem_basy_y;
317         struct mtk_vcodec_mem *mem_basy_c;
318         struct vdec_vp9_vsi *vsi = inst->vsi;
319
320         for (idx = 0;
321                 idx < ARRAY_SIZE(vsi->sf_ref_fb);
322                 idx++) {
323                 if (vsi->sf_ref_fb[idx].fb.base_y.va &&
324                     vsi->sf_ref_fb[idx].used == 0) {
325                         return idx;
326                 }
327         }
328
329         for (idx = 0;
330                 idx < ARRAY_SIZE(vsi->sf_ref_fb);
331                 idx++) {
332                 if (vsi->sf_ref_fb[idx].fb.base_y.va == NULL)
333                         break;
334         }
335
336         if (idx == ARRAY_SIZE(vsi->sf_ref_fb)) {
337                 mtk_vcodec_err(inst, "List Full");
338                 return -1;
339         }
340
341         mem_basy_y = &vsi->sf_ref_fb[idx].fb.base_y;
342         mem_basy_y->size = vsi->buf_sz_y_bs +
343                 vsi->buf_len_sz_y;
344
345         if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_y)) {
346                 mtk_vcodec_err(inst, "Cannot allocate sf_ref_buf y_buf");
347                 return -1;
348         }
349
350         mem_basy_c = &vsi->sf_ref_fb[idx].fb.base_c;
351         mem_basy_c->size = vsi->buf_sz_c_bs +
352                 vsi->buf_len_sz_c;
353
354         if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_c)) {
355                 mtk_vcodec_err(inst, "Cannot allocate sf_ref_fb c_buf");
356                 return -1;
357         }
358         vsi->sf_ref_fb[idx].used = 0;
359
360         return idx;
361 }
362
363 static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst)
364 {
365         struct vdec_vp9_vsi *vsi = inst->vsi;
366         int result;
367         struct mtk_vcodec_mem *mem;
368
369         unsigned int max_pic_w;
370         unsigned int max_pic_h;
371
372
373         if (!(inst->ctx->dev->dec_capability &
374                 VCODEC_CAPABILITY_4K_DISABLED)) {
375                 max_pic_w = VCODEC_DEC_4K_CODED_WIDTH;
376                 max_pic_h = VCODEC_DEC_4K_CODED_HEIGHT;
377         } else {
378                 max_pic_w = MTK_VDEC_MAX_W;
379                 max_pic_h = MTK_VDEC_MAX_H;
380         }
381
382         if ((vsi->pic_w > max_pic_w) ||
383                 (vsi->pic_h > max_pic_h)) {
384                 mtk_vcodec_err(inst, "Invalid w/h %d/%d",
385                                 vsi->pic_w, vsi->pic_h);
386                 return false;
387         }
388
389         mtk_vcodec_debug(inst, "BUF CHG(%d): w/h/sb_w/sb_h=%d/%d/%d/%d",
390                         vsi->resolution_changed,
391                         vsi->pic_w,
392                         vsi->pic_h,
393                         vsi->buf_w,
394                         vsi->buf_h);
395
396         mem = &inst->mv_buf;
397         if (mem->va)
398                 mtk_vcodec_mem_free(inst->ctx, mem);
399
400         mem->size = ((vsi->buf_w / 64) *
401                     (vsi->buf_h / 64) + 2) * 36 * 16;
402         result = mtk_vcodec_mem_alloc(inst->ctx, mem);
403         if (result) {
404                 mem->size = 0;
405                 mtk_vcodec_err(inst, "Cannot allocate mv_buf");
406                 return false;
407         }
408         /* Set the va again */
409         vsi->mv_buf.va = (unsigned long)mem->va;
410         vsi->mv_buf.pa = (unsigned long)mem->dma_addr;
411         vsi->mv_buf.sz = (unsigned int)mem->size;
412
413
414         mem = &inst->seg_id_buf;
415         if (mem->va)
416                 mtk_vcodec_mem_free(inst->ctx, mem);
417
418         mem->size = VP9_SEG_ID_SZ;
419         result = mtk_vcodec_mem_alloc(inst->ctx, mem);
420         if (result) {
421                 mem->size = 0;
422                 mtk_vcodec_err(inst, "Cannot allocate seg_id_buf");
423                 return false;
424         }
425         /* Set the va again */
426         vsi->seg_id_buf.va = (unsigned long)mem->va;
427         vsi->seg_id_buf.pa = (unsigned long)mem->dma_addr;
428         vsi->seg_id_buf.sz = (unsigned int)mem->size;
429
430
431         vp9_free_all_sf_ref_fb(inst);
432         vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
433
434         return true;
435 }
436
437 static bool vp9_add_to_fb_disp_list(struct vdec_vp9_inst *inst,
438                              struct vdec_fb *fb)
439 {
440         struct vdec_fb_node *node;
441
442         if (!fb) {
443                 mtk_vcodec_err(inst, "fb == NULL");
444                 return false;
445         }
446
447         node = list_first_entry_or_null(&inst->available_fb_node_list,
448                                         struct vdec_fb_node, list);
449         if (node) {
450                 node->fb = fb;
451                 list_move_tail(&node->list, &inst->fb_disp_list);
452         } else {
453                 mtk_vcodec_err(inst, "No available fb node");
454                 return false;
455         }
456
457         return true;
458 }
459
460 /* If any buffer updating is signaled it should be done here. */
461 static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst)
462 {
463         struct vdec_vp9_vsi *vsi = inst->vsi;
464         struct vp9_fb_info *frm_to_show;
465         int ref_index = 0, mask;
466
467         for (mask = vsi->refresh_frm_flags; mask; mask >>= 1) {
468                 if (mask & 1)
469                         vp9_ref_cnt_fb(inst, &vsi->ref_frm_map[ref_index],
470                                        vsi->new_fb_idx);
471                 ++ref_index;
472         }
473
474         frm_to_show = &vsi->frm_bufs[vsi->new_fb_idx].buf;
475         vsi->frm_bufs[vsi->new_fb_idx].ref_cnt--;
476
477         if (frm_to_show->fb != inst->cur_fb) {
478                 /* This frame is show exist frame and no decode output
479                  * copy frame data from frm_to_show to current CAPTURE
480                  * buffer
481                  */
482                 if ((frm_to_show->fb != NULL) &&
483                         (inst->cur_fb->base_y.size >=
484                         frm_to_show->fb->base_y.size)) {
485                         memcpy((void *)inst->cur_fb->base_y.va,
486                                 (void *)frm_to_show->fb->base_y.va,
487                                 vsi->buf_w *
488                                 vsi->buf_h);
489                         memcpy((void *)inst->cur_fb->base_c.va,
490                                 (void *)frm_to_show->fb->base_c.va,
491                                 vsi->buf_w *
492                                 vsi->buf_h / 2);
493                 } else {
494                         /* After resolution change case, current CAPTURE buffer
495                          * may have less buffer size than frm_to_show buffer
496                          * size
497                          */
498                         if (frm_to_show->fb != NULL)
499                                 mtk_vcodec_err(inst,
500                                         "inst->cur_fb->base_y.size=%zu, frm_to_show->fb.base_y.size=%zu",
501                                         inst->cur_fb->base_y.size,
502                                         frm_to_show->fb->base_y.size);
503                 }
504                 if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {
505                         if (vsi->show_frame)
506                                 vp9_add_to_fb_disp_list(inst, inst->cur_fb);
507                 }
508         } else {
509                 if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {
510                         if (vsi->show_frame)
511                                 vp9_add_to_fb_disp_list(inst, frm_to_show->fb);
512                 }
513         }
514
515         /* when ref_cnt ==0, move this fb to fb_free_list. v4l2 driver will
516          * clean fb_free_list
517          */
518         if (vsi->frm_bufs[vsi->new_fb_idx].ref_cnt == 0) {
519                 if (!vp9_is_sf_ref_fb(
520                         inst, vsi->frm_bufs[vsi->new_fb_idx].buf.fb)) {
521                         struct vdec_fb *fb;
522
523                         fb = vp9_rm_from_fb_use_list(inst,
524                         vsi->frm_bufs[vsi->new_fb_idx].buf.fb->base_y.va);
525
526                         vp9_add_to_fb_free_list(inst, fb);
527                 } else {
528                         vp9_free_sf_ref_fb(
529                                 vsi->frm_bufs[vsi->new_fb_idx].buf.fb);
530                 }
531         }
532
533         /* if this super frame and it is not last sub-frame, get next fb for
534          * sub-frame decode
535          */
536         if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt - 1)
537                 vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
538 }
539
540 static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst)
541 {
542         struct mtk_vcodec_ctx *ctx = inst->ctx;
543
544         mtk_vcodec_wait_for_done_ctx(inst->ctx,
545                         MTK_INST_IRQ_RECEIVED,
546                         WAIT_INTR_TIMEOUT_MS);
547
548         if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
549                 return true;
550         else
551                 return false;
552 }
553
554 static struct vdec_vp9_inst *vp9_alloc_inst(struct mtk_vcodec_ctx *ctx)
555 {
556         int result;
557         struct mtk_vcodec_mem mem;
558         struct vdec_vp9_inst *inst;
559
560         memset(&mem, 0, sizeof(mem));
561         mem.size = sizeof(struct vdec_vp9_inst);
562         result = mtk_vcodec_mem_alloc(ctx, &mem);
563         if (result)
564                 return NULL;
565
566         inst = mem.va;
567         inst->mem = mem;
568
569         return inst;
570 }
571
572 static void vp9_free_inst(struct vdec_vp9_inst *inst)
573 {
574         struct mtk_vcodec_mem mem;
575
576         mem = inst->mem;
577         if (mem.va)
578                 mtk_vcodec_mem_free(inst->ctx, &mem);
579 }
580
581 static bool vp9_decode_end_proc(struct vdec_vp9_inst *inst)
582 {
583         struct vdec_vp9_vsi *vsi = inst->vsi;
584         bool ret = false;
585
586         if (!vsi->show_existing_frame) {
587                 ret = vp9_wait_dec_end(inst);
588                 if (!ret) {
589                         mtk_vcodec_err(inst, "Decode failed, Decode Timeout @[%d]",
590                                 vsi->frm_num);
591                         return false;
592                 }
593
594                 if (vpu_dec_end(&inst->vpu)) {
595                         mtk_vcodec_err(inst, "vp9_dec_vpu_end failed");
596                         return false;
597                 }
598                 mtk_vcodec_debug(inst, "Decode Ok @%d (%d/%d)", vsi->frm_num,
599                                 vsi->pic_w, vsi->pic_h);
600         } else {
601                 mtk_vcodec_debug(inst, "Decode Ok @%d (show_existing_frame)",
602                                 vsi->frm_num);
603         }
604
605         vp9_swap_frm_bufs(inst);
606         vsi->frm_num++;
607         return true;
608 }
609
610 static bool vp9_is_last_sub_frm(struct vdec_vp9_inst *inst)
611 {
612         struct vdec_vp9_vsi *vsi = inst->vsi;
613
614         if (vsi->sf_frm_cnt <= 0 || vsi->sf_frm_idx == vsi->sf_frm_cnt)
615                 return true;
616
617         return false;
618 }
619
620 static struct vdec_fb *vp9_rm_from_fb_disp_list(struct vdec_vp9_inst *inst)
621 {
622         struct vdec_fb_node *node;
623         struct vdec_fb *fb = NULL;
624
625         node = list_first_entry_or_null(&inst->fb_disp_list,
626                                         struct vdec_fb_node, list);
627         if (node) {
628                 fb = (struct vdec_fb *)node->fb;
629                 fb->status |= FB_ST_DISPLAY;
630                 list_move_tail(&node->list, &inst->available_fb_node_list);
631                 mtk_vcodec_debug(inst, "[FB] get disp fb %p st=%d",
632                                  node->fb, fb->status);
633         } else
634                 mtk_vcodec_debug(inst, "[FB] there is no disp fb");
635
636         return fb;
637 }
638
639 static bool vp9_add_to_fb_use_list(struct vdec_vp9_inst *inst,
640                             struct vdec_fb *fb)
641 {
642         struct vdec_fb_node *node;
643
644         if (!fb) {
645                 mtk_vcodec_debug(inst, "fb == NULL");
646                 return false;
647         }
648
649         node = list_first_entry_or_null(&inst->available_fb_node_list,
650                                         struct vdec_fb_node, list);
651         if (node) {
652                 node->fb = fb;
653                 list_move_tail(&node->list, &inst->fb_use_list);
654         } else {
655                 mtk_vcodec_err(inst, "No free fb node");
656                 return false;
657         }
658         return true;
659 }
660
661 static void vp9_reset(struct vdec_vp9_inst *inst)
662 {
663         struct vdec_fb_node *node, *tmp;
664
665         list_for_each_entry_safe(node, tmp, &inst->fb_use_list, list)
666                 list_move_tail(&node->list, &inst->fb_free_list);
667
668         vp9_free_all_sf_ref_fb(inst);
669         inst->vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
670
671         if (vpu_dec_reset(&inst->vpu))
672                 mtk_vcodec_err(inst, "vp9_dec_vpu_reset failed");
673
674         /* Set the va again, since vpu_dec_reset will clear mv_buf in vpu */
675         inst->vsi->mv_buf.va = (unsigned long)inst->mv_buf.va;
676         inst->vsi->mv_buf.pa = (unsigned long)inst->mv_buf.dma_addr;
677         inst->vsi->mv_buf.sz = (unsigned long)inst->mv_buf.size;
678
679         /* Set the va again, since vpu_dec_reset will clear seg_id_buf in vpu */
680         inst->vsi->seg_id_buf.va = (unsigned long)inst->seg_id_buf.va;
681         inst->vsi->seg_id_buf.pa = (unsigned long)inst->seg_id_buf.dma_addr;
682         inst->vsi->seg_id_buf.sz = (unsigned long)inst->seg_id_buf.size;
683
684 }
685
686 static void init_all_fb_lists(struct vdec_vp9_inst *inst)
687 {
688         int i;
689
690         INIT_LIST_HEAD(&inst->available_fb_node_list);
691         INIT_LIST_HEAD(&inst->fb_use_list);
692         INIT_LIST_HEAD(&inst->fb_free_list);
693         INIT_LIST_HEAD(&inst->fb_disp_list);
694
695         for (i = 0; i < ARRAY_SIZE(inst->dec_fb); i++) {
696                 INIT_LIST_HEAD(&inst->dec_fb[i].list);
697                 inst->dec_fb[i].fb = NULL;
698                 list_add_tail(&inst->dec_fb[i].list,
699                               &inst->available_fb_node_list);
700         }
701 }
702
703 static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic)
704 {
705         pic->y_bs_sz = inst->vsi->buf_sz_y_bs;
706         pic->c_bs_sz = inst->vsi->buf_sz_c_bs;
707         pic->y_len_sz = inst->vsi->buf_len_sz_y;
708         pic->c_len_sz = inst->vsi->buf_len_sz_c;
709
710         pic->pic_w = inst->vsi->pic_w;
711         pic->pic_h = inst->vsi->pic_h;
712         pic->buf_w = inst->vsi->buf_w;
713         pic->buf_h = inst->vsi->buf_h;
714
715         mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
716                  pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
717         mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz,
718                  pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
719 }
720
721 static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
722 {
723
724         *out_fb = vp9_rm_from_fb_disp_list(inst);
725         if (*out_fb)
726                 (*out_fb)->status |= FB_ST_DISPLAY;
727 }
728
729 static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
730 {
731         struct vdec_fb_node *node;
732         struct vdec_fb *fb = NULL;
733
734         node = list_first_entry_or_null(&inst->fb_free_list,
735                                         struct vdec_fb_node, list);
736         if (node) {
737                 list_move_tail(&node->list, &inst->available_fb_node_list);
738                 fb = (struct vdec_fb *)node->fb;
739                 fb->status |= FB_ST_FREE;
740                 mtk_vcodec_debug(inst, "[FB] get free fb %p st=%d",
741                                  node->fb, fb->status);
742         } else {
743                 mtk_vcodec_debug(inst, "[FB] there is no free fb");
744         }
745
746         *out_fb = fb;
747 }
748
749 static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst,
750                 struct vdec_vp9_vsi *vsi) {
751         if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM - 1) {
752                 mtk_vcodec_err(inst, "Invalid vsi->sf_frm_idx=%u.",
753                                 vsi->sf_frm_idx);
754                 return -EIO;
755         }
756         if (vsi->frm_to_show_idx >= VP9_MAX_FRM_BUF_NUM) {
757                 mtk_vcodec_err(inst, "Invalid vsi->frm_to_show_idx=%u.",
758                                 vsi->frm_to_show_idx);
759                 return -EIO;
760         }
761         if (vsi->new_fb_idx >= VP9_MAX_FRM_BUF_NUM) {
762                 mtk_vcodec_err(inst, "Invalid vsi->new_fb_idx=%u.",
763                                 vsi->new_fb_idx);
764                 return -EIO;
765         }
766         return 0;
767 }
768
769 static void vdec_vp9_deinit(unsigned long h_vdec)
770 {
771         struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
772         struct mtk_vcodec_mem *mem;
773         int ret = 0;
774
775         ret = vpu_dec_deinit(&inst->vpu);
776         if (ret)
777                 mtk_vcodec_err(inst, "vpu_dec_deinit failed");
778
779         mem = &inst->mv_buf;
780         if (mem->va)
781                 mtk_vcodec_mem_free(inst->ctx, mem);
782
783         mem = &inst->seg_id_buf;
784         if (mem->va)
785                 mtk_vcodec_mem_free(inst->ctx, mem);
786
787         vp9_free_all_sf_ref_fb(inst);
788         vp9_free_inst(inst);
789 }
790
791 static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec)
792 {
793         struct vdec_vp9_inst *inst;
794
795         inst = vp9_alloc_inst(ctx);
796         if (!inst)
797                 return -ENOMEM;
798
799         inst->total_frm_cnt = 0;
800         inst->ctx = ctx;
801
802         inst->vpu.id = IPI_VDEC_VP9;
803         inst->vpu.dev = ctx->dev->vpu_plat_dev;
804         inst->vpu.ctx = ctx;
805         inst->vpu.handler = vpu_dec_ipi_handler;
806
807         if (vpu_dec_init(&inst->vpu)) {
808                 mtk_vcodec_err(inst, "vp9_dec_vpu_init failed");
809                 goto err_deinit_inst;
810         }
811
812         inst->vsi = (struct vdec_vp9_vsi *)inst->vpu.vsi;
813         init_all_fb_lists(inst);
814
815         (*h_vdec) = (unsigned long)inst;
816         return 0;
817
818 err_deinit_inst:
819         vp9_free_inst(inst);
820
821         return -EINVAL;
822 }
823
824 static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs,
825                    struct vdec_fb *fb, bool *res_chg)
826 {
827         int ret = 0;
828         struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
829         struct vdec_vp9_vsi *vsi = inst->vsi;
830         u32 data[3];
831         int i;
832
833         *res_chg = false;
834
835         if ((bs == NULL) && (fb == NULL)) {
836                 mtk_vcodec_debug(inst, "[EOS]");
837                 vp9_reset(inst);
838                 return ret;
839         }
840
841         if (bs == NULL) {
842                 mtk_vcodec_err(inst, "bs == NULL");
843                 return -EINVAL;
844         }
845
846         mtk_vcodec_debug(inst, "Input BS Size = %zu", bs->size);
847
848         while (1) {
849                 struct vdec_fb *cur_fb = NULL;
850
851                 data[0] = *((unsigned int *)bs->va);
852                 data[1] = *((unsigned int *)(bs->va + 4));
853                 data[2] = *((unsigned int *)(bs->va + 8));
854
855                 vsi->bs = *bs;
856
857                 if (fb)
858                         vsi->fb = *fb;
859
860                 if (!vsi->sf_init) {
861                         unsigned int sf_bs_sz;
862                         unsigned int sf_bs_off;
863                         unsigned char *sf_bs_src;
864                         unsigned char *sf_bs_dst;
865
866                         sf_bs_sz = bs->size > VP9_SUPER_FRAME_BS_SZ ?
867                                         VP9_SUPER_FRAME_BS_SZ : bs->size;
868                         sf_bs_off = VP9_SUPER_FRAME_BS_SZ - sf_bs_sz;
869                         sf_bs_src = bs->va + bs->size - sf_bs_sz;
870                         sf_bs_dst = vsi->sf_bs_buf + sf_bs_off;
871                         memcpy(sf_bs_dst, sf_bs_src, sf_bs_sz);
872                 } else {
873                         if ((vsi->sf_frm_cnt > 0) &&
874                                 (vsi->sf_frm_idx < vsi->sf_frm_cnt)) {
875                                 unsigned int idx = vsi->sf_frm_idx;
876
877                                 memcpy((void *)bs->va,
878                                         (void *)(bs->va +
879                                         vsi->sf_frm_offset[idx]),
880                                         vsi->sf_frm_sz[idx]);
881                         }
882                 }
883                 memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size);
884                 ret = vpu_dec_start(&inst->vpu, data, 3);
885                 if (ret) {
886                         mtk_vcodec_err(inst, "vpu_dec_start failed");
887                         goto DECODE_ERROR;
888                 }
889
890                 ret = validate_vsi_array_indexes(inst, vsi);
891                 if (ret) {
892                         mtk_vcodec_err(inst, "Invalid values from VPU.");
893                         goto DECODE_ERROR;
894                 }
895
896                 if (vsi->resolution_changed) {
897                         if (!vp9_alloc_work_buf(inst)) {
898                                 ret = -EINVAL;
899                                 goto DECODE_ERROR;
900                         }
901                 }
902
903                 if (vsi->sf_frm_cnt > 0) {
904                         cur_fb = &vsi->sf_ref_fb[vsi->sf_next_ref_fb_idx].fb;
905
906                         if (vsi->sf_frm_idx < vsi->sf_frm_cnt)
907                                 inst->cur_fb = cur_fb;
908                         else
909                                 inst->cur_fb = fb;
910                 } else {
911                         inst->cur_fb = fb;
912                 }
913
914                 vsi->frm_bufs[vsi->new_fb_idx].buf.fb = inst->cur_fb;
915                 if (!vp9_is_sf_ref_fb(inst, inst->cur_fb))
916                         vp9_add_to_fb_use_list(inst, inst->cur_fb);
917
918                 mtk_vcodec_debug(inst, "[#pic %d]", vsi->frm_num);
919
920                 if (vsi->show_existing_frame)
921                         mtk_vcodec_debug(inst,
922                                 "drv->new_fb_idx=%d, drv->frm_to_show_idx=%d",
923                                 vsi->new_fb_idx, vsi->frm_to_show_idx);
924
925                 if (vsi->show_existing_frame && (vsi->frm_to_show_idx <
926                                         VP9_MAX_FRM_BUF_NUM)) {
927                         mtk_vcodec_err(inst,
928                                 "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d",
929                                 vsi->new_fb_idx, vsi->frm_to_show_idx);
930
931                         vp9_ref_cnt_fb(inst, &vsi->new_fb_idx,
932                                         vsi->frm_to_show_idx);
933                         ret = -EINVAL;
934                         goto DECODE_ERROR;
935                 }
936
937                 /* VPU assign the buffer pointer in its address space,
938                  * reassign here
939                  */
940                 for (i = 0; i < ARRAY_SIZE(vsi->frm_refs); i++) {
941                         unsigned int idx = vsi->frm_refs[i].idx;
942
943                         vsi->frm_refs[i].buf = &vsi->frm_bufs[idx].buf;
944                 }
945
946                 if (vsi->resolution_changed) {
947                         *res_chg = true;
948                         mtk_vcodec_debug(inst, "VDEC_ST_RESOLUTION_CHANGED");
949
950                         ret = 0;
951                         goto DECODE_ERROR;
952                 }
953
954                 if (vp9_decode_end_proc(inst) != true) {
955                         mtk_vcodec_err(inst, "vp9_decode_end_proc");
956                         ret = -EINVAL;
957                         goto DECODE_ERROR;
958                 }
959
960                 if (vp9_is_last_sub_frm(inst))
961                         break;
962
963         }
964         inst->total_frm_cnt++;
965
966 DECODE_ERROR:
967         if (ret < 0)
968                 vp9_add_to_fb_free_list(inst, fb);
969
970         return ret;
971 }
972
973 static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr)
974 {
975         cr->left = 0;
976         cr->top = 0;
977         cr->width = inst->vsi->pic_w;
978         cr->height = inst->vsi->pic_h;
979         mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d\n",
980                          cr->left, cr->top, cr->width, cr->height);
981 }
982
983 static int vdec_vp9_get_param(unsigned long h_vdec,
984                 enum vdec_get_param_type type, void *out)
985 {
986         struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
987         int ret = 0;
988
989         switch (type) {
990         case GET_PARAM_DISP_FRAME_BUFFER:
991                 get_disp_fb(inst, out);
992                 break;
993         case GET_PARAM_FREE_FRAME_BUFFER:
994                 get_free_fb(inst, out);
995                 break;
996         case GET_PARAM_PIC_INFO:
997                 get_pic_info(inst, out);
998                 break;
999         case GET_PARAM_DPB_SIZE:
1000                 *((unsigned int *)out) = MAX_VP9_DPB_SIZE;
1001                 break;
1002         case GET_PARAM_CROP_INFO:
1003                 get_crop_info(inst, out);
1004                 break;
1005         default:
1006                 mtk_vcodec_err(inst, "not supported param type %d", type);
1007                 ret = -EINVAL;
1008                 break;
1009         }
1010
1011         return ret;
1012 }
1013
1014 static struct vdec_common_if vdec_vp9_if = {
1015         .init           = vdec_vp9_init,
1016         .decode         = vdec_vp9_decode,
1017         .get_param      = vdec_vp9_get_param,
1018         .deinit         = vdec_vp9_deinit,
1019 };
1020
1021 struct vdec_common_if *get_vp9_dec_comm_if(void);
1022
1023 struct vdec_common_if *get_vp9_dec_comm_if(void)
1024 {
1025         return &vdec_vp9_if;
1026 }