vdec_vp9_if.c (26266B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2016 MediaTek Inc. 4 * Author: Daniel Hsiao <daniel.hsiao@mediatek.com> 5 * Kai-Sean Yang <kai-sean.yang@mediatek.com> 6 * Tiffany Lin <tiffany.lin@mediatek.com> 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 * struct vp9_dram_buf - contains buffer info for vpu 30 * @va : cpu address 31 * @pa : iova address 32 * @sz : buffer size 33 * @padding : for 64 bytes alignment 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 * struct vp9_fb_info - contains frame buffer info 44 * @fb : frmae buffer 45 * @reserved : reserved field used by vpu 46 */ 47struct vp9_fb_info { 48 struct vdec_fb *fb; 49 unsigned int reserved[32]; 50}; 51 52/** 53 * struct vp9_ref_cnt_buf - contains reference buffer information 54 * @buf : referenced frame buffer 55 * @ref_cnt : referenced frame buffer's reference count. 56 * When reference count=0, remove it from reference list 57 */ 58struct vp9_ref_cnt_buf { 59 struct vp9_fb_info buf; 60 unsigned int ref_cnt; 61}; 62 63/** 64 * struct vp9_ref_buf - contains current frame's reference buffer information 65 * @buf : reference buffer 66 * @idx : reference buffer index to frm_bufs 67 * @reserved : reserved field used by vpu 68 */ 69struct vp9_ref_buf { 70 struct vp9_fb_info *buf; 71 unsigned int idx; 72 unsigned int reserved[6]; 73}; 74 75/** 76 * struct vp9_sf_ref_fb - contains frame buffer info 77 * @fb : super frame reference frame buffer 78 * @used : this reference frame info entry is used 79 * @padding : for 64 bytes size align 80 */ 81struct vp9_sf_ref_fb { 82 struct vdec_fb fb; 83 int used; 84 int padding; 85}; 86 87/* 88 * struct vdec_vp9_vsi - shared buffer between host and VPU firmware 89 * AP-W/R : AP is writer/reader on this item 90 * VPU-W/R: VPU is write/reader on this item 91 * @sf_bs_buf : super frame backup buffer (AP-W, VPU-R) 92 * @sf_ref_fb : record supoer frame reference buffer information 93 * (AP-R/W, VPU-R/W) 94 * @sf_next_ref_fb_idx : next available super frame (AP-W, VPU-R) 95 * @sf_frm_cnt : super frame count, filled by vpu (AP-R, VPU-W) 96 * @sf_frm_offset : super frame offset, filled by vpu (AP-R, VPU-W) 97 * @sf_frm_sz : super frame size, filled by vpu (AP-R, VPU-W) 98 * @sf_frm_idx : current super frame (AP-R, VPU-W) 99 * @sf_init : inform super frame info already parsed by vpu (AP-R, VPU-W) 100 * @fb : capture buffer (AP-W, VPU-R) 101 * @bs : bs buffer (AP-W, VPU-R) 102 * @cur_fb : current show capture buffer (AP-R/W, VPU-R/W) 103 * @pic_w : picture width (AP-R, VPU-W) 104 * @pic_h : picture height (AP-R, VPU-W) 105 * @buf_w : codec width (AP-R, VPU-W) 106 * @buf_h : coded height (AP-R, VPU-W) 107 * @buf_sz_y_bs : ufo compressed y plane size (AP-R, VPU-W) 108 * @buf_sz_c_bs : ufo compressed cbcr plane size (AP-R, VPU-W) 109 * @buf_len_sz_y : size used to store y plane ufo info (AP-R, VPU-W) 110 * @buf_len_sz_c : size used to store cbcr plane ufo info (AP-R, VPU-W) 111 112 * @profile : profile sparsed from vpu (AP-R, VPU-W) 113 * @show_frame : [BIT(0)] display this frame or not (AP-R, VPU-W) 114 * [BIT(1)] reset segment data or not (AP-R, VPU-W) 115 * [BIT(2)] trig decoder hardware or not (AP-R, VPU-W) 116 * [BIT(3)] ask VPU to set bits(0~4) accordingly (AP-W, VPU-R) 117 * [BIT(4)] do not reset segment data before every frame (AP-R, VPU-W) 118 * @show_existing_frame : inform this frame is show existing frame 119 * (AP-R, VPU-W) 120 * @frm_to_show_idx : index to show frame (AP-R, VPU-W) 121 122 * @refresh_frm_flags : indicate when frame need to refine reference count 123 * (AP-R, VPU-W) 124 * @resolution_changed : resolution change in this frame (AP-R, VPU-W) 125 126 * @frm_bufs : maintain reference buffer info (AP-R/W, VPU-R/W) 127 * @ref_frm_map : maintain reference buffer map info (AP-R/W, VPU-R/W) 128 * @new_fb_idx : index to frm_bufs array (AP-R, VPU-W) 129 * @frm_num : decoded frame number, include sub-frame count (AP-R, VPU-W) 130 * @mv_buf : motion vector working buffer (AP-W, VPU-R) 131 * @frm_refs : maintain three reference buffer info (AP-R/W, VPU-R/W) 132 * @seg_id_buf : segmentation map working buffer (AP-W, VPU-R) 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 * struct vdec_vp9_inst - vp9 decode instance 174 * @mv_buf : working buffer for mv 175 * @seg_id_buf : working buffer for segmentation map 176 * @dec_fb : vdec_fb node to link fb to different fb_xxx_list 177 * @available_fb_node_list : current available vdec_fb node 178 * @fb_use_list : current used or referenced vdec_fb 179 * @fb_free_list : current available to free vdec_fb 180 * @fb_disp_list : current available to display vdec_fb 181 * @cur_fb : current frame buffer 182 * @ctx : current decode context 183 * @vpu : vpu instance information 184 * @vsi : shared buffer between host and VPU firmware 185 * @total_frm_cnt : total frame count, it do not include sub-frames in super 186 * frame 187 * @mem : instance memory information 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/* For each sub-frame except the last one, the driver will dynamically 305 * allocate reference buffer by calling vp9_get_sf_ref_fb() 306 * The last sub-frame will use the original fb provided by the 307 * vp9_dec_decode() interface 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 /* Set the va again */ 405 vsi->mv_buf.va = (unsigned long)mem->va; 406 vsi->mv_buf.pa = (unsigned long)mem->dma_addr; 407 vsi->mv_buf.sz = (unsigned int)mem->size; 408 409 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 /* Set the va again */ 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/* If any buffer updating is signaled it should be done here. */ 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 /* This frame is show exist frame and no decode output 475 * copy frame data from frm_to_show to current CAPTURE 476 * buffer 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 /* After resolution change case, current CAPTURE buffer 491 * may have less buffer size than frm_to_show buffer 492 * size 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 /* when ref_cnt ==0, move this fb to fb_free_list. v4l2 driver will 512 * clean fb_free_list 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 /* if this super frame and it is not last sub-frame, get next fb for 530 * sub-frame decode 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, 0); 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 /* Set the va again, since vpu_dec_reset will clear mv_buf in vpu */ 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 /* Set the va again, since vpu_dec_reset will clear seg_id_buf in vpu */ 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 /* VPU assign the buffer pointer in its address space, 947 * reassign here 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};