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