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