1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016 MediaTek Inc.
4  * Author: PC Chen <pc.chen@mediatek.com>
5  */
6 
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 
10 #include "../vdec_drv_if.h"
11 #include "../mtk_vcodec_util.h"
12 #include "../mtk_vcodec_dec.h"
13 #include "../mtk_vcodec_intr.h"
14 #include "../vdec_vpu_if.h"
15 #include "../vdec_drv_base.h"
16 
17 #define NAL_NON_IDR_SLICE			0x01
18 #define NAL_IDR_SLICE				0x05
19 #define NAL_H264_PPS				0x08
20 #define NAL_TYPE(value)				((value) & 0x1F)
21 
22 #define BUF_PREDICTION_SZ			(32 * 1024)
23 
24 #define MB_UNIT_LEN				16
25 
26 /* motion vector size (bytes) for every macro block */
27 #define HW_MB_STORE_SZ				64
28 
29 #define H264_MAX_FB_NUM				17
30 #define HDR_PARSING_BUF_SZ			1024
31 
32 #define DEC_ERR_RET(ret)			((ret) >> 16)
33 #define H264_ERR_NOT_VALID			3
34 
35 /**
36  * struct h264_fb - h264 decode frame buffer information
37  * @vdec_fb_va  : virtual address of struct vdec_fb
38  * @y_fb_dma    : dma address of Y frame buffer (luma)
39  * @c_fb_dma    : dma address of C frame buffer (chroma)
40  * @poc         : picture order count of frame buffer
41  * @reserved    : for 8 bytes alignment
42  */
43 struct h264_fb {
44 	uint64_t vdec_fb_va;
45 	uint64_t y_fb_dma;
46 	uint64_t c_fb_dma;
47 	int32_t poc;
48 	uint32_t reserved;
49 };
50 
51 /**
52  * struct h264_ring_fb_list - ring frame buffer list
53  * @fb_list   : frame buffer array
54  * @read_idx  : read index
55  * @write_idx : write index
56  * @count     : buffer count in list
57  * @reserved  : for 8 bytes alignment
58  */
59 struct h264_ring_fb_list {
60 	struct h264_fb fb_list[H264_MAX_FB_NUM];
61 	unsigned int read_idx;
62 	unsigned int write_idx;
63 	unsigned int count;
64 	unsigned int reserved;
65 };
66 
67 /**
68  * struct vdec_h264_dec_info - decode information
69  * @dpb_sz		: decoding picture buffer size
70  * @resolution_changed  : resolution change happen
71  * @realloc_mv_buf	: flag to notify driver to re-allocate mv buffer
72  * @reserved		: for 8 bytes alignment
73  * @bs_dma		: Input bit-stream buffer dma address
74  * @y_fb_dma		: Y frame buffer dma address
75  * @c_fb_dma		: C frame buffer dma address
76  * @vdec_fb_va		: VDEC frame buffer struct virtual address
77  */
78 struct vdec_h264_dec_info {
79 	uint32_t dpb_sz;
80 	uint32_t resolution_changed;
81 	uint32_t realloc_mv_buf;
82 	uint32_t reserved;
83 	uint64_t bs_dma;
84 	uint64_t y_fb_dma;
85 	uint64_t c_fb_dma;
86 	uint64_t vdec_fb_va;
87 };
88 
89 /**
90  * struct vdec_h264_vsi - shared memory for decode information exchange
91  *                        between VPU and Host.
92  *                        The memory is allocated by VPU then mapping to Host
93  *                        in vpu_dec_init() and freed in vpu_dec_deinit()
94  *                        by VPU.
95  *                        AP-W/R : AP is writer/reader on this item
96  *                        VPU-W/R: VPU is write/reader on this item
97  * @hdr_buf      : Header parsing buffer (AP-W, VPU-R)
98  * @pred_buf_dma : HW working predication buffer dma address (AP-W, VPU-R)
99  * @mv_buf_dma   : HW working motion vector buffer dma address (AP-W, VPU-R)
100  * @list_free    : free frame buffer ring list (AP-W/R, VPU-W)
101  * @list_disp    : display frame buffer ring list (AP-R, VPU-W)
102  * @dec          : decode information (AP-R, VPU-W)
103  * @pic          : picture information (AP-R, VPU-W)
104  * @crop         : crop information (AP-R, VPU-W)
105  */
106 struct vdec_h264_vsi {
107 	unsigned char hdr_buf[HDR_PARSING_BUF_SZ];
108 	uint64_t pred_buf_dma;
109 	uint64_t mv_buf_dma[H264_MAX_FB_NUM];
110 	struct h264_ring_fb_list list_free;
111 	struct h264_ring_fb_list list_disp;
112 	struct vdec_h264_dec_info dec;
113 	struct vdec_pic_info pic;
114 	struct v4l2_rect crop;
115 };
116 
117 /**
118  * struct vdec_h264_inst - h264 decoder instance
119  * @num_nalu : how many nalus be decoded
120  * @ctx      : point to mtk_vcodec_ctx
121  * @pred_buf : HW working predication buffer
122  * @mv_buf   : HW working motion vector buffer
123  * @vpu      : VPU instance
124  * @vsi      : VPU shared information
125  */
126 struct vdec_h264_inst {
127 	unsigned int num_nalu;
128 	struct mtk_vcodec_ctx *ctx;
129 	struct mtk_vcodec_mem pred_buf;
130 	struct mtk_vcodec_mem mv_buf[H264_MAX_FB_NUM];
131 	struct vdec_vpu_inst vpu;
132 	struct vdec_h264_vsi *vsi;
133 };
134 
get_mv_buf_size(unsigned int width,unsigned int height)135 static unsigned int get_mv_buf_size(unsigned int width, unsigned int height)
136 {
137 	return HW_MB_STORE_SZ * (width/MB_UNIT_LEN) * (height/MB_UNIT_LEN);
138 }
139 
allocate_predication_buf(struct vdec_h264_inst * inst)140 static int allocate_predication_buf(struct vdec_h264_inst *inst)
141 {
142 	int err = 0;
143 
144 	inst->pred_buf.size = BUF_PREDICTION_SZ;
145 	err = mtk_vcodec_mem_alloc(inst->ctx, &inst->pred_buf);
146 	if (err) {
147 		mtk_vcodec_err(inst, "failed to allocate ppl buf");
148 		return err;
149 	}
150 
151 	inst->vsi->pred_buf_dma = inst->pred_buf.dma_addr;
152 	return 0;
153 }
154 
free_predication_buf(struct vdec_h264_inst * inst)155 static void free_predication_buf(struct vdec_h264_inst *inst)
156 {
157 	struct mtk_vcodec_mem *mem = NULL;
158 
159 	mtk_vcodec_debug_enter(inst);
160 
161 	inst->vsi->pred_buf_dma = 0;
162 	mem = &inst->pred_buf;
163 	if (mem->va)
164 		mtk_vcodec_mem_free(inst->ctx, mem);
165 }
166 
alloc_mv_buf(struct vdec_h264_inst * inst,struct vdec_pic_info * pic)167 static int alloc_mv_buf(struct vdec_h264_inst *inst, struct vdec_pic_info *pic)
168 {
169 	int i;
170 	int err;
171 	struct mtk_vcodec_mem *mem = NULL;
172 	unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
173 
174 	for (i = 0; i < H264_MAX_FB_NUM; i++) {
175 		mem = &inst->mv_buf[i];
176 		if (mem->va)
177 			mtk_vcodec_mem_free(inst->ctx, mem);
178 		mem->size = buf_sz;
179 		err = mtk_vcodec_mem_alloc(inst->ctx, mem);
180 		if (err) {
181 			mtk_vcodec_err(inst, "failed to allocate mv buf");
182 			return err;
183 		}
184 		inst->vsi->mv_buf_dma[i] = mem->dma_addr;
185 	}
186 
187 	return 0;
188 }
189 
free_mv_buf(struct vdec_h264_inst * inst)190 static void free_mv_buf(struct vdec_h264_inst *inst)
191 {
192 	int i;
193 	struct mtk_vcodec_mem *mem = NULL;
194 
195 	for (i = 0; i < H264_MAX_FB_NUM; i++) {
196 		inst->vsi->mv_buf_dma[i] = 0;
197 		mem = &inst->mv_buf[i];
198 		if (mem->va)
199 			mtk_vcodec_mem_free(inst->ctx, mem);
200 	}
201 }
202 
check_list_validity(struct vdec_h264_inst * inst,bool disp_list)203 static int check_list_validity(struct vdec_h264_inst *inst, bool disp_list)
204 {
205 	struct h264_ring_fb_list *list;
206 
207 	list = disp_list ? &inst->vsi->list_disp : &inst->vsi->list_free;
208 
209 	if (list->count > H264_MAX_FB_NUM ||
210 	    list->read_idx >= H264_MAX_FB_NUM ||
211 	    list->write_idx >= H264_MAX_FB_NUM) {
212 		mtk_vcodec_err(inst, "%s list err: cnt=%d r_idx=%d w_idx=%d",
213 			       disp_list ? "disp" : "free", list->count,
214 			       list->read_idx, list->write_idx);
215 		return -EINVAL;
216 	}
217 
218 	return 0;
219 }
220 
put_fb_to_free(struct vdec_h264_inst * inst,struct vdec_fb * fb)221 static void put_fb_to_free(struct vdec_h264_inst *inst, struct vdec_fb *fb)
222 {
223 	struct h264_ring_fb_list *list;
224 
225 	if (fb) {
226 		if (check_list_validity(inst, false))
227 			return;
228 
229 		list = &inst->vsi->list_free;
230 		if (list->count == H264_MAX_FB_NUM) {
231 			mtk_vcodec_err(inst, "[FB] put fb free_list full");
232 			return;
233 		}
234 
235 		mtk_vcodec_debug(inst, "[FB] put fb into free_list @(%p, %llx)",
236 				 fb->base_y.va, (u64)fb->base_y.dma_addr);
237 
238 		list->fb_list[list->write_idx].vdec_fb_va = (u64)(uintptr_t)fb;
239 		list->write_idx = (list->write_idx == H264_MAX_FB_NUM - 1) ?
240 				  0 : list->write_idx + 1;
241 		list->count++;
242 	}
243 }
244 
get_pic_info(struct vdec_h264_inst * inst,struct vdec_pic_info * pic)245 static void get_pic_info(struct vdec_h264_inst *inst,
246 			 struct vdec_pic_info *pic)
247 {
248 	*pic = inst->vsi->pic;
249 	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
250 			 pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
251 	mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
252 			 pic->fb_sz[0], pic->fb_sz[1]);
253 }
254 
get_crop_info(struct vdec_h264_inst * inst,struct v4l2_rect * cr)255 static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr)
256 {
257 	cr->left = inst->vsi->crop.left;
258 	cr->top = inst->vsi->crop.top;
259 	cr->width = inst->vsi->crop.width;
260 	cr->height = inst->vsi->crop.height;
261 
262 	mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
263 			 cr->left, cr->top, cr->width, cr->height);
264 }
265 
get_dpb_size(struct vdec_h264_inst * inst,unsigned int * dpb_sz)266 static void get_dpb_size(struct vdec_h264_inst *inst, unsigned int *dpb_sz)
267 {
268 	*dpb_sz = inst->vsi->dec.dpb_sz;
269 	mtk_vcodec_debug(inst, "sz=%d", *dpb_sz);
270 }
271 
vdec_h264_init(struct mtk_vcodec_ctx * ctx)272 static int vdec_h264_init(struct mtk_vcodec_ctx *ctx)
273 {
274 	struct vdec_h264_inst *inst = NULL;
275 	int err;
276 
277 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
278 	if (!inst)
279 		return -ENOMEM;
280 
281 	inst->ctx = ctx;
282 
283 	inst->vpu.id = IPI_VDEC_H264;
284 	inst->vpu.ctx = ctx;
285 
286 	err = vpu_dec_init(&inst->vpu);
287 	if (err) {
288 		mtk_vcodec_err(inst, "vdec_h264 init err=%d", err);
289 		goto error_free_inst;
290 	}
291 
292 	inst->vsi = (struct vdec_h264_vsi *)inst->vpu.vsi;
293 	err = allocate_predication_buf(inst);
294 	if (err)
295 		goto error_deinit;
296 
297 	mtk_vcodec_debug(inst, "H264 Instance >> %p", inst);
298 
299 	ctx->drv_handle = inst;
300 	return 0;
301 
302 error_deinit:
303 	vpu_dec_deinit(&inst->vpu);
304 
305 error_free_inst:
306 	kfree(inst);
307 	return err;
308 }
309 
vdec_h264_deinit(void * h_vdec)310 static void vdec_h264_deinit(void *h_vdec)
311 {
312 	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
313 
314 	mtk_vcodec_debug_enter(inst);
315 
316 	vpu_dec_deinit(&inst->vpu);
317 	free_predication_buf(inst);
318 	free_mv_buf(inst);
319 
320 	kfree(inst);
321 }
322 
find_start_code(unsigned char * data,unsigned int data_sz)323 static int find_start_code(unsigned char *data, unsigned int data_sz)
324 {
325 	if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1)
326 		return 3;
327 
328 	if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 &&
329 	    data[3] == 1)
330 		return 4;
331 
332 	return -1;
333 }
334 
vdec_h264_decode(void * h_vdec,struct mtk_vcodec_mem * bs,struct vdec_fb * fb,bool * res_chg)335 static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
336 			    struct vdec_fb *fb, bool *res_chg)
337 {
338 	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
339 	struct vdec_vpu_inst *vpu = &inst->vpu;
340 	int nal_start_idx = 0;
341 	int err = 0;
342 	unsigned int nal_start;
343 	unsigned int nal_type;
344 	unsigned char *buf;
345 	unsigned int buf_sz;
346 	unsigned int data[2];
347 	uint64_t vdec_fb_va = (u64)(uintptr_t)fb;
348 	uint64_t y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
349 	uint64_t c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
350 
351 	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
352 			 ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
353 
354 	/* bs NULL means flush decoder */
355 	if (bs == NULL)
356 		return vpu_dec_reset(vpu);
357 
358 	buf = (unsigned char *)bs->va;
359 	buf_sz = bs->size;
360 	nal_start_idx = find_start_code(buf, buf_sz);
361 	if (nal_start_idx < 0) {
362 		mtk_vcodec_err(inst, "invalid nal start code");
363 		err = -EIO;
364 		goto err_free_fb_out;
365 	}
366 
367 	nal_start = buf[nal_start_idx];
368 	nal_type = NAL_TYPE(buf[nal_start_idx]);
369 	mtk_vcodec_debug(inst, "\n + NALU[%d] type %d +\n", inst->num_nalu,
370 			 nal_type);
371 
372 	if (nal_type == NAL_H264_PPS) {
373 		buf_sz -= nal_start_idx;
374 		if (buf_sz > HDR_PARSING_BUF_SZ) {
375 			err = -EILSEQ;
376 			goto err_free_fb_out;
377 		}
378 		memcpy(inst->vsi->hdr_buf, buf + nal_start_idx, buf_sz);
379 	}
380 
381 	inst->vsi->dec.bs_dma = (uint64_t)bs->dma_addr;
382 	inst->vsi->dec.y_fb_dma = y_fb_dma;
383 	inst->vsi->dec.c_fb_dma = c_fb_dma;
384 	inst->vsi->dec.vdec_fb_va = vdec_fb_va;
385 
386 	data[0] = buf_sz;
387 	data[1] = nal_start;
388 	err = vpu_dec_start(vpu, data, 2);
389 	if (err) {
390 		if (err > 0 && (DEC_ERR_RET(err) == H264_ERR_NOT_VALID)) {
391 			mtk_vcodec_err(inst, "- error bitstream - err = %d -",
392 				       err);
393 			err = -EIO;
394 		}
395 		goto err_free_fb_out;
396 	}
397 
398 	*res_chg = inst->vsi->dec.resolution_changed;
399 	if (*res_chg) {
400 		struct vdec_pic_info pic;
401 
402 		mtk_vcodec_debug(inst, "- resolution changed -");
403 		get_pic_info(inst, &pic);
404 
405 		if (inst->vsi->dec.realloc_mv_buf) {
406 			err = alloc_mv_buf(inst, &pic);
407 			if (err)
408 				goto err_free_fb_out;
409 		}
410 	}
411 
412 	if (nal_type == NAL_NON_IDR_SLICE || nal_type == NAL_IDR_SLICE) {
413 		/* wait decoder done interrupt */
414 		err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
415 						   MTK_INST_IRQ_RECEIVED,
416 						   WAIT_INTR_TIMEOUT_MS);
417 		if (err)
418 			goto err_free_fb_out;
419 
420 		vpu_dec_end(vpu);
421 	}
422 
423 	mtk_vcodec_debug(inst, "\n - NALU[%d] type=%d -\n", inst->num_nalu,
424 			 nal_type);
425 	return 0;
426 
427 err_free_fb_out:
428 	put_fb_to_free(inst, fb);
429 	mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err);
430 	return err;
431 }
432 
vdec_h264_get_fb(struct vdec_h264_inst * inst,struct h264_ring_fb_list * list,bool disp_list,struct vdec_fb ** out_fb)433 static void vdec_h264_get_fb(struct vdec_h264_inst *inst,
434 			     struct h264_ring_fb_list *list,
435 			     bool disp_list, struct vdec_fb **out_fb)
436 {
437 	struct vdec_fb *fb;
438 
439 	if (check_list_validity(inst, disp_list))
440 		return;
441 
442 	if (list->count == 0) {
443 		mtk_vcodec_debug(inst, "[FB] there is no %s fb",
444 				 disp_list ? "disp" : "free");
445 		*out_fb = NULL;
446 		return;
447 	}
448 
449 	fb = (struct vdec_fb *)
450 		(uintptr_t)list->fb_list[list->read_idx].vdec_fb_va;
451 	fb->status |= (disp_list ? FB_ST_DISPLAY : FB_ST_FREE);
452 
453 	*out_fb = fb;
454 	mtk_vcodec_debug(inst, "[FB] get %s fb st=%d poc=%d %llx",
455 			 disp_list ? "disp" : "free",
456 			 fb->status, list->fb_list[list->read_idx].poc,
457 			 list->fb_list[list->read_idx].vdec_fb_va);
458 
459 	list->read_idx = (list->read_idx == H264_MAX_FB_NUM - 1) ?
460 			 0 : list->read_idx + 1;
461 	list->count--;
462 }
463 
vdec_h264_get_param(void * h_vdec,enum vdec_get_param_type type,void * out)464 static int vdec_h264_get_param(void *h_vdec, enum vdec_get_param_type type,
465 			       void *out)
466 {
467 	struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
468 
469 	switch (type) {
470 	case GET_PARAM_DISP_FRAME_BUFFER:
471 		vdec_h264_get_fb(inst, &inst->vsi->list_disp, true, out);
472 		break;
473 
474 	case GET_PARAM_FREE_FRAME_BUFFER:
475 		vdec_h264_get_fb(inst, &inst->vsi->list_free, false, out);
476 		break;
477 
478 	case GET_PARAM_PIC_INFO:
479 		get_pic_info(inst, out);
480 		break;
481 
482 	case GET_PARAM_DPB_SIZE:
483 		get_dpb_size(inst, out);
484 		break;
485 
486 	case GET_PARAM_CROP_INFO:
487 		get_crop_info(inst, out);
488 		break;
489 
490 	default:
491 		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
492 		return -EINVAL;
493 	}
494 
495 	return 0;
496 }
497 
498 const struct vdec_common_if vdec_h264_if = {
499 	.init		= vdec_h264_init,
500 	.decode		= vdec_h264_decode,
501 	.get_param	= vdec_h264_get_param,
502 	.deinit		= vdec_h264_deinit,
503 };
504