ARM: cpu topology: Add debugfs interface for cpu_power
[cmplus.git] / drivers / remoteproc / omap_remoteproc.c
blob3329b03d2032d717ca490b46f98722ce58e3db48
1 /*
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 {
41 struct iommu *iommu;
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;
46 void __iomem *idle;
47 u32 idle_mask;
48 void __iomem *suspend;
49 u32 suspend_mask;
50 #endif
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))
68 return 0;
69 schedule();
72 return -EAGAIN;
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)))
80 return _suspend(rpp);
82 return -EBUSY;
84 #endif
86 static void omap_rproc_dump_registers(struct rproc *rproc)
88 unsigned long flags;
89 char buf[64];
90 struct pt_regs regs;
92 if (!rproc->cdump_buf1)
93 return;
95 remoteproc_fill_pt_regs(&regs,
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(&regs));
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,
107 regs.ARM_r8);
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';
120 buf[4] = '\0';
122 pr_info("Flags: %s IRQs o%s FIQs o%s\n",
123 buf, interrupts_enabled(&regs) ? "n" : "ff",
124 fast_interrupts_enabled(&regs) ? "n" : "ff");
127 static int
128 omap_rproc_map(struct device *dev, struct iommu *obj, u32 da, u32 pa, u32 size)
130 struct iotlb_entry e;
131 u32 all_bits;
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};
135 int i, ret;
137 while (size) {
139 * To find the max. page size with which both PA & VA are
140 * aligned
142 all_bits = pa | da;
143 for (i = 0; i < 4; i++) {
144 if ((size >= pg_size[i]) &&
145 ((all_bits & (pg_size[i] - 1)) == 0)) {
146 break;
150 memset(&e, 0, sizeof(e));
152 e.da = da;
153 e.pa = pa;
154 e.valid = 1;
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);
160 if (ret) {
161 dev_err(dev, "iopgtable_store_entry fail: %d\n", ret);
162 return ret;
165 size -= pg_size[i];
166 da += pg_size[i];
167 pa += pg_size[i];
170 return 0;
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;
178 int ret = -EIO;
180 if (rpp && rpp->iommu_cb)
181 ret = rpp->iommu_cb(rproc, (u64)da, errs);
183 return ret;
186 int omap_rproc_activate(struct omap_device *od)
188 int i, ret = 0;
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;
195 struct iommu *iommu;
197 if (!rpp->iommu) {
198 iommu = iommu_get(pdata->iommu_name);
199 if (IS_ERR(iommu)) {
200 dev_err(dev, "iommu_get error: %ld\n",
201 PTR_ERR(iommu));
202 return PTR_ERR(iommu);
204 rpp->iommu = iommu;
207 if (!rpp->mbox)
208 rpp->mbox = omap_mbox_get(pdata->sus_mbox_name, NULL);
209 #endif
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).
216 if (pdata->clkdm)
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]);
224 if (ret) {
225 for (i = 0; i < pdata->timers_cnt; i++)
226 omap_dm_timer_stop(timers[i].odt);
227 break;
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).
236 if (pdata->clkdm)
237 clkdm_allow_idle(pdata->clkdm);
239 return ret;
242 int omap_rproc_deactivate(struct omap_device *od)
244 int i, ret = 0;
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;
251 #endif
252 if (pdata->clkdm)
253 clkdm_wakeup(pdata->clkdm);
255 for (i = 0; i < od->hwmods_cnt; i++) {
256 ret = omap_hwmod_shutdown(od->hwmods[i]);
257 if (ret)
258 goto err;
261 for (i = 0; i < pdata->timers_cnt; i++)
262 omap_dm_timer_stop(timers[i].odt);
264 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
265 if (rpp->iommu) {
266 iommu_put(rpp->iommu);
267 rpp->iommu = NULL;
270 if (rpp->mbox) {
271 omap_mbox_put(rpp->mbox, NULL);
272 rpp->mbox = NULL;
274 #endif
275 err:
276 if (pdata->clkdm)
277 clkdm_allow_idle(pdata->clkdm);
279 return ret;
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;
287 int ret, i;
288 struct iommu *iommu;
289 struct omap_rproc_priv *rpp;
291 rpp = kzalloc(sizeof(*rpp), GFP_KERNEL);
292 if (!rpp)
293 return -ENOMEM;
295 if (pdata->clkdm)
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,
299 rproc->secure_ttb);
300 iommu = iommu_get(pdata->iommu_name);
301 if (IS_ERR(iommu)) {
302 ret = PTR_ERR(iommu);
303 dev_err(dev, "iommu_get error: %d\n", ret);
304 goto err_mmu;
307 rpp->iommu = iommu;
308 rpp->iommu_cb = callback;
309 rproc->priv = rpp;
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,
317 me->size);
318 if (ret)
319 goto err_map;
322 if (pdata->clkdm)
323 clkdm_allow_idle(pdata->clkdm);
325 return 0;
327 err_map:
328 iommu_put(iommu);
329 err_mmu:
330 iommu_set_secure(pdata->iommu_name, false, NULL);
331 if (pdata->clkdm)
332 clkdm_allow_idle(pdata->clkdm);
333 kfree(rpp);
334 return ret;
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;
344 if (!rpp->mbox) {
345 mbox = omap_mbox_get(pdata->sus_mbox_name, NULL);
346 if (IS_ERR(mbox))
347 return PTR_ERR(mbox);
348 rpp->mbox = mbox;
350 if (!pdata->idle_addr)
351 goto err_idle;
353 rpp->idle = ioremap(pdata->idle_addr, sizeof(u32));
354 if (!rpp->idle)
355 goto err_idle;
357 if (!pdata->suspend_addr)
358 goto err_suspend;
360 rpp->suspend = ioremap(pdata->suspend_addr, sizeof(u32));
361 if (!rpp->suspend)
362 goto err_suspend;
364 rpp->idle_mask = pdata->idle_mask;
365 rpp->suspend_mask = pdata->suspend_mask;
367 return 0;
368 err_suspend:
369 iounmap(rpp->idle);
370 rpp->idle = NULL;
371 err_idle:
372 omap_mbox_put(rpp->mbox, NULL);
373 rpp->mbox = NULL;
374 return -EIO;
377 static void _destroy_pm_flags(struct rproc *rproc)
379 struct omap_rproc_priv *rpp = rproc->priv;
381 if (rpp->mbox) {
382 omap_mbox_put(rpp->mbox, NULL);
383 rpp->mbox = NULL;
385 if (rpp->idle) {
386 iounmap(rpp->idle);
387 rpp->idle = NULL;
389 if (rpp->suspend) {
390 iounmap(rpp->suspend);
391 rpp->suspend = NULL;
394 #endif
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;
402 return 0;
405 static int omap_rproc_watchdog_exit(struct rproc *rproc)
407 struct omap_rproc_priv *rpp = rproc->priv;
409 rpp->wdt_cb = NULL;
410 return 0;
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;
420 int i;
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;
425 break;
429 if (!timer)
430 return IRQ_NONE;
432 omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW);
434 if (rpp->wdt_cb)
435 rpp->wdt_cb(rproc);
437 return IRQ_HANDLED;
439 #endif
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;
446 int i;
447 int ret = 0;
449 if (rproc->secure_mode) {
450 rproc->secure_reset = true;
451 ret = rproc_drm_invoke_service(rproc->secure_mode);
452 if (ret) {
453 dev_err(rproc->dev, "rproc_drm_invoke_service failed "
454 "for secure_enable ret = 0x%x\n", ret);
455 return -ENXIO;
459 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
460 _init_pm_flags(rproc);
461 #endif
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) {
465 ret = -EBUSY;
466 goto out;
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,
474 "rproc-wdt", rproc);
475 /* Clean counter, remoteproc proc will set the value */
476 omap_dm_timer_set_load(timers[i].odt, 0, 0);
478 #endif
481 ret = omap_device_enable(pdev);
482 out:
483 if (ret) {
484 while (i--) {
485 omap_dm_timer_free(timers[i].odt);
486 timers[i].odt = NULL;
490 return ret;
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;
498 if (pdata->clkdm)
499 clkdm_wakeup(pdata->clkdm);
501 if (rpp->iommu)
502 iommu_put(rpp->iommu);
503 kfree(rpp);
504 if (pdata->clkdm)
505 clkdm_allow_idle(pdata->clkdm);
507 return 0;
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;
516 int ret, i;
518 #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
519 _destroy_pm_flags(rproc);
520 #endif
521 if (rproc->secure_reset) {
522 ret = rproc_drm_invoke_service(false);
523 if (ret)
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);
530 if (ret)
531 goto err;
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);
538 #endif
539 omap_dm_timer_free(timers[i].odt);
540 timers[i].odt = NULL;
542 err:
543 return ret;
546 static int omap_rproc_set_lat(struct rproc *rproc, long val)
548 pm_qos_update_request(rproc->qos_request, val);
549 return 0;
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,
567 #endif
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,
576 #endif
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),
601 .driver = {
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");