root/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vp9_is_sf_ref_fb
  2. vp9_rm_from_fb_use_list
  3. vp9_add_to_fb_free_list
  4. vp9_free_sf_ref_fb
  5. vp9_ref_cnt_fb
  6. vp9_free_all_sf_ref_fb
  7. vp9_get_sf_ref_fb
  8. vp9_alloc_work_buf
  9. vp9_add_to_fb_disp_list
  10. vp9_swap_frm_bufs
  11. vp9_wait_dec_end
  12. vp9_alloc_inst
  13. vp9_free_inst
  14. vp9_decode_end_proc
  15. vp9_is_last_sub_frm
  16. vp9_rm_from_fb_disp_list
  17. vp9_add_to_fb_use_list
  18. vp9_reset
  19. init_all_fb_lists
  20. get_pic_info
  21. get_disp_fb
  22. get_free_fb
  23. validate_vsi_array_indexes
  24. vdec_vp9_deinit
  25. vdec_vp9_init
  26. vdec_vp9_decode
  27. get_crop_info
  28. vdec_vp9_get_param

   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  */
  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  * struct vp9_fb_info - contains frame buffer info
  44  * @fb : frmae buffer
  45  * @reserved : reserved field used by vpu
  46  */
  47 struct 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  */
  58 struct vp9_ref_cnt_buf {
  59         struct vp9_fb_info buf;
  60         unsigned int ref_cnt;
  61 };
  62 
  63 /**
  64  * struct vp9_fb_info - 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  */
  69 struct vp9_ref_buf {
  70         struct vp9_fb_info *buf;
  71         unsigned int idx;
  72         unsigned int reserved[6];
  73 };
  74 
  75 /**
  76  * struct vp9_fb_info - 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  */
  81 struct 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 : display this frame or not (AP-R, VPU-W)
 114  * @show_existing_frame : inform this frame is show existing frame
 115  *      (AP-R, VPU-W)
 116  * @frm_to_show_idx : index to show frame (AP-R, VPU-W)
 117 
 118  * @refresh_frm_flags : indicate when frame need to refine reference count
 119  *      (AP-R, VPU-W)
 120  * @resolution_changed : resolution change in this frame (AP-R, VPU-W)
 121 
 122  * @frm_bufs : maintain reference buffer info (AP-R/W, VPU-R/W)
 123  * @ref_frm_map : maintain reference buffer map info (AP-R/W, VPU-R/W)
 124  * @new_fb_idx : index to frm_bufs array (AP-R, VPU-W)
 125  * @frm_num : decoded frame number, include sub-frame count (AP-R, VPU-W)
 126  * @mv_buf : motion vector working buffer (AP-W, VPU-R)
 127  * @frm_refs : maintain three reference buffer info (AP-R/W, VPU-R/W)
 128  * @seg_id_buf : segmentation map working buffer (AP-W, VPU-R)
 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  * struct vdec_vp9_inst - vp9 decode instance
 170  * @mv_buf : working buffer for mv
 171  * @seg_id_buf : working buffer for segmentation map
 172  * @dec_fb : vdec_fb node to link fb to different fb_xxx_list
 173  * @available_fb_node_list : current available vdec_fb node
 174  * @fb_use_list : current used or referenced vdec_fb
 175  * @fb_free_list : current available to free vdec_fb
 176  * @fb_disp_list : current available to display vdec_fb
 177  * @cur_fb : current frame buffer
 178  * @ctx : current decode context
 179  * @vpu : vpu instance information
 180  * @vsi : shared buffer between host and VPU firmware
 181  * @total_frm_cnt : total frame count, it do not include sub-frames in super
 182  *          frame
 183  * @mem : instance memory information
 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 /* For each sub-frame except the last one, the driver will dynamically
 301  * allocate reference buffer by calling vp9_get_sf_ref_fb()
 302  * The last sub-frame will use the original fb provided by the
 303  * vp9_dec_decode() interface
 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         /* Set the va again */
 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         /* Set the va again */
 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 /* If any buffer updating is signaled it should be done here. */
 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                 /* This frame is show exist frame and no decode output
 471                  * copy frame data from frm_to_show to current CAPTURE
 472                  * buffer
 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                         /* After resolution change case, current CAPTURE buffer
 487                          * may have less buffer size than frm_to_show buffer
 488                          * size
 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         /* when ref_cnt ==0, move this fb to fb_free_list. v4l2 driver will
 508          * clean fb_free_list
 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         /* if this super frame and it is not last sub-frame, get next fb for
 526          * sub-frame decode
 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         /* 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 
 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                 /* VPU assign the buffer pointer in its address space,
 927                  * reassign here
 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 };

/* [<][>][^][v][top][bottom][index][help] */