vdec_vp9_if.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967
  1. /*
  2. * Copyright (c) 2016 MediaTek Inc.
  3. * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
  4. * Kai-Sean Yang <kai-sean.yang@mediatek.com>
  5. * Tiffany Lin <tiffany.lin@mediatek.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * version 2 as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <linux/fs.h>
  17. #include <linux/slab.h>
  18. #include <linux/syscalls.h>
  19. #include <linux/delay.h>
  20. #include <linux/time.h>
  21. #include "../mtk_vcodec_intr.h"
  22. #include "../vdec_drv_base.h"
  23. #include "../vdec_vpu_if.h"
  24. #define VP9_SUPER_FRAME_BS_SZ 64
  25. #define MAX_VP9_DPB_SIZE 9
  26. #define REFS_PER_FRAME 3
  27. #define MAX_NUM_REF_FRAMES 8
  28. #define VP9_MAX_FRM_BUF_NUM 9
  29. #define VP9_MAX_FRM_BUF_NODE_NUM (VP9_MAX_FRM_BUF_NUM * 2)
  30. /**
  31. * struct vp9_dram_buf - contains buffer info for vpu
  32. * @va : cpu address
  33. * @pa : iova address
  34. * @sz : buffer size
  35. * @padding : for 64 bytes alignment
  36. */
  37. struct vp9_dram_buf {
  38. unsigned long va;
  39. unsigned long pa;
  40. unsigned int sz;
  41. unsigned int padding;
  42. };
  43. /**
  44. * struct vp9_fb_info - contains frame buffer info
  45. * @fb : frmae buffer
  46. * @reserved : reserved field used by vpu
  47. */
  48. struct vp9_fb_info {
  49. struct vdec_fb *fb;
  50. unsigned int reserved[32];
  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. * struct vp9_fb_info - contains current frame's reference buffer information
  64. * @buf : reference buffer
  65. * @idx : reference buffer index to frm_bufs
  66. * @reserved : reserved field used by vpu
  67. */
  68. struct vp9_ref_buf {
  69. struct vp9_fb_info *buf;
  70. unsigned int idx;
  71. unsigned int reserved[6];
  72. };
  73. /**
  74. * struct vp9_fb_info - contains frame buffer info
  75. * @fb : super frame reference frame buffer
  76. * @used : this reference frame info entry is used
  77. * @padding : for 64 bytes size align
  78. */
  79. struct vp9_sf_ref_fb {
  80. struct vdec_fb fb;
  81. int used;
  82. int padding;
  83. };
  84. /*
  85. * struct vdec_vp9_vsi - shared buffer between host and VPU firmware
  86. * AP-W/R : AP is writer/reader on this item
  87. * VPU-W/R: VPU is write/reader on this item
  88. * @sf_bs_buf : super frame backup buffer (AP-W, VPU-R)
  89. * @sf_ref_fb : record supoer frame reference buffer information
  90. * (AP-R/W, VPU-R/W)
  91. * @sf_next_ref_fb_idx : next available super frame (AP-W, VPU-R)
  92. * @sf_frm_cnt : super frame count, filled by vpu (AP-R, VPU-W)
  93. * @sf_frm_offset : super frame offset, filled by vpu (AP-R, VPU-W)
  94. * @sf_frm_sz : super frame size, filled by vpu (AP-R, VPU-W)
  95. * @sf_frm_idx : current super frame (AP-R, VPU-W)
  96. * @sf_init : inform super frame info already parsed by vpu (AP-R, VPU-W)
  97. * @fb : capture buffer (AP-W, VPU-R)
  98. * @bs : bs buffer (AP-W, VPU-R)
  99. * @cur_fb : current show capture buffer (AP-R/W, VPU-R/W)
  100. * @pic_w : picture width (AP-R, VPU-W)
  101. * @pic_h : picture height (AP-R, VPU-W)
  102. * @buf_w : codec width (AP-R, VPU-W)
  103. * @buf_h : coded height (AP-R, VPU-W)
  104. * @buf_sz_y_bs : ufo compressed y plane size (AP-R, VPU-W)
  105. * @buf_sz_c_bs : ufo compressed cbcr plane size (AP-R, VPU-W)
  106. * @buf_len_sz_y : size used to store y plane ufo info (AP-R, VPU-W)
  107. * @buf_len_sz_c : size used to store cbcr plane ufo info (AP-R, VPU-W)
  108. * @profile : profile sparsed from vpu (AP-R, VPU-W)
  109. * @show_frame : display this frame or not (AP-R, VPU-W)
  110. * @show_existing_frame : inform this frame is show existing frame
  111. * (AP-R, VPU-W)
  112. * @frm_to_show_idx : index to show frame (AP-R, VPU-W)
  113. * @refresh_frm_flags : indicate when frame need to refine reference count
  114. * (AP-R, VPU-W)
  115. * @resolution_changed : resolution change in this frame (AP-R, VPU-W)
  116. * @frm_bufs : maintain reference buffer info (AP-R/W, VPU-R/W)
  117. * @ref_frm_map : maintain reference buffer map info (AP-R/W, VPU-R/W)
  118. * @new_fb_idx : index to frm_bufs array (AP-R, VPU-W)
  119. * @frm_num : decoded frame number, include sub-frame count (AP-R, VPU-W)
  120. * @mv_buf : motion vector working buffer (AP-W, VPU-R)
  121. * @frm_refs : maintain three reference buffer info (AP-R/W, VPU-R/W)
  122. */
  123. struct vdec_vp9_vsi {
  124. unsigned char sf_bs_buf[VP9_SUPER_FRAME_BS_SZ];
  125. struct vp9_sf_ref_fb sf_ref_fb[VP9_MAX_FRM_BUF_NUM-1];
  126. int sf_next_ref_fb_idx;
  127. unsigned int sf_frm_cnt;
  128. unsigned int sf_frm_offset[VP9_MAX_FRM_BUF_NUM-1];
  129. unsigned int sf_frm_sz[VP9_MAX_FRM_BUF_NUM-1];
  130. unsigned int sf_frm_idx;
  131. unsigned int sf_init;
  132. struct vdec_fb fb;
  133. struct mtk_vcodec_mem bs;
  134. struct vdec_fb cur_fb;
  135. unsigned int pic_w;
  136. unsigned int pic_h;
  137. unsigned int buf_w;
  138. unsigned int buf_h;
  139. unsigned int buf_sz_y_bs;
  140. unsigned int buf_sz_c_bs;
  141. unsigned int buf_len_sz_y;
  142. unsigned int buf_len_sz_c;
  143. unsigned int profile;
  144. unsigned int show_frame;
  145. unsigned int show_existing_frame;
  146. unsigned int frm_to_show_idx;
  147. unsigned int refresh_frm_flags;
  148. unsigned int resolution_changed;
  149. struct vp9_ref_cnt_buf frm_bufs[VP9_MAX_FRM_BUF_NUM];
  150. int ref_frm_map[MAX_NUM_REF_FRAMES];
  151. unsigned int new_fb_idx;
  152. unsigned int frm_num;
  153. struct vp9_dram_buf mv_buf;
  154. struct vp9_ref_buf frm_refs[REFS_PER_FRAME];
  155. };
  156. /*
  157. * struct vdec_vp9_inst - vp9 decode instance
  158. * @mv_buf : working buffer for mv
  159. * @dec_fb : vdec_fb node to link fb to different fb_xxx_list
  160. * @available_fb_node_list : current available vdec_fb node
  161. * @fb_use_list : current used or referenced vdec_fb
  162. * @fb_free_list : current available to free vdec_fb
  163. * @fb_disp_list : current available to display vdec_fb
  164. * @cur_fb : current frame buffer
  165. * @ctx : current decode context
  166. * @vpu : vpu instance information
  167. * @vsi : shared buffer between host and VPU firmware
  168. * @total_frm_cnt : total frame count, it do not include sub-frames in super
  169. * frame
  170. * @mem : instance memory information
  171. */
  172. struct vdec_vp9_inst {
  173. struct mtk_vcodec_mem mv_buf;
  174. struct vdec_fb_node dec_fb[VP9_MAX_FRM_BUF_NODE_NUM];
  175. struct list_head available_fb_node_list;
  176. struct list_head fb_use_list;
  177. struct list_head fb_free_list;
  178. struct list_head fb_disp_list;
  179. struct vdec_fb *cur_fb;
  180. struct mtk_vcodec_ctx *ctx;
  181. struct vdec_vpu_inst vpu;
  182. struct vdec_vp9_vsi *vsi;
  183. unsigned int total_frm_cnt;
  184. struct mtk_vcodec_mem mem;
  185. };
  186. static bool vp9_is_sf_ref_fb(struct vdec_vp9_inst *inst, struct vdec_fb *fb)
  187. {
  188. int i;
  189. struct vdec_vp9_vsi *vsi = inst->vsi;
  190. for (i = 0; i < ARRAY_SIZE(vsi->sf_ref_fb); i++) {
  191. if (fb == &vsi->sf_ref_fb[i].fb)
  192. return true;
  193. }
  194. return false;
  195. }
  196. static struct vdec_fb *vp9_rm_from_fb_use_list(struct vdec_vp9_inst
  197. *inst, void *addr)
  198. {
  199. struct vdec_fb *fb = NULL;
  200. struct vdec_fb_node *node;
  201. list_for_each_entry(node, &inst->fb_use_list, list) {
  202. fb = (struct vdec_fb *)node->fb;
  203. if (fb->base_y.va == addr) {
  204. list_move_tail(&node->list,
  205. &inst->available_fb_node_list);
  206. break;
  207. }
  208. }
  209. return fb;
  210. }
  211. static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst,
  212. struct vdec_fb *fb)
  213. {
  214. struct vdec_fb_node *node;
  215. if (fb) {
  216. node = list_first_entry_or_null(&inst->available_fb_node_list,
  217. struct vdec_fb_node, list);
  218. if (node) {
  219. node->fb = fb;
  220. list_move_tail(&node->list, &inst->fb_free_list);
  221. }
  222. } else {
  223. mtk_vcodec_debug(inst, "No free fb node");
  224. }
  225. }
  226. static void vp9_free_sf_ref_fb(struct vdec_fb *fb)
  227. {
  228. struct vp9_sf_ref_fb *sf_ref_fb =
  229. container_of(fb, struct vp9_sf_ref_fb, fb);
  230. sf_ref_fb->used = 0;
  231. }
  232. static void vp9_ref_cnt_fb(struct vdec_vp9_inst *inst, int *idx,
  233. int new_idx)
  234. {
  235. struct vdec_vp9_vsi *vsi = inst->vsi;
  236. int ref_idx = *idx;
  237. if (ref_idx >= 0 && vsi->frm_bufs[ref_idx].ref_cnt > 0) {
  238. vsi->frm_bufs[ref_idx].ref_cnt--;
  239. if (vsi->frm_bufs[ref_idx].ref_cnt == 0) {
  240. if (!vp9_is_sf_ref_fb(inst,
  241. vsi->frm_bufs[ref_idx].buf.fb)) {
  242. struct vdec_fb *fb;
  243. fb = vp9_rm_from_fb_use_list(inst,
  244. vsi->frm_bufs[ref_idx].buf.fb->base_y.va);
  245. vp9_add_to_fb_free_list(inst, fb);
  246. } else
  247. vp9_free_sf_ref_fb(
  248. vsi->frm_bufs[ref_idx].buf.fb);
  249. }
  250. }
  251. *idx = new_idx;
  252. vsi->frm_bufs[new_idx].ref_cnt++;
  253. }
  254. static void vp9_free_all_sf_ref_fb(struct vdec_vp9_inst *inst)
  255. {
  256. int i;
  257. struct vdec_vp9_vsi *vsi = inst->vsi;
  258. for (i = 0; i < ARRAY_SIZE(vsi->sf_ref_fb); i++) {
  259. if (vsi->sf_ref_fb[i].fb.base_y.va) {
  260. mtk_vcodec_mem_free(inst->ctx,
  261. &vsi->sf_ref_fb[i].fb.base_y);
  262. mtk_vcodec_mem_free(inst->ctx,
  263. &vsi->sf_ref_fb[i].fb.base_c);
  264. vsi->sf_ref_fb[i].used = 0;
  265. }
  266. }
  267. }
  268. /* For each sub-frame except the last one, the driver will dynamically
  269. * allocate reference buffer by calling vp9_get_sf_ref_fb()
  270. * The last sub-frame will use the original fb provided by the
  271. * vp9_dec_decode() interface
  272. */
  273. static int vp9_get_sf_ref_fb(struct vdec_vp9_inst *inst)
  274. {
  275. int idx;
  276. struct mtk_vcodec_mem *mem_basy_y;
  277. struct mtk_vcodec_mem *mem_basy_c;
  278. struct vdec_vp9_vsi *vsi = inst->vsi;
  279. for (idx = 0;
  280. idx < ARRAY_SIZE(vsi->sf_ref_fb);
  281. idx++) {
  282. if (vsi->sf_ref_fb[idx].fb.base_y.va &&
  283. vsi->sf_ref_fb[idx].used == 0) {
  284. return idx;
  285. }
  286. }
  287. for (idx = 0;
  288. idx < ARRAY_SIZE(vsi->sf_ref_fb);
  289. idx++) {
  290. if (vsi->sf_ref_fb[idx].fb.base_y.va == NULL)
  291. break;
  292. }
  293. if (idx == ARRAY_SIZE(vsi->sf_ref_fb)) {
  294. mtk_vcodec_err(inst, "List Full");
  295. return -1;
  296. }
  297. mem_basy_y = &vsi->sf_ref_fb[idx].fb.base_y;
  298. mem_basy_y->size = vsi->buf_sz_y_bs +
  299. vsi->buf_len_sz_y;
  300. if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_y)) {
  301. mtk_vcodec_err(inst, "Cannot allocate sf_ref_buf y_buf");
  302. return -1;
  303. }
  304. mem_basy_c = &vsi->sf_ref_fb[idx].fb.base_c;
  305. mem_basy_c->size = vsi->buf_sz_c_bs +
  306. vsi->buf_len_sz_c;
  307. if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_c)) {
  308. mtk_vcodec_err(inst, "Cannot allocate sf_ref_fb c_buf");
  309. return -1;
  310. }
  311. vsi->sf_ref_fb[idx].used = 0;
  312. return idx;
  313. }
  314. static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst)
  315. {
  316. struct vdec_vp9_vsi *vsi = inst->vsi;
  317. int result;
  318. struct mtk_vcodec_mem *mem;
  319. unsigned int max_pic_w;
  320. unsigned int max_pic_h;
  321. if (!(inst->ctx->dev->dec_capability &
  322. VCODEC_CAPABILITY_4K_DISABLED)) {
  323. max_pic_w = VCODEC_DEC_4K_CODED_WIDTH;
  324. max_pic_h = VCODEC_DEC_4K_CODED_HEIGHT;
  325. } else {
  326. max_pic_w = MTK_VDEC_MAX_W;
  327. max_pic_h = MTK_VDEC_MAX_H;
  328. }
  329. if ((vsi->pic_w > max_pic_w) ||
  330. (vsi->pic_h > max_pic_h)) {
  331. mtk_vcodec_err(inst, "Invalid w/h %d/%d",
  332. vsi->pic_w, vsi->pic_h);
  333. return false;
  334. }
  335. mtk_vcodec_debug(inst, "BUF CHG(%d): w/h/sb_w/sb_h=%d/%d/%d/%d",
  336. vsi->resolution_changed,
  337. vsi->pic_w,
  338. vsi->pic_h,
  339. vsi->buf_w,
  340. vsi->buf_h);
  341. mem = &inst->mv_buf;
  342. if (mem->va)
  343. mtk_vcodec_mem_free(inst->ctx, mem);
  344. mem->size = ((vsi->buf_w / 64) *
  345. (vsi->buf_h / 64) + 2) * 36 * 16;
  346. result = mtk_vcodec_mem_alloc(inst->ctx, mem);
  347. if (result) {
  348. mem->size = 0;
  349. mtk_vcodec_err(inst, "Cannot allocate mv_buf");
  350. return false;
  351. }
  352. /* Set the va again */
  353. vsi->mv_buf.va = (unsigned long)mem->va;
  354. vsi->mv_buf.pa = (unsigned long)mem->dma_addr;
  355. vsi->mv_buf.sz = (unsigned int)mem->size;
  356. vp9_free_all_sf_ref_fb(inst);
  357. vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
  358. return true;
  359. }
  360. static bool vp9_add_to_fb_disp_list(struct vdec_vp9_inst *inst,
  361. struct vdec_fb *fb)
  362. {
  363. struct vdec_fb_node *node;
  364. if (!fb) {
  365. mtk_vcodec_err(inst, "fb == NULL");
  366. return false;
  367. }
  368. node = list_first_entry_or_null(&inst->available_fb_node_list,
  369. struct vdec_fb_node, list);
  370. if (node) {
  371. node->fb = fb;
  372. list_move_tail(&node->list, &inst->fb_disp_list);
  373. } else {
  374. mtk_vcodec_err(inst, "No available fb node");
  375. return false;
  376. }
  377. return true;
  378. }
  379. /* If any buffer updating is signaled it should be done here. */
  380. static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst)
  381. {
  382. struct vdec_vp9_vsi *vsi = inst->vsi;
  383. struct vp9_fb_info *frm_to_show;
  384. int ref_index = 0, mask;
  385. for (mask = vsi->refresh_frm_flags; mask; mask >>= 1) {
  386. if (mask & 1)
  387. vp9_ref_cnt_fb(inst, &vsi->ref_frm_map[ref_index],
  388. vsi->new_fb_idx);
  389. ++ref_index;
  390. }
  391. frm_to_show = &vsi->frm_bufs[vsi->new_fb_idx].buf;
  392. vsi->frm_bufs[vsi->new_fb_idx].ref_cnt--;
  393. if (frm_to_show->fb != inst->cur_fb) {
  394. /* This frame is show exist frame and no decode output
  395. * copy frame data from frm_to_show to current CAPTURE
  396. * buffer
  397. */
  398. if ((frm_to_show->fb != NULL) &&
  399. (inst->cur_fb->base_y.size >=
  400. frm_to_show->fb->base_y.size)) {
  401. memcpy((void *)inst->cur_fb->base_y.va,
  402. (void *)frm_to_show->fb->base_y.va,
  403. vsi->buf_w *
  404. vsi->buf_h);
  405. memcpy((void *)inst->cur_fb->base_c.va,
  406. (void *)frm_to_show->fb->base_c.va,
  407. vsi->buf_w *
  408. vsi->buf_h / 2);
  409. } else {
  410. /* After resolution change case, current CAPTURE buffer
  411. * may have less buffer size than frm_to_show buffer
  412. * size
  413. */
  414. if (frm_to_show->fb != NULL)
  415. mtk_vcodec_err(inst,
  416. "inst->cur_fb->base_y.size=%zu, frm_to_show->fb.base_y.size=%zu",
  417. inst->cur_fb->base_y.size,
  418. frm_to_show->fb->base_y.size);
  419. }
  420. if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {
  421. if (vsi->show_frame)
  422. vp9_add_to_fb_disp_list(inst, inst->cur_fb);
  423. }
  424. } else {
  425. if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {
  426. if (vsi->show_frame)
  427. vp9_add_to_fb_disp_list(inst, frm_to_show->fb);
  428. }
  429. }
  430. /* when ref_cnt ==0, move this fb to fb_free_list. v4l2 driver will
  431. * clean fb_free_list
  432. */
  433. if (vsi->frm_bufs[vsi->new_fb_idx].ref_cnt == 0) {
  434. if (!vp9_is_sf_ref_fb(
  435. inst, vsi->frm_bufs[vsi->new_fb_idx].buf.fb)) {
  436. struct vdec_fb *fb;
  437. fb = vp9_rm_from_fb_use_list(inst,
  438. vsi->frm_bufs[vsi->new_fb_idx].buf.fb->base_y.va);
  439. vp9_add_to_fb_free_list(inst, fb);
  440. } else {
  441. vp9_free_sf_ref_fb(
  442. vsi->frm_bufs[vsi->new_fb_idx].buf.fb);
  443. }
  444. }
  445. /* if this super frame and it is not last sub-frame, get next fb for
  446. * sub-frame decode
  447. */
  448. if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt - 1)
  449. vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
  450. }
  451. static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst)
  452. {
  453. struct mtk_vcodec_ctx *ctx = inst->ctx;
  454. mtk_vcodec_wait_for_done_ctx(inst->ctx,
  455. MTK_INST_IRQ_RECEIVED,
  456. WAIT_INTR_TIMEOUT_MS);
  457. if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
  458. return true;
  459. else
  460. return false;
  461. }
  462. static struct vdec_vp9_inst *vp9_alloc_inst(struct mtk_vcodec_ctx *ctx)
  463. {
  464. int result;
  465. struct mtk_vcodec_mem mem;
  466. struct vdec_vp9_inst *inst;
  467. memset(&mem, 0, sizeof(mem));
  468. mem.size = sizeof(struct vdec_vp9_inst);
  469. result = mtk_vcodec_mem_alloc(ctx, &mem);
  470. if (result)
  471. return NULL;
  472. inst = mem.va;
  473. inst->mem = mem;
  474. return inst;
  475. }
  476. static void vp9_free_inst(struct vdec_vp9_inst *inst)
  477. {
  478. struct mtk_vcodec_mem mem;
  479. mem = inst->mem;
  480. if (mem.va)
  481. mtk_vcodec_mem_free(inst->ctx, &mem);
  482. }
  483. static bool vp9_decode_end_proc(struct vdec_vp9_inst *inst)
  484. {
  485. struct vdec_vp9_vsi *vsi = inst->vsi;
  486. bool ret = false;
  487. if (!vsi->show_existing_frame) {
  488. ret = vp9_wait_dec_end(inst);
  489. if (!ret) {
  490. mtk_vcodec_err(inst, "Decode failed, Decode Timeout @[%d]",
  491. vsi->frm_num);
  492. return false;
  493. }
  494. if (vpu_dec_end(&inst->vpu)) {
  495. mtk_vcodec_err(inst, "vp9_dec_vpu_end failed");
  496. return false;
  497. }
  498. mtk_vcodec_debug(inst, "Decode Ok @%d (%d/%d)", vsi->frm_num,
  499. vsi->pic_w, vsi->pic_h);
  500. } else {
  501. mtk_vcodec_debug(inst, "Decode Ok @%d (show_existing_frame)",
  502. vsi->frm_num);
  503. }
  504. vp9_swap_frm_bufs(inst);
  505. vsi->frm_num++;
  506. return true;
  507. }
  508. static bool vp9_is_last_sub_frm(struct vdec_vp9_inst *inst)
  509. {
  510. struct vdec_vp9_vsi *vsi = inst->vsi;
  511. if (vsi->sf_frm_cnt <= 0 || vsi->sf_frm_idx == vsi->sf_frm_cnt)
  512. return true;
  513. return false;
  514. }
  515. static struct vdec_fb *vp9_rm_from_fb_disp_list(struct vdec_vp9_inst *inst)
  516. {
  517. struct vdec_fb_node *node;
  518. struct vdec_fb *fb = NULL;
  519. node = list_first_entry_or_null(&inst->fb_disp_list,
  520. struct vdec_fb_node, list);
  521. if (node) {
  522. fb = (struct vdec_fb *)node->fb;
  523. fb->status |= FB_ST_DISPLAY;
  524. list_move_tail(&node->list, &inst->available_fb_node_list);
  525. mtk_vcodec_debug(inst, "[FB] get disp fb %p st=%d",
  526. node->fb, fb->status);
  527. } else
  528. mtk_vcodec_debug(inst, "[FB] there is no disp fb");
  529. return fb;
  530. }
  531. static bool vp9_add_to_fb_use_list(struct vdec_vp9_inst *inst,
  532. struct vdec_fb *fb)
  533. {
  534. struct vdec_fb_node *node;
  535. if (!fb) {
  536. mtk_vcodec_debug(inst, "fb == NULL");
  537. return false;
  538. }
  539. node = list_first_entry_or_null(&inst->available_fb_node_list,
  540. struct vdec_fb_node, list);
  541. if (node) {
  542. node->fb = fb;
  543. list_move_tail(&node->list, &inst->fb_use_list);
  544. } else {
  545. mtk_vcodec_err(inst, "No free fb node");
  546. return false;
  547. }
  548. return true;
  549. }
  550. static void vp9_reset(struct vdec_vp9_inst *inst)
  551. {
  552. struct vdec_fb_node *node, *tmp;
  553. list_for_each_entry_safe(node, tmp, &inst->fb_use_list, list)
  554. list_move_tail(&node->list, &inst->fb_free_list);
  555. vp9_free_all_sf_ref_fb(inst);
  556. inst->vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
  557. if (vpu_dec_reset(&inst->vpu))
  558. mtk_vcodec_err(inst, "vp9_dec_vpu_reset failed");
  559. /* Set the va again, since vpu_dec_reset will clear mv_buf in vpu */
  560. inst->vsi->mv_buf.va = (unsigned long)inst->mv_buf.va;
  561. inst->vsi->mv_buf.pa = (unsigned long)inst->mv_buf.dma_addr;
  562. inst->vsi->mv_buf.sz = (unsigned long)inst->mv_buf.size;
  563. }
  564. static void init_all_fb_lists(struct vdec_vp9_inst *inst)
  565. {
  566. int i;
  567. INIT_LIST_HEAD(&inst->available_fb_node_list);
  568. INIT_LIST_HEAD(&inst->fb_use_list);
  569. INIT_LIST_HEAD(&inst->fb_free_list);
  570. INIT_LIST_HEAD(&inst->fb_disp_list);
  571. for (i = 0; i < ARRAY_SIZE(inst->dec_fb); i++) {
  572. INIT_LIST_HEAD(&inst->dec_fb[i].list);
  573. inst->dec_fb[i].fb = NULL;
  574. list_add_tail(&inst->dec_fb[i].list,
  575. &inst->available_fb_node_list);
  576. }
  577. }
  578. static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic)
  579. {
  580. pic->y_bs_sz = inst->vsi->buf_sz_y_bs;
  581. pic->c_bs_sz = inst->vsi->buf_sz_c_bs;
  582. pic->y_len_sz = inst->vsi->buf_len_sz_y;
  583. pic->c_len_sz = inst->vsi->buf_len_sz_c;
  584. pic->pic_w = inst->vsi->pic_w;
  585. pic->pic_h = inst->vsi->pic_h;
  586. pic->buf_w = inst->vsi->buf_w;
  587. pic->buf_h = inst->vsi->buf_h;
  588. mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
  589. pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
  590. mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz,
  591. pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
  592. }
  593. static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
  594. {
  595. *out_fb = vp9_rm_from_fb_disp_list(inst);
  596. if (*out_fb)
  597. (*out_fb)->status |= FB_ST_DISPLAY;
  598. }
  599. static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
  600. {
  601. struct vdec_fb_node *node;
  602. struct vdec_fb *fb = NULL;
  603. node = list_first_entry_or_null(&inst->fb_free_list,
  604. struct vdec_fb_node, list);
  605. if (node) {
  606. list_move_tail(&node->list, &inst->available_fb_node_list);
  607. fb = (struct vdec_fb *)node->fb;
  608. fb->status |= FB_ST_FREE;
  609. mtk_vcodec_debug(inst, "[FB] get free fb %p st=%d",
  610. node->fb, fb->status);
  611. } else {
  612. mtk_vcodec_debug(inst, "[FB] there is no free fb");
  613. }
  614. *out_fb = fb;
  615. }
  616. static void vdec_vp9_deinit(unsigned long h_vdec)
  617. {
  618. struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
  619. struct mtk_vcodec_mem *mem;
  620. int ret = 0;
  621. ret = vpu_dec_deinit(&inst->vpu);
  622. if (ret)
  623. mtk_vcodec_err(inst, "vpu_dec_deinit failed");
  624. mem = &inst->mv_buf;
  625. if (mem->va)
  626. mtk_vcodec_mem_free(inst->ctx, mem);
  627. vp9_free_all_sf_ref_fb(inst);
  628. vp9_free_inst(inst);
  629. }
  630. static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx, unsigned long *h_vdec)
  631. {
  632. struct vdec_vp9_inst *inst;
  633. inst = vp9_alloc_inst(ctx);
  634. if (!inst)
  635. return -ENOMEM;
  636. inst->total_frm_cnt = 0;
  637. inst->ctx = ctx;
  638. inst->vpu.id = IPI_VDEC_VP9;
  639. inst->vpu.dev = ctx->dev->vpu_plat_dev;
  640. inst->vpu.ctx = ctx;
  641. inst->vpu.handler = vpu_dec_ipi_handler;
  642. if (vpu_dec_init(&inst->vpu)) {
  643. mtk_vcodec_err(inst, "vp9_dec_vpu_init failed");
  644. goto err_deinit_inst;
  645. }
  646. inst->vsi = (struct vdec_vp9_vsi *)inst->vpu.vsi;
  647. init_all_fb_lists(inst);
  648. (*h_vdec) = (unsigned long)inst;
  649. return 0;
  650. err_deinit_inst:
  651. vp9_free_inst(inst);
  652. return -EINVAL;
  653. }
  654. static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs,
  655. struct vdec_fb *fb, bool *res_chg)
  656. {
  657. int ret = 0;
  658. struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
  659. struct vdec_vp9_vsi *vsi = inst->vsi;
  660. u32 data[3];
  661. int i;
  662. *res_chg = false;
  663. if ((bs == NULL) && (fb == NULL)) {
  664. mtk_vcodec_debug(inst, "[EOS]");
  665. vp9_reset(inst);
  666. return ret;
  667. }
  668. if (bs == NULL) {
  669. mtk_vcodec_err(inst, "bs == NULL");
  670. return -EINVAL;
  671. }
  672. mtk_vcodec_debug(inst, "Input BS Size = %zu", bs->size);
  673. while (1) {
  674. struct vdec_fb *cur_fb = NULL;
  675. data[0] = *((unsigned int *)bs->va);
  676. data[1] = *((unsigned int *)(bs->va + 4));
  677. data[2] = *((unsigned int *)(bs->va + 8));
  678. vsi->bs = *bs;
  679. if (fb)
  680. vsi->fb = *fb;
  681. if (!vsi->sf_init) {
  682. unsigned int sf_bs_sz;
  683. unsigned int sf_bs_off;
  684. unsigned char *sf_bs_src;
  685. unsigned char *sf_bs_dst;
  686. sf_bs_sz = bs->size > VP9_SUPER_FRAME_BS_SZ ?
  687. VP9_SUPER_FRAME_BS_SZ : bs->size;
  688. sf_bs_off = VP9_SUPER_FRAME_BS_SZ - sf_bs_sz;
  689. sf_bs_src = bs->va + bs->size - sf_bs_sz;
  690. sf_bs_dst = vsi->sf_bs_buf + sf_bs_off;
  691. memcpy(sf_bs_dst, sf_bs_src, sf_bs_sz);
  692. } else {
  693. if ((vsi->sf_frm_cnt > 0) &&
  694. (vsi->sf_frm_idx < vsi->sf_frm_cnt)) {
  695. unsigned int idx = vsi->sf_frm_idx;
  696. memcpy((void *)bs->va,
  697. (void *)(bs->va +
  698. vsi->sf_frm_offset[idx]),
  699. vsi->sf_frm_sz[idx]);
  700. }
  701. }
  702. ret = vpu_dec_start(&inst->vpu, data, 3);
  703. if (ret) {
  704. mtk_vcodec_err(inst, "vpu_dec_start failed");
  705. goto DECODE_ERROR;
  706. }
  707. if (vsi->resolution_changed) {
  708. if (!vp9_alloc_work_buf(inst)) {
  709. ret = -EINVAL;
  710. goto DECODE_ERROR;
  711. }
  712. }
  713. if (vsi->sf_frm_cnt > 0) {
  714. cur_fb = &vsi->sf_ref_fb[vsi->sf_next_ref_fb_idx].fb;
  715. if (vsi->sf_frm_idx < vsi->sf_frm_cnt)
  716. inst->cur_fb = cur_fb;
  717. else
  718. inst->cur_fb = fb;
  719. } else {
  720. inst->cur_fb = fb;
  721. }
  722. vsi->frm_bufs[vsi->new_fb_idx].buf.fb = inst->cur_fb;
  723. if (!vp9_is_sf_ref_fb(inst, inst->cur_fb))
  724. vp9_add_to_fb_use_list(inst, inst->cur_fb);
  725. mtk_vcodec_debug(inst, "[#pic %d]", vsi->frm_num);
  726. if (vsi->show_existing_frame)
  727. mtk_vcodec_debug(inst,
  728. "drv->new_fb_idx=%d, drv->frm_to_show_idx=%d",
  729. vsi->new_fb_idx, vsi->frm_to_show_idx);
  730. if (vsi->show_existing_frame && (vsi->frm_to_show_idx <
  731. VP9_MAX_FRM_BUF_NUM)) {
  732. mtk_vcodec_err(inst,
  733. "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d",
  734. vsi->new_fb_idx, vsi->frm_to_show_idx);
  735. vp9_ref_cnt_fb(inst, &vsi->new_fb_idx,
  736. vsi->frm_to_show_idx);
  737. ret = -EINVAL;
  738. goto DECODE_ERROR;
  739. }
  740. /* VPU assign the buffer pointer in its address space,
  741. * reassign here
  742. */
  743. for (i = 0; i < ARRAY_SIZE(vsi->frm_refs); i++) {
  744. unsigned int idx = vsi->frm_refs[i].idx;
  745. vsi->frm_refs[i].buf = &vsi->frm_bufs[idx].buf;
  746. }
  747. if (vsi->resolution_changed) {
  748. *res_chg = true;
  749. mtk_vcodec_debug(inst, "VDEC_ST_RESOLUTION_CHANGED");
  750. ret = 0;
  751. goto DECODE_ERROR;
  752. }
  753. if (vp9_decode_end_proc(inst) != true) {
  754. mtk_vcodec_err(inst, "vp9_decode_end_proc");
  755. ret = -EINVAL;
  756. goto DECODE_ERROR;
  757. }
  758. if (vp9_is_last_sub_frm(inst))
  759. break;
  760. }
  761. inst->total_frm_cnt++;
  762. DECODE_ERROR:
  763. if (ret < 0)
  764. vp9_add_to_fb_free_list(inst, fb);
  765. return ret;
  766. }
  767. static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr)
  768. {
  769. cr->left = 0;
  770. cr->top = 0;
  771. cr->width = inst->vsi->pic_w;
  772. cr->height = inst->vsi->pic_h;
  773. mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d\n",
  774. cr->left, cr->top, cr->width, cr->height);
  775. }
  776. static int vdec_vp9_get_param(unsigned long h_vdec,
  777. enum vdec_get_param_type type, void *out)
  778. {
  779. struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
  780. int ret = 0;
  781. switch (type) {
  782. case GET_PARAM_DISP_FRAME_BUFFER:
  783. get_disp_fb(inst, out);
  784. break;
  785. case GET_PARAM_FREE_FRAME_BUFFER:
  786. get_free_fb(inst, out);
  787. break;
  788. case GET_PARAM_PIC_INFO:
  789. get_pic_info(inst, out);
  790. break;
  791. case GET_PARAM_DPB_SIZE:
  792. *((unsigned int *)out) = MAX_VP9_DPB_SIZE;
  793. break;
  794. case GET_PARAM_CROP_INFO:
  795. get_crop_info(inst, out);
  796. break;
  797. default:
  798. mtk_vcodec_err(inst, "not supported param type %d", type);
  799. ret = -EINVAL;
  800. break;
  801. }
  802. return ret;
  803. }
  804. static struct vdec_common_if vdec_vp9_if = {
  805. vdec_vp9_init,
  806. vdec_vp9_decode,
  807. vdec_vp9_get_param,
  808. vdec_vp9_deinit,
  809. };
  810. struct vdec_common_if *get_vp9_dec_comm_if(void);
  811. struct vdec_common_if *get_vp9_dec_comm_if(void)
  812. {
  813. return &vdec_vp9_if;
  814. }