1 // SPDX-License-Identifier: GPL-2.0-only
3 * OMAP Remote Processor driver
5 * Copyright (C) 2011-2020 Texas Instruments Incorporated - http://www.ti.com/
6 * Copyright (C) 2011 Google, Inc.
8 * Ohad Ben-Cohen <ohad@wizery.com>
9 * Brian Swetland <swetland@google.com>
10 * Fernando Guzman Lugo <fernando.lugo@ti.com>
11 * Mark Grosen <mgrosen@ti.com>
12 * Suman Anna <s-anna@ti.com>
13 * Hari Kanigeri <h-kanigeri2@ti.com>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/clk.h>
19 #include <linux/clk/ti.h>
20 #include <linux/err.h>
23 #include <linux/of_platform.h>
24 #include <linux/of_reserved_mem.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/interrupt.h>
29 #include <linux/remoteproc.h>
30 #include <linux/mailbox_client.h>
31 #include <linux/omap-iommu.h>
32 #include <linux/omap-mailbox.h>
33 #include <linux/regmap.h>
34 #include <linux/mfd/syscon.h>
35 #include <linux/reset.h>
36 #include <clocksource/timer-ti-dm.h>
38 #include <linux/platform_data/dmtimer-omap.h>
40 #include "omap_remoteproc.h"
41 #include "remoteproc_internal.h"
43 /* default auto-suspend delay (ms) */
44 #define DEFAULT_AUTOSUSPEND_DELAY 10000
47 * struct omap_rproc_boot_data - boot data structure for the DSP omap rprocs
48 * @syscon: regmap handle for the system control configuration module
49 * @boot_reg: boot register offset within the @syscon regmap
50 * @boot_reg_shift: bit-field shift required for the boot address value in
53 struct omap_rproc_boot_data
{
54 struct regmap
*syscon
;
55 unsigned int boot_reg
;
56 unsigned int boot_reg_shift
;
60 * struct omap_rproc_mem - internal memory structure
61 * @cpu_addr: MPU virtual address of the memory region
62 * @bus_addr: bus address used to access the memory region
63 * @dev_addr: device address of the memory region from DSP view
64 * @size: size of the memory region
66 struct omap_rproc_mem
{
67 void __iomem
*cpu_addr
;
74 * struct omap_rproc_timer - data structure for a timer used by a omap rproc
76 * @timer_ops: OMAP dmtimer ops for @odt timer
79 struct omap_rproc_timer
{
80 struct omap_dm_timer
*odt
;
81 const struct omap_dm_timer_ops
*timer_ops
;
86 * struct omap_rproc - omap remote processor state
87 * @mbox: mailbox channel handle
88 * @client: mailbox client to request the mailbox channel
89 * @boot_data: boot data structure for setting processor boot address
90 * @mem: internal memory regions data
91 * @num_mems: number of internal memory regions
92 * @num_timers: number of rproc timer(s)
93 * @num_wd_timers: number of rproc watchdog timers
94 * @timers: timer(s) info used by rproc
95 * @autosuspend_delay: auto-suspend delay value to be used for runtime pm
96 * @need_resume: if true a resume is needed in the system resume callback
97 * @rproc: rproc handle
98 * @reset: reset handle
99 * @pm_comp: completion primitive to sync for suspend response
100 * @fck: functional clock for the remoteproc
101 * @suspend_acked: state machine flag to store the suspend request ack
104 struct mbox_chan
*mbox
;
105 struct mbox_client client
;
106 struct omap_rproc_boot_data
*boot_data
;
107 struct omap_rproc_mem
*mem
;
111 struct omap_rproc_timer
*timers
;
112 int autosuspend_delay
;
115 struct reset_control
*reset
;
116 struct completion pm_comp
;
122 * struct omap_rproc_mem_data - memory definitions for an omap remote processor
123 * @name: name for this memory entry
124 * @dev_addr: device address for the memory entry
126 struct omap_rproc_mem_data
{
132 * struct omap_rproc_dev_data - device data for the omap remote processor
133 * @device_name: device name of the remote processor
134 * @mems: memory definitions for this remote processor
136 struct omap_rproc_dev_data
{
137 const char *device_name
;
138 const struct omap_rproc_mem_data
*mems
;
142 * omap_rproc_request_timer() - request a timer for a remoteproc
143 * @dev: device requesting the timer
144 * @np: device node pointer to the desired timer
145 * @timer: handle to a struct omap_rproc_timer to return the timer handle
147 * This helper function is used primarily to request a timer associated with
148 * a remoteproc. The returned handle is stored in the .odt field of the
149 * @timer structure passed in, and is used to invoke other timer specific
150 * ops (like starting a timer either during device initialization or during
151 * a resume operation, or for stopping/freeing a timer).
153 * Return: 0 on success, otherwise an appropriate failure
155 static int omap_rproc_request_timer(struct device
*dev
, struct device_node
*np
,
156 struct omap_rproc_timer
*timer
)
160 timer
->odt
= timer
->timer_ops
->request_by_node(np
);
162 dev_err(dev
, "request for timer node %p failed\n", np
);
166 ret
= timer
->timer_ops
->set_source(timer
->odt
, OMAP_TIMER_SRC_SYS_CLK
);
168 dev_err(dev
, "error setting OMAP_TIMER_SRC_SYS_CLK as source for timer node %p\n",
170 timer
->timer_ops
->free(timer
->odt
);
174 /* clean counter, remoteproc code will set the value */
175 timer
->timer_ops
->set_load(timer
->odt
, 0);
181 * omap_rproc_start_timer() - start a timer for a remoteproc
182 * @timer: handle to a OMAP rproc timer
184 * This helper function is used to start a timer associated with a remoteproc,
185 * obtained using the request_timer ops. The helper function needs to be
186 * invoked by the driver to start the timer (during device initialization)
187 * or to just resume the timer.
189 * Return: 0 on success, otherwise a failure as returned by DMTimer ops
191 static inline int omap_rproc_start_timer(struct omap_rproc_timer
*timer
)
193 return timer
->timer_ops
->start(timer
->odt
);
197 * omap_rproc_stop_timer() - stop a timer for a remoteproc
198 * @timer: handle to a OMAP rproc timer
200 * This helper function is used to disable a timer associated with a
201 * remoteproc, and needs to be called either during a device shutdown
202 * or suspend operation. The separate helper function allows the driver
203 * to just stop a timer without having to release the timer during a
206 * Return: 0 on success, otherwise a failure as returned by DMTimer ops
208 static inline int omap_rproc_stop_timer(struct omap_rproc_timer
*timer
)
210 return timer
->timer_ops
->stop(timer
->odt
);
214 * omap_rproc_release_timer() - release a timer for a remoteproc
215 * @timer: handle to a OMAP rproc timer
217 * This helper function is used primarily to release a timer associated
218 * with a remoteproc. The dmtimer will be available for other clients to
221 * Return: 0 on success, otherwise a failure as returned by DMTimer ops
223 static inline int omap_rproc_release_timer(struct omap_rproc_timer
*timer
)
225 return timer
->timer_ops
->free(timer
->odt
);
229 * omap_rproc_get_timer_irq() - get the irq for a timer
230 * @timer: handle to a OMAP rproc timer
232 * This function is used to get the irq associated with a watchdog timer. The
233 * function is called by the OMAP remoteproc driver to register a interrupt
234 * handler to handle watchdog events on the remote processor.
236 * Return: irq id on success, otherwise a failure as returned by DMTimer ops
238 static inline int omap_rproc_get_timer_irq(struct omap_rproc_timer
*timer
)
240 return timer
->timer_ops
->get_irq(timer
->odt
);
244 * omap_rproc_ack_timer_irq() - acknowledge a timer irq
245 * @timer: handle to a OMAP rproc timer
247 * This function is used to clear the irq associated with a watchdog timer.
248 * The function is called by the OMAP remoteproc upon a watchdog event on the
249 * remote processor to clear the interrupt status of the watchdog timer.
251 static inline void omap_rproc_ack_timer_irq(struct omap_rproc_timer
*timer
)
253 timer
->timer_ops
->write_status(timer
->odt
, OMAP_TIMER_INT_OVERFLOW
);
257 * omap_rproc_watchdog_isr() - Watchdog ISR handler for remoteproc device
258 * @irq: IRQ number associated with a watchdog timer
259 * @data: IRQ handler data
261 * This ISR routine executes the required necessary low-level code to
262 * acknowledge a watchdog timer interrupt. There can be multiple watchdog
263 * timers associated with a rproc (like IPUs which have 2 watchdog timers,
264 * one per Cortex M3/M4 core), so a lookup has to be performed to identify
265 * the timer to acknowledge its interrupt.
267 * The function also invokes rproc_report_crash to report the watchdog event
268 * to the remoteproc driver core, to trigger a recovery.
270 * Return: IRQ_HANDLED on success, otherwise IRQ_NONE
272 static irqreturn_t
omap_rproc_watchdog_isr(int irq
, void *data
)
274 struct rproc
*rproc
= data
;
275 struct omap_rproc
*oproc
= rproc
->priv
;
276 struct device
*dev
= rproc
->dev
.parent
;
277 struct omap_rproc_timer
*timers
= oproc
->timers
;
278 struct omap_rproc_timer
*wd_timer
= NULL
;
279 int num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
282 for (i
= oproc
->num_timers
; i
< num_timers
; i
++) {
283 if (timers
[i
].irq
> 0 && irq
== timers
[i
].irq
) {
284 wd_timer
= &timers
[i
];
290 dev_err(dev
, "invalid timer\n");
294 omap_rproc_ack_timer_irq(wd_timer
);
296 rproc_report_crash(rproc
, RPROC_WATCHDOG
);
302 * omap_rproc_enable_timers() - enable the timers for a remoteproc
303 * @rproc: handle of a remote processor
304 * @configure: boolean flag used to acquire and configure the timer handle
306 * This function is used primarily to enable the timers associated with
307 * a remoteproc. The configure flag is provided to allow the driver
308 * to either acquire and start a timer (during device initialization) or
309 * to just start a timer (during a resume operation).
311 * Return: 0 on success, otherwise an appropriate failure
313 static int omap_rproc_enable_timers(struct rproc
*rproc
, bool configure
)
317 struct platform_device
*tpdev
;
318 struct dmtimer_platform_data
*tpdata
;
319 const struct omap_dm_timer_ops
*timer_ops
;
320 struct omap_rproc
*oproc
= rproc
->priv
;
321 struct omap_rproc_timer
*timers
= oproc
->timers
;
322 struct device
*dev
= rproc
->dev
.parent
;
323 struct device_node
*np
= NULL
;
324 int num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
332 for (i
= 0; i
< num_timers
; i
++) {
333 if (i
< oproc
->num_timers
)
334 np
= of_parse_phandle(dev
->of_node
, "ti,timers", i
);
336 np
= of_parse_phandle(dev
->of_node
,
337 "ti,watchdog-timers",
338 (i
- oproc
->num_timers
));
341 dev_err(dev
, "device node lookup for timer at index %d failed: %d\n",
342 i
< oproc
->num_timers
? i
:
343 i
- oproc
->num_timers
, ret
);
347 tpdev
= of_find_device_by_node(np
);
350 dev_err(dev
, "could not get timer platform device\n");
354 tpdata
= dev_get_platdata(&tpdev
->dev
);
355 put_device(&tpdev
->dev
);
358 dev_err(dev
, "dmtimer pdata structure NULL\n");
362 timer_ops
= tpdata
->timer_ops
;
363 if (!timer_ops
|| !timer_ops
->request_by_node
||
364 !timer_ops
->set_source
|| !timer_ops
->set_load
||
365 !timer_ops
->free
|| !timer_ops
->start
||
366 !timer_ops
->stop
|| !timer_ops
->get_irq
||
367 !timer_ops
->write_status
) {
369 dev_err(dev
, "device does not have required timer ops\n");
374 timers
[i
].timer_ops
= timer_ops
;
375 ret
= omap_rproc_request_timer(dev
, np
, &timers
[i
]);
377 dev_err(dev
, "request for timer %p failed: %d\n", np
,
383 if (i
>= oproc
->num_timers
) {
384 timers
[i
].irq
= omap_rproc_get_timer_irq(&timers
[i
]);
385 if (timers
[i
].irq
< 0) {
386 dev_err(dev
, "get_irq for timer %p failed: %d\n",
392 ret
= request_irq(timers
[i
].irq
,
393 omap_rproc_watchdog_isr
, IRQF_SHARED
,
396 dev_err(dev
, "error requesting irq for timer %p\n",
398 omap_rproc_release_timer(&timers
[i
]);
399 timers
[i
].odt
= NULL
;
400 timers
[i
].timer_ops
= NULL
;
408 for (i
= 0; i
< num_timers
; i
++) {
409 ret
= omap_rproc_start_timer(&timers
[i
]);
411 dev_err(dev
, "start timer %p failed failed: %d\n", np
,
418 omap_rproc_stop_timer(&timers
[i
]);
430 if (i
>= oproc
->num_timers
)
431 free_irq(timers
[i
].irq
, rproc
);
432 omap_rproc_release_timer(&timers
[i
]);
433 timers
[i
].odt
= NULL
;
434 timers
[i
].timer_ops
= NULL
;
442 * omap_rproc_disable_timers() - disable the timers for a remoteproc
443 * @rproc: handle of a remote processor
444 * @configure: boolean flag used to release the timer handle
446 * This function is used primarily to disable the timers associated with
447 * a remoteproc. The configure flag is provided to allow the driver
448 * to either stop and release a timer (during device shutdown) or to just
449 * stop a timer (during a suspend operation).
451 * Return: 0 on success or no timers
453 static int omap_rproc_disable_timers(struct rproc
*rproc
, bool configure
)
456 struct omap_rproc
*oproc
= rproc
->priv
;
457 struct omap_rproc_timer
*timers
= oproc
->timers
;
458 int num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
463 for (i
= 0; i
< num_timers
; i
++) {
464 omap_rproc_stop_timer(&timers
[i
]);
466 if (i
>= oproc
->num_timers
)
467 free_irq(timers
[i
].irq
, rproc
);
468 omap_rproc_release_timer(&timers
[i
]);
469 timers
[i
].odt
= NULL
;
470 timers
[i
].timer_ops
= NULL
;
479 * omap_rproc_mbox_callback() - inbound mailbox message handler
480 * @client: mailbox client pointer used for requesting the mailbox channel
481 * @data: mailbox payload
483 * This handler is invoked by omap's mailbox driver whenever a mailbox
484 * message is received. Usually, the mailbox payload simply contains
485 * the index of the virtqueue that is kicked by the remote processor,
486 * and we let remoteproc core handle it.
488 * In addition to virtqueue indices, we also have some out-of-band values
489 * that indicates different events. Those values are deliberately very
490 * big so they don't coincide with virtqueue indices.
492 static void omap_rproc_mbox_callback(struct mbox_client
*client
, void *data
)
494 struct omap_rproc
*oproc
= container_of(client
, struct omap_rproc
,
496 struct device
*dev
= oproc
->rproc
->dev
.parent
;
497 const char *name
= oproc
->rproc
->name
;
500 dev_dbg(dev
, "mbox msg: 0x%x\n", msg
);
505 * remoteproc detected an exception, notify the rproc core.
506 * The remoteproc core will handle the recovery.
508 dev_err(dev
, "omap rproc %s crashed\n", name
);
509 rproc_report_crash(oproc
->rproc
, RPROC_FATAL_ERROR
);
511 case RP_MBOX_ECHO_REPLY
:
512 dev_info(dev
, "received echo reply from %s\n", name
);
514 case RP_MBOX_SUSPEND_ACK
:
515 case RP_MBOX_SUSPEND_CANCEL
:
516 oproc
->suspend_acked
= msg
== RP_MBOX_SUSPEND_ACK
;
517 complete(&oproc
->pm_comp
);
520 if (msg
>= RP_MBOX_READY
&& msg
< RP_MBOX_END_MSG
)
522 if (msg
> oproc
->rproc
->max_notifyid
) {
523 dev_dbg(dev
, "dropping unknown message 0x%x", msg
);
526 /* msg contains the index of the triggered vring */
527 if (rproc_vq_interrupt(oproc
->rproc
, msg
) == IRQ_NONE
)
528 dev_dbg(dev
, "no message was found in vqid %d\n", msg
);
532 /* kick a virtqueue */
533 static void omap_rproc_kick(struct rproc
*rproc
, int vqid
)
535 struct omap_rproc
*oproc
= rproc
->priv
;
536 struct device
*dev
= rproc
->dev
.parent
;
539 /* wake up the rproc before kicking it */
540 ret
= pm_runtime_get_sync(dev
);
541 if (WARN_ON(ret
< 0)) {
542 dev_err(dev
, "pm_runtime_get_sync() failed during kick, ret = %d\n",
544 pm_runtime_put_noidle(dev
);
548 /* send the index of the triggered virtqueue in the mailbox payload */
549 ret
= mbox_send_message(oproc
->mbox
, (void *)vqid
);
551 dev_err(dev
, "failed to send mailbox message, status = %d\n",
554 pm_runtime_mark_last_busy(dev
);
555 pm_runtime_put_autosuspend(dev
);
559 * omap_rproc_write_dsp_boot_addr() - set boot address for DSP remote processor
560 * @rproc: handle of a remote processor
562 * Set boot address for a supported DSP remote processor.
564 * Return: 0 on success, or -EINVAL if boot address is not aligned properly
566 static int omap_rproc_write_dsp_boot_addr(struct rproc
*rproc
)
568 struct device
*dev
= rproc
->dev
.parent
;
569 struct omap_rproc
*oproc
= rproc
->priv
;
570 struct omap_rproc_boot_data
*bdata
= oproc
->boot_data
;
571 u32 offset
= bdata
->boot_reg
;
575 if (rproc
->bootaddr
& (SZ_1K
- 1)) {
576 dev_err(dev
, "invalid boot address 0x%llx, must be aligned on a 1KB boundary\n",
581 value
= rproc
->bootaddr
>> bdata
->boot_reg_shift
;
582 mask
= ~(SZ_1K
- 1) >> bdata
->boot_reg_shift
;
584 return regmap_update_bits(bdata
->syscon
, offset
, mask
, value
);
588 * Power up the remote processor.
590 * This function will be invoked only after the firmware for this rproc
591 * was loaded, parsed successfully, and all of its resource requirements
594 static int omap_rproc_start(struct rproc
*rproc
)
596 struct omap_rproc
*oproc
= rproc
->priv
;
597 struct device
*dev
= rproc
->dev
.parent
;
599 struct mbox_client
*client
= &oproc
->client
;
601 if (oproc
->boot_data
) {
602 ret
= omap_rproc_write_dsp_boot_addr(rproc
);
608 client
->tx_done
= NULL
;
609 client
->rx_callback
= omap_rproc_mbox_callback
;
610 client
->tx_block
= false;
611 client
->knows_txdone
= false;
613 oproc
->mbox
= mbox_request_channel(client
, 0);
614 if (IS_ERR(oproc
->mbox
)) {
616 dev_err(dev
, "mbox_request_channel failed: %ld\n",
617 PTR_ERR(oproc
->mbox
));
622 * Ping the remote processor. this is only for sanity-sake;
623 * there is no functional effect whatsoever.
625 * Note that the reply will _not_ arrive immediately: this message
626 * will wait in the mailbox fifo until the remote processor is booted.
628 ret
= mbox_send_message(oproc
->mbox
, (void *)RP_MBOX_ECHO_REQUEST
);
630 dev_err(dev
, "mbox_send_message failed: %d\n", ret
);
634 ret
= omap_rproc_enable_timers(rproc
, true);
636 dev_err(dev
, "omap_rproc_enable_timers failed: %d\n", ret
);
640 ret
= reset_control_deassert(oproc
->reset
);
642 dev_err(dev
, "reset control deassert failed: %d\n", ret
);
647 * remote processor is up, so update the runtime pm status and
648 * enable the auto-suspend. The device usage count is incremented
649 * manually for balancing it for auto-suspend
651 pm_runtime_set_active(dev
);
652 pm_runtime_use_autosuspend(dev
);
653 pm_runtime_get_noresume(dev
);
654 pm_runtime_enable(dev
);
655 pm_runtime_mark_last_busy(dev
);
656 pm_runtime_put_autosuspend(dev
);
661 omap_rproc_disable_timers(rproc
, true);
663 mbox_free_channel(oproc
->mbox
);
667 /* power off the remote processor */
668 static int omap_rproc_stop(struct rproc
*rproc
)
670 struct device
*dev
= rproc
->dev
.parent
;
671 struct omap_rproc
*oproc
= rproc
->priv
;
675 * cancel any possible scheduled runtime suspend by incrementing
676 * the device usage count, and resuming the device. The remoteproc
677 * also needs to be woken up if suspended, to avoid the remoteproc
678 * OS to continue to remember any context that it has saved, and
679 * avoid potential issues in misindentifying a subsequent device
680 * reboot as a power restore boot
682 ret
= pm_runtime_get_sync(dev
);
684 pm_runtime_put_noidle(dev
);
688 ret
= reset_control_assert(oproc
->reset
);
692 ret
= omap_rproc_disable_timers(rproc
, true);
696 mbox_free_channel(oproc
->mbox
);
699 * update the runtime pm states and status now that the remoteproc
702 pm_runtime_disable(dev
);
703 pm_runtime_dont_use_autosuspend(dev
);
704 pm_runtime_put_noidle(dev
);
705 pm_runtime_set_suspended(dev
);
710 reset_control_deassert(oproc
->reset
);
712 /* schedule the next auto-suspend */
713 pm_runtime_mark_last_busy(dev
);
714 pm_runtime_put_autosuspend(dev
);
719 * omap_rproc_da_to_va() - internal memory translation helper
720 * @rproc: remote processor to apply the address translation for
721 * @da: device address to translate
722 * @len: length of the memory buffer
724 * Custom function implementing the rproc .da_to_va ops to provide address
725 * translation (device address to kernel virtual address) for internal RAMs
726 * present in a DSP or IPU device). The translated addresses can be used
727 * either by the remoteproc core for loading, or by any rpmsg bus drivers.
729 * Return: translated virtual address in kernel memory space on success,
730 * or NULL on failure.
732 static void *omap_rproc_da_to_va(struct rproc
*rproc
, u64 da
, size_t len
, bool *is_iomem
)
734 struct omap_rproc
*oproc
= rproc
->priv
;
741 if (!oproc
->num_mems
)
744 for (i
= 0; i
< oproc
->num_mems
; i
++) {
745 if (da
>= oproc
->mem
[i
].dev_addr
&& da
+ len
<=
746 oproc
->mem
[i
].dev_addr
+ oproc
->mem
[i
].size
) {
747 offset
= da
- oproc
->mem
[i
].dev_addr
;
748 /* __force to make sparse happy with type conversion */
749 return (__force
void *)(oproc
->mem
[i
].cpu_addr
+
757 static const struct rproc_ops omap_rproc_ops
= {
758 .start
= omap_rproc_start
,
759 .stop
= omap_rproc_stop
,
760 .kick
= omap_rproc_kick
,
761 .da_to_va
= omap_rproc_da_to_va
,
765 static bool _is_rproc_in_standby(struct omap_rproc
*oproc
)
767 return ti_clk_is_in_standby(oproc
->fck
);
770 /* 1 sec is long enough time to let the remoteproc side suspend the device */
771 #define DEF_SUSPEND_TIMEOUT 1000
772 static int _omap_rproc_suspend(struct rproc
*rproc
, bool auto_suspend
)
774 struct device
*dev
= rproc
->dev
.parent
;
775 struct omap_rproc
*oproc
= rproc
->priv
;
776 unsigned long to
= msecs_to_jiffies(DEF_SUSPEND_TIMEOUT
);
777 unsigned long ta
= jiffies
+ to
;
778 u32 suspend_msg
= auto_suspend
?
779 RP_MBOX_SUSPEND_AUTO
: RP_MBOX_SUSPEND_SYSTEM
;
782 reinit_completion(&oproc
->pm_comp
);
783 oproc
->suspend_acked
= false;
784 ret
= mbox_send_message(oproc
->mbox
, (void *)suspend_msg
);
786 dev_err(dev
, "PM mbox_send_message failed: %d\n", ret
);
790 ret
= wait_for_completion_timeout(&oproc
->pm_comp
, to
);
791 if (!oproc
->suspend_acked
)
795 * The remoteproc side is returning the ACK message before saving the
796 * context, because the context saving is performed within a SYS/BIOS
797 * function, and it cannot have any inter-dependencies against the IPC
798 * layer. Also, as the SYS/BIOS needs to preserve properly the processor
799 * register set, sending this ACK or signalling the completion of the
800 * context save through a shared memory variable can never be the
801 * absolute last thing to be executed on the remoteproc side, and the
802 * MPU cannot use the ACK message as a sync point to put the remoteproc
803 * into reset. The only way to ensure that the remote processor has
804 * completed saving the context is to check that the module has reached
805 * STANDBY state (after saving the context, the SYS/BIOS executes the
806 * appropriate target-specific WFI instruction causing the module to
809 while (!_is_rproc_in_standby(oproc
)) {
810 if (time_after(jiffies
, ta
))
815 ret
= reset_control_assert(oproc
->reset
);
817 dev_err(dev
, "reset assert during suspend failed %d\n", ret
);
821 ret
= omap_rproc_disable_timers(rproc
, false);
823 dev_err(dev
, "disabling timers during suspend failed %d\n",
829 * IOMMUs would have to be disabled specifically for runtime suspend.
830 * They are handled automatically through System PM callbacks for
831 * regular system suspend
834 ret
= omap_iommu_domain_deactivate(rproc
->domain
);
836 dev_err(dev
, "iommu domain deactivate failed %d\n",
845 /* ignore errors on re-enabling code */
846 omap_rproc_enable_timers(rproc
, false);
848 reset_control_deassert(oproc
->reset
);
852 static int _omap_rproc_resume(struct rproc
*rproc
, bool auto_suspend
)
854 struct device
*dev
= rproc
->dev
.parent
;
855 struct omap_rproc
*oproc
= rproc
->priv
;
859 * IOMMUs would have to be enabled specifically for runtime resume.
860 * They would have been already enabled automatically through System
861 * PM callbacks for regular system resume
864 ret
= omap_iommu_domain_activate(rproc
->domain
);
866 dev_err(dev
, "omap_iommu activate failed %d\n", ret
);
871 /* boot address could be lost after suspend, so restore it */
872 if (oproc
->boot_data
) {
873 ret
= omap_rproc_write_dsp_boot_addr(rproc
);
875 dev_err(dev
, "boot address restore failed %d\n", ret
);
880 ret
= omap_rproc_enable_timers(rproc
, false);
882 dev_err(dev
, "enabling timers during resume failed %d\n", ret
);
886 ret
= reset_control_deassert(oproc
->reset
);
888 dev_err(dev
, "reset deassert during resume failed %d\n", ret
);
895 omap_rproc_disable_timers(rproc
, false);
898 omap_iommu_domain_deactivate(rproc
->domain
);
903 static int __maybe_unused
omap_rproc_suspend(struct device
*dev
)
905 struct rproc
*rproc
= dev_get_drvdata(dev
);
906 struct omap_rproc
*oproc
= rproc
->priv
;
909 mutex_lock(&rproc
->lock
);
910 if (rproc
->state
== RPROC_OFFLINE
)
913 if (rproc
->state
== RPROC_SUSPENDED
)
916 if (rproc
->state
!= RPROC_RUNNING
) {
921 ret
= _omap_rproc_suspend(rproc
, false);
923 dev_err(dev
, "suspend failed %d\n", ret
);
928 * remoteproc is running at the time of system suspend, so remember
929 * it so as to wake it up during system resume
931 oproc
->need_resume
= true;
932 rproc
->state
= RPROC_SUSPENDED
;
935 mutex_unlock(&rproc
->lock
);
939 static int __maybe_unused
omap_rproc_resume(struct device
*dev
)
941 struct rproc
*rproc
= dev_get_drvdata(dev
);
942 struct omap_rproc
*oproc
= rproc
->priv
;
945 mutex_lock(&rproc
->lock
);
946 if (rproc
->state
== RPROC_OFFLINE
)
949 if (rproc
->state
!= RPROC_SUSPENDED
) {
955 * remoteproc was auto-suspended at the time of system suspend,
956 * so no need to wake-up the processor (leave it in suspended
957 * state, will be woken up during a subsequent runtime_resume)
959 if (!oproc
->need_resume
)
962 ret
= _omap_rproc_resume(rproc
, false);
964 dev_err(dev
, "resume failed %d\n", ret
);
968 oproc
->need_resume
= false;
969 rproc
->state
= RPROC_RUNNING
;
971 pm_runtime_mark_last_busy(dev
);
973 mutex_unlock(&rproc
->lock
);
977 static int omap_rproc_runtime_suspend(struct device
*dev
)
979 struct rproc
*rproc
= dev_get_drvdata(dev
);
980 struct omap_rproc
*oproc
= rproc
->priv
;
983 mutex_lock(&rproc
->lock
);
984 if (rproc
->state
== RPROC_CRASHED
) {
985 dev_dbg(dev
, "rproc cannot be runtime suspended when crashed!\n");
990 if (WARN_ON(rproc
->state
!= RPROC_RUNNING
)) {
991 dev_err(dev
, "rproc cannot be runtime suspended when not running!\n");
997 * do not even attempt suspend if the remote processor is not
998 * idled for runtime auto-suspend
1000 if (!_is_rproc_in_standby(oproc
)) {
1005 ret
= _omap_rproc_suspend(rproc
, true);
1009 rproc
->state
= RPROC_SUSPENDED
;
1010 mutex_unlock(&rproc
->lock
);
1014 pm_runtime_mark_last_busy(dev
);
1016 mutex_unlock(&rproc
->lock
);
1020 static int omap_rproc_runtime_resume(struct device
*dev
)
1022 struct rproc
*rproc
= dev_get_drvdata(dev
);
1025 mutex_lock(&rproc
->lock
);
1026 if (WARN_ON(rproc
->state
!= RPROC_SUSPENDED
)) {
1027 dev_err(dev
, "rproc cannot be runtime resumed if not suspended! state=%d\n",
1033 ret
= _omap_rproc_resume(rproc
, true);
1035 dev_err(dev
, "runtime resume failed %d\n", ret
);
1039 rproc
->state
= RPROC_RUNNING
;
1041 mutex_unlock(&rproc
->lock
);
1044 #endif /* CONFIG_PM */
1046 static const struct omap_rproc_mem_data ipu_mems
[] = {
1047 { .name
= "l2ram", .dev_addr
= 0x20000000 },
1051 static const struct omap_rproc_mem_data dra7_dsp_mems
[] = {
1052 { .name
= "l2ram", .dev_addr
= 0x800000 },
1053 { .name
= "l1pram", .dev_addr
= 0xe00000 },
1054 { .name
= "l1dram", .dev_addr
= 0xf00000 },
1058 static const struct omap_rproc_dev_data omap4_dsp_dev_data
= {
1059 .device_name
= "dsp",
1062 static const struct omap_rproc_dev_data omap4_ipu_dev_data
= {
1063 .device_name
= "ipu",
1067 static const struct omap_rproc_dev_data omap5_dsp_dev_data
= {
1068 .device_name
= "dsp",
1071 static const struct omap_rproc_dev_data omap5_ipu_dev_data
= {
1072 .device_name
= "ipu",
1076 static const struct omap_rproc_dev_data dra7_dsp_dev_data
= {
1077 .device_name
= "dsp",
1078 .mems
= dra7_dsp_mems
,
1081 static const struct omap_rproc_dev_data dra7_ipu_dev_data
= {
1082 .device_name
= "ipu",
1086 static const struct of_device_id omap_rproc_of_match
[] = {
1088 .compatible
= "ti,omap4-dsp",
1089 .data
= &omap4_dsp_dev_data
,
1092 .compatible
= "ti,omap4-ipu",
1093 .data
= &omap4_ipu_dev_data
,
1096 .compatible
= "ti,omap5-dsp",
1097 .data
= &omap5_dsp_dev_data
,
1100 .compatible
= "ti,omap5-ipu",
1101 .data
= &omap5_ipu_dev_data
,
1104 .compatible
= "ti,dra7-dsp",
1105 .data
= &dra7_dsp_dev_data
,
1108 .compatible
= "ti,dra7-ipu",
1109 .data
= &dra7_ipu_dev_data
,
1115 MODULE_DEVICE_TABLE(of
, omap_rproc_of_match
);
1117 static const char *omap_rproc_get_firmware(struct platform_device
*pdev
)
1119 const char *fw_name
;
1122 ret
= of_property_read_string(pdev
->dev
.of_node
, "firmware-name",
1125 return ERR_PTR(ret
);
1130 static int omap_rproc_get_boot_data(struct platform_device
*pdev
,
1131 struct rproc
*rproc
)
1133 struct device_node
*np
= pdev
->dev
.of_node
;
1134 struct omap_rproc
*oproc
= rproc
->priv
;
1135 const struct omap_rproc_dev_data
*data
;
1138 data
= of_device_get_match_data(&pdev
->dev
);
1142 if (!of_property_read_bool(np
, "ti,bootreg"))
1145 oproc
->boot_data
= devm_kzalloc(&pdev
->dev
, sizeof(*oproc
->boot_data
),
1147 if (!oproc
->boot_data
)
1150 oproc
->boot_data
->syscon
=
1151 syscon_regmap_lookup_by_phandle(np
, "ti,bootreg");
1152 if (IS_ERR(oproc
->boot_data
->syscon
)) {
1153 ret
= PTR_ERR(oproc
->boot_data
->syscon
);
1157 if (of_property_read_u32_index(np
, "ti,bootreg", 1,
1158 &oproc
->boot_data
->boot_reg
)) {
1159 dev_err(&pdev
->dev
, "couldn't get the boot register\n");
1163 of_property_read_u32_index(np
, "ti,bootreg", 2,
1164 &oproc
->boot_data
->boot_reg_shift
);
1169 static int omap_rproc_of_get_internal_memories(struct platform_device
*pdev
,
1170 struct rproc
*rproc
)
1172 struct omap_rproc
*oproc
= rproc
->priv
;
1173 struct device
*dev
= &pdev
->dev
;
1174 const struct omap_rproc_dev_data
*data
;
1175 struct resource
*res
;
1179 data
= of_device_get_match_data(dev
);
1186 num_mems
= of_property_count_elems_of_size(dev
->of_node
, "reg",
1189 oproc
->mem
= devm_kcalloc(dev
, num_mems
, sizeof(*oproc
->mem
),
1194 for (i
= 0; data
->mems
[i
].name
; i
++) {
1195 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1196 data
->mems
[i
].name
);
1198 dev_err(dev
, "no memory defined for %s\n",
1199 data
->mems
[i
].name
);
1202 oproc
->mem
[i
].cpu_addr
= devm_ioremap_resource(dev
, res
);
1203 if (IS_ERR(oproc
->mem
[i
].cpu_addr
)) {
1204 dev_err(dev
, "failed to parse and map %s memory\n",
1205 data
->mems
[i
].name
);
1206 return PTR_ERR(oproc
->mem
[i
].cpu_addr
);
1208 oproc
->mem
[i
].bus_addr
= res
->start
;
1209 oproc
->mem
[i
].dev_addr
= data
->mems
[i
].dev_addr
;
1210 oproc
->mem
[i
].size
= resource_size(res
);
1212 dev_dbg(dev
, "memory %8s: bus addr %pa size 0x%x va %pK da 0x%x\n",
1213 data
->mems
[i
].name
, &oproc
->mem
[i
].bus_addr
,
1214 oproc
->mem
[i
].size
, oproc
->mem
[i
].cpu_addr
,
1215 oproc
->mem
[i
].dev_addr
);
1217 oproc
->num_mems
= num_mems
;
1222 #ifdef CONFIG_OMAP_REMOTEPROC_WATCHDOG
1223 static int omap_rproc_count_wdog_timers(struct device
*dev
)
1225 struct device_node
*np
= dev
->of_node
;
1228 ret
= of_count_phandle_with_args(np
, "ti,watchdog-timers", NULL
);
1230 dev_dbg(dev
, "device does not have watchdog timers, status = %d\n",
1238 static int omap_rproc_count_wdog_timers(struct device
*dev
)
1244 static int omap_rproc_of_get_timers(struct platform_device
*pdev
,
1245 struct rproc
*rproc
)
1247 struct device_node
*np
= pdev
->dev
.of_node
;
1248 struct omap_rproc
*oproc
= rproc
->priv
;
1249 struct device
*dev
= &pdev
->dev
;
1253 * Timer nodes are directly used in client nodes as phandles, so
1254 * retrieve the count using appropriate size
1256 oproc
->num_timers
= of_count_phandle_with_args(np
, "ti,timers", NULL
);
1257 if (oproc
->num_timers
<= 0) {
1258 dev_dbg(dev
, "device does not have timers, status = %d\n",
1260 oproc
->num_timers
= 0;
1263 oproc
->num_wd_timers
= omap_rproc_count_wdog_timers(dev
);
1265 num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
1267 oproc
->timers
= devm_kcalloc(dev
, num_timers
,
1268 sizeof(*oproc
->timers
),
1273 dev_dbg(dev
, "device has %d tick timers and %d watchdog timers\n",
1274 oproc
->num_timers
, oproc
->num_wd_timers
);
1280 static void omap_rproc_mem_release(void *data
)
1282 struct device
*dev
= data
;
1284 of_reserved_mem_device_release(dev
);
1287 static int omap_rproc_probe(struct platform_device
*pdev
)
1289 struct device_node
*np
= pdev
->dev
.of_node
;
1290 struct omap_rproc
*oproc
;
1291 struct rproc
*rproc
;
1292 const char *firmware
;
1294 struct reset_control
*reset
;
1297 dev_err(&pdev
->dev
, "only DT-based devices are supported\n");
1301 reset
= devm_reset_control_array_get_exclusive(&pdev
->dev
);
1303 return PTR_ERR(reset
);
1305 firmware
= omap_rproc_get_firmware(pdev
);
1306 if (IS_ERR(firmware
))
1307 return PTR_ERR(firmware
);
1309 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
1311 dev_err(&pdev
->dev
, "dma_set_coherent_mask: %d\n", ret
);
1315 rproc
= devm_rproc_alloc(&pdev
->dev
, dev_name(&pdev
->dev
), &omap_rproc_ops
,
1316 firmware
, sizeof(*oproc
));
1320 oproc
= rproc
->priv
;
1321 oproc
->rproc
= rproc
;
1322 oproc
->reset
= reset
;
1323 /* All existing OMAP IPU and DSP processors have an MMU */
1324 rproc
->has_iommu
= true;
1326 ret
= omap_rproc_of_get_internal_memories(pdev
, rproc
);
1330 ret
= omap_rproc_get_boot_data(pdev
, rproc
);
1334 ret
= omap_rproc_of_get_timers(pdev
, rproc
);
1338 init_completion(&oproc
->pm_comp
);
1339 oproc
->autosuspend_delay
= DEFAULT_AUTOSUSPEND_DELAY
;
1341 of_property_read_u32(pdev
->dev
.of_node
, "ti,autosuspend-delay-ms",
1342 &oproc
->autosuspend_delay
);
1344 pm_runtime_set_autosuspend_delay(&pdev
->dev
, oproc
->autosuspend_delay
);
1346 oproc
->fck
= devm_clk_get(&pdev
->dev
, 0);
1347 if (IS_ERR(oproc
->fck
))
1348 return PTR_ERR(oproc
->fck
);
1350 ret
= of_reserved_mem_device_init(&pdev
->dev
);
1352 dev_warn(&pdev
->dev
, "device does not have specific CMA pool.\n");
1353 dev_warn(&pdev
->dev
, "Typically this should be provided,\n");
1354 dev_warn(&pdev
->dev
, "only omit if you know what you are doing.\n");
1356 ret
= devm_add_action_or_reset(&pdev
->dev
, omap_rproc_mem_release
, &pdev
->dev
);
1360 platform_set_drvdata(pdev
, rproc
);
1362 ret
= devm_rproc_add(&pdev
->dev
, rproc
);
1369 static const struct dev_pm_ops omap_rproc_pm_ops
= {
1370 SET_SYSTEM_SLEEP_PM_OPS(omap_rproc_suspend
, omap_rproc_resume
)
1371 SET_RUNTIME_PM_OPS(omap_rproc_runtime_suspend
,
1372 omap_rproc_runtime_resume
, NULL
)
1375 static struct platform_driver omap_rproc_driver
= {
1376 .probe
= omap_rproc_probe
,
1378 .name
= "omap-rproc",
1379 .pm
= &omap_rproc_pm_ops
,
1380 .of_match_table
= omap_rproc_of_match
,
1384 module_platform_driver(omap_rproc_driver
);
1386 MODULE_LICENSE("GPL v2");
1387 MODULE_DESCRIPTION("OMAP Remote Processor control driver");