1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4 *
5 * author:
6 * Alpha Lin, alpha.lin@rock-chips.com
7 * Randy Li, randy.li@rock-chips.com
8 * Ding Wei, leo.ding@rock-chips.com
9 *
10 */
11 #include <asm/cacheflush.h>
12 #include <linux/delay.h>
13 #include <linux/iopoll.h>
14 #include <linux/interrupt.h>
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/of_platform.h>
18 #include <linux/slab.h>
19 #include <linux/seq_file.h>
20 #include <linux/uaccess.h>
21 #include <linux/regmap.h>
22 #include <linux/proc_fs.h>
23 #include <linux/nospec.h>
24 #include <soc/rockchip/pm_domains.h>
25
26 #include "mpp_debug.h"
27 #include "mpp_common.h"
28 #include "mpp_iommu.h"
29 #include "hack/mpp_hack_px30.h"
30
31 #define VEPU2_DRIVER_NAME "mpp_vepu2"
32
33 #define VEPU2_SESSION_MAX_BUFFERS 20
34 /* The maximum registers number of all the version */
35 #define VEPU2_REG_NUM 184
36 #define VEPU2_REG_HW_ID_INDEX (-1) /* INVALID */
37 #define VEPU2_REG_START_INDEX 0
38 #define VEPU2_REG_END_INDEX 183
39
40 #define VEPU2_REG_ENC_EN 0x19c
41 #define VEPU2_REG_ENC_EN_INDEX (103)
42 #define VEPU2_ENC_START BIT(0)
43
44 #define VEPU2_GET_FORMAT(x) (((x) >> 4) & 0x3)
45 #define VEPU2_FORMAT_MASK (0x30)
46 #define VEPU2_GET_WIDTH(x) ((((x) >> 8) & 0x1ff) << 4)
47 #define VEPU2_GET_HEIGHT(x) ((((x) >> 20) & 0x1ff) << 4)
48
49 #define VEPU2_FMT_RESERVED (0)
50 #define VEPU2_FMT_VP8E (1)
51 #define VEPU2_FMT_JPEGE (2)
52 #define VEPU2_FMT_H264E (3)
53
54 #define VEPU2_REG_MB_CTRL 0x1a0
55 #define VEPU2_REG_MB_CTRL_INDEX (104)
56
57 #define VEPU2_REG_INT 0x1b4
58 #define VEPU2_REG_INT_INDEX (109)
59 #define VEPU2_MV_SAD_WR_EN BIT(24)
60 #define VEPU2_ROCON_WRITE_DIS BIT(20)
61 #define VEPU2_INT_SLICE_EN BIT(16)
62 #define VEPU2_CLOCK_GATE_EN BIT(12)
63 #define VEPU2_INT_TIMEOUT_EN BIT(10)
64 #define VEPU2_INT_CLEAR BIT(9)
65 #define VEPU2_IRQ_DIS BIT(8)
66 #define VEPU2_INT_TIMEOUT BIT(6)
67 #define VEPU2_INT_BUF_FULL BIT(5)
68 #define VEPU2_INT_BUS_ERROR BIT(4)
69 #define VEPU2_INT_SLICE BIT(2)
70 #define VEPU2_INT_RDY BIT(1)
71 #define VEPU2_INT_RAW BIT(0)
72
73 #define RKVPUE2_REG_DMV_4P_1P(i) (0x1e0 + ((i) << 4))
74 #define RKVPUE2_REG_DMV_4P_1P_INDEX(i) (120 + (i))
75
76 #define VEPU2_REG_CLR_CACHE_BASE 0xc10
77
78 #define to_vepu_task(task) container_of(task, struct vepu_task, mpp_task)
79 #define to_vepu_dev(dev) container_of(dev, struct vepu_dev, mpp)
80
81 struct vepu_task {
82 struct mpp_task mpp_task;
83
84 enum MPP_CLOCK_MODE clk_mode;
85 u32 reg[VEPU2_REG_NUM];
86
87 struct reg_offset_info off_inf;
88 u32 irq_status;
89 /* req for current task */
90 u32 w_req_cnt;
91 struct mpp_request w_reqs[MPP_MAX_MSG_NUM];
92 u32 r_req_cnt;
93 struct mpp_request r_reqs[MPP_MAX_MSG_NUM];
94 /* image info */
95 u32 width;
96 u32 height;
97 u32 pixels;
98 };
99
100 struct vepu_session_priv {
101 struct rw_semaphore rw_sem;
102 /* codec info from user */
103 struct {
104 /* show mode */
105 u32 flag;
106 /* item data */
107 u64 val;
108 } codec_info[ENC_INFO_BUTT];
109 };
110
111 struct vepu_dev {
112 struct mpp_dev mpp;
113
114 struct mpp_clk_info aclk_info;
115 struct mpp_clk_info hclk_info;
116 u32 default_max_load;
117 #ifdef CONFIG_ROCKCHIP_MPP_PROC_FS
118 struct proc_dir_entry *procfs;
119 #endif
120 struct reset_control *rst_a;
121 struct reset_control *rst_h;
122 /* for ccu(central control unit) */
123 struct vepu_ccu *ccu;
124 struct list_head core_link;
125 bool disable_work;
126 };
127
128 struct vepu_ccu {
129 u32 core_num;
130 /* lock for core attach */
131 struct mutex lock;
132 struct list_head core_list;
133 struct mpp_dev *main_core;
134 };
135
136 static struct mpp_hw_info vepu_v2_hw_info = {
137 .reg_num = VEPU2_REG_NUM,
138 .reg_id = VEPU2_REG_HW_ID_INDEX,
139 .reg_start = VEPU2_REG_START_INDEX,
140 .reg_end = VEPU2_REG_END_INDEX,
141 .reg_en = VEPU2_REG_ENC_EN_INDEX,
142 };
143
144 /*
145 * file handle translate information
146 */
147 static const u16 trans_tbl_default[] = {48, 49, 50, 56, 57, 63, 64, 77, 78, 81};
148
149 static const u16 trans_tbl_vp8e[] = {
150 27, 44, 45, 48, 49, 50, 56, 57, 63, 64, 76, 77, 78, 80, 81, 106, 108,
151 };
152
153 static struct mpp_trans_info trans_rk_vepu2[] = {
154 [VEPU2_FMT_RESERVED] =
155 {
156 .count = 0,
157 .table = NULL,
158 },
159 [VEPU2_FMT_VP8E] =
160 {
161 .count = ARRAY_SIZE(trans_tbl_vp8e),
162 .table = trans_tbl_vp8e,
163 },
164 [VEPU2_FMT_JPEGE] =
165 {
166 .count = ARRAY_SIZE(trans_tbl_default),
167 .table = trans_tbl_default,
168 },
169 [VEPU2_FMT_H264E] =
170 {
171 .count = ARRAY_SIZE(trans_tbl_default),
172 .table = trans_tbl_default,
173 },
174 };
175
vepu_process_reg_fd(struct mpp_session * session,struct vepu_task * task,struct mpp_task_msgs * msgs)176 static int vepu_process_reg_fd(struct mpp_session *session, struct vepu_task *task, struct mpp_task_msgs *msgs)
177 {
178 int ret;
179 int fmt = VEPU2_GET_FORMAT(task->reg[VEPU2_REG_ENC_EN_INDEX]);
180
181 ret = mpp_translate_reg_address(session, &task->mpp_task, fmt, task->reg, &task->off_inf);
182 if (ret) {
183 return ret;
184 }
185
186 mpp_translate_reg_offset_info(&task->mpp_task, &task->off_inf, task->reg);
187
188 return 0;
189 }
190
vepu_extract_task_msg(struct vepu_task * task,struct mpp_task_msgs * msgs)191 static int vepu_extract_task_msg(struct vepu_task *task, struct mpp_task_msgs *msgs)
192 {
193 u32 i;
194 int ret;
195 struct mpp_request *req;
196 struct mpp_hw_info *hw_info = task->mpp_task.hw_info;
197 for (i = 0; i < msgs->req_cnt; i++) {
198 u32 off_s, off_e;
199 req = &msgs->reqs[i];
200 if (!req->size) {
201 continue;
202 }
203 switch (req->cmd) {
204 case MPP_CMD_SET_REG_WRITE: {
205 off_s = hw_info->reg_start * sizeof(u32);
206 off_e = hw_info->reg_end * sizeof(u32);
207 ret = mpp_check_req(req, 0, sizeof(task->reg), off_s, off_e);
208 if (ret) {
209 continue;
210 }
211 if (copy_from_user((u8 *)task->reg + req->offset, req->data, req->size)) {
212 mpp_err("copy_from_user reg failed\n");
213 return -EIO;
214 }
215 memcpy(&task->w_reqs[task->w_req_cnt++], req, sizeof(*req));
216 break;
217 }
218 case MPP_CMD_SET_REG_READ: {
219 off_s = hw_info->reg_start * sizeof(u32);
220 off_e = hw_info->reg_end * sizeof(u32);
221 ret = mpp_check_req(req, 0, sizeof(task->reg), off_s, off_e);
222 if (ret) {
223 continue;
224 }
225 memcpy(&task->r_reqs[task->r_req_cnt++], req, sizeof(*req));
226 break;
227 }
228 case MPP_CMD_SET_REG_ADDR_OFFSET: {
229 mpp_extract_reg_offset_info(&task->off_inf, req);
230 break;
231 }
232 default:
233 break;
234 }
235 }
236 mpp_debug(DEBUG_TASK_INFO, "w_req_cnt %d, r_req_cnt %d\n", task->w_req_cnt, task->r_req_cnt);
237 return 0;
238 }
239
vepu_alloc_task(struct mpp_session * session,struct mpp_task_msgs * msgs)240 static void *vepu_alloc_task(struct mpp_session *session, struct mpp_task_msgs *msgs)
241 {
242 int ret;
243 struct mpp_task *mpp_task = NULL;
244 struct vepu_task *task = NULL;
245 struct mpp_dev *mpp = session->mpp;
246
247 mpp_debug_enter();
248
249 task = kzalloc(sizeof(*task), GFP_KERNEL);
250 if (!task) {
251 return NULL;
252 }
253
254 mpp_task = &task->mpp_task;
255 mpp_task_init(session, mpp_task);
256 mpp_task->hw_info = mpp->var->hw_info;
257 mpp_task->reg = task->reg;
258 /* extract reqs for current task */
259 ret = vepu_extract_task_msg(task, msgs);
260 if (ret) {
261 goto fail;
262 }
263 /* process fd in register */
264 if (!(msgs->flags & MPP_FLAGS_REG_FD_NO_TRANS)) {
265 ret = vepu_process_reg_fd(session, task, msgs);
266 if (ret) {
267 goto fail;
268 }
269 }
270 task->clk_mode = CLK_MODE_NORMAL;
271 /* get resolution info */
272 task->width = VEPU2_GET_WIDTH(task->reg[VEPU2_REG_ENC_EN_INDEX]);
273 task->height = VEPU2_GET_HEIGHT(task->reg[VEPU2_REG_ENC_EN_INDEX]);
274 task->pixels = task->width * task->height;
275 mpp_debug(DEBUG_TASK_INFO, "width=%d, height=%d\n", task->width, task->height);
276
277 mpp_debug_leave();
278
279 return mpp_task;
280
281 fail:
282 mpp_task_dump_mem_region(mpp, mpp_task);
283 mpp_task_dump_reg(mpp, mpp_task);
284 mpp_task_finalize(session, mpp_task);
285 kfree(task);
286 return NULL;
287 }
288
vepu_core_balance(struct vepu_ccu * ccu)289 static struct vepu_dev *vepu_core_balance(struct vepu_ccu *ccu)
290 {
291 struct vepu_dev *enc;
292 struct vepu_dev *core = NULL, *n;
293
294 mpp_debug_enter();
295
296 mutex_lock(&ccu->lock);
297 enc = list_first_entry(&ccu->core_list, struct vepu_dev, core_link);
298 list_for_each_entry_safe(core, n, &ccu->core_list, core_link)
299 {
300 mpp_debug(DEBUG_DEVICE, "%s, disable_work=%d, task_count=%d, task_index=%d\n", dev_name(core->mpp.dev),
301 core->disable_work, atomic_read(&core->mpp.task_count), atomic_read(&core->mpp.task_index));
302 /* if core (except main-core) disabled, skip it */
303 if (core->disable_work) {
304 continue;
305 }
306 /* choose core with less task in queue */
307 if (atomic_read(&core->mpp.task_count) < atomic_read(&enc->mpp.task_count)) {
308 enc = core;
309 break;
310 }
311 /* choose core with less task which done */
312 if (atomic_read(&core->mpp.task_index) < atomic_read(&enc->mpp.task_index)) {
313 enc = core;
314 }
315 }
316 mutex_unlock(&ccu->lock);
317
318 mpp_debug_leave();
319
320 return enc;
321 }
322
vepu_ccu_alloc_task(struct mpp_session * session,struct mpp_task_msgs * msgs)323 static void *vepu_ccu_alloc_task(struct mpp_session *session, struct mpp_task_msgs *msgs)
324 {
325 struct vepu_dev *enc = to_vepu_dev(session->mpp);
326
327 /* if multi-cores, choose one for current task */
328 if (enc->ccu) {
329 enc = vepu_core_balance(enc->ccu);
330 session->mpp = &enc->mpp;
331 }
332
333 return vepu_alloc_task(session, msgs);
334 }
335
vepu_run(struct mpp_dev * mpp,struct mpp_task * mpp_task)336 static int vepu_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
337 {
338 u32 i;
339 u32 reg_en;
340 struct vepu_task *task = to_vepu_task(mpp_task);
341
342 mpp_debug_enter();
343
344 /* clear cache */
345 mpp_write_relaxed(mpp, VEPU2_REG_CLR_CACHE_BASE, 1);
346
347 reg_en = mpp_task->hw_info->reg_en;
348 /* First, flush correct encoder format */
349 mpp_write_relaxed(mpp, VEPU2_REG_ENC_EN, task->reg[reg_en] & VEPU2_FORMAT_MASK);
350 /* Second, flush others register */
351 for (i = 0; i < task->w_req_cnt; i++) {
352 struct mpp_request *req = &task->w_reqs[i];
353 int s = req->offset / sizeof(u32);
354 int e = s + req->size / sizeof(u32);
355
356 mpp_write_req(mpp, task->reg, s, e, reg_en);
357 }
358 /* init current task */
359 mpp->cur_task = mpp_task;
360 /* Last, flush the registers */
361 wmb();
362 mpp_write(mpp, VEPU2_REG_ENC_EN, task->reg[reg_en] | VEPU2_ENC_START);
363
364 mpp_debug_leave();
365
366 return 0;
367 }
368
vepu_irq(struct mpp_dev * mpp)369 static int vepu_irq(struct mpp_dev *mpp)
370 {
371 mpp->irq_status = mpp_read(mpp, VEPU2_REG_INT);
372 if (!(mpp->irq_status & VEPU2_INT_RAW)) {
373 return IRQ_NONE;
374 }
375
376 mpp_write(mpp, VEPU2_REG_INT, 0);
377
378 return IRQ_WAKE_THREAD;
379 }
380
vepu_isr(struct mpp_dev * mpp)381 static int vepu_isr(struct mpp_dev *mpp)
382 {
383 u32 err_mask;
384 struct vepu_task *task = NULL;
385 struct mpp_task *mpp_task = mpp->cur_task;
386 /* use a spin lock here */
387 if (!mpp_task) {
388 dev_err(mpp->dev, "no current task\n");
389 return IRQ_HANDLED;
390 }
391 mpp_time_diff(mpp_task);
392 mpp->cur_task = NULL;
393 task = to_vepu_task(mpp_task);
394 task->irq_status = mpp->irq_status;
395 mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", task->irq_status);
396 err_mask = VEPU2_INT_TIMEOUT | VEPU2_INT_BUF_FULL | VEPU2_INT_BUS_ERROR;
397 if (err_mask & task->irq_status) {
398 atomic_inc(&mpp->reset_request);
399 }
400 mpp_task_finish(mpp_task->session, mpp_task);
401 mpp_debug_leave();
402 return IRQ_HANDLED;
403 }
404
vepu_finish(struct mpp_dev * mpp,struct mpp_task * mpp_task)405 static int vepu_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task)
406 {
407 u32 i;
408 u32 s, e;
409 struct mpp_request *req;
410 struct vepu_task *task = to_vepu_task(mpp_task);
411
412 mpp_debug_enter();
413
414 /* read register after running */
415 for (i = 0; i < task->r_req_cnt; i++) {
416 req = &task->r_reqs[i];
417 s = req->offset / sizeof(u32);
418 e = s + req->size / sizeof(u32);
419 mpp_read_req(mpp, task->reg, s, e);
420 }
421 /* revert hack for irq status */
422 task->reg[VEPU2_REG_INT_INDEX] = task->irq_status;
423
424 mpp_debug_leave();
425
426 return 0;
427 }
428
vepu_result(struct mpp_dev * mpp,struct mpp_task * mpp_task,struct mpp_task_msgs * msgs)429 static int vepu_result(struct mpp_dev *mpp, struct mpp_task *mpp_task, struct mpp_task_msgs *msgs)
430 {
431 u32 i;
432 struct mpp_request *req;
433 struct vepu_task *task = to_vepu_task(mpp_task);
434
435 /* may overflow the kernel */
436 for (i = 0; i < task->r_req_cnt; i++) {
437 req = &task->r_reqs[i];
438
439 if (copy_to_user(req->data, (u8 *)task->reg + req->offset, req->size)) {
440 mpp_err("copy_to_user reg fail\n");
441 return -EIO;
442 }
443 }
444
445 return 0;
446 }
447
vepu_free_task(struct mpp_session * session,struct mpp_task * mpp_task)448 static int vepu_free_task(struct mpp_session *session, struct mpp_task *mpp_task)
449 {
450 struct vepu_task *task = to_vepu_task(mpp_task);
451
452 mpp_task_finalize(session, mpp_task);
453 kfree(task);
454
455 return 0;
456 }
457
vepu_control(struct mpp_session * session,struct mpp_request * req)458 static int vepu_control(struct mpp_session *session, struct mpp_request *req)
459 {
460 switch (req->cmd) {
461 case MPP_CMD_SEND_CODEC_INFO: {
462 int i;
463 int cnt;
464 struct codec_info_elem elem;
465 struct vepu_session_priv *priv;
466 if (!session || !session->priv) {
467 mpp_err("session info null\n");
468 return -EINVAL;
469 }
470 priv = session->priv;
471 cnt = req->size / sizeof(elem);
472 cnt = (cnt > ENC_INFO_BUTT) ? ENC_INFO_BUTT : cnt;
473 mpp_debug(DEBUG_IOCTL, "codec info count %d\n", cnt);
474 for (i = 0; i < cnt; i++) {
475 if (copy_from_user(&elem, req->data + i * sizeof(elem), sizeof(elem))) {
476 mpp_err("copy_from_user failed\n");
477 continue;
478 }
479 if (elem.type > ENC_INFO_BASE && elem.type < ENC_INFO_BUTT && elem.flag > CODEC_INFO_FLAG_NULL &&
480 elem.flag < CODEC_INFO_FLAG_BUTT) {
481 elem.type = array_index_nospec(elem.type, ENC_INFO_BUTT);
482 priv->codec_info[elem.type].flag = elem.flag;
483 priv->codec_info[elem.type].val = elem.data;
484 } else {
485 mpp_err("codec info invalid, type %d, flag %d\n", elem.type, elem.flag);
486 }
487 }
488 break;
489 }
490 default: {
491 mpp_err("unknown mpp ioctl cmd %x\n", req->cmd);
492 break;
493 }
494 }
495 return 0;
496 }
497
vepu_free_session(struct mpp_session * session)498 static int vepu_free_session(struct mpp_session *session)
499 {
500 if (session && session->priv) {
501 kfree(session->priv);
502 session->priv = NULL;
503 }
504
505 return 0;
506 }
507
vepu_init_session(struct mpp_session * session)508 static int vepu_init_session(struct mpp_session *session)
509 {
510 struct vepu_session_priv *priv;
511
512 if (!session) {
513 mpp_err("session is null\n");
514 return -EINVAL;
515 }
516
517 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
518 if (!priv) {
519 return -ENOMEM;
520 }
521
522 init_rwsem(&priv->rw_sem);
523 session->priv = priv;
524
525 return 0;
526 }
527
528 #ifdef CONFIG_ROCKCHIP_MPP_PROC_FS
vepu_procfs_remove(struct mpp_dev * mpp)529 static int vepu_procfs_remove(struct mpp_dev *mpp)
530 {
531 struct vepu_dev *enc = to_vepu_dev(mpp);
532
533 if (enc->procfs) {
534 proc_remove(enc->procfs);
535 enc->procfs = NULL;
536 }
537
538 return 0;
539 }
540
vepu_dump_session(struct mpp_session * session,struct seq_file * seq)541 static int vepu_dump_session(struct mpp_session *session, struct seq_file *seq)
542 {
543 int i;
544 struct vepu_session_priv *priv = session->priv;
545
546 down_read(&priv->rw_sem);
547 /* item name */
548 seq_puts(seq, "------------------------------------------------------");
549 seq_puts(seq, "------------------------------------------------------\n");
550 seq_printf(seq, "|%8s|", (const char *)"session");
551 seq_printf(seq, "%8s|", (const char *)"device");
552 for (i = ENC_INFO_BASE; i < ENC_INFO_BUTT; i++) {
553 bool show = priv->codec_info[i].flag;
554
555 if (show) {
556 seq_printf(seq, "%8s|", enc_info_item_name[i]);
557 }
558 }
559 seq_puts(seq, "\n");
560 /* item data */
561 seq_printf(seq, "|%8p|", session);
562 seq_printf(seq, "%8s|", mpp_device_name[session->device_type]);
563 for (i = ENC_INFO_BASE; i < ENC_INFO_BUTT; i++) {
564 u32 flag = priv->codec_info[i].flag;
565
566 if (!flag) {
567 continue;
568 }
569 if (flag == CODEC_INFO_FLAG_NUMBER) {
570 u32 data = priv->codec_info[i].val;
571
572 seq_printf(seq, "%8d|", data);
573 } else if (flag == CODEC_INFO_FLAG_STRING) {
574 const char *name = (const char *)&priv->codec_info[i].val;
575
576 seq_printf(seq, "%8s|", name);
577 } else {
578 seq_printf(seq, "%8s|", (const char *)"null");
579 }
580 }
581 seq_puts(seq, "\n");
582 up_read(&priv->rw_sem);
583
584 return 0;
585 }
586
vepu_show_session_info(struct seq_file * seq,void * offset)587 static int vepu_show_session_info(struct seq_file *seq, void *offset)
588 {
589 struct mpp_session *session = NULL, *n;
590 struct mpp_dev *mpp = seq->private;
591
592 mutex_lock(&mpp->srv->session_lock);
593 list_for_each_entry_safe(session, n, &mpp->srv->session_list, session_link)
594 {
595 if (session->device_type != MPP_DEVICE_VEPU2) {
596 continue;
597 }
598 if (!session->priv) {
599 continue;
600 }
601 if (mpp->dev_ops->dump_session) {
602 mpp->dev_ops->dump_session(session, seq);
603 }
604 }
605 mutex_unlock(&mpp->srv->session_lock);
606
607 return 0;
608 }
609
vepu_procfs_init(struct mpp_dev * mpp)610 static int vepu_procfs_init(struct mpp_dev *mpp)
611 {
612 struct vepu_dev *enc = to_vepu_dev(mpp);
613 char name[32];
614
615 if (!mpp->dev || !mpp->dev->of_node || !mpp->dev->of_node->name || !mpp->srv || !mpp->srv->procfs) {
616 return -EINVAL;
617 }
618
619 snprintf(name, sizeof(name) - 1, "%s%d", mpp->dev->of_node->name, mpp->core_id);
620
621 enc->procfs = proc_mkdir(name, mpp->srv->procfs);
622 if (IS_ERR_OR_NULL(enc->procfs)) {
623 mpp_err("failed on open procfs\n");
624 enc->procfs = NULL;
625 return -EIO;
626 }
627 mpp_procfs_create_u32("aclk", FILE_RIGHT_644, enc->procfs, &enc->aclk_info.debug_rate_hz);
628 mpp_procfs_create_u32("session_buffers", FILE_RIGHT_644, enc->procfs, &mpp->session_max_buffers);
629 /* for show session info */
630 proc_create_single_data("sessions-info", FILE_RIGHT_444, enc->procfs, vepu_show_session_info, mpp);
631
632 return 0;
633 }
634
vepu_procfs_ccu_init(struct mpp_dev * mpp)635 static int vepu_procfs_ccu_init(struct mpp_dev *mpp)
636 {
637 struct vepu_dev *enc = to_vepu_dev(mpp);
638
639 if (!enc->procfs) {
640 goto done;
641 }
642
643 mpp_procfs_create_u32("disable_work", FILE_RIGHT_644, enc->procfs, &enc->disable_work);
644 done:
645 return 0;
646 }
647 #else
vepu_procfs_remove(struct mpp_dev * mpp)648 static inline int vepu_procfs_remove(struct mpp_dev *mpp)
649 {
650 return 0;
651 }
652
vepu_procfs_init(struct mpp_dev * mpp)653 static inline int vepu_procfs_init(struct mpp_dev *mpp)
654 {
655 return 0;
656 }
657
vepu_procfs_ccu_init(struct mpp_dev * mpp)658 static inline int vepu_procfs_ccu_init(struct mpp_dev *mpp)
659 {
660 return 0;
661 }
662
vepu_dump_session(struct mpp_session * session,struct seq_file * seq)663 static inline int vepu_dump_session(struct mpp_session *session, struct seq_file *seq)
664 {
665 return 0;
666 }
667 #endif
668
vepu_init(struct mpp_dev * mpp)669 static int vepu_init(struct mpp_dev *mpp)
670 {
671 int ret;
672 struct vepu_dev *enc = to_vepu_dev(mpp);
673
674 mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_VEPU2];
675
676 /* Get clock info from dtsi */
677 ret = mpp_get_clk_info(mpp, &enc->aclk_info, "aclk_vcodec");
678 if (ret) {
679 mpp_err("failed on clk_get aclk_vcodec\n");
680 }
681 ret = mpp_get_clk_info(mpp, &enc->hclk_info, "hclk_vcodec");
682 if (ret) {
683 mpp_err("failed on clk_get hclk_vcodec\n");
684 }
685 /* Get normal max workload from dtsi */
686 of_property_read_u32(mpp->dev->of_node, "rockchip,default-max-load", &enc->default_max_load);
687 /* Set default rates */
688 mpp_set_clk_info_rate_hz(&enc->aclk_info, CLK_MODE_DEFAULT, 0x12C * MHZ);
689
690 /* Get reset control from dtsi */
691 enc->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
692 if (!enc->rst_a) {
693 mpp_err("No aclk reset resource define\n");
694 }
695 enc->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "video_h");
696 if (!enc->rst_h) {
697 mpp_err("No hclk reset resource define\n");
698 }
699
700 return 0;
701 }
702
vepu_px30_init(struct mpp_dev * mpp)703 static int vepu_px30_init(struct mpp_dev *mpp)
704 {
705 vepu_init(mpp);
706 return px30_workaround_combo_init(mpp);
707 }
708
vepu_clk_on(struct mpp_dev * mpp)709 static int vepu_clk_on(struct mpp_dev *mpp)
710 {
711 struct vepu_dev *enc = to_vepu_dev(mpp);
712
713 mpp_clk_safe_enable(enc->aclk_info.clk);
714 mpp_clk_safe_enable(enc->hclk_info.clk);
715
716 return 0;
717 }
718
vepu_clk_off(struct mpp_dev * mpp)719 static int vepu_clk_off(struct mpp_dev *mpp)
720 {
721 struct vepu_dev *enc = to_vepu_dev(mpp);
722
723 mpp_clk_safe_disable(enc->aclk_info.clk);
724 mpp_clk_safe_disable(enc->hclk_info.clk);
725
726 return 0;
727 }
728
vepu_get_freq(struct mpp_dev * mpp,struct mpp_task * mpp_task)729 static int vepu_get_freq(struct mpp_dev *mpp, struct mpp_task *mpp_task)
730 {
731 u32 task_cnt;
732 u32 workload;
733 struct mpp_task *loop = NULL, *n;
734 struct vepu_dev *enc = to_vepu_dev(mpp);
735 struct vepu_task *task = to_vepu_task(mpp_task);
736
737 /* if not set max load, consider not have advanced mode */
738 if (!enc->default_max_load) {
739 return 0;
740 }
741
742 task_cnt = 1;
743 workload = task->pixels;
744 /* calc workload in pending list */
745 mutex_lock(&mpp->queue->pending_lock);
746 list_for_each_entry_safe(loop, n, &mpp->queue->pending_list, queue_link)
747 {
748 struct vepu_task *loop_task = to_vepu_task(loop);
749
750 task_cnt++;
751 workload += loop_task->pixels;
752 }
753 mutex_unlock(&mpp->queue->pending_lock);
754
755 if (workload > enc->default_max_load) {
756 task->clk_mode = CLK_MODE_ADVANCED;
757 }
758
759 mpp_debug(DEBUG_TASK_INFO, "pending task %d, workload %d, clk_mode=%d\n", task_cnt, workload, task->clk_mode);
760
761 return 0;
762 }
763
vepu_set_freq(struct mpp_dev * mpp,struct mpp_task * mpp_task)764 static int vepu_set_freq(struct mpp_dev *mpp, struct mpp_task *mpp_task)
765 {
766 struct vepu_dev *enc = to_vepu_dev(mpp);
767 struct vepu_task *task = to_vepu_task(mpp_task);
768
769 mpp_clk_set_rate(&enc->aclk_info, task->clk_mode);
770
771 return 0;
772 }
773
vepu_reduce_freq(struct mpp_dev * mpp)774 static int vepu_reduce_freq(struct mpp_dev *mpp)
775 {
776 struct vepu_dev *enc = to_vepu_dev(mpp);
777
778 mpp_clk_set_rate(&enc->aclk_info, CLK_MODE_REDUCE);
779
780 return 0;
781 }
782
vepu_reset(struct mpp_dev * mpp)783 static int vepu_reset(struct mpp_dev *mpp)
784 {
785 struct vepu_dev *enc = to_vepu_dev(mpp);
786
787 if (enc->rst_a && enc->rst_h) {
788 /* Don't skip this or iommu won't work after reset */
789 rockchip_pmu_idle_request(mpp->dev, true);
790 mpp_safe_reset(enc->rst_a);
791 mpp_safe_reset(enc->rst_h);
792 udelay(0x5);
793 mpp_safe_unreset(enc->rst_a);
794 mpp_safe_unreset(enc->rst_h);
795 rockchip_pmu_idle_request(mpp->dev, false);
796 }
797 mpp_write(mpp, VEPU2_REG_INT, VEPU2_INT_CLEAR);
798
799 return 0;
800 }
801
802 static struct mpp_hw_ops vepu_v2_hw_ops = {
803 .init = vepu_init,
804 .clk_on = vepu_clk_on,
805 .clk_off = vepu_clk_off,
806 .get_freq = vepu_get_freq,
807 .set_freq = vepu_set_freq,
808 .reduce_freq = vepu_reduce_freq,
809 .reset = vepu_reset,
810 };
811
812 static struct mpp_hw_ops vepu_px30_hw_ops = {
813 .init = vepu_px30_init,
814 .clk_on = vepu_clk_on,
815 .clk_off = vepu_clk_off,
816 .set_freq = vepu_set_freq,
817 .reduce_freq = vepu_reduce_freq,
818 .reset = vepu_reset,
819 .set_grf = px30_workaround_combo_switch_grf,
820 };
821
822 static struct mpp_dev_ops vepu_v2_dev_ops = {
823 .alloc_task = vepu_alloc_task,
824 .run = vepu_run,
825 .irq = vepu_irq,
826 .isr = vepu_isr,
827 .finish = vepu_finish,
828 .result = vepu_result,
829 .free_task = vepu_free_task,
830 .ioctl = vepu_control,
831 .init_session = vepu_init_session,
832 .free_session = vepu_free_session,
833 .dump_session = vepu_dump_session,
834 };
835
836 static struct mpp_dev_ops vepu_ccu_dev_ops = {
837 .alloc_task = vepu_ccu_alloc_task,
838 .run = vepu_run,
839 .irq = vepu_irq,
840 .isr = vepu_isr,
841 .finish = vepu_finish,
842 .result = vepu_result,
843 .free_task = vepu_free_task,
844 .ioctl = vepu_control,
845 .init_session = vepu_init_session,
846 .free_session = vepu_free_session,
847 .dump_session = vepu_dump_session,
848 };
849
850 static const struct mpp_dev_var vepu_v2_data = {
851 .device_type = MPP_DEVICE_VEPU2,
852 .hw_info = &vepu_v2_hw_info,
853 .trans_info = trans_rk_vepu2,
854 .hw_ops = &vepu_v2_hw_ops,
855 .dev_ops = &vepu_v2_dev_ops,
856 };
857
858 static const struct mpp_dev_var vepu_px30_data = {
859 .device_type = MPP_DEVICE_VEPU2,
860 .hw_info = &vepu_v2_hw_info,
861 .trans_info = trans_rk_vepu2,
862 .hw_ops = &vepu_px30_hw_ops,
863 .dev_ops = &vepu_v2_dev_ops,
864 };
865
866 static const struct mpp_dev_var vepu_ccu_data = {
867 .device_type = MPP_DEVICE_VEPU2,
868 .hw_info = &vepu_v2_hw_info,
869 .trans_info = trans_rk_vepu2,
870 .hw_ops = &vepu_v2_hw_ops,
871 .dev_ops = &vepu_ccu_dev_ops,
872 };
873
874 static const struct of_device_id mpp_vepu2_dt_match[] = {
875 {
876 .compatible = "rockchip,vpu-encoder-v2",
877 .data = &vepu_v2_data,
878 },
879 #ifdef CONFIG_CPU_PX30
880 {
881 .compatible = "rockchip,vpu-encoder-px30",
882 .data = &vepu_px30_data,
883 },
884 #endif
885 #ifdef CONFIG_CPU_RK3588
886 {
887 .compatible = "rockchip,vpu-encoder-v2-core",
888 .data = &vepu_ccu_data,
889 },
890 {
891 .compatible = "rockchip,vpu-encoder-v2-ccu",
892 },
893 #endif
894 {},
895 };
896
vepu_ccu_probe(struct platform_device * pdev)897 static int vepu_ccu_probe(struct platform_device *pdev)
898 {
899 struct vepu_ccu *ccu;
900 struct device *dev = &pdev->dev;
901
902 ccu = devm_kzalloc(dev, sizeof(*ccu), GFP_KERNEL);
903 if (!ccu) {
904 return -ENOMEM;
905 }
906
907 platform_set_drvdata(pdev, ccu);
908 mutex_init(&ccu->lock);
909 INIT_LIST_HEAD(&ccu->core_list);
910
911 return 0;
912 }
913
vepu_attach_ccu(struct device * dev,struct vepu_dev * enc)914 static int vepu_attach_ccu(struct device *dev, struct vepu_dev *enc)
915 {
916 struct device_node *np;
917 struct platform_device *pdev;
918 struct vepu_ccu *ccu;
919
920 np = of_parse_phandle(dev->of_node, "rockchip,ccu", 0);
921 if (!np || !of_device_is_available(np)) {
922 return -ENODEV;
923 }
924
925 pdev = of_find_device_by_node(np);
926 of_node_put(np);
927 if (!pdev) {
928 return -ENODEV;
929 }
930
931 ccu = platform_get_drvdata(pdev);
932 if (!ccu) {
933 return -ENOMEM;
934 }
935
936 INIT_LIST_HEAD(&enc->core_link);
937 mutex_lock(&ccu->lock);
938 ccu->core_num++;
939 list_add_tail(&enc->core_link, &ccu->core_list);
940 mutex_unlock(&ccu->lock);
941
942 /* attach the ccu-domain to current core */
943 if (!ccu->main_core) {
944 /**
945 * set the first device for the main-core,
946 * then the domain of the main-core named ccu-domain
947 */
948 ccu->main_core = &enc->mpp;
949 } else {
950 struct mpp_iommu_info *ccu_info, *cur_info;
951
952 /* set the ccu domain for current device */
953 ccu_info = ccu->main_core->iommu_info;
954 cur_info = enc->mpp.iommu_info;
955
956 cur_info->domain = ccu_info->domain;
957 mpp_iommu_attach(cur_info);
958 }
959 enc->ccu = ccu;
960
961 dev_info(dev, "attach ccu success\n");
962 return 0;
963 }
964
vepu_core_probe(struct platform_device * pdev)965 static int vepu_core_probe(struct platform_device *pdev)
966 {
967 struct device *dev = &pdev->dev;
968 struct vepu_dev *enc = NULL;
969 struct mpp_dev *mpp = NULL;
970 const struct of_device_id *match = NULL;
971 int ret = 0;
972
973 enc = devm_kzalloc(dev, sizeof(struct vepu_dev), GFP_KERNEL);
974 if (!enc) {
975 return -ENOMEM;
976 }
977
978 mpp = &enc->mpp;
979 platform_set_drvdata(pdev, enc);
980
981 if (pdev->dev.of_node) {
982 match = of_match_node(mpp_vepu2_dt_match, pdev->dev.of_node);
983 if (match) {
984 mpp->var = (struct mpp_dev_var *)match->data;
985 }
986
987 mpp->core_id = of_alias_get_id(pdev->dev.of_node, "jpege");
988 }
989
990 ret = mpp_dev_probe(mpp, pdev);
991 if (ret) {
992 dev_err(dev, "probe sub driver failed\n");
993 return -EINVAL;
994 }
995 /* current device attach to ccu */
996 ret = vepu_attach_ccu(dev, enc);
997 if (ret) {
998 return ret;
999 }
1000
1001 ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, mpp_dev_isr_sched, IRQF_SHARED, dev_name(dev), mpp);
1002 if (ret) {
1003 dev_err(dev, "register interrupter runtime failed\n");
1004 return -EINVAL;
1005 }
1006
1007 mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
1008 vepu_procfs_init(mpp);
1009 vepu_procfs_ccu_init(mpp);
1010 /* if current is main-core, register current device to mpp service */
1011 if (mpp == enc->ccu->main_core) {
1012 mpp_dev_register_srv(mpp, mpp->srv);
1013 }
1014
1015 return 0;
1016 }
1017
vepu_probe_default(struct platform_device * pdev)1018 static int vepu_probe_default(struct platform_device *pdev)
1019 {
1020 struct device *dev = &pdev->dev;
1021 struct vepu_dev *enc = NULL;
1022 struct mpp_dev *mpp = NULL;
1023 const struct of_device_id *match = NULL;
1024 int ret = 0;
1025
1026 enc = devm_kzalloc(dev, sizeof(struct vepu_dev), GFP_KERNEL);
1027 if (!enc) {
1028 return -ENOMEM;
1029 }
1030
1031 mpp = &enc->mpp;
1032 platform_set_drvdata(pdev, enc);
1033
1034 if (pdev->dev.of_node) {
1035 match = of_match_node(mpp_vepu2_dt_match, pdev->dev.of_node);
1036 if (match) {
1037 mpp->var = (struct mpp_dev_var *)match->data;
1038 }
1039 }
1040
1041 ret = mpp_dev_probe(mpp, pdev);
1042 if (ret) {
1043 dev_err(dev, "probe sub driver failed\n");
1044 return -EINVAL;
1045 }
1046
1047 ret = devm_request_threaded_irq(dev, mpp->irq, mpp_dev_irq, mpp_dev_isr_sched, IRQF_SHARED, dev_name(dev), mpp);
1048 if (ret) {
1049 dev_err(dev, "register interrupter runtime failed\n");
1050 return -EINVAL;
1051 }
1052
1053 mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
1054 vepu_procfs_init(mpp);
1055 /* register current device to mpp service */
1056 mpp_dev_register_srv(mpp, mpp->srv);
1057
1058 return 0;
1059 }
1060
vepu_probe(struct platform_device * pdev)1061 static int vepu_probe(struct platform_device *pdev)
1062 {
1063 int ret;
1064 struct device *dev = &pdev->dev;
1065 struct device_node *np = dev->of_node;
1066
1067 dev_info(dev, "probing start\n");
1068
1069 if (strstr(np->name, "ccu")) {
1070 ret = vepu_ccu_probe(pdev);
1071 } else if (strstr(np->name, "core")) {
1072 ret = vepu_core_probe(pdev);
1073 } else {
1074 ret = vepu_probe_default(pdev);
1075 }
1076
1077 dev_info(dev, "probing finish\n");
1078
1079 return ret;
1080 }
1081
vepu_remove(struct platform_device * pdev)1082 static int vepu_remove(struct platform_device *pdev)
1083 {
1084 struct device *dev = &pdev->dev;
1085 struct device_node *np = dev->of_node;
1086
1087 if (strstr(np->name, "ccu")) {
1088 dev_info(dev, "remove ccu device\n");
1089 } else if (strstr(np->name, "core")) {
1090 struct vepu_dev *enc = platform_get_drvdata(pdev);
1091
1092 dev_info(dev, "remove core\n");
1093 if (enc->ccu) {
1094 mutex_lock(&enc->ccu->lock);
1095 list_del_init(&enc->core_link);
1096 enc->ccu->core_num--;
1097 mutex_unlock(&enc->ccu->lock);
1098 }
1099 mpp_dev_remove(&enc->mpp);
1100 vepu_procfs_remove(&enc->mpp);
1101 } else {
1102 struct vepu_dev *enc = platform_get_drvdata(pdev);
1103
1104 dev_info(dev, "remove device\n");
1105 mpp_dev_remove(&enc->mpp);
1106 vepu_procfs_remove(&enc->mpp);
1107 }
1108
1109 return 0;
1110 }
1111
vepu_shutdown(struct platform_device * pdev)1112 static void vepu_shutdown(struct platform_device *pdev)
1113 {
1114 struct device *dev = &pdev->dev;
1115
1116 if (!strstr(dev_name(dev), "ccu")) {
1117 int ret;
1118 int val;
1119 struct vepu_dev *enc = platform_get_drvdata(pdev);
1120 struct mpp_dev *mpp = &enc->mpp;
1121
1122 dev_info(dev, "shutdown device\n");
1123
1124 if (mpp->srv) {
1125 atomic_inc(&mpp->srv->shutdown_request);
1126 }
1127
1128 ret = readx_poll_timeout(atomic_read, &mpp->task_count, val, val == 0, 0x4E20, 0x30D40);
1129 if (ret == -ETIMEDOUT) {
1130 dev_err(dev, "wait total running time out\n");
1131 }
1132 }
1133 dev_info(dev, "shutdown success\n");
1134 }
1135
1136 struct platform_driver rockchip_vepu2_driver = {
1137 .probe = vepu_probe,
1138 .remove = vepu_remove,
1139 .shutdown = vepu_shutdown,
1140 .driver =
1141 {
1142 .name = VEPU2_DRIVER_NAME,
1143 .of_match_table = of_match_ptr(mpp_vepu2_dt_match),
1144 },
1145 };
1146 EXPORT_SYMBOL(rockchip_vepu2_driver);
1147