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