1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/clk.h>
15#include <linux/debugfs.h>
16#include <linux/firmware.h>
17#include <linux/interrupt.h>
18#include <linux/iommu.h>
19#include <linux/module.h>
20#include <linux/of_address.h>
21#include <linux/of_irq.h>
22#include <linux/of_platform.h>
23#include <linux/of_reserved_mem.h>
24#include <linux/sched.h>
25#include <linux/sizes.h>
26
27#include "mtk_vpu.h"
28
29
30
31
32
33
34
35#define INIT_TIMEOUT_MS 2000U
36#define IPI_TIMEOUT_MS 2000U
37#define VPU_FW_VER_LEN 16
38
39
40#define VPU_PTCM_SIZE (96 * SZ_1K)
41#define VPU_DTCM_SIZE (32 * SZ_1K)
42
43#define VPU_DTCM_OFFSET 0x18000UL
44
45#define VPU_EXT_P_SIZE SZ_1M
46#define VPU_EXT_D_SIZE SZ_4M
47
48#define VPU_P_FW_SIZE (VPU_PTCM_SIZE + VPU_EXT_P_SIZE)
49#define VPU_D_FW_SIZE (VPU_DTCM_SIZE + VPU_EXT_D_SIZE)
50
51#define SHARE_BUF_SIZE 48
52
53
54#define VPU_P_FW "vpu_p.bin"
55#define VPU_D_FW "vpu_d.bin"
56
57#define VPU_RESET 0x0
58#define VPU_TCM_CFG 0x0008
59#define VPU_PMEM_EXT0_ADDR 0x000C
60#define VPU_PMEM_EXT1_ADDR 0x0010
61#define VPU_TO_HOST 0x001C
62#define VPU_DMEM_EXT0_ADDR 0x0014
63#define VPU_DMEM_EXT1_ADDR 0x0018
64#define HOST_TO_VPU 0x0024
65#define VPU_PC_REG 0x0060
66#define VPU_WDT_REG 0x0084
67
68
69#define VPU_IPC_INT BIT(8)
70
71
72
73
74
75
76
77
78enum vpu_fw_type {
79 P_FW,
80 D_FW,
81};
82
83
84
85
86
87
88
89
90struct vpu_mem {
91 void *va;
92 dma_addr_t pa;
93};
94
95
96
97
98
99
100
101
102struct vpu_regs {
103 void __iomem *tcm;
104 void __iomem *cfg;
105 int irq;
106};
107
108
109
110
111
112
113
114struct vpu_wdt_handler {
115 void (*reset_func)(void *);
116 void *priv;
117};
118
119
120
121
122
123
124
125
126struct vpu_wdt {
127 struct vpu_wdt_handler handler[VPU_RST_MAX];
128 struct work_struct ws;
129 struct workqueue_struct *wq;
130};
131
132
133
134
135
136
137
138
139
140
141struct vpu_run {
142 u32 signaled;
143 char fw_ver[VPU_FW_VER_LEN];
144 unsigned int enc_capability;
145 wait_queue_head_t wq;
146};
147
148
149
150
151
152
153
154
155struct vpu_ipi_desc {
156 ipi_handler_t handler;
157 const char *name;
158 void *priv;
159};
160
161
162
163
164
165
166
167
168
169struct share_obj {
170 s32 id;
171 u32 len;
172 unsigned char share_buf[SHARE_BUF_SIZE];
173};
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203struct mtk_vpu {
204 struct vpu_mem extmem[2];
205 struct vpu_regs reg;
206 struct vpu_run run;
207 struct vpu_wdt wdt;
208 struct vpu_ipi_desc ipi_desc[IPI_MAX];
209 struct share_obj *recv_buf;
210 struct share_obj *send_buf;
211 struct device *dev;
212 struct clk *clk;
213 bool fw_loaded;
214 bool enable_4GB;
215 struct mutex vpu_mutex;
216 u32 wdt_refcnt;
217 wait_queue_head_t ack_wq;
218 bool ipi_id_ack[IPI_MAX];
219};
220
221static inline void vpu_cfg_writel(struct mtk_vpu *vpu, u32 val, u32 offset)
222{
223 writel(val, vpu->reg.cfg + offset);
224}
225
226static inline u32 vpu_cfg_readl(struct mtk_vpu *vpu, u32 offset)
227{
228 return readl(vpu->reg.cfg + offset);
229}
230
231static inline bool vpu_running(struct mtk_vpu *vpu)
232{
233 return vpu_cfg_readl(vpu, VPU_RESET) & BIT(0);
234}
235
236static void vpu_clock_disable(struct mtk_vpu *vpu)
237{
238
239 mutex_lock(&vpu->vpu_mutex);
240 if (!--vpu->wdt_refcnt)
241 vpu_cfg_writel(vpu,
242 vpu_cfg_readl(vpu, VPU_WDT_REG) & ~(1L << 31),
243 VPU_WDT_REG);
244 mutex_unlock(&vpu->vpu_mutex);
245
246 clk_disable(vpu->clk);
247}
248
249static int vpu_clock_enable(struct mtk_vpu *vpu)
250{
251 int ret;
252
253 ret = clk_enable(vpu->clk);
254 if (ret)
255 return ret;
256
257 mutex_lock(&vpu->vpu_mutex);
258 if (!vpu->wdt_refcnt++)
259 vpu_cfg_writel(vpu,
260 vpu_cfg_readl(vpu, VPU_WDT_REG) | (1L << 31),
261 VPU_WDT_REG);
262 mutex_unlock(&vpu->vpu_mutex);
263
264 return ret;
265}
266
267int vpu_ipi_register(struct platform_device *pdev,
268 enum ipi_id id, ipi_handler_t handler,
269 const char *name, void *priv)
270{
271 struct mtk_vpu *vpu = platform_get_drvdata(pdev);
272 struct vpu_ipi_desc *ipi_desc;
273
274 if (!vpu) {
275 dev_err(&pdev->dev, "vpu device in not ready\n");
276 return -EPROBE_DEFER;
277 }
278
279 if (id >= 0 && id < IPI_MAX && handler) {
280 ipi_desc = vpu->ipi_desc;
281 ipi_desc[id].name = name;
282 ipi_desc[id].handler = handler;
283 ipi_desc[id].priv = priv;
284 return 0;
285 }
286
287 dev_err(&pdev->dev, "register vpu ipi id %d with invalid arguments\n",
288 id);
289 return -EINVAL;
290}
291EXPORT_SYMBOL_GPL(vpu_ipi_register);
292
293int vpu_ipi_send(struct platform_device *pdev,
294 enum ipi_id id, void *buf,
295 unsigned int len)
296{
297 struct mtk_vpu *vpu = platform_get_drvdata(pdev);
298 struct share_obj *send_obj = vpu->send_buf;
299 unsigned long timeout;
300 int ret = 0;
301
302 if (id <= IPI_VPU_INIT || id >= IPI_MAX ||
303 len > sizeof(send_obj->share_buf) || !buf) {
304 dev_err(vpu->dev, "failed to send ipi message\n");
305 return -EINVAL;
306 }
307
308 ret = vpu_clock_enable(vpu);
309 if (ret) {
310 dev_err(vpu->dev, "failed to enable vpu clock\n");
311 return ret;
312 }
313 if (!vpu_running(vpu)) {
314 dev_err(vpu->dev, "vpu_ipi_send: VPU is not running\n");
315 ret = -EINVAL;
316 goto clock_disable;
317 }
318
319 mutex_lock(&vpu->vpu_mutex);
320
321
322 timeout = jiffies + msecs_to_jiffies(IPI_TIMEOUT_MS);
323 do {
324 if (time_after(jiffies, timeout)) {
325 dev_err(vpu->dev, "vpu_ipi_send: IPI timeout!\n");
326 ret = -EIO;
327 goto mut_unlock;
328 }
329 } while (vpu_cfg_readl(vpu, HOST_TO_VPU));
330
331 memcpy((void *)send_obj->share_buf, buf, len);
332 send_obj->len = len;
333 send_obj->id = id;
334
335 vpu->ipi_id_ack[id] = false;
336
337 vpu_cfg_writel(vpu, 0x1, HOST_TO_VPU);
338
339 mutex_unlock(&vpu->vpu_mutex);
340
341
342 timeout = msecs_to_jiffies(IPI_TIMEOUT_MS);
343 ret = wait_event_timeout(vpu->ack_wq, vpu->ipi_id_ack[id], timeout);
344 vpu->ipi_id_ack[id] = false;
345 if (ret == 0) {
346 dev_err(vpu->dev, "vpu ipi %d ack time out !", id);
347 ret = -EIO;
348 goto clock_disable;
349 }
350 vpu_clock_disable(vpu);
351
352 return 0;
353
354mut_unlock:
355 mutex_unlock(&vpu->vpu_mutex);
356clock_disable:
357 vpu_clock_disable(vpu);
358
359 return ret;
360}
361EXPORT_SYMBOL_GPL(vpu_ipi_send);
362
363static void vpu_wdt_reset_func(struct work_struct *ws)
364{
365 struct vpu_wdt *wdt = container_of(ws, struct vpu_wdt, ws);
366 struct mtk_vpu *vpu = container_of(wdt, struct mtk_vpu, wdt);
367 struct vpu_wdt_handler *handler = wdt->handler;
368 int index, ret;
369
370 dev_info(vpu->dev, "vpu reset\n");
371 ret = vpu_clock_enable(vpu);
372 if (ret) {
373 dev_err(vpu->dev, "[VPU] wdt enables clock failed %d\n", ret);
374 return;
375 }
376 mutex_lock(&vpu->vpu_mutex);
377 vpu_cfg_writel(vpu, 0x0, VPU_RESET);
378 vpu->fw_loaded = false;
379 mutex_unlock(&vpu->vpu_mutex);
380 vpu_clock_disable(vpu);
381
382 for (index = 0; index < VPU_RST_MAX; index++) {
383 if (handler[index].reset_func) {
384 handler[index].reset_func(handler[index].priv);
385 dev_dbg(vpu->dev, "wdt handler func %d\n", index);
386 }
387 }
388}
389
390int vpu_wdt_reg_handler(struct platform_device *pdev,
391 void wdt_reset(void *),
392 void *priv, enum rst_id id)
393{
394 struct mtk_vpu *vpu = platform_get_drvdata(pdev);
395 struct vpu_wdt_handler *handler;
396
397 if (!vpu) {
398 dev_err(&pdev->dev, "vpu device in not ready\n");
399 return -EPROBE_DEFER;
400 }
401
402 handler = vpu->wdt.handler;
403
404 if (id >= 0 && id < VPU_RST_MAX && wdt_reset) {
405 dev_dbg(vpu->dev, "wdt register id %d\n", id);
406 mutex_lock(&vpu->vpu_mutex);
407 handler[id].reset_func = wdt_reset;
408 handler[id].priv = priv;
409 mutex_unlock(&vpu->vpu_mutex);
410 return 0;
411 }
412
413 dev_err(vpu->dev, "register vpu wdt handler failed\n");
414 return -EINVAL;
415}
416EXPORT_SYMBOL_GPL(vpu_wdt_reg_handler);
417
418unsigned int vpu_get_venc_hw_capa(struct platform_device *pdev)
419{
420 struct mtk_vpu *vpu = platform_get_drvdata(pdev);
421
422 return vpu->run.enc_capability;
423}
424EXPORT_SYMBOL_GPL(vpu_get_venc_hw_capa);
425
426void *vpu_mapping_dm_addr(struct platform_device *pdev,
427 u32 dtcm_dmem_addr)
428{
429 struct mtk_vpu *vpu = platform_get_drvdata(pdev);
430
431 if (!dtcm_dmem_addr ||
432 (dtcm_dmem_addr > (VPU_DTCM_SIZE + VPU_EXT_D_SIZE))) {
433 dev_err(vpu->dev, "invalid virtual data memory address\n");
434 return ERR_PTR(-EINVAL);
435 }
436
437 if (dtcm_dmem_addr < VPU_DTCM_SIZE)
438 return (__force void *)(dtcm_dmem_addr + vpu->reg.tcm +
439 VPU_DTCM_OFFSET);
440
441 return vpu->extmem[D_FW].va + (dtcm_dmem_addr - VPU_DTCM_SIZE);
442}
443EXPORT_SYMBOL_GPL(vpu_mapping_dm_addr);
444
445struct platform_device *vpu_get_plat_device(struct platform_device *pdev)
446{
447 struct device *dev = &pdev->dev;
448 struct device_node *vpu_node;
449 struct platform_device *vpu_pdev;
450
451 vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
452 if (!vpu_node) {
453 dev_err(dev, "can't get vpu node\n");
454 return NULL;
455 }
456
457 vpu_pdev = of_find_device_by_node(vpu_node);
458 if (WARN_ON(!vpu_pdev)) {
459 dev_err(dev, "vpu pdev failed\n");
460 of_node_put(vpu_node);
461 return NULL;
462 }
463
464 return vpu_pdev;
465}
466EXPORT_SYMBOL_GPL(vpu_get_plat_device);
467
468
469static int load_requested_vpu(struct mtk_vpu *vpu,
470 const struct firmware *vpu_fw,
471 u8 fw_type)
472{
473 size_t tcm_size = fw_type ? VPU_DTCM_SIZE : VPU_PTCM_SIZE;
474 size_t fw_size = fw_type ? VPU_D_FW_SIZE : VPU_P_FW_SIZE;
475 char *fw_name = fw_type ? VPU_D_FW : VPU_P_FW;
476 size_t dl_size = 0;
477 size_t extra_fw_size = 0;
478 void *dest;
479 int ret;
480
481 ret = request_firmware(&vpu_fw, fw_name, vpu->dev);
482 if (ret < 0) {
483 dev_err(vpu->dev, "Failed to load %s, %d\n", fw_name, ret);
484 return ret;
485 }
486 dl_size = vpu_fw->size;
487 if (dl_size > fw_size) {
488 dev_err(vpu->dev, "fw %s size %zu is abnormal\n", fw_name,
489 dl_size);
490 release_firmware(vpu_fw);
491 return -EFBIG;
492 }
493 dev_dbg(vpu->dev, "Downloaded fw %s size: %zu.\n",
494 fw_name,
495 dl_size);
496
497 vpu_cfg_writel(vpu, 0x0, VPU_RESET);
498
499
500 if (dl_size > tcm_size) {
501 dev_dbg(vpu->dev, "fw size %zu > limited fw size %zu\n",
502 dl_size, tcm_size);
503 extra_fw_size = dl_size - tcm_size;
504 dev_dbg(vpu->dev, "extra_fw_size %zu\n", extra_fw_size);
505 dl_size = tcm_size;
506 }
507 dest = (__force void *)vpu->reg.tcm;
508 if (fw_type == D_FW)
509 dest += VPU_DTCM_OFFSET;
510 memcpy(dest, vpu_fw->data, dl_size);
511
512 if (extra_fw_size > 0) {
513 dest = vpu->extmem[fw_type].va;
514 dev_dbg(vpu->dev, "download extended memory type %x\n",
515 fw_type);
516 memcpy(dest, vpu_fw->data + tcm_size, extra_fw_size);
517 }
518
519 release_firmware(vpu_fw);
520
521 return 0;
522}
523
524int vpu_load_firmware(struct platform_device *pdev)
525{
526 struct mtk_vpu *vpu = platform_get_drvdata(pdev);
527 struct device *dev = &pdev->dev;
528 struct vpu_run *run = &vpu->run;
529 const struct firmware *vpu_fw = NULL;
530 int ret;
531
532 if (!pdev) {
533 dev_err(dev, "VPU platform device is invalid\n");
534 return -EINVAL;
535 }
536
537 mutex_lock(&vpu->vpu_mutex);
538 if (vpu->fw_loaded) {
539 mutex_unlock(&vpu->vpu_mutex);
540 return 0;
541 }
542 mutex_unlock(&vpu->vpu_mutex);
543
544 ret = vpu_clock_enable(vpu);
545 if (ret) {
546 dev_err(dev, "enable clock failed %d\n", ret);
547 return ret;
548 }
549
550 mutex_lock(&vpu->vpu_mutex);
551
552 run->signaled = false;
553 dev_dbg(vpu->dev, "firmware request\n");
554
555 ret = load_requested_vpu(vpu, vpu_fw, P_FW);
556 if (ret < 0) {
557 dev_err(dev, "Failed to request %s, %d\n", VPU_P_FW, ret);
558 goto OUT_LOAD_FW;
559 }
560
561
562 ret = load_requested_vpu(vpu, vpu_fw, D_FW);
563 if (ret < 0) {
564 dev_err(dev, "Failed to request %s, %d\n", VPU_D_FW, ret);
565 goto OUT_LOAD_FW;
566 }
567
568 vpu->fw_loaded = true;
569
570 vpu_cfg_writel(vpu, 0x1, VPU_RESET);
571
572 ret = wait_event_interruptible_timeout(run->wq,
573 run->signaled,
574 msecs_to_jiffies(INIT_TIMEOUT_MS)
575 );
576 if (ret == 0) {
577 ret = -ETIME;
578 dev_err(dev, "wait vpu initialization timout!\n");
579 goto OUT_LOAD_FW;
580 } else if (-ERESTARTSYS == ret) {
581 dev_err(dev, "wait vpu interrupted by a signal!\n");
582 goto OUT_LOAD_FW;
583 }
584
585 ret = 0;
586 dev_info(dev, "vpu is ready. Fw version %s\n", run->fw_ver);
587
588OUT_LOAD_FW:
589 mutex_unlock(&vpu->vpu_mutex);
590 vpu_clock_disable(vpu);
591
592 return ret;
593}
594EXPORT_SYMBOL_GPL(vpu_load_firmware);
595
596static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv)
597{
598 struct mtk_vpu *vpu = (struct mtk_vpu *)priv;
599 struct vpu_run *run = (struct vpu_run *)data;
600
601 vpu->run.signaled = run->signaled;
602 strncpy(vpu->run.fw_ver, run->fw_ver, VPU_FW_VER_LEN);
603 vpu->run.enc_capability = run->enc_capability;
604 wake_up_interruptible(&vpu->run.wq);
605}
606
607#ifdef CONFIG_DEBUG_FS
608static ssize_t vpu_debug_read(struct file *file, char __user *user_buf,
609 size_t count, loff_t *ppos)
610{
611 char buf[256];
612 unsigned int len;
613 unsigned int running, pc, vpu_to_host, host_to_vpu, wdt;
614 int ret;
615 struct device *dev = file->private_data;
616 struct mtk_vpu *vpu = dev_get_drvdata(dev);
617
618 ret = vpu_clock_enable(vpu);
619 if (ret) {
620 dev_err(vpu->dev, "[VPU] enable clock failed %d\n", ret);
621 return 0;
622 }
623
624
625 running = vpu_running(vpu);
626 pc = vpu_cfg_readl(vpu, VPU_PC_REG);
627 wdt = vpu_cfg_readl(vpu, VPU_WDT_REG);
628 host_to_vpu = vpu_cfg_readl(vpu, HOST_TO_VPU);
629 vpu_to_host = vpu_cfg_readl(vpu, VPU_TO_HOST);
630 vpu_clock_disable(vpu);
631
632 if (running) {
633 len = snprintf(buf, sizeof(buf), "VPU is running\n\n"
634 "FW Version: %s\n"
635 "PC: 0x%x\n"
636 "WDT: 0x%x\n"
637 "Host to VPU: 0x%x\n"
638 "VPU to Host: 0x%x\n",
639 vpu->run.fw_ver, pc, wdt,
640 host_to_vpu, vpu_to_host);
641 } else {
642 len = snprintf(buf, sizeof(buf), "VPU not running\n");
643 }
644
645 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
646}
647
648static const struct file_operations vpu_debug_fops = {
649 .open = simple_open,
650 .read = vpu_debug_read,
651};
652#endif
653
654static void vpu_free_ext_mem(struct mtk_vpu *vpu, u8 fw_type)
655{
656 struct device *dev = vpu->dev;
657 size_t fw_ext_size = fw_type ? VPU_EXT_D_SIZE : VPU_EXT_P_SIZE;
658
659 dma_free_coherent(dev, fw_ext_size, vpu->extmem[fw_type].va,
660 vpu->extmem[fw_type].pa);
661}
662
663static int vpu_alloc_ext_mem(struct mtk_vpu *vpu, u32 fw_type)
664{
665 struct device *dev = vpu->dev;
666 size_t fw_ext_size = fw_type ? VPU_EXT_D_SIZE : VPU_EXT_P_SIZE;
667 u32 vpu_ext_mem0 = fw_type ? VPU_DMEM_EXT0_ADDR : VPU_PMEM_EXT0_ADDR;
668 u32 vpu_ext_mem1 = fw_type ? VPU_DMEM_EXT1_ADDR : VPU_PMEM_EXT1_ADDR;
669 u32 offset_4gb = vpu->enable_4GB ? 0x40000000 : 0;
670
671 vpu->extmem[fw_type].va = dma_alloc_coherent(dev,
672 fw_ext_size,
673 &vpu->extmem[fw_type].pa,
674 GFP_KERNEL);
675 if (!vpu->extmem[fw_type].va) {
676 dev_err(dev, "Failed to allocate the extended program memory\n");
677 return PTR_ERR(vpu->extmem[fw_type].va);
678 }
679
680
681 vpu_cfg_writel(vpu, 0x1, vpu_ext_mem0);
682 vpu_cfg_writel(vpu, (vpu->extmem[fw_type].pa & 0xFFFFF000) + offset_4gb,
683 vpu_ext_mem1);
684
685 dev_info(dev, "%s extend memory phy=0x%llx virt=0x%p\n",
686 fw_type ? "Data" : "Program",
687 (unsigned long long)vpu->extmem[fw_type].pa,
688 vpu->extmem[fw_type].va);
689
690 return 0;
691}
692
693static void vpu_ipi_handler(struct mtk_vpu *vpu)
694{
695 struct share_obj *rcv_obj = vpu->recv_buf;
696 struct vpu_ipi_desc *ipi_desc = vpu->ipi_desc;
697
698 if (rcv_obj->id < IPI_MAX && ipi_desc[rcv_obj->id].handler) {
699 ipi_desc[rcv_obj->id].handler(rcv_obj->share_buf,
700 rcv_obj->len,
701 ipi_desc[rcv_obj->id].priv);
702 if (rcv_obj->id > IPI_VPU_INIT) {
703 vpu->ipi_id_ack[rcv_obj->id] = true;
704 wake_up(&vpu->ack_wq);
705 }
706 } else {
707 dev_err(vpu->dev, "No such ipi id = %d\n", rcv_obj->id);
708 }
709}
710
711static int vpu_ipi_init(struct mtk_vpu *vpu)
712{
713
714 vpu_cfg_writel(vpu, 0x0, VPU_TO_HOST);
715
716
717 vpu->recv_buf = (__force struct share_obj *)(vpu->reg.tcm +
718 VPU_DTCM_OFFSET);
719 vpu->send_buf = vpu->recv_buf + 1;
720 memset(vpu->recv_buf, 0, sizeof(struct share_obj));
721 memset(vpu->send_buf, 0, sizeof(struct share_obj));
722
723 return 0;
724}
725
726static irqreturn_t vpu_irq_handler(int irq, void *priv)
727{
728 struct mtk_vpu *vpu = priv;
729 u32 vpu_to_host;
730 int ret;
731
732
733
734
735
736
737 ret = clk_enable(vpu->clk);
738 if (ret) {
739 dev_err(vpu->dev, "[VPU] enable clock failed %d\n", ret);
740 return IRQ_NONE;
741 }
742 vpu_to_host = vpu_cfg_readl(vpu, VPU_TO_HOST);
743 if (vpu_to_host & VPU_IPC_INT) {
744 vpu_ipi_handler(vpu);
745 } else {
746 dev_err(vpu->dev, "vpu watchdog timeout! 0x%x", vpu_to_host);
747 queue_work(vpu->wdt.wq, &vpu->wdt.ws);
748 }
749
750
751 vpu_cfg_writel(vpu, 0x0, VPU_TO_HOST);
752 clk_disable(vpu->clk);
753
754 return IRQ_HANDLED;
755}
756
757#ifdef CONFIG_DEBUG_FS
758static struct dentry *vpu_debugfs;
759#endif
760static int mtk_vpu_probe(struct platform_device *pdev)
761{
762 struct mtk_vpu *vpu;
763 struct device *dev;
764 struct resource *res;
765 int ret = 0;
766
767 dev_dbg(&pdev->dev, "initialization\n");
768
769 dev = &pdev->dev;
770 vpu = devm_kzalloc(dev, sizeof(*vpu), GFP_KERNEL);
771 if (!vpu)
772 return -ENOMEM;
773
774 vpu->dev = &pdev->dev;
775 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcm");
776 vpu->reg.tcm = devm_ioremap_resource(dev, res);
777 if (IS_ERR((__force void *)vpu->reg.tcm))
778 return PTR_ERR((__force void *)vpu->reg.tcm);
779
780 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_reg");
781 vpu->reg.cfg = devm_ioremap_resource(dev, res);
782 if (IS_ERR((__force void *)vpu->reg.cfg))
783 return PTR_ERR((__force void *)vpu->reg.cfg);
784
785
786 vpu->clk = devm_clk_get(dev, "main");
787 if (IS_ERR(vpu->clk)) {
788 dev_err(dev, "get vpu clock failed\n");
789 return PTR_ERR(vpu->clk);
790 }
791
792 platform_set_drvdata(pdev, vpu);
793
794 ret = clk_prepare(vpu->clk);
795 if (ret) {
796 dev_err(dev, "prepare vpu clock failed\n");
797 return ret;
798 }
799
800
801 vpu->wdt.wq = create_singlethread_workqueue("vpu_wdt");
802 if (!vpu->wdt.wq) {
803 dev_err(dev, "initialize wdt workqueue failed\n");
804 return -ENOMEM;
805 }
806 INIT_WORK(&vpu->wdt.ws, vpu_wdt_reset_func);
807 mutex_init(&vpu->vpu_mutex);
808
809 ret = vpu_clock_enable(vpu);
810 if (ret) {
811 dev_err(dev, "enable vpu clock failed\n");
812 goto workqueue_destroy;
813 }
814
815 dev_dbg(dev, "vpu ipi init\n");
816 ret = vpu_ipi_init(vpu);
817 if (ret) {
818 dev_err(dev, "Failed to init ipi\n");
819 goto disable_vpu_clk;
820 }
821
822
823 ret = vpu_ipi_register(pdev, IPI_VPU_INIT, vpu_init_ipi_handler,
824 "vpu_init", vpu);
825 if (ret) {
826 dev_err(dev, "Failed to register IPI_VPU_INIT\n");
827 goto vpu_mutex_destroy;
828 }
829
830#ifdef CONFIG_DEBUG_FS
831 vpu_debugfs = debugfs_create_file("mtk_vpu", S_IRUGO, NULL, (void *)dev,
832 &vpu_debug_fops);
833 if (!vpu_debugfs) {
834 ret = -ENOMEM;
835 goto cleanup_ipi;
836 }
837#endif
838
839
840 vpu_cfg_writel(vpu, 0x2, VPU_TCM_CFG);
841
842 vpu->enable_4GB = !!(totalram_pages > (SZ_2G >> PAGE_SHIFT));
843 dev_info(dev, "4GB mode %u\n", vpu->enable_4GB);
844
845 if (vpu->enable_4GB) {
846 ret = of_reserved_mem_device_init(dev);
847 if (ret)
848 dev_info(dev, "init reserved memory failed\n");
849
850 }
851
852 ret = vpu_alloc_ext_mem(vpu, D_FW);
853 if (ret) {
854 dev_err(dev, "Allocate DM failed\n");
855 goto remove_debugfs;
856 }
857
858 ret = vpu_alloc_ext_mem(vpu, P_FW);
859 if (ret) {
860 dev_err(dev, "Allocate PM failed\n");
861 goto free_d_mem;
862 }
863
864 init_waitqueue_head(&vpu->run.wq);
865 init_waitqueue_head(&vpu->ack_wq);
866
867 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
868 if (!res) {
869 dev_err(dev, "get IRQ resource failed.\n");
870 ret = -ENXIO;
871 goto free_p_mem;
872 }
873 vpu->reg.irq = platform_get_irq(pdev, 0);
874 ret = devm_request_irq(dev, vpu->reg.irq, vpu_irq_handler, 0,
875 pdev->name, vpu);
876 if (ret) {
877 dev_err(dev, "failed to request irq\n");
878 goto free_p_mem;
879 }
880
881 vpu_clock_disable(vpu);
882 dev_dbg(dev, "initialization completed\n");
883
884 return 0;
885
886free_p_mem:
887 vpu_free_ext_mem(vpu, P_FW);
888free_d_mem:
889 vpu_free_ext_mem(vpu, D_FW);
890remove_debugfs:
891 of_reserved_mem_device_release(dev);
892#ifdef CONFIG_DEBUG_FS
893 debugfs_remove(vpu_debugfs);
894cleanup_ipi:
895#endif
896 memset(vpu->ipi_desc, 0, sizeof(struct vpu_ipi_desc) * IPI_MAX);
897vpu_mutex_destroy:
898 mutex_destroy(&vpu->vpu_mutex);
899disable_vpu_clk:
900 vpu_clock_disable(vpu);
901workqueue_destroy:
902 destroy_workqueue(vpu->wdt.wq);
903
904 return ret;
905}
906
907static const struct of_device_id mtk_vpu_match[] = {
908 {
909 .compatible = "mediatek,mt8173-vpu",
910 },
911 {},
912};
913MODULE_DEVICE_TABLE(of, mtk_vpu_match);
914
915static int mtk_vpu_remove(struct platform_device *pdev)
916{
917 struct mtk_vpu *vpu = platform_get_drvdata(pdev);
918
919#ifdef CONFIG_DEBUG_FS
920 debugfs_remove(vpu_debugfs);
921#endif
922 if (vpu->wdt.wq) {
923 flush_workqueue(vpu->wdt.wq);
924 destroy_workqueue(vpu->wdt.wq);
925 }
926 vpu_free_ext_mem(vpu, P_FW);
927 vpu_free_ext_mem(vpu, D_FW);
928 mutex_destroy(&vpu->vpu_mutex);
929 clk_unprepare(vpu->clk);
930
931 return 0;
932}
933
934static struct platform_driver mtk_vpu_driver = {
935 .probe = mtk_vpu_probe,
936 .remove = mtk_vpu_remove,
937 .driver = {
938 .name = "mtk_vpu",
939 .of_match_table = mtk_vpu_match,
940 },
941};
942
943module_platform_driver(mtk_vpu_driver);
944
945MODULE_LICENSE("GPL v2");
946MODULE_DESCRIPTION("Mediatek Video Prosessor Unit driver");
947