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