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