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