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