2 * Remote processor machine-specific module for OMAP4
4 * Copyright (C) 2011 Texas Instruments, Inc.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #define pr_fmt(fmt) "%s: " fmt, __func__
18 #include <linux/kernel.h>
19 #include <linux/clk.h>
20 #include <linux/err.h>
21 #include <linux/slab.h>
22 #include <linux/platform_device.h>
23 #include <linux/remoteproc.h>
24 #include <linux/sched.h>
25 #include <linux/rproc_drm.h>
27 #include <plat/iommu.h>
28 #include <plat/omap_device.h>
29 #include <plat/remoteproc.h>
30 #include <plat/mailbox.h>
31 #include <plat/common.h>
32 #include <plat/omap-pm.h>
33 #include <plat/dmtimer.h>
34 #include "../../arch/arm/mach-omap2/dvfs.h"
35 #include "../../arch/arm/mach-omap2/clockdomain.h"
37 #define PM_SUSPEND_MBOX 0xffffff07
38 #define PM_SUSPEND_TIMEOUT 300
40 struct omap_rproc_priv
{
42 int (*iommu_cb
)(struct rproc
*, u64
, u32
);
43 int (*wdt_cb
)(struct rproc
*);
44 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
45 struct omap_mbox
*mbox
;
48 void __iomem
*suspend
;
53 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
54 static bool _may_suspend(struct omap_rproc_priv
*rpp
)
56 return readl(rpp
->idle
) & rpp
->idle_mask
;
59 static int _suspend(struct omap_rproc_priv
*rpp
)
61 unsigned long timeout
= msecs_to_jiffies(PM_SUSPEND_TIMEOUT
) + jiffies
;
63 omap_mbox_msg_send(rpp
->mbox
, PM_SUSPEND_MBOX
);
65 while (time_after(timeout
, jiffies
)) {
66 if ((readl(rpp
->suspend
) & rpp
->suspend_mask
) &&
67 (readl(rpp
->idle
) & rpp
->idle_mask
))
75 static int omap_suspend(struct rproc
*rproc
, bool force
)
77 struct omap_rproc_priv
*rpp
= rproc
->priv
;
79 if (rpp
->idle
&& (force
|| _may_suspend(rpp
)))
86 static void omap_rproc_dump_registers(struct rproc
*rproc
)
92 if (!rproc
->cdump_buf1
)
95 remoteproc_fill_pt_regs(®s
,
96 (struct exc_regs
*)rproc
->cdump_buf1
);
98 pr_info("REGISTER DUMP FOR REMOTEPROC %s\n", rproc
->name
);
99 pr_info("PC is at %08lx\n", instruction_pointer(®s
));
100 pr_info("LR is at %08lx\n", regs
.ARM_lr
);
101 pr_info("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n"
102 "sp : %08lx ip : %08lx fp : %08lx\n",
103 regs
.ARM_pc
, regs
.ARM_lr
, regs
.ARM_cpsr
,
104 regs
.ARM_sp
, regs
.ARM_ip
, regs
.ARM_fp
);
105 pr_info("r10: %08lx r9 : %08lx r8 : %08lx\n",
106 regs
.ARM_r10
, regs
.ARM_r9
,
108 pr_info("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
109 regs
.ARM_r7
, regs
.ARM_r6
,
110 regs
.ARM_r5
, regs
.ARM_r4
);
111 pr_info("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
112 regs
.ARM_r3
, regs
.ARM_r2
,
113 regs
.ARM_r1
, regs
.ARM_r0
);
115 flags
= regs
.ARM_cpsr
;
116 buf
[0] = flags
& PSR_N_BIT
? 'N' : 'n';
117 buf
[1] = flags
& PSR_Z_BIT
? 'Z' : 'z';
118 buf
[2] = flags
& PSR_C_BIT
? 'C' : 'c';
119 buf
[3] = flags
& PSR_V_BIT
? 'V' : 'v';
122 pr_info("Flags: %s IRQs o%s FIQs o%s\n",
123 buf
, interrupts_enabled(®s
) ? "n" : "ff",
124 fast_interrupts_enabled(®s
) ? "n" : "ff");
128 omap_rproc_map(struct device
*dev
, struct iommu
*obj
, u32 da
, u32 pa
, u32 size
)
130 struct iotlb_entry e
;
132 u32 pg_size
[] = {SZ_16M
, SZ_1M
, SZ_64K
, SZ_4K
};
133 int size_flag
[] = {MMU_CAM_PGSZ_16M
, MMU_CAM_PGSZ_1M
,
134 MMU_CAM_PGSZ_64K
, MMU_CAM_PGSZ_4K
};
139 * To find the max. page size with which both PA & VA are
143 for (i
= 0; i
< 4; i
++) {
144 if ((size
>= pg_size
[i
]) &&
145 ((all_bits
& (pg_size
[i
] - 1)) == 0)) {
150 memset(&e
, 0, sizeof(e
));
155 e
.pgsz
= size_flag
[i
];
156 e
.endian
= MMU_RAM_ENDIAN_LITTLE
;
157 e
.elsz
= MMU_RAM_ELSZ_32
;
159 ret
= iopgtable_store_entry(obj
, &e
);
161 dev_err(dev
, "iopgtable_store_entry fail: %d\n", ret
);
174 static int omap_rproc_iommu_isr(struct iommu
*iommu
, u32 da
, u32 errs
, void *p
)
176 struct rproc
*rproc
= p
;
177 struct omap_rproc_priv
*rpp
= rproc
->priv
;
180 if (rpp
&& rpp
->iommu_cb
)
181 ret
= rpp
->iommu_cb(rproc
, (u64
)da
, errs
);
186 int omap_rproc_activate(struct omap_device
*od
)
189 struct rproc
*rproc
= platform_get_drvdata(&od
->pdev
);
190 struct device
*dev
= rproc
->dev
;
191 struct omap_rproc_pdata
*pdata
= dev
->platform_data
;
192 struct omap_rproc_timers_info
*timers
= pdata
->timers
;
193 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
194 struct omap_rproc_priv
*rpp
= rproc
->priv
;
198 iommu
= iommu_get(pdata
->iommu_name
);
200 dev_err(dev
, "iommu_get error: %ld\n",
202 return PTR_ERR(iommu
);
208 rpp
->mbox
= omap_mbox_get(pdata
->sus_mbox_name
, NULL
);
212 * Domain is in HW SUP thus in hw_auto but
213 * since remoteproc will be enabled clkdm
214 * needs to be in sw_sup (Do not let it idle).
217 clkdm_wakeup(pdata
->clkdm
);
219 for (i
= 0; i
< pdata
->timers_cnt
; i
++)
220 omap_dm_timer_start(timers
[i
].odt
);
222 for (i
= 0; i
< od
->hwmods_cnt
; i
++) {
223 ret
= omap_hwmod_enable(od
->hwmods
[i
]);
225 for (i
= 0; i
< pdata
->timers_cnt
; i
++)
226 omap_dm_timer_stop(timers
[i
].odt
);
232 * Domain is in force_wkup but since remoteproc
233 * was enabled it is safe now to switch clkdm
234 * to hw_auto (let it idle).
237 clkdm_allow_idle(pdata
->clkdm
);
242 int omap_rproc_deactivate(struct omap_device
*od
)
245 struct rproc
*rproc
= platform_get_drvdata(&od
->pdev
);
246 struct device
*dev
= rproc
->dev
;
247 struct omap_rproc_pdata
*pdata
= dev
->platform_data
;
248 struct omap_rproc_timers_info
*timers
= pdata
->timers
;
249 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
250 struct omap_rproc_priv
*rpp
= rproc
->priv
;
253 clkdm_wakeup(pdata
->clkdm
);
255 for (i
= 0; i
< od
->hwmods_cnt
; i
++) {
256 ret
= omap_hwmod_shutdown(od
->hwmods
[i
]);
261 for (i
= 0; i
< pdata
->timers_cnt
; i
++)
262 omap_dm_timer_stop(timers
[i
].odt
);
264 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
266 iommu_put(rpp
->iommu
);
271 omap_mbox_put(rpp
->mbox
, NULL
);
277 clkdm_allow_idle(pdata
->clkdm
);
282 static int omap_rproc_iommu_init(struct rproc
*rproc
,
283 int (*callback
)(struct rproc
*rproc
, u64 fa
, u32 flags
))
285 struct device
*dev
= rproc
->dev
;
286 struct omap_rproc_pdata
*pdata
= dev
->platform_data
;
289 struct omap_rproc_priv
*rpp
;
291 rpp
= kzalloc(sizeof(*rpp
), GFP_KERNEL
);
296 clkdm_wakeup(pdata
->clkdm
);
297 iommu_set_isr(pdata
->iommu_name
, omap_rproc_iommu_isr
, rproc
);
298 iommu_set_secure(pdata
->iommu_name
, rproc
->secure_mode
,
300 iommu
= iommu_get(pdata
->iommu_name
);
302 ret
= PTR_ERR(iommu
);
303 dev_err(dev
, "iommu_get error: %d\n", ret
);
308 rpp
->iommu_cb
= callback
;
311 if (!rproc
->secure_mode
) {
312 for (i
= 0; rproc
->memory_maps
[i
].size
; i
++) {
313 const struct rproc_mem_entry
*me
=
314 &rproc
->memory_maps
[i
];
316 ret
= omap_rproc_map(dev
, iommu
, me
->da
, me
->pa
,
323 clkdm_allow_idle(pdata
->clkdm
);
330 iommu_set_secure(pdata
->iommu_name
, false, NULL
);
332 clkdm_allow_idle(pdata
->clkdm
);
337 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
338 static int _init_pm_flags(struct rproc
*rproc
)
340 struct omap_rproc_pdata
*pdata
= rproc
->dev
->platform_data
;
341 struct omap_rproc_priv
*rpp
= rproc
->priv
;
342 struct omap_mbox
*mbox
;
345 mbox
= omap_mbox_get(pdata
->sus_mbox_name
, NULL
);
347 return PTR_ERR(mbox
);
350 if (!pdata
->idle_addr
)
353 rpp
->idle
= ioremap(pdata
->idle_addr
, sizeof(u32
));
357 if (!pdata
->suspend_addr
)
360 rpp
->suspend
= ioremap(pdata
->suspend_addr
, sizeof(u32
));
364 rpp
->idle_mask
= pdata
->idle_mask
;
365 rpp
->suspend_mask
= pdata
->suspend_mask
;
372 omap_mbox_put(rpp
->mbox
, NULL
);
377 static void _destroy_pm_flags(struct rproc
*rproc
)
379 struct omap_rproc_priv
*rpp
= rproc
->priv
;
382 omap_mbox_put(rpp
->mbox
, NULL
);
390 iounmap(rpp
->suspend
);
395 #ifdef CONFIG_REMOTEPROC_WATCHDOG
396 static int omap_rproc_watchdog_init(struct rproc
*rproc
,
397 int (*callback
)(struct rproc
*rproc
))
399 struct omap_rproc_priv
*rpp
= rproc
->priv
;
401 rpp
->wdt_cb
= callback
;
405 static int omap_rproc_watchdog_exit(struct rproc
*rproc
)
407 struct omap_rproc_priv
*rpp
= rproc
->priv
;
413 static irqreturn_t
omap_rproc_watchdog_isr(int irq
, void *p
)
415 struct rproc
*rproc
= p
;
416 struct omap_rproc_pdata
*pdata
= rproc
->dev
->platform_data
;
417 struct omap_rproc_timers_info
*timers
= pdata
->timers
;
418 struct omap_dm_timer
*timer
= NULL
;
419 struct omap_rproc_priv
*rpp
= rproc
->priv
;
422 for (i
= 0; i
< pdata
->timers_cnt
; i
++) {
423 if (irq
== omap_dm_timer_get_irq(timers
[i
].odt
)) {
424 timer
= timers
[i
].odt
;
432 omap_dm_timer_write_status(timer
, OMAP_TIMER_INT_OVERFLOW
);
440 static inline int omap_rproc_start(struct rproc
*rproc
, u64 bootaddr
)
442 struct device
*dev
= rproc
->dev
;
443 struct platform_device
*pdev
= to_platform_device(dev
);
444 struct omap_rproc_pdata
*pdata
= dev
->platform_data
;
445 struct omap_rproc_timers_info
*timers
= pdata
->timers
;
449 if (rproc
->secure_mode
) {
450 rproc
->secure_reset
= true;
451 ret
= rproc_drm_invoke_service(rproc
->secure_mode
);
453 dev_err(rproc
->dev
, "rproc_drm_invoke_service failed "
454 "for secure_enable ret = 0x%x\n", ret
);
459 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
460 _init_pm_flags(rproc
);
462 for (i
= 0; i
< pdata
->timers_cnt
; i
++) {
463 timers
[i
].odt
= omap_dm_timer_request_specific(timers
[i
].id
);
464 if (!timers
[i
].odt
) {
468 omap_dm_timer_set_source(timers
[i
].odt
, OMAP_TIMER_SRC_SYS_CLK
);
469 #ifdef CONFIG_REMOTEPROC_WATCHDOG
470 /* GPT 9 and 11 are using as WDT */
471 if (timers
[i
].id
== 9 || timers
[i
].id
== 11) {
472 ret
= request_irq(omap_dm_timer_get_irq(timers
[i
].odt
),
473 omap_rproc_watchdog_isr
, IRQF_DISABLED
,
475 /* Clean counter, remoteproc proc will set the value */
476 omap_dm_timer_set_load(timers
[i
].odt
, 0, 0);
481 ret
= omap_device_enable(pdev
);
485 omap_dm_timer_free(timers
[i
].odt
);
486 timers
[i
].odt
= NULL
;
493 static int omap_rproc_iommu_exit(struct rproc
*rproc
)
495 struct omap_rproc_priv
*rpp
= rproc
->priv
;
496 struct omap_rproc_pdata
*pdata
= rproc
->dev
->platform_data
;
499 clkdm_wakeup(pdata
->clkdm
);
502 iommu_put(rpp
->iommu
);
505 clkdm_allow_idle(pdata
->clkdm
);
510 static inline int omap_rproc_stop(struct rproc
*rproc
)
512 struct device
*dev
= rproc
->dev
;
513 struct platform_device
*pdev
= to_platform_device(dev
);
514 struct omap_rproc_pdata
*pdata
= dev
->platform_data
;
515 struct omap_rproc_timers_info
*timers
= pdata
->timers
;
518 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
519 _destroy_pm_flags(rproc
);
521 if (rproc
->secure_reset
) {
522 ret
= rproc_drm_invoke_service(false);
524 dev_err(rproc
->dev
, "rproc_drm_invoke_service failed "
525 "for secure disable ret = 0x%x\n", ret
);
526 rproc
->secure_reset
= false;
529 ret
= omap_device_idle(pdev
);
533 for (i
= 0; i
< pdata
->timers_cnt
; i
++) {
534 #ifdef CONFIG_REMOTEPROC_WATCHDOG
535 /* GPT 9 and 11 are used as WDT */
536 if (timers
[i
].id
== 9 || timers
[i
].id
== 11)
537 free_irq(omap_dm_timer_get_irq(timers
[i
].odt
), rproc
);
539 omap_dm_timer_free(timers
[i
].odt
);
540 timers
[i
].odt
= NULL
;
546 static int omap_rproc_set_lat(struct rproc
*rproc
, long val
)
548 pm_qos_update_request(rproc
->qos_request
, val
);
552 static int omap_rproc_set_l3_bw(struct rproc
*rproc
, long val
)
554 return omap_pm_set_min_bus_tput(rproc
->dev
, OCP_INITIATOR_AGENT
, val
);
557 static int omap_rproc_scale(struct rproc
*rproc
, long val
)
559 return omap_device_scale(rproc
->dev
, rproc
->dev
, val
);
562 static struct rproc_ops omap_rproc_ops
= {
563 .start
= omap_rproc_start
,
564 .stop
= omap_rproc_stop
,
565 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
566 .suspend
= omap_suspend
,
568 .iommu_init
= omap_rproc_iommu_init
,
569 .iommu_exit
= omap_rproc_iommu_exit
,
570 .set_lat
= omap_rproc_set_lat
,
571 .set_bw
= omap_rproc_set_l3_bw
,
572 .scale
= omap_rproc_scale
,
573 #ifdef CONFIG_REMOTEPROC_WATCHDOG
574 .watchdog_init
= omap_rproc_watchdog_init
,
575 .watchdog_exit
= omap_rproc_watchdog_exit
,
577 .dump_registers
= omap_rproc_dump_registers
,
580 static int omap_rproc_probe(struct platform_device
*pdev
)
582 struct omap_rproc_pdata
*pdata
= pdev
->dev
.platform_data
;
584 pdata
->clkdm
= clkdm_lookup(pdata
->clkdm_name
);
586 return rproc_register(&pdev
->dev
, pdata
->name
, &omap_rproc_ops
,
587 pdata
->firmware
, pdata
->memory_pool
,
588 THIS_MODULE
, pdata
->sus_timeout
);
591 static int __devexit
omap_rproc_remove(struct platform_device
*pdev
)
593 struct omap_rproc_pdata
*pdata
= pdev
->dev
.platform_data
;
595 return rproc_unregister(pdata
->name
);
598 static struct platform_driver omap_rproc_driver
= {
599 .probe
= omap_rproc_probe
,
600 .remove
= __devexit_p(omap_rproc_remove
),
602 .name
= "omap-rproc",
603 .owner
= THIS_MODULE
,
604 .pm
= GENERIC_RPROC_PM_OPS
,
608 static int __init
omap_rproc_init(void)
610 return platform_driver_register(&omap_rproc_driver
);
612 /* must be ready in time for device_initcall users */
613 subsys_initcall(omap_rproc_init
);
615 static void __exit
omap_rproc_exit(void)
617 platform_driver_unregister(&omap_rproc_driver
);
619 module_exit(omap_rproc_exit
);
621 MODULE_LICENSE("GPL v2");
622 MODULE_DESCRIPTION("OMAP Remote Processor control driver");