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