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 
vp9_is_sf_ref_fb(struct vdec_vp9_inst * inst,struct vdec_fb * fb)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 
vp9_rm_from_fb_use_list(struct vdec_vp9_inst * inst,void * addr)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 
vp9_add_to_fb_free_list(struct vdec_vp9_inst * inst,struct vdec_fb * fb)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 
vp9_free_sf_ref_fb(struct vdec_fb * fb)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 
vp9_ref_cnt_fb(struct vdec_vp9_inst * inst,int * idx,int new_idx)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 
vp9_free_all_sf_ref_fb(struct vdec_vp9_inst * inst)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  */
vp9_get_sf_ref_fb(struct vdec_vp9_inst * inst)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 
vp9_alloc_work_buf(struct vdec_vp9_inst * inst)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 
vp9_add_to_fb_disp_list(struct vdec_vp9_inst * inst,struct vdec_fb * fb)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. */
vp9_swap_frm_bufs(struct vdec_vp9_inst * inst)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 
vp9_wait_dec_end(struct vdec_vp9_inst * inst)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 
vp9_alloc_inst(struct mtk_vcodec_ctx * ctx)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 
vp9_free_inst(struct vdec_vp9_inst * inst)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 
vp9_decode_end_proc(struct vdec_vp9_inst * inst)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 
vp9_is_last_sub_frm(struct vdec_vp9_inst * inst)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 
vp9_rm_from_fb_disp_list(struct vdec_vp9_inst * inst)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 
vp9_add_to_fb_use_list(struct vdec_vp9_inst * inst,struct vdec_fb * fb)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 
vp9_reset(struct vdec_vp9_inst * inst)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 
init_all_fb_lists(struct vdec_vp9_inst * inst)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 
get_pic_info(struct vdec_vp9_inst * inst,struct vdec_pic_info * pic)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 
get_disp_fb(struct vdec_vp9_inst * inst,struct vdec_fb ** out_fb)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 
get_free_fb(struct vdec_vp9_inst * inst,struct vdec_fb ** out_fb)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 
validate_vsi_array_indexes(struct vdec_vp9_inst * inst,struct vdec_vp9_vsi * vsi)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 
vdec_vp9_deinit(void * h_vdec)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 
vdec_vp9_init(struct mtk_vcodec_ctx * ctx)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 
vdec_vp9_decode(void * h_vdec,struct mtk_vcodec_mem * bs,struct vdec_fb * fb,bool * res_chg)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 
get_crop_info(struct vdec_vp9_inst * inst,struct v4l2_rect * cr)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 
vdec_vp9_get_param(void * h_vdec,enum vdec_get_param_type type,void * out)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 };
1009