• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd
4  *
5  * author:
6  *	Ding Wei, leo.ding@rock-chips.com
7  *
8  */
9 
10 #include <asm/cacheflush.h>
11 #include <linux/clk.h>
12 #include <linux/clk/clk-conf.h>
13 #include <linux/delay.h>
14 #include <linux/iopoll.h>
15 #include <linux/interrupt.h>
16 #include <linux/module.h>
17 #include <linux/types.h>
18 #include <linux/of_platform.h>
19 #include <linux/pm_domain.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/slab.h>
22 #include <linux/uaccess.h>
23 #include <linux/regmap.h>
24 #include <linux/proc_fs.h>
25 #include <soc/rockchip/pm_domains.h>
26 
27 #include "mpp_debug.h"
28 #include "mpp_common.h"
29 #include "mpp_iommu.h"
30 
31 #define AV1DEC_DRIVER_NAME			"mpp_av1dec"
32 
33 #define	AV1DEC_SESSION_MAX_BUFFERS		40
34 
35 /* REG_DEC_INT, bits for interrupt */
36 #define	AV1DEC_INT_PIC_INF		BIT(24)
37 #define	AV1DEC_INT_TIMEOUT		BIT(18)
38 #define	AV1DEC_INT_SLICE		BIT(17)
39 #define	AV1DEC_INT_STRM_ERROR		BIT(16)
40 #define	AV1DEC_INT_ASO_ERROR		BIT(15)
41 #define	AV1DEC_INT_BUF_EMPTY		BIT(14)
42 #define	AV1DEC_INT_BUS_ERROR		BIT(13)
43 #define	AV1DEC_DEC_INT			BIT(12)
44 #define	AV1DEC_DEC_INT_RAW		BIT(8)
45 #define	AV1DEC_DEC_IRQ_DIS		BIT(4)
46 #define	AV1DEC_DEC_START		BIT(0)
47 
48 #define MPP_ALIGN(x, a)         (((x)+(a)-1)&~((a)-1))
49 /* REG_DEC_EN, bit for gate */
50 #define	AV1DEC_CLOCK_GATE_EN		BIT(10)
51 
52 #define to_av1dec_info(info)		\
53 		container_of(info, struct av1dec_hw_info, hw)
54 #define to_av1dec_task(ctx)		\
55 		container_of(ctx, struct av1dec_task, mpp_task)
56 #define to_av1dec_dev(dev)		\
57 		container_of(dev, struct av1dec_dev, mpp)
58 
59 /* define functions */
60 #define MPP_GET_BITS(v, p, b)	(((v) >> (p)) & ((1 << (b)) - 1))
61 #define MPP_BASE_TO_IDX(a)	((a) / sizeof(u32))
62 
63 enum AV1DEC_CLASS_TYPE {
64 	AV1DEC_CLASS_VCD	= 0,
65 	AV1DEC_CLASS_CACHE	= 1,
66 	AV1DEC_CLASS_AFBC	= 2,
67 	AV1DEC_CLASS_BUTT,
68 };
69 
70 enum av1dec_trans_type {
71 	AV1DEC_TRANS_BASE	= 0x0000,
72 
73 	AV1DEC_TRANS_VCD	= AV1DEC_TRANS_BASE + 0,
74 	AV1DEC_TRANS_CACHE	= AV1DEC_TRANS_BASE + 1,
75 	AV1DEC_TRANS_AFBC	= AV1DEC_TRANS_BASE + 2,
76 	AV1DEC_TRANS_BUTT,
77 };
78 
79 struct av1dec_hw_info {
80 	struct mpp_hw_info hw;
81 	/* register range by class */
82 	u32 reg_class_num;
83 	struct {
84 		u32 base_s;
85 		u32 base_e;
86 	} reg_class[AV1DEC_CLASS_BUTT];
87 	/* fd translate for class */
88 	u32 trans_class_num;
89 	struct {
90 		u32 class;
91 		u32 trans_fmt;
92 	} trans_class[AV1DEC_TRANS_BUTT];
93 
94 	/* interrupt config register */
95 	int int_base;
96 	/* enable hardware register */
97 	int en_base;
98 	/* status register */
99 	int sta_base;
100 	/* clear irq register */
101 	int clr_base;
102 	/* stream register */
103 	int strm_base;
104 
105 	u32 err_mask;
106 };
107 
108 struct av1dec_task {
109 	struct mpp_task mpp_task;
110 
111 	struct av1dec_hw_info *hw_info;
112 	/* for malloc register data buffer */
113 	u32 *reg_data;
114 	/* class register */
115 	struct {
116 		u32 valid;
117 		u32 base;
118 		u32 *data;
119 		/* offset base reg_data */
120 		u32 off;
121 		/* length for class */
122 		u32 len;
123 	} reg_class[AV1DEC_CLASS_BUTT];
124 	/* register offset info */
125 	struct reg_offset_info off_inf;
126 
127 	enum MPP_CLOCK_MODE clk_mode;
128 	u32 irq_status;
129 	/* req for current task */
130 	u32 w_req_cnt;
131 	struct mpp_request w_reqs[MPP_MAX_MSG_NUM];
132 	u32 r_req_cnt;
133 	struct mpp_request r_reqs[MPP_MAX_MSG_NUM];
134 };
135 
136 struct av1dec_dev {
137 	struct mpp_dev mpp;
138 	struct av1dec_hw_info *hw_info;
139 
140 	struct mpp_clk_info aclk_info;
141 	struct mpp_clk_info hclk_info;
142 	u32 default_max_load;
143 #ifdef CONFIG_PROC_FS
144 	struct proc_dir_entry *procfs;
145 #endif
146 	struct reset_control *rst_a;
147 	struct reset_control *rst_h;
148 
149 	void __iomem *reg_base[AV1DEC_CLASS_BUTT];
150 	int irq[AV1DEC_CLASS_BUTT];
151 };
152 
153 static struct av1dec_hw_info av1dec_hw_info = {
154 	.hw = {
155 		.reg_num = 512,
156 		.reg_id = 0,
157 		.reg_en = 1,
158 		.reg_start = 1,
159 		.reg_end = 319,
160 	},
161 	.reg_class_num = 3,
162 	.reg_class[AV1DEC_CLASS_VCD] = {
163 		.base_s = 0x0000,
164 		.base_e = 0x07fc,
165 	},
166 	.reg_class[AV1DEC_CLASS_CACHE] = {
167 		.base_s = 0x10000,
168 		.base_e = 0x10294,
169 	},
170 	.reg_class[AV1DEC_CLASS_AFBC] = {
171 		.base_s = 0x20000,
172 		.base_e = 0x2034c,
173 	},
174 	.trans_class_num = AV1DEC_TRANS_BUTT,
175 	.trans_class[AV1DEC_CLASS_VCD] = {
176 		.class = AV1DEC_CLASS_VCD,
177 		.trans_fmt = AV1DEC_TRANS_VCD,
178 	},
179 	.trans_class[AV1DEC_CLASS_CACHE] = {
180 		.class = AV1DEC_CLASS_CACHE,
181 		.trans_fmt = AV1DEC_TRANS_CACHE,
182 	},
183 	.trans_class[AV1DEC_CLASS_AFBC] = {
184 		.class = AV1DEC_CLASS_AFBC,
185 		.trans_fmt = AV1DEC_TRANS_AFBC,
186 	},
187 	.int_base = 0x0004,
188 	.en_base = 0x0004,
189 	.sta_base = 0x0004,
190 	.clr_base = 0x0004,
191 	.strm_base = 0x02a4,
192 	.err_mask = 0x7e000,
193 };
194 
195 /*
196  * file handle translate information for v2
197  */
198 static const u16 trans_tbl_av1_vcd[] = {
199 	65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91,
200 	93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115,
201 	117, 133, 135, 137, 139, 141, 143, 145, 147,
202 	167, 169, 171, 173, 175, 177, 179, 183, 190, 192, 194,
203 	196, 198, 200, 202, 204, 224, 226, 228, 230, 232, 234,
204 	236, 238, 326, 328, 339, 341, 348, 350, 505, 507
205 };
206 
207 static const u16 trans_tbl_av1_cache[] = {
208 	13, 18, 23, 28, 33, 38, 43, 48, 53, 58, 63, 68, 73, 78, 83, 88,
209 	134, 135, 138, 139, 142, 143, 146, 147,
210 };
211 
212 static const u16 trans_tbl_av1_afbc[] = {
213 	32, 33, 34, 35, 48, 49, 50, 51, 96, 97, 98, 99
214 };
215 
216 static struct mpp_trans_info trans_av1dec[] = {
217 	[AV1DEC_TRANS_VCD] = {
218 		.count = ARRAY_SIZE(trans_tbl_av1_vcd),
219 		.table = trans_tbl_av1_vcd,
220 	},
221 	[AV1DEC_TRANS_CACHE] = {
222 		.count = ARRAY_SIZE(trans_tbl_av1_cache),
223 		.table = trans_tbl_av1_cache,
224 	},
225 	[AV1DEC_TRANS_AFBC] = {
226 		.count = ARRAY_SIZE(trans_tbl_av1_afbc),
227 		.table = trans_tbl_av1_afbc,
228 	},
229 };
230 
req_over_class(struct mpp_request * req,struct av1dec_task * task,int class)231 static bool req_over_class(struct mpp_request *req,
232 			   struct av1dec_task *task, int class)
233 {
234 	bool ret;
235 	u32 base_s, base_e, req_e;
236 	struct av1dec_hw_info *hw = task->hw_info;
237 
238 	if (class > hw->reg_class_num)
239 		return false;
240 
241 	base_s = hw->reg_class[class].base_s;
242 	base_e = hw->reg_class[class].base_e;
243 	req_e = req->offset + req->size - sizeof(u32);
244 
245 	ret = (req->offset <= base_e && req_e >= base_s) ? true : false;
246 
247 	return ret;
248 }
249 
av1dec_alloc_reg_class(struct av1dec_task * task)250 static int av1dec_alloc_reg_class(struct av1dec_task *task)
251 {
252 	int i;
253 	u32 data_size;
254 	struct av1dec_hw_info *hw = task->hw_info;
255 
256 	data_size = 0;
257 	for (i = 0; i < hw->reg_class_num; i++) {
258 		u32 base_s = hw->reg_class[i].base_s;
259 		u32 base_e = hw->reg_class[i].base_e;
260 
261 		task->reg_class[i].base = base_s;
262 		task->reg_class[i].off = data_size;
263 		task->reg_class[i].len = base_e - base_s + sizeof(u32);
264 		data_size += task->reg_class[i].len;
265 	}
266 
267 	task->reg_data = kzalloc(data_size, GFP_KERNEL);
268 	if (!task->reg_data)
269 		return -ENOMEM;
270 
271 	for (i = 0; i < hw->reg_class_num; i++)
272 		task->reg_class[i].data = task->reg_data + (task->reg_class[i].off / sizeof(u32));
273 
274 	return 0;
275 }
276 
av1dec_update_req(struct av1dec_task * task,int class,struct mpp_request * req_in,struct mpp_request * req_out)277 static int av1dec_update_req(struct av1dec_task *task, int class,
278 			     struct mpp_request *req_in,
279 			     struct mpp_request *req_out)
280 {
281 	u32 base_s, base_e, req_e, s, e;
282 	struct av1dec_hw_info *hw = task->hw_info;
283 
284 	if (class > hw->reg_class_num)
285 		return -EINVAL;
286 
287 	base_s = hw->reg_class[class].base_s;
288 	base_e = hw->reg_class[class].base_e;
289 	req_e = req_in->offset + req_in->size - sizeof(u32);
290 	s = max(req_in->offset, base_s);
291 	e = min(req_e, base_e);
292 
293 	req_out->offset = s;
294 	req_out->size = e - s + sizeof(u32);
295 	req_out->data = (u8 *)req_in->data + (s - req_in->offset);
296 	mpp_debug(DEBUG_TASK_INFO, "req_out->offset=%08x, req_out->size=%d\n",
297 		  req_out->offset, req_out->size);
298 
299 	return 0;
300 }
301 
av1dec_extract_task_msg(struct av1dec_task * task,struct mpp_task_msgs * msgs)302 static int av1dec_extract_task_msg(struct av1dec_task *task,
303 				   struct mpp_task_msgs *msgs)
304 {
305 	int ret;
306 	u32 i;
307 	struct mpp_request *req;
308 	struct av1dec_hw_info *hw = task->hw_info;
309 
310 	mpp_debug_enter();
311 
312 	mpp_debug(DEBUG_TASK_INFO, "req_cnt=%d, set_cnt=%d, poll_cnt=%d, reg_class=%d\n",
313 		msgs->req_cnt, msgs->set_cnt, msgs->poll_cnt, hw->reg_class_num);
314 
315 	for (i = 0; i < msgs->req_cnt; i++) {
316 		req = &msgs->reqs[i];
317 		mpp_debug(DEBUG_TASK_INFO, "msg: cmd %08x, offset %08x, size %d\n",
318 			req->cmd, req->offset, req->size);
319 		if (!req->size)
320 			continue;
321 
322 		switch (req->cmd) {
323 		case MPP_CMD_SET_REG_WRITE: {
324 			u32 class;
325 			u32 base, *regs;
326 			struct mpp_request *wreq;
327 
328 			for (class = 0; class < hw->reg_class_num; class++) {
329 				if (!req_over_class(req, task, class))
330 					continue;
331 				mpp_debug(DEBUG_TASK_INFO, "found write_calss %d\n", class);
332 				wreq = &task->w_reqs[task->w_req_cnt];
333 				av1dec_update_req(task, class, req, wreq);
334 
335 				base = task->reg_class[class].base;
336 				regs = (u32 *)task->reg_class[class].data;
337 				regs += MPP_BASE_TO_IDX(req->offset - base);
338 				if (copy_from_user(regs, wreq->data, wreq->size)) {
339 					mpp_err("copy_from_user fail, offset %08x\n", wreq->offset);
340 					ret = -EIO;
341 					goto fail;
342 				}
343 				task->w_req_cnt++;
344 			}
345 		} break;
346 		case MPP_CMD_SET_REG_READ: {
347 			u32 class;
348 			struct mpp_request *rreq;
349 
350 			for (class = 0; class < hw->reg_class_num; class++) {
351 				if (!req_over_class(req, task, class))
352 					continue;
353 				mpp_debug(DEBUG_TASK_INFO, "found read_calss %d\n", class);
354 				rreq = &task->r_reqs[task->r_req_cnt];
355 				av1dec_update_req(task, class, req, rreq);
356 				task->r_req_cnt++;
357 			}
358 		} break;
359 		case MPP_CMD_SET_REG_ADDR_OFFSET: {
360 			mpp_extract_reg_offset_info(&task->off_inf, req);
361 		} break;
362 		default:
363 			break;
364 		}
365 	}
366 	mpp_debug(DEBUG_TASK_INFO, "w_req_cnt=%d, r_req_cnt=%d\n",
367 		  task->w_req_cnt, task->r_req_cnt);
368 
369 	mpp_debug_leave();
370 	return 0;
371 
372 fail:
373 	mpp_debug_leave();
374 	return ret;
375 }
376 
av1dec_alloc_task(struct mpp_session * session,struct mpp_task_msgs * msgs)377 static void *av1dec_alloc_task(struct mpp_session *session,
378 			       struct mpp_task_msgs *msgs)
379 {
380 	int ret;
381 	u32 i, j;
382 	struct mpp_task *mpp_task = NULL;
383 	struct av1dec_task *task = NULL;
384 	struct mpp_dev *mpp = session->mpp;
385 
386 	mpp_debug_enter();
387 
388 	task = kzalloc(sizeof(*task), GFP_KERNEL);
389 	if (!task)
390 		return NULL;
391 
392 	mpp_task = &task->mpp_task;
393 	mpp_task_init(session, mpp_task);
394 	mpp_task->hw_info = mpp->var->hw_info;
395 	task->hw_info = to_av1dec_info(mpp_task->hw_info);
396 
397 	/* alloc reg data for task */
398 	ret = av1dec_alloc_reg_class(task);
399 	if (ret)
400 		goto free_task;
401 	mpp_task->reg = task->reg_class[0].data;
402 	/* extract reqs for current task */
403 	ret = av1dec_extract_task_msg(task, msgs);
404 	if (ret)
405 		goto free_reg_class;
406 
407 	/* process fd in register */
408 	if (!(msgs->flags & MPP_FLAGS_REG_FD_NO_TRANS)) {
409 		int cnt;
410 		const u16 *tbl;
411 		u32 offset;
412 		struct av1dec_hw_info *hw = task->hw_info;
413 
414 		for (i = 0; i < task->w_req_cnt; i++) {
415 			struct mpp_request *req = &task->w_reqs[i];
416 
417 			for (i = 0; i < hw->trans_class_num; i++) {
418 				u32 class = hw->trans_class[i].class;
419 				u32 fmt = hw->trans_class[i].trans_fmt;
420 				u32 *reg = task->reg_class[class].data;
421 				u32 base_idx = MPP_BASE_TO_IDX(task->reg_class[class].base);
422 
423 				if (!req_over_class(req, task, i))
424 					continue;
425 				mpp_debug(DEBUG_TASK_INFO, "class=%d, base_idx=%d\n",
426 					  class, base_idx);
427 				if (!reg)
428 					continue;
429 
430 				ret = mpp_translate_reg_address(session, mpp_task, fmt, reg, NULL);
431 				if (ret)
432 					goto fail;
433 
434 				cnt = mpp->var->trans_info[fmt].count;
435 				tbl = mpp->var->trans_info[fmt].table;
436 				for (j = 0; j < cnt; j++) {
437 					offset = mpp_query_reg_offset_info(&task->off_inf,
438 									tbl[j] + base_idx);
439 					mpp_debug(DEBUG_IOMMU,
440 						"reg[%d] + offset %d\n", tbl[j] + base_idx, offset);
441 					reg[tbl[j]] += offset;
442 				}
443 			}
444 		}
445 	}
446 	task->clk_mode = CLK_MODE_NORMAL;
447 
448 	mpp_debug_leave();
449 
450 	return mpp_task;
451 
452 fail:
453 	mpp_task_dump_mem_region(mpp, mpp_task);
454 	mpp_task_dump_reg(mpp, mpp_task);
455 	mpp_task_finalize(session, mpp_task);
456 free_reg_class:
457 	kfree(task->reg_data);
458 free_task:
459 	kfree(task);
460 
461 	return NULL;
462 }
463 #define AV1_PP_CONFIG_INDEX	321
464 #define AV1_PP_TILE_SIZE	GENMASK_ULL(10, 9)
465 #define AV1_PP_TILE_16X16	BIT(10)
466 
467 #define AV1_PP_OUT_LUMA_ADR_INDEX	326
468 #define AV1_PP_OUT_CHROMA_ADR_INDEX	328
469 
470 #define AV1_L2_CACHE_SHAPER_CTRL	0x20
471 #define AV1_L2_CACHE_SHAPER_EN		BIT(0)
472 #define AV1_L2_CACHE_PP0_Y_CONFIG0	0x84
473 #define AV1_L2_CACHE_PP0_Y_CONFIG2	0x8c
474 #define AV1_L2_CACHE_PP0_Y_CONFIG3	0x90
475 #define AV1_L2_CACHE_PP0_U_CONFIG0	0x98
476 #define AV1_L2_CACHE_PP0_U_CONFIG2	0xa0
477 #define AV1_L2_CACHE_PP0_U_CONFIG3	0xa4
478 
479 #define AV1_L2_CACHE_RD_ONLY_CTRL	0x204
480 #define AV1_L2_CACHE_RD_ONLY_CONFIG	0x208
481 
av1dec_set_l2_cache(struct av1dec_dev * dec,struct av1dec_task * task)482 static int av1dec_set_l2_cache(struct av1dec_dev *dec, struct av1dec_task *task)
483 {
484 	int val;
485 	u32 *regs = (u32 *)task->reg_class[0].data;
486 	u32 width = (regs[4] >> 19) * 8;
487 	u32 height = ((regs[4] >> 6) & 0x1fff) * 8;
488 	u32 pixel_width = (((regs[322]) >> 27) & 0x1F) == 1 ? 8 : 16;
489 	u32 pre_fetch_height = 136;
490 	u32 max_h;
491 	u32 line_cnt;
492 	u32 line_size;
493 	u32 line_stride;
494 
495 	/* channel 4, PPU0_Y Configuration */
496 	/* afbc sharper can't use open cache.
497 	 * afbc out must be tile 16x16.
498 	 */
499 	if ((regs[AV1_PP_CONFIG_INDEX] & AV1_PP_TILE_SIZE) != AV1_PP_TILE_16X16) {
500 		line_size = MPP_ALIGN(MPP_ALIGN(width * pixel_width, 8) / 8, 16);
501 		line_stride = MPP_ALIGN(MPP_ALIGN(width * pixel_width, 8) / 8, 16) >> 4;
502 		line_cnt = height;
503 		max_h = pre_fetch_height;
504 
505 		writel_relaxed(regs[AV1_PP_OUT_LUMA_ADR_INDEX] + 0x1,
506 			       dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_Y_CONFIG0);
507 		val = line_size | (line_stride << 16);
508 		writel_relaxed(val, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_Y_CONFIG2);
509 
510 		val = line_cnt | (max_h << 16);
511 		writel_relaxed(val, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_Y_CONFIG3);
512 
513 		/* channel 5, PPU0_U Configuration */
514 		line_size = MPP_ALIGN(MPP_ALIGN(width * pixel_width, 8) / 8, 16);
515 		line_stride = MPP_ALIGN(MPP_ALIGN(width * pixel_width, 8) / 8, 16) >> 4;
516 		line_cnt = height >> 1;
517 		max_h = pre_fetch_height >> 1;
518 
519 		writel_relaxed(regs[AV1_PP_OUT_CHROMA_ADR_INDEX] + 0x1,
520 			       dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_U_CONFIG0);
521 		val = line_size | (line_stride << 16);
522 		writel_relaxed(val, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_U_CONFIG2);
523 
524 		val = line_cnt | (max_h << 16);
525 		writel_relaxed(val, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_U_CONFIG3);
526 		/* shaper enable */
527 		writel_relaxed(AV1_L2_CACHE_SHAPER_EN,
528 			       dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_SHAPER_CTRL);
529 	}
530 
531 	/* TODO: set exception list */
532 
533 	/* multi id enable bit */
534 	writel_relaxed(0x00000001, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_RD_ONLY_CONFIG);
535 	/* reorder_e and cache_e */
536 	writel_relaxed(0x00000081, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_RD_ONLY_CTRL);
537 	/* wmb */
538 	wmb();
539 
540 	return 0;
541 }
542 #define REG_CONTROL		0x20
543 #define REG_INTRENBL		0x34
544 #define REG_ACKNOWLEDGE		0x38
545 #define REG_FORMAT		0x100
546 #define REG_COMPRESSENABLE	0x340
547 #define REG_HEADERBASE		0x80
548 #define REG_PAYLOADBASE		0xC0
549 #define REG_INPUTBUFBASE	0x180
550 #define REG_INPUTBUFSTRIDE	0x200
551 #define REG_INPUTBUFSIZE	0x140
552 
av1dec_set_afbc(struct av1dec_dev * dec,struct av1dec_task * task)553 static int av1dec_set_afbc(struct av1dec_dev *dec, struct av1dec_task *task)
554 {
555 	u32 *regs = (u32 *)task->reg_class[0].data;
556 	u32 width = (regs[4] >> 19) * 8;
557 	u32 height = ((regs[4] >> 6) & 0x1fff) * 8;
558 	u32 pixel_width_y, pixel_width_c, pixel_width = 8;
559 	u32 vir_top  =  (((regs[503]) >> 16) & 0xf);
560 	u32 vir_left  =  (((regs[503]) >> 20) & 0xf);
561 	u32 vir_bottom = (((regs[503]) >> 24) & 0xf);
562 	u32 vir_right  =  (((regs[503]) >> 28) & 0xf);
563 	u32 fbc_format = 0;
564 	u32 fbc_stream_number = 0;
565 	u32 fbc_comp_en[2] = {0, 0};
566 	u32 pp_width_final[2] = {0, 0};
567 	u32 pp_height_final[2] = {0, 0};
568 	u32 pp_hdr_base[2] = {0, 0};
569 	u32 pp_payload_base[2] = {0, 0};
570 	u32 pp_input_base[2] = {0, 0};
571 	u32 pp_input_stride[2] = {0, 0};
572 	u32 bus_address;
573 	u32 i = 0;
574 
575 	pixel_width_y = ((regs[8] >> 6) & 0x3) + 8;
576 	pixel_width_c = ((regs[8] >> 4) & 0x3) + 8;
577 	pixel_width = (pixel_width_y == 8 && pixel_width_c == 8) ? 8 : 10;
578 
579 	if ((regs[AV1_PP_CONFIG_INDEX] & AV1_PP_TILE_SIZE) == AV1_PP_TILE_16X16) {
580 		u32 offset = MPP_ALIGN((vir_left + width + vir_right) *
581 			     (height + 28) / 16, 64);
582 
583 		bus_address = regs[505];
584 		fbc_stream_number++;
585 		if (pixel_width == 10)
586 			fbc_format = 3;
587 		else
588 			fbc_format = 9;
589 		fbc_comp_en[0] = 1;
590 		fbc_comp_en[1] = 1;
591 
592 		pp_width_final[0] = pp_width_final[1] = vir_left + width + vir_right;
593 		pp_height_final[0] = pp_height_final[1] = vir_top + height + vir_bottom;
594 
595 		if (pixel_width == 10)
596 			pp_input_stride[0] = pp_input_stride[1] = 2 * pp_width_final[0];
597 		else
598 			pp_input_stride[0] = pp_input_stride[1] = pp_width_final[0];
599 
600 		pp_hdr_base[0] = pp_hdr_base[1] = bus_address;
601 		pp_payload_base[0] = pp_payload_base[1] = bus_address + offset;
602 		pp_input_base[0] = pp_input_base[1] = bus_address;
603 
604 		writel_relaxed((fbc_stream_number << 9),
605 			       dec->reg_base[AV1DEC_CLASS_AFBC] + REG_CONTROL);
606 		writel_relaxed(0x1, dec->reg_base[AV1DEC_CLASS_AFBC] + REG_INTRENBL);
607 
608 		for (i = 0; i < 2; i++) {
609 			writel_relaxed(fbc_format,
610 				       dec->reg_base[AV1DEC_CLASS_AFBC] + REG_FORMAT + i * 4);
611 			writel_relaxed(fbc_comp_en[i], dec->reg_base[AV1DEC_CLASS_AFBC] +
612 				       REG_COMPRESSENABLE + i * 4);
613 			/* hdr base */
614 			writel_relaxed(pp_hdr_base[i],
615 				       dec->reg_base[AV1DEC_CLASS_AFBC] + REG_HEADERBASE + i * 4);
616 			/* payload */
617 			writel_relaxed(pp_payload_base[i],
618 				       dec->reg_base[AV1DEC_CLASS_AFBC] + REG_PAYLOADBASE + i * 4);
619 			/* bufsize */
620 			writel_relaxed(((pp_height_final[i] << 15) | pp_width_final[i]),
621 				       dec->reg_base[AV1DEC_CLASS_AFBC] + REG_INPUTBUFSIZE + i * 4);
622 			/* buf */
623 			writel_relaxed(pp_input_base[i],
624 				       dec->reg_base[AV1DEC_CLASS_AFBC] + REG_INPUTBUFBASE + i * 4);
625 			/* stride */
626 			writel_relaxed(pp_input_stride[i], dec->reg_base[AV1DEC_CLASS_AFBC] +
627 				       REG_INPUTBUFSTRIDE + i * 4);
628 		}
629 		/* wmb */
630 		wmb();
631 		writel(((fbc_stream_number << 9) | (1 << 7)),
632 		       dec->reg_base[AV1DEC_CLASS_AFBC] + REG_CONTROL); /* update */
633 		writel((fbc_stream_number << 9), dec->reg_base[AV1DEC_CLASS_AFBC] + REG_CONTROL);
634 
635 	}
636 	return 0;
637 }
638 
av1dec_run(struct mpp_dev * mpp,struct mpp_task * mpp_task)639 static int av1dec_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
640 {
641 	int i;
642 	u32 en_val = 0;
643 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
644 	struct av1dec_hw_info *hw = dec->hw_info;
645 	struct av1dec_task *task = to_av1dec_task(mpp_task);
646 
647 	mpp_debug_enter();
648 	mpp_iommu_flush_tlb(mpp->iommu_info);
649 	av1dec_set_l2_cache(dec, task);
650 	av1dec_set_afbc(dec, task);
651 
652 	for (i = 0; i < task->w_req_cnt; i++) {
653 		int class;
654 		struct mpp_request *req = &task->w_reqs[i];
655 
656 		for (class = 0; class < hw->reg_class_num; class++) {
657 			int j, s, e;
658 			u32 base, *regs;
659 
660 			if (!req_over_class(req, task, class))
661 				continue;
662 			base = task->reg_class[class].base;
663 			s = MPP_BASE_TO_IDX(req->offset - base);
664 			e = s + req->size / sizeof(u32);
665 			regs = (u32 *)task->reg_class[class].data;
666 
667 			mpp_debug(DEBUG_TASK_INFO, "found rd_class %d, base=%08x, s=%d, e=%d\n",
668 				  class, base, s, e);
669 			for (j = s; j < e; j++) {
670 				if (class == 0 && j == hw->hw.reg_en) {
671 					en_val = regs[j];
672 					continue;
673 				}
674 				writel_relaxed(regs[j], dec->reg_base[class] + j * sizeof(u32));
675 			}
676 		}
677 	}
678 
679 	/* init current task */
680 	mpp->cur_task = mpp_task;
681 	/* Flush the register before the start the device */
682 	wmb();
683 	mpp_write(mpp, hw->en_base, en_val);
684 
685 	mpp_debug_leave();
686 
687 	return 0;
688 }
689 
av1dec_vcd_irq(struct mpp_dev * mpp)690 static int av1dec_vcd_irq(struct mpp_dev *mpp)
691 {
692 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
693 	struct av1dec_hw_info *hw = dec->hw_info;
694 
695 	mpp_debug_enter();
696 
697 	mpp->irq_status = mpp_read(mpp, hw->sta_base);
698 	if (!mpp->irq_status)
699 		return IRQ_NONE;
700 
701 	mpp_write(mpp, hw->clr_base, 0);
702 
703 	mpp_debug_leave();
704 
705 	return IRQ_WAKE_THREAD;
706 }
707 
av1dec_isr(struct mpp_dev * mpp)708 static int av1dec_isr(struct mpp_dev *mpp)
709 {
710 	struct mpp_task *mpp_task = mpp->cur_task;
711 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
712 	struct av1dec_task *task = to_av1dec_task(mpp_task);
713 	u32 *regs = (u32 *)task->reg_class[0].data;
714 
715 	mpp_debug_enter();
716 
717 	/* FIXME use a spin lock here */
718 	if (!mpp_task) {
719 		dev_err(mpp->dev, "no current task\n");
720 		return IRQ_HANDLED;
721 	}
722 
723 	mpp_time_diff(mpp_task);
724 	mpp->cur_task = NULL;
725 
726 	/* clear l2 cache status */
727 	writel_relaxed(0x0, dec->reg_base[AV1DEC_CLASS_CACHE] + 0x020);
728 	writel_relaxed(0x0, dec->reg_base[AV1DEC_CLASS_CACHE] + 0x204);
729 	/* multi id enable bit */
730 	writel_relaxed(0x00000000, dec->reg_base[AV1DEC_CLASS_CACHE] + 0x208);
731 
732 	if (((regs[321] >> 9) & 0x3) == 0x2) {
733 		u32 ack_status = readl(dec->reg_base[AV1DEC_CLASS_AFBC] + REG_ACKNOWLEDGE);
734 
735 		if ((ack_status & 0x1) == 0x1) {
736 			u32 ctl_val = readl(dec->reg_base[AV1DEC_CLASS_AFBC] + REG_CONTROL);
737 
738 			ctl_val |= 1;
739 			writel_relaxed(ctl_val, dec->reg_base[AV1DEC_CLASS_AFBC] + REG_CONTROL);
740 		}
741 	}
742 	task->irq_status = mpp->irq_status;
743 	mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", task->irq_status);
744 	if (task->irq_status & dec->hw_info->err_mask) {
745 		atomic_inc(&mpp->reset_request);
746 		/* dump register */
747 		if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG)) {
748 			mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n",
749 				  task->irq_status);
750 			mpp_task_dump_hw_reg(mpp);
751 		}
752 	}
753 	mpp_task_finish(mpp_task->session, mpp_task);
754 
755 	mpp_debug_leave();
756 
757 	return IRQ_HANDLED;
758 }
759 
av1dec_finish(struct mpp_dev * mpp,struct mpp_task * mpp_task)760 static int av1dec_finish(struct mpp_dev *mpp,
761 			 struct mpp_task *mpp_task)
762 {
763 	u32 i;
764 	struct av1dec_task *task = to_av1dec_task(mpp_task);
765 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
766 	struct av1dec_hw_info *hw = dec->hw_info;
767 
768 	mpp_debug_enter();
769 
770 	for (i = 0; i < task->r_req_cnt; i++) {
771 		int class;
772 		struct mpp_request *req = &task->r_reqs[i];
773 
774 		for (class = 0; class < hw->reg_class_num; class++) {
775 			int j, s, e;
776 			u32 base, *regs;
777 
778 			if (!req_over_class(req, task, class))
779 				continue;
780 			base = task->reg_class[class].base;
781 			s = MPP_BASE_TO_IDX(req->offset - base);
782 			e = s + req->size / sizeof(u32);
783 			regs = (u32 *)task->reg_class[class].data;
784 
785 			mpp_debug(DEBUG_TASK_INFO, "found rd_class %d, base=%08x, s=%d, e=%d\n",
786 				  class, base, s, e);
787 			for (j = s; j < e; j++) {
788 				/* revert hack for irq status */
789 				if (class == 0 && j == MPP_BASE_TO_IDX(hw->sta_base)) {
790 					regs[j] = task->irq_status;
791 					continue;
792 				}
793 				regs[j] = readl_relaxed(dec->reg_base[class] + j * sizeof(u32));
794 			}
795 		}
796 	}
797 
798 	mpp_debug_leave();
799 
800 	return 0;
801 }
802 
av1dec_result(struct mpp_dev * mpp,struct mpp_task * mpp_task,struct mpp_task_msgs * msgs)803 static int av1dec_result(struct mpp_dev *mpp,
804 			 struct mpp_task *mpp_task,
805 			 struct mpp_task_msgs *msgs)
806 {
807 	u32 i;
808 	struct av1dec_task *task = to_av1dec_task(mpp_task);
809 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
810 	struct av1dec_hw_info *hw = dec->hw_info;
811 
812 	mpp_debug_enter();
813 
814 	for (i = 0; i < task->r_req_cnt; i++) {
815 		int class;
816 		struct mpp_request *req = &task->r_reqs[i];
817 
818 		for (class = 0; class < hw->reg_class_num; class++) {
819 			u32 base, *regs;
820 
821 			if (!req_over_class(req, task, class))
822 				continue;
823 			base = task->reg_class[class].base;
824 			regs = (u32 *)task->reg_class[class].data;
825 			regs += MPP_BASE_TO_IDX(req->offset - base);
826 
827 			if (copy_to_user(req->data, regs, req->size)) {
828 				mpp_err("copy_to_user reg fail\n");
829 				return -EIO;
830 			}
831 		}
832 	}
833 	mpp_debug_leave();
834 
835 	return 0;
836 }
837 
av1dec_free_task(struct mpp_session * session,struct mpp_task * mpp_task)838 static int av1dec_free_task(struct mpp_session *session,
839 			    struct mpp_task *mpp_task)
840 {
841 	struct av1dec_task *task = to_av1dec_task(mpp_task);
842 
843 	mpp_task_finalize(session, mpp_task);
844 	kfree(task->reg_data);
845 	kfree(task);
846 
847 	return 0;
848 }
849 
850 #ifdef CONFIG_PROC_FS
av1dec_procfs_remove(struct mpp_dev * mpp)851 static int av1dec_procfs_remove(struct mpp_dev *mpp)
852 {
853 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
854 
855 	if (dec->procfs) {
856 		proc_remove(dec->procfs);
857 		dec->procfs = NULL;
858 	}
859 
860 	return 0;
861 }
862 
av1dec_procfs_init(struct mpp_dev * mpp)863 static int av1dec_procfs_init(struct mpp_dev *mpp)
864 {
865 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
866 
867 	dec->procfs = proc_mkdir(mpp->dev->of_node->name, mpp->srv->procfs);
868 	if (IS_ERR_OR_NULL(dec->procfs)) {
869 		mpp_err("failed on open procfs\n");
870 		dec->procfs = NULL;
871 		return -EIO;
872 	}
873 	/* for debug */
874 	mpp_procfs_create_u32("aclk", 0644,
875 			      dec->procfs, &dec->aclk_info.debug_rate_hz);
876 	mpp_procfs_create_u32("session_buffers", 0644,
877 			      dec->procfs, &mpp->session_max_buffers);
878 
879 	return 0;
880 }
881 #else
av1dec_procfs_remove(struct mpp_dev * mpp)882 static inline int av1dec_procfs_remove(struct mpp_dev *mpp)
883 {
884 	return 0;
885 }
886 
av1dec_procfs_init(struct mpp_dev * mpp)887 static inline int av1dec_procfs_init(struct mpp_dev *mpp)
888 {
889 	return 0;
890 }
891 #endif
892 
av1dec_init(struct mpp_dev * mpp)893 static int av1dec_init(struct mpp_dev *mpp)
894 {
895 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
896 	int ret = 0;
897 
898 	/* Get clock info from dtsi */
899 	ret = mpp_get_clk_info(mpp, &dec->aclk_info, "aclk_vcodec");
900 	if (ret)
901 		mpp_err("failed on clk_get aclk_vcodec\n");
902 	ret = mpp_get_clk_info(mpp, &dec->hclk_info, "hclk_vcodec");
903 	if (ret)
904 		mpp_err("failed on clk_get hclk_vcodec\n");
905 
906 	/* Get normal max workload from dtsi */
907 	of_property_read_u32(mpp->dev->of_node,
908 			     "rockchip,default-max-load",
909 			     &dec->default_max_load);
910 	/* Set default rates */
911 	mpp_set_clk_info_rate_hz(&dec->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
912 
913 	/* Get reset control from dtsi */
914 	dec->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
915 	if (!dec->rst_a)
916 		mpp_err("No aclk reset resource define\n");
917 	dec->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "video_h");
918 	if (!dec->rst_h)
919 		mpp_err("No hclk reset resource define\n");
920 
921 	return 0;
922 }
923 
av1dec_reset(struct mpp_dev * mpp)924 static int av1dec_reset(struct mpp_dev *mpp)
925 {
926 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
927 
928 	mpp_debug_enter();
929 
930 	if (dec->rst_a && dec->rst_h) {
931 		rockchip_pmu_idle_request(mpp->dev, true);
932 		mpp_safe_reset(dec->rst_a);
933 		mpp_safe_reset(dec->rst_h);
934 		udelay(5);
935 		mpp_safe_unreset(dec->rst_a);
936 		mpp_safe_unreset(dec->rst_h);
937 		rockchip_pmu_idle_request(mpp->dev, false);
938 	}
939 
940 	mpp_debug_leave();
941 
942 	return 0;
943 }
944 
av1dec_clk_on(struct mpp_dev * mpp)945 static int av1dec_clk_on(struct mpp_dev *mpp)
946 {
947 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
948 
949 	mpp_clk_safe_enable(dec->aclk_info.clk);
950 	mpp_clk_safe_enable(dec->hclk_info.clk);
951 
952 	return 0;
953 }
954 
av1dec_clk_off(struct mpp_dev * mpp)955 static int av1dec_clk_off(struct mpp_dev *mpp)
956 {
957 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
958 
959 	clk_disable_unprepare(dec->aclk_info.clk);
960 	clk_disable_unprepare(dec->hclk_info.clk);
961 
962 	return 0;
963 }
964 
av1dec_set_freq(struct mpp_dev * mpp,struct mpp_task * mpp_task)965 static int av1dec_set_freq(struct mpp_dev *mpp,
966 			   struct mpp_task *mpp_task)
967 {
968 	struct av1dec_dev *dec = to_av1dec_dev(mpp);
969 	struct av1dec_task *task = to_av1dec_task(mpp_task);
970 
971 	mpp_clk_set_rate(&dec->aclk_info, task->clk_mode);
972 
973 	return 0;
974 }
975 
976 static struct mpp_hw_ops av1dec_hw_ops = {
977 	.init = av1dec_init,
978 	.clk_on = av1dec_clk_on,
979 	.clk_off = av1dec_clk_off,
980 	.set_freq = av1dec_set_freq,
981 	.reset = av1dec_reset,
982 };
983 
984 static struct mpp_dev_ops av1dec_dev_ops = {
985 	.alloc_task = av1dec_alloc_task,
986 	.run = av1dec_run,
987 	.irq = av1dec_vcd_irq,
988 	.isr = av1dec_isr,
989 	.finish = av1dec_finish,
990 	.result = av1dec_result,
991 	.free_task = av1dec_free_task,
992 };
993 static const struct mpp_dev_var av1dec_data = {
994 	.device_type = MPP_DEVICE_AV1DEC,
995 	.hw_info = &av1dec_hw_info.hw,
996 	.trans_info = trans_av1dec,
997 	.hw_ops = &av1dec_hw_ops,
998 	.dev_ops = &av1dec_dev_ops,
999 };
1000 
1001 static const struct of_device_id mpp_av1dec_dt_match[] = {
1002 	{
1003 		.compatible = "rockchip,av1-decoder",
1004 		.data = &av1dec_data,
1005 	},
1006 	{},
1007 };
1008 
av1dec_device_match(struct device * dev,struct device_driver * drv)1009 static int av1dec_device_match(struct device *dev, struct device_driver *drv)
1010 {
1011 	return 1;
1012 }
1013 
av1dec_device_probe(struct device * dev)1014 static int av1dec_device_probe(struct device *dev)
1015 {
1016 	int ret;
1017 	const struct platform_driver *drv;
1018 	struct platform_device *pdev = to_platform_device(dev);
1019 
1020 	ret = of_clk_set_defaults(dev->of_node, false);
1021 	if (ret < 0)
1022 		return ret;
1023 
1024 	ret = dev_pm_domain_attach(dev, true);
1025 	if (ret)
1026 		return ret;
1027 
1028 	drv = to_platform_driver(dev->driver);
1029 	if (drv->probe) {
1030 		ret = drv->probe(pdev);
1031 		if (ret)
1032 			dev_pm_domain_detach(dev, true);
1033 	}
1034 
1035 	return ret;
1036 }
1037 
av1dec_device_remove(struct device * dev)1038 static int av1dec_device_remove(struct device *dev)
1039 {
1040 
1041 	struct platform_device *pdev = to_platform_device(dev);
1042 	struct platform_driver *drv = to_platform_driver(dev->driver);
1043 
1044 	if (dev->driver && drv->remove)
1045 		drv->remove(pdev);
1046 
1047 	dev_pm_domain_detach(dev, true);
1048 
1049 	return 0;
1050 }
1051 
av1dec_device_shutdown(struct device * dev)1052 static void av1dec_device_shutdown(struct device *dev)
1053 {
1054 	struct platform_device *pdev = to_platform_device(dev);
1055 	struct platform_driver *drv = to_platform_driver(dev->driver);
1056 
1057 	if (dev->driver && drv->shutdown)
1058 		drv->shutdown(pdev);
1059 }
1060 
av1dec_dma_configure(struct device * dev)1061 static int av1dec_dma_configure(struct device *dev)
1062 {
1063 	return of_dma_configure(dev, dev->of_node, true);
1064 }
1065 
1066 static const struct dev_pm_ops platform_dev_pm_ops = {
1067 	.runtime_suspend = pm_generic_runtime_suspend,
1068 	.runtime_resume = pm_generic_runtime_resume,
1069 };
1070 
1071 struct bus_type av1dec_bus = {
1072 	.name		= "av1dec_bus",
1073 	.match		= av1dec_device_match,
1074 	.probe		= av1dec_device_probe,
1075 	.remove		= av1dec_device_remove,
1076 	.shutdown	= av1dec_device_shutdown,
1077 	.dma_configure  = av1dec_dma_configure,
1078 	.pm		= &platform_dev_pm_ops,
1079 };
1080 
av1_of_device_add(struct platform_device * ofdev)1081 static int av1_of_device_add(struct platform_device *ofdev)
1082 {
1083 	WARN_ON(ofdev->dev.of_node == NULL);
1084 
1085 	/* name and id have to be set so that the platform bus doesn't get
1086 	 * confused on matching
1087 	 */
1088 	ofdev->name = dev_name(&ofdev->dev);
1089 	ofdev->id = PLATFORM_DEVID_NONE;
1090 
1091 	/*
1092 	 * If this device has not binding numa node in devicetree, that is
1093 	 * of_node_to_nid returns NUMA_NO_NODE. device_add will assume that this
1094 	 * device is on the same node as the parent.
1095 	 */
1096 	set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node));
1097 
1098 	return device_add(&ofdev->dev);
1099 }
1100 
av1dec_device_create(void)1101 struct platform_device *av1dec_device_create(void)
1102 {
1103 	int ret = -ENODEV;
1104 	struct device_node *root, *child;
1105 	struct platform_device *pdev;
1106 
1107 	root = of_find_node_by_path("/");
1108 
1109 	for_each_child_of_node(root, child) {
1110 		if (!of_match_node(mpp_av1dec_dt_match, child))
1111 			continue;
1112 
1113 		pr_info("Adding child %pOF\n", child);
1114 
1115 		pdev = of_device_alloc(child, "av1d-master", NULL);
1116 		if (!pdev)
1117 			return ERR_PTR(-ENOMEM);
1118 
1119 		pdev->dev.bus = &av1dec_bus;
1120 
1121 		dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
1122 
1123 		ret = av1_of_device_add(pdev);
1124 		if (ret) {
1125 			platform_device_put(pdev);
1126 			return ERR_PTR(-EINVAL);
1127 		}
1128 
1129 		pr_info("register device %s\n", dev_name(&pdev->dev));
1130 
1131 		return  pdev;
1132 	}
1133 
1134 	return ERR_PTR(ret);
1135 }
1136 
av1dec_driver_register(struct platform_driver * drv)1137 int av1dec_driver_register(struct platform_driver *drv)
1138 {
1139 	int ret;
1140 	/* 1. register bus */
1141 	ret = bus_register(&av1dec_bus);
1142 	if (ret) {
1143 		pr_err("failed to register av1 bus: %d\n", ret);
1144 		return ret;
1145 	}
1146 	/* 2. register iommu driver */
1147 	platform_driver_register(&rockchip_av1_iommu_driver);
1148 	/* 3. create device */
1149 	av1dec_device_create();
1150 	/* 4. register av1 driver */
1151 	return driver_register(&drv->driver);
1152 }
1153 
av1dec_cache_irq(int irq,void * dev_id)1154 static irqreturn_t av1dec_cache_irq(int irq, void *dev_id)
1155 {
1156 	struct av1dec_dev *dec = dev_id;
1157 	u32 shaper_st, rd_st;
1158 
1159 	shaper_st = readl(dec->reg_base[AV1DEC_CLASS_CACHE] + 0x2c);
1160 	rd_st = readl(dec->reg_base[AV1DEC_CLASS_CACHE] + 0x204);
1161 
1162 	mpp_debug(DEBUG_IRQ_STATUS, "cache irq st shaper 0x%x read 0x%x\n", shaper_st, rd_st);
1163 
1164 	writel(shaper_st, dec->reg_base[AV1DEC_CLASS_CACHE] + 0x2c);
1165 	writel(rd_st, dec->reg_base[AV1DEC_CLASS_CACHE] + 0x204);
1166 
1167 	return IRQ_HANDLED;
1168 }
1169 
av1dec_cache_init(struct platform_device * pdev,struct av1dec_dev * dec)1170 static int av1dec_cache_init(struct platform_device *pdev, struct av1dec_dev *dec)
1171 {
1172 	int ret;
1173 	struct resource *res;
1174 	struct device *dev = &pdev->dev;
1175 
1176 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cache");
1177 	if (!res)
1178 		return -ENOMEM;
1179 
1180 	dec->reg_base[AV1DEC_CLASS_CACHE] = devm_ioremap(dev, res->start, resource_size(res));
1181 	if (!dec->reg_base[AV1DEC_CLASS_CACHE]) {
1182 		dev_err(dev, "ioremap failed for resource %pR\n", res);
1183 		return -EINVAL;
1184 	}
1185 
1186 	dec->irq[AV1DEC_CLASS_CACHE] = platform_get_irq(pdev, 1);
1187 
1188 	ret = devm_request_irq(dev, dec->irq[AV1DEC_CLASS_CACHE],
1189 			       av1dec_cache_irq, IRQF_SHARED, "irq_cache", dec);
1190 	if (ret)
1191 		mpp_err("ret=%d\n", ret);
1192 	return ret;
1193 }
1194 
av1dec_afbc_init(struct platform_device * pdev,struct av1dec_dev * dec)1195 static int av1dec_afbc_init(struct platform_device *pdev, struct av1dec_dev *dec)
1196 {
1197 	struct resource *res;
1198 	struct device *dev = &pdev->dev;
1199 
1200 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "afbc");
1201 	if (!res)
1202 		return -ENOMEM;
1203 
1204 	dec->reg_base[AV1DEC_CLASS_AFBC] = devm_ioremap(dev, res->start, resource_size(res));
1205 	if (!dec->reg_base[AV1DEC_CLASS_AFBC]) {
1206 		dev_err(dev, "ioremap failed for resource %pR\n", res);
1207 		return -EINVAL;
1208 	}
1209 	dec->irq[AV1DEC_CLASS_AFBC] = platform_get_irq(pdev, 2);
1210 
1211 	return 0;
1212 }
1213 
av1dec_probe(struct platform_device * pdev)1214 static int av1dec_probe(struct platform_device *pdev)
1215 {
1216 	int ret = 0;
1217 	struct device *dev = &pdev->dev;
1218 	struct av1dec_dev *dec = NULL;
1219 	struct mpp_dev *mpp = NULL;
1220 	const struct of_device_id *match = NULL;
1221 
1222 	dev_info(dev, "probing start\n");
1223 
1224 	dec = devm_kzalloc(dev, sizeof(*dec), GFP_KERNEL);
1225 	if (!dec)
1226 		return -ENOMEM;
1227 
1228 	mpp = &dec->mpp;
1229 	platform_set_drvdata(pdev, dec);
1230 
1231 	if (pdev->dev.of_node) {
1232 		match = of_match_node(mpp_av1dec_dt_match, pdev->dev.of_node);
1233 		if (match)
1234 			mpp->var = (struct mpp_dev_var *)match->data;
1235 	}
1236 	/* get vcd resource */
1237 	ret = mpp_dev_probe(mpp, pdev);
1238 	if (ret)
1239 		return ret;
1240 
1241 	/* iommu may disabled */
1242 	if (mpp->iommu_info)
1243 		mpp->iommu_info->skip_refresh = 1;
1244 
1245 	dec->reg_base[AV1DEC_CLASS_VCD] = mpp->reg_base;
1246 	ret = devm_request_threaded_irq(dev, mpp->irq,
1247 					mpp_dev_irq,
1248 					mpp_dev_isr_sched,
1249 					IRQF_SHARED,
1250 					dev_name(dev), mpp);
1251 	if (ret) {
1252 		dev_err(dev, "register interrupter runtime failed\n");
1253 		goto failed_get_irq;
1254 	}
1255 	dec->irq[AV1DEC_CLASS_VCD] = mpp->irq;
1256 	/* get cache resource */
1257 	ret = av1dec_cache_init(pdev, dec);
1258 	if (ret)
1259 		goto failed_get_irq;
1260 	/* get afbc resource */
1261 	ret = av1dec_afbc_init(pdev, dec);
1262 	if (ret)
1263 		goto failed_get_irq;
1264 	mpp->session_max_buffers = AV1DEC_SESSION_MAX_BUFFERS;
1265 	dec->hw_info = to_av1dec_info(mpp->var->hw_info);
1266 	av1dec_procfs_init(mpp);
1267 	mpp_dev_register_srv(mpp, mpp->srv);
1268 	dev_info(dev, "probing finish\n");
1269 
1270 	return 0;
1271 
1272 failed_get_irq:
1273 	mpp_dev_remove(mpp);
1274 
1275 	return ret;
1276 }
1277 
av1dec_remove(struct platform_device * pdev)1278 static int av1dec_remove(struct platform_device *pdev)
1279 {
1280 	struct device *dev = &pdev->dev;
1281 	struct av1dec_dev *dec = platform_get_drvdata(pdev);
1282 
1283 	dev_info(dev, "remove device\n");
1284 	mpp_dev_remove(&dec->mpp);
1285 	av1dec_procfs_remove(&dec->mpp);
1286 
1287 	return 0;
1288 }
1289 
av1dec_shutdown(struct platform_device * pdev)1290 static void av1dec_shutdown(struct platform_device *pdev)
1291 {
1292 	int ret;
1293 	int val;
1294 	struct device *dev = &pdev->dev;
1295 	struct av1dec_dev *dec = platform_get_drvdata(pdev);
1296 	struct mpp_dev *mpp = &dec->mpp;
1297 
1298 	dev_info(dev, "shutdown device\n");
1299 
1300 	atomic_inc(&mpp->srv->shutdown_request);
1301 	ret = readx_poll_timeout(atomic_read,
1302 				 &mpp->task_count,
1303 				 val, val == 0, 1000, 200000);
1304 	if (ret == -ETIMEDOUT)
1305 		dev_err(dev, "wait total running time out\n");
1306 
1307 	dev_info(dev, "shutdown success\n");
1308 }
1309 
1310 struct platform_driver rockchip_av1dec_driver = {
1311 	.probe = av1dec_probe,
1312 	.remove = av1dec_remove,
1313 	.shutdown = av1dec_shutdown,
1314 	.driver = {
1315 		.name = AV1DEC_DRIVER_NAME,
1316 		.of_match_table = of_match_ptr(mpp_av1dec_dt_match),
1317 		.bus = &av1dec_bus,
1318 	},
1319 };
1320