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>
22 #include <linux/of_device.h>
23 #include <linux/of_reserved_mem.h>
24 #include <linux/platform_device.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/interrupt.h>
28 #include <linux/remoteproc.h>
29 #include <linux/mailbox_client.h>
30 #include <linux/omap-iommu.h>
31 #include <linux/omap-mailbox.h>
32 #include <linux/regmap.h>
33 #include <linux/mfd/syscon.h>
34 #include <linux/reset.h>
35 #include <clocksource/timer-ti-dm.h>
37 #include <linux/platform_data/dmtimer-omap.h>
39 #include "omap_remoteproc.h"
40 #include "remoteproc_internal.h"
42 /* default auto-suspend delay (ms) */
43 #define DEFAULT_AUTOSUSPEND_DELAY 10000
46 * struct omap_rproc_boot_data - boot data structure for the DSP omap rprocs
47 * @syscon: regmap handle for the system control configuration module
48 * @boot_reg: boot register offset within the @syscon regmap
49 * @boot_reg_shift: bit-field shift required for the boot address value in
52 struct omap_rproc_boot_data
{
53 struct regmap
*syscon
;
54 unsigned int boot_reg
;
55 unsigned int boot_reg_shift
;
59 * struct omap_rproc_mem - internal memory structure
60 * @cpu_addr: MPU virtual address of the memory region
61 * @bus_addr: bus address used to access the memory region
62 * @dev_addr: device address of the memory region from DSP view
63 * @size: size of the memory region
65 struct omap_rproc_mem
{
66 void __iomem
*cpu_addr
;
73 * struct omap_rproc_timer - data structure for a timer used by a omap rproc
75 * @timer_ops: OMAP dmtimer ops for @odt timer
78 struct omap_rproc_timer
{
79 struct omap_dm_timer
*odt
;
80 const struct omap_dm_timer_ops
*timer_ops
;
85 * struct omap_rproc - omap remote processor state
86 * @mbox: mailbox channel handle
87 * @client: mailbox client to request the mailbox channel
88 * @boot_data: boot data structure for setting processor boot address
89 * @mem: internal memory regions data
90 * @num_mems: number of internal memory regions
91 * @num_timers: number of rproc timer(s)
92 * @num_wd_timers: number of rproc watchdog timers
93 * @timers: timer(s) info used by rproc
94 * @autosuspend_delay: auto-suspend delay value to be used for runtime pm
95 * @need_resume: if true a resume is needed in the system resume callback
96 * @rproc: rproc handle
97 * @reset: reset handle
98 * @pm_comp: completion primitive to sync for suspend response
99 * @fck: functional clock for the remoteproc
100 * @suspend_acked: state machine flag to store the suspend request ack
103 struct mbox_chan
*mbox
;
104 struct mbox_client client
;
105 struct omap_rproc_boot_data
*boot_data
;
106 struct omap_rproc_mem
*mem
;
110 struct omap_rproc_timer
*timers
;
111 int autosuspend_delay
;
114 struct reset_control
*reset
;
115 struct completion pm_comp
;
121 * struct omap_rproc_mem_data - memory definitions for an omap remote processor
122 * @name: name for this memory entry
123 * @dev_addr: device address for the memory entry
125 struct omap_rproc_mem_data
{
131 * struct omap_rproc_dev_data - device data for the omap remote processor
132 * @device_name: device name of the remote processor
133 * @mems: memory definitions for this remote processor
135 struct omap_rproc_dev_data
{
136 const char *device_name
;
137 const struct omap_rproc_mem_data
*mems
;
141 * omap_rproc_request_timer() - request a timer for a remoteproc
142 * @dev: device requesting the timer
143 * @np: device node pointer to the desired timer
144 * @timer: handle to a struct omap_rproc_timer to return the timer handle
146 * This helper function is used primarily to request a timer associated with
147 * a remoteproc. The returned handle is stored in the .odt field of the
148 * @timer structure passed in, and is used to invoke other timer specific
149 * ops (like starting a timer either during device initialization or during
150 * a resume operation, or for stopping/freeing a timer).
152 * Return: 0 on success, otherwise an appropriate failure
154 static int omap_rproc_request_timer(struct device
*dev
, struct device_node
*np
,
155 struct omap_rproc_timer
*timer
)
159 timer
->odt
= timer
->timer_ops
->request_by_node(np
);
161 dev_err(dev
, "request for timer node %p failed\n", np
);
165 ret
= timer
->timer_ops
->set_source(timer
->odt
, OMAP_TIMER_SRC_SYS_CLK
);
167 dev_err(dev
, "error setting OMAP_TIMER_SRC_SYS_CLK as source for timer node %p\n",
169 timer
->timer_ops
->free(timer
->odt
);
173 /* clean counter, remoteproc code will set the value */
174 timer
->timer_ops
->set_load(timer
->odt
, 0);
180 * omap_rproc_start_timer() - start a timer for a remoteproc
181 * @timer: handle to a OMAP rproc timer
183 * This helper function is used to start a timer associated with a remoteproc,
184 * obtained using the request_timer ops. The helper function needs to be
185 * invoked by the driver to start the timer (during device initialization)
186 * or to just resume the timer.
188 * Return: 0 on success, otherwise a failure as returned by DMTimer ops
190 static inline int omap_rproc_start_timer(struct omap_rproc_timer
*timer
)
192 return timer
->timer_ops
->start(timer
->odt
);
196 * omap_rproc_stop_timer() - stop a timer for a remoteproc
197 * @timer: handle to a OMAP rproc timer
199 * This helper function is used to disable a timer associated with a
200 * remoteproc, and needs to be called either during a device shutdown
201 * or suspend operation. The separate helper function allows the driver
202 * to just stop a timer without having to release the timer during a
205 * Return: 0 on success, otherwise a failure as returned by DMTimer ops
207 static inline int omap_rproc_stop_timer(struct omap_rproc_timer
*timer
)
209 return timer
->timer_ops
->stop(timer
->odt
);
213 * omap_rproc_release_timer() - release a timer for a remoteproc
214 * @timer: handle to a OMAP rproc timer
216 * This helper function is used primarily to release a timer associated
217 * with a remoteproc. The dmtimer will be available for other clients to
220 * Return: 0 on success, otherwise a failure as returned by DMTimer ops
222 static inline int omap_rproc_release_timer(struct omap_rproc_timer
*timer
)
224 return timer
->timer_ops
->free(timer
->odt
);
228 * omap_rproc_get_timer_irq() - get the irq for a timer
229 * @timer: handle to a OMAP rproc timer
231 * This function is used to get the irq associated with a watchdog timer. The
232 * function is called by the OMAP remoteproc driver to register a interrupt
233 * handler to handle watchdog events on the remote processor.
235 * Return: irq id on success, otherwise a failure as returned by DMTimer ops
237 static inline int omap_rproc_get_timer_irq(struct omap_rproc_timer
*timer
)
239 return timer
->timer_ops
->get_irq(timer
->odt
);
243 * omap_rproc_ack_timer_irq() - acknowledge a timer irq
244 * @timer: handle to a OMAP rproc timer
246 * This function is used to clear the irq associated with a watchdog timer. The
247 * The function is called by the OMAP remoteproc upon a watchdog event on the
248 * remote processor to clear the interrupt status of the watchdog timer.
250 static inline void omap_rproc_ack_timer_irq(struct omap_rproc_timer
*timer
)
252 timer
->timer_ops
->write_status(timer
->odt
, OMAP_TIMER_INT_OVERFLOW
);
256 * omap_rproc_watchdog_isr() - Watchdog ISR handler for remoteproc device
257 * @irq: IRQ number associated with a watchdog timer
258 * @data: IRQ handler data
260 * This ISR routine executes the required necessary low-level code to
261 * acknowledge a watchdog timer interrupt. There can be multiple watchdog
262 * timers associated with a rproc (like IPUs which have 2 watchdog timers,
263 * one per Cortex M3/M4 core), so a lookup has to be performed to identify
264 * the timer to acknowledge its interrupt.
266 * The function also invokes rproc_report_crash to report the watchdog event
267 * to the remoteproc driver core, to trigger a recovery.
269 * Return: IRQ_HANDLED on success, otherwise IRQ_NONE
271 static irqreturn_t
omap_rproc_watchdog_isr(int irq
, void *data
)
273 struct rproc
*rproc
= data
;
274 struct omap_rproc
*oproc
= rproc
->priv
;
275 struct device
*dev
= rproc
->dev
.parent
;
276 struct omap_rproc_timer
*timers
= oproc
->timers
;
277 struct omap_rproc_timer
*wd_timer
= NULL
;
278 int num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
281 for (i
= oproc
->num_timers
; i
< num_timers
; i
++) {
282 if (timers
[i
].irq
> 0 && irq
== timers
[i
].irq
) {
283 wd_timer
= &timers
[i
];
289 dev_err(dev
, "invalid timer\n");
293 omap_rproc_ack_timer_irq(wd_timer
);
295 rproc_report_crash(rproc
, RPROC_WATCHDOG
);
301 * omap_rproc_enable_timers() - enable the timers for a remoteproc
302 * @rproc: handle of a remote processor
303 * @configure: boolean flag used to acquire and configure the timer handle
305 * This function is used primarily to enable the timers associated with
306 * a remoteproc. The configure flag is provided to allow the driver to
307 * to either acquire and start a timer (during device initialization) or
308 * to just start a timer (during a resume operation).
310 * Return: 0 on success, otherwise an appropriate failure
312 static int omap_rproc_enable_timers(struct rproc
*rproc
, bool configure
)
316 struct platform_device
*tpdev
;
317 struct dmtimer_platform_data
*tpdata
;
318 const struct omap_dm_timer_ops
*timer_ops
;
319 struct omap_rproc
*oproc
= rproc
->priv
;
320 struct omap_rproc_timer
*timers
= oproc
->timers
;
321 struct device
*dev
= rproc
->dev
.parent
;
322 struct device_node
*np
= NULL
;
323 int num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
331 for (i
= 0; i
< num_timers
; i
++) {
332 if (i
< oproc
->num_timers
)
333 np
= of_parse_phandle(dev
->of_node
, "ti,timers", i
);
335 np
= of_parse_phandle(dev
->of_node
,
336 "ti,watchdog-timers",
337 (i
- oproc
->num_timers
));
340 dev_err(dev
, "device node lookup for timer at index %d failed: %d\n",
341 i
< oproc
->num_timers
? i
:
342 i
- oproc
->num_timers
, ret
);
346 tpdev
= of_find_device_by_node(np
);
349 dev_err(dev
, "could not get timer platform device\n");
353 tpdata
= dev_get_platdata(&tpdev
->dev
);
354 put_device(&tpdev
->dev
);
357 dev_err(dev
, "dmtimer pdata structure NULL\n");
361 timer_ops
= tpdata
->timer_ops
;
362 if (!timer_ops
|| !timer_ops
->request_by_node
||
363 !timer_ops
->set_source
|| !timer_ops
->set_load
||
364 !timer_ops
->free
|| !timer_ops
->start
||
365 !timer_ops
->stop
|| !timer_ops
->get_irq
||
366 !timer_ops
->write_status
) {
368 dev_err(dev
, "device does not have required timer ops\n");
373 timers
[i
].timer_ops
= timer_ops
;
374 ret
= omap_rproc_request_timer(dev
, np
, &timers
[i
]);
376 dev_err(dev
, "request for timer %p failed: %d\n", np
,
382 if (i
>= oproc
->num_timers
) {
383 timers
[i
].irq
= omap_rproc_get_timer_irq(&timers
[i
]);
384 if (timers
[i
].irq
< 0) {
385 dev_err(dev
, "get_irq for timer %p failed: %d\n",
391 ret
= request_irq(timers
[i
].irq
,
392 omap_rproc_watchdog_isr
, IRQF_SHARED
,
395 dev_err(dev
, "error requesting irq for timer %p\n",
397 omap_rproc_release_timer(&timers
[i
]);
398 timers
[i
].odt
= NULL
;
399 timers
[i
].timer_ops
= NULL
;
407 for (i
= 0; i
< num_timers
; i
++) {
408 ret
= omap_rproc_start_timer(&timers
[i
]);
410 dev_err(dev
, "start timer %p failed failed: %d\n", np
,
417 omap_rproc_stop_timer(&timers
[i
]);
429 if (i
>= oproc
->num_timers
)
430 free_irq(timers
[i
].irq
, rproc
);
431 omap_rproc_release_timer(&timers
[i
]);
432 timers
[i
].odt
= NULL
;
433 timers
[i
].timer_ops
= NULL
;
441 * omap_rproc_disable_timers() - disable the timers for a remoteproc
442 * @rproc: handle of a remote processor
443 * @configure: boolean flag used to release the timer handle
445 * This function is used primarily to disable the timers associated with
446 * a remoteproc. The configure flag is provided to allow the driver to
447 * to either stop and release a timer (during device shutdown) or to just
448 * stop a timer (during a suspend operation).
450 * Return: 0 on success or no timers
452 static int omap_rproc_disable_timers(struct rproc
*rproc
, bool configure
)
455 struct omap_rproc
*oproc
= rproc
->priv
;
456 struct omap_rproc_timer
*timers
= oproc
->timers
;
457 int num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
462 for (i
= 0; i
< num_timers
; i
++) {
463 omap_rproc_stop_timer(&timers
[i
]);
465 if (i
>= oproc
->num_timers
)
466 free_irq(timers
[i
].irq
, rproc
);
467 omap_rproc_release_timer(&timers
[i
]);
468 timers
[i
].odt
= NULL
;
469 timers
[i
].timer_ops
= NULL
;
478 * omap_rproc_mbox_callback() - inbound mailbox message handler
479 * @client: mailbox client pointer used for requesting the mailbox channel
480 * @data: mailbox payload
482 * This handler is invoked by omap's mailbox driver whenever a mailbox
483 * message is received. Usually, the mailbox payload simply contains
484 * the index of the virtqueue that is kicked by the remote processor,
485 * and we let remoteproc core handle it.
487 * In addition to virtqueue indices, we also have some out-of-band values
488 * that indicates different events. Those values are deliberately very
489 * big so they don't coincide with virtqueue indices.
491 static void omap_rproc_mbox_callback(struct mbox_client
*client
, void *data
)
493 struct omap_rproc
*oproc
= container_of(client
, struct omap_rproc
,
495 struct device
*dev
= oproc
->rproc
->dev
.parent
;
496 const char *name
= oproc
->rproc
->name
;
499 dev_dbg(dev
, "mbox msg: 0x%x\n", msg
);
504 * remoteproc detected an exception, notify the rproc core.
505 * The remoteproc core will handle the recovery.
507 dev_err(dev
, "omap rproc %s crashed\n", name
);
508 rproc_report_crash(oproc
->rproc
, RPROC_FATAL_ERROR
);
510 case RP_MBOX_ECHO_REPLY
:
511 dev_info(dev
, "received echo reply from %s\n", name
);
513 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
)
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 platform_device
*pdev
= to_platform_device(dev
);
906 struct rproc
*rproc
= platform_get_drvdata(pdev
);
907 struct omap_rproc
*oproc
= rproc
->priv
;
910 mutex_lock(&rproc
->lock
);
911 if (rproc
->state
== RPROC_OFFLINE
)
914 if (rproc
->state
== RPROC_SUSPENDED
)
917 if (rproc
->state
!= RPROC_RUNNING
) {
922 ret
= _omap_rproc_suspend(rproc
, false);
924 dev_err(dev
, "suspend failed %d\n", ret
);
929 * remoteproc is running at the time of system suspend, so remember
930 * it so as to wake it up during system resume
932 oproc
->need_resume
= true;
933 rproc
->state
= RPROC_SUSPENDED
;
936 mutex_unlock(&rproc
->lock
);
940 static int __maybe_unused
omap_rproc_resume(struct device
*dev
)
942 struct platform_device
*pdev
= to_platform_device(dev
);
943 struct rproc
*rproc
= platform_get_drvdata(pdev
);
944 struct omap_rproc
*oproc
= rproc
->priv
;
947 mutex_lock(&rproc
->lock
);
948 if (rproc
->state
== RPROC_OFFLINE
)
951 if (rproc
->state
!= RPROC_SUSPENDED
) {
957 * remoteproc was auto-suspended at the time of system suspend,
958 * so no need to wake-up the processor (leave it in suspended
959 * state, will be woken up during a subsequent runtime_resume)
961 if (!oproc
->need_resume
)
964 ret
= _omap_rproc_resume(rproc
, false);
966 dev_err(dev
, "resume failed %d\n", ret
);
970 oproc
->need_resume
= false;
971 rproc
->state
= RPROC_RUNNING
;
973 pm_runtime_mark_last_busy(dev
);
975 mutex_unlock(&rproc
->lock
);
979 static int omap_rproc_runtime_suspend(struct device
*dev
)
981 struct rproc
*rproc
= dev_get_drvdata(dev
);
982 struct omap_rproc
*oproc
= rproc
->priv
;
985 mutex_lock(&rproc
->lock
);
986 if (rproc
->state
== RPROC_CRASHED
) {
987 dev_dbg(dev
, "rproc cannot be runtime suspended when crashed!\n");
992 if (WARN_ON(rproc
->state
!= RPROC_RUNNING
)) {
993 dev_err(dev
, "rproc cannot be runtime suspended when not running!\n");
999 * do not even attempt suspend if the remote processor is not
1000 * idled for runtime auto-suspend
1002 if (!_is_rproc_in_standby(oproc
)) {
1007 ret
= _omap_rproc_suspend(rproc
, true);
1011 rproc
->state
= RPROC_SUSPENDED
;
1012 mutex_unlock(&rproc
->lock
);
1016 pm_runtime_mark_last_busy(dev
);
1018 mutex_unlock(&rproc
->lock
);
1022 static int omap_rproc_runtime_resume(struct device
*dev
)
1024 struct rproc
*rproc
= dev_get_drvdata(dev
);
1027 mutex_lock(&rproc
->lock
);
1028 if (WARN_ON(rproc
->state
!= RPROC_SUSPENDED
)) {
1029 dev_err(dev
, "rproc cannot be runtime resumed if not suspended! state=%d\n",
1035 ret
= _omap_rproc_resume(rproc
, true);
1037 dev_err(dev
, "runtime resume failed %d\n", ret
);
1041 rproc
->state
= RPROC_RUNNING
;
1043 mutex_unlock(&rproc
->lock
);
1046 #endif /* CONFIG_PM */
1048 static const struct omap_rproc_mem_data ipu_mems
[] = {
1049 { .name
= "l2ram", .dev_addr
= 0x20000000 },
1053 static const struct omap_rproc_mem_data dra7_dsp_mems
[] = {
1054 { .name
= "l2ram", .dev_addr
= 0x800000 },
1055 { .name
= "l1pram", .dev_addr
= 0xe00000 },
1056 { .name
= "l1dram", .dev_addr
= 0xf00000 },
1060 static const struct omap_rproc_dev_data omap4_dsp_dev_data
= {
1061 .device_name
= "dsp",
1064 static const struct omap_rproc_dev_data omap4_ipu_dev_data
= {
1065 .device_name
= "ipu",
1069 static const struct omap_rproc_dev_data omap5_dsp_dev_data
= {
1070 .device_name
= "dsp",
1073 static const struct omap_rproc_dev_data omap5_ipu_dev_data
= {
1074 .device_name
= "ipu",
1078 static const struct omap_rproc_dev_data dra7_dsp_dev_data
= {
1079 .device_name
= "dsp",
1080 .mems
= dra7_dsp_mems
,
1083 static const struct omap_rproc_dev_data dra7_ipu_dev_data
= {
1084 .device_name
= "ipu",
1088 static const struct of_device_id omap_rproc_of_match
[] = {
1090 .compatible
= "ti,omap4-dsp",
1091 .data
= &omap4_dsp_dev_data
,
1094 .compatible
= "ti,omap4-ipu",
1095 .data
= &omap4_ipu_dev_data
,
1098 .compatible
= "ti,omap5-dsp",
1099 .data
= &omap5_dsp_dev_data
,
1102 .compatible
= "ti,omap5-ipu",
1103 .data
= &omap5_ipu_dev_data
,
1106 .compatible
= "ti,dra7-dsp",
1107 .data
= &dra7_dsp_dev_data
,
1110 .compatible
= "ti,dra7-ipu",
1111 .data
= &dra7_ipu_dev_data
,
1117 MODULE_DEVICE_TABLE(of
, omap_rproc_of_match
);
1119 static const char *omap_rproc_get_firmware(struct platform_device
*pdev
)
1121 const char *fw_name
;
1124 ret
= of_property_read_string(pdev
->dev
.of_node
, "firmware-name",
1127 return ERR_PTR(ret
);
1132 static int omap_rproc_get_boot_data(struct platform_device
*pdev
,
1133 struct rproc
*rproc
)
1135 struct device_node
*np
= pdev
->dev
.of_node
;
1136 struct omap_rproc
*oproc
= rproc
->priv
;
1137 const struct omap_rproc_dev_data
*data
;
1140 data
= of_device_get_match_data(&pdev
->dev
);
1144 if (!of_property_read_bool(np
, "ti,bootreg"))
1147 oproc
->boot_data
= devm_kzalloc(&pdev
->dev
, sizeof(*oproc
->boot_data
),
1149 if (!oproc
->boot_data
)
1152 oproc
->boot_data
->syscon
=
1153 syscon_regmap_lookup_by_phandle(np
, "ti,bootreg");
1154 if (IS_ERR(oproc
->boot_data
->syscon
)) {
1155 ret
= PTR_ERR(oproc
->boot_data
->syscon
);
1159 if (of_property_read_u32_index(np
, "ti,bootreg", 1,
1160 &oproc
->boot_data
->boot_reg
)) {
1161 dev_err(&pdev
->dev
, "couldn't get the boot register\n");
1165 of_property_read_u32_index(np
, "ti,bootreg", 2,
1166 &oproc
->boot_data
->boot_reg_shift
);
1171 static int omap_rproc_of_get_internal_memories(struct platform_device
*pdev
,
1172 struct rproc
*rproc
)
1174 struct omap_rproc
*oproc
= rproc
->priv
;
1175 struct device
*dev
= &pdev
->dev
;
1176 const struct omap_rproc_dev_data
*data
;
1177 struct resource
*res
;
1181 data
= of_device_get_match_data(dev
);
1188 num_mems
= of_property_count_elems_of_size(dev
->of_node
, "reg",
1191 oproc
->mem
= devm_kcalloc(dev
, num_mems
, sizeof(*oproc
->mem
),
1196 for (i
= 0; data
->mems
[i
].name
; i
++) {
1197 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1198 data
->mems
[i
].name
);
1200 dev_err(dev
, "no memory defined for %s\n",
1201 data
->mems
[i
].name
);
1204 oproc
->mem
[i
].cpu_addr
= devm_ioremap_resource(dev
, res
);
1205 if (IS_ERR(oproc
->mem
[i
].cpu_addr
)) {
1206 dev_err(dev
, "failed to parse and map %s memory\n",
1207 data
->mems
[i
].name
);
1208 return PTR_ERR(oproc
->mem
[i
].cpu_addr
);
1210 oproc
->mem
[i
].bus_addr
= res
->start
;
1211 oproc
->mem
[i
].dev_addr
= data
->mems
[i
].dev_addr
;
1212 oproc
->mem
[i
].size
= resource_size(res
);
1214 dev_dbg(dev
, "memory %8s: bus addr %pa size 0x%x va %pK da 0x%x\n",
1215 data
->mems
[i
].name
, &oproc
->mem
[i
].bus_addr
,
1216 oproc
->mem
[i
].size
, oproc
->mem
[i
].cpu_addr
,
1217 oproc
->mem
[i
].dev_addr
);
1219 oproc
->num_mems
= num_mems
;
1224 #ifdef CONFIG_OMAP_REMOTEPROC_WATCHDOG
1225 static int omap_rproc_count_wdog_timers(struct device
*dev
)
1227 struct device_node
*np
= dev
->of_node
;
1230 ret
= of_count_phandle_with_args(np
, "ti,watchdog-timers", NULL
);
1232 dev_dbg(dev
, "device does not have watchdog timers, status = %d\n",
1240 static int omap_rproc_count_wdog_timers(struct device
*dev
)
1246 static int omap_rproc_of_get_timers(struct platform_device
*pdev
,
1247 struct rproc
*rproc
)
1249 struct device_node
*np
= pdev
->dev
.of_node
;
1250 struct omap_rproc
*oproc
= rproc
->priv
;
1251 struct device
*dev
= &pdev
->dev
;
1255 * Timer nodes are directly used in client nodes as phandles, so
1256 * retrieve the count using appropriate size
1258 oproc
->num_timers
= of_count_phandle_with_args(np
, "ti,timers", NULL
);
1259 if (oproc
->num_timers
<= 0) {
1260 dev_dbg(dev
, "device does not have timers, status = %d\n",
1262 oproc
->num_timers
= 0;
1265 oproc
->num_wd_timers
= omap_rproc_count_wdog_timers(dev
);
1267 num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
1269 oproc
->timers
= devm_kcalloc(dev
, num_timers
,
1270 sizeof(*oproc
->timers
),
1275 dev_dbg(dev
, "device has %d tick timers and %d watchdog timers\n",
1276 oproc
->num_timers
, oproc
->num_wd_timers
);
1282 static int omap_rproc_probe(struct platform_device
*pdev
)
1284 struct device_node
*np
= pdev
->dev
.of_node
;
1285 struct omap_rproc
*oproc
;
1286 struct rproc
*rproc
;
1287 const char *firmware
;
1289 struct reset_control
*reset
;
1292 dev_err(&pdev
->dev
, "only DT-based devices are supported\n");
1296 reset
= devm_reset_control_array_get_exclusive(&pdev
->dev
);
1298 return PTR_ERR(reset
);
1300 firmware
= omap_rproc_get_firmware(pdev
);
1301 if (IS_ERR(firmware
))
1302 return PTR_ERR(firmware
);
1304 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
1306 dev_err(&pdev
->dev
, "dma_set_coherent_mask: %d\n", ret
);
1310 rproc
= rproc_alloc(&pdev
->dev
, dev_name(&pdev
->dev
), &omap_rproc_ops
,
1311 firmware
, sizeof(*oproc
));
1315 oproc
= rproc
->priv
;
1316 oproc
->rproc
= rproc
;
1317 oproc
->reset
= reset
;
1318 /* All existing OMAP IPU and DSP processors have an MMU */
1319 rproc
->has_iommu
= true;
1321 ret
= omap_rproc_of_get_internal_memories(pdev
, rproc
);
1325 ret
= omap_rproc_get_boot_data(pdev
, rproc
);
1329 ret
= omap_rproc_of_get_timers(pdev
, rproc
);
1333 init_completion(&oproc
->pm_comp
);
1334 oproc
->autosuspend_delay
= DEFAULT_AUTOSUSPEND_DELAY
;
1336 of_property_read_u32(pdev
->dev
.of_node
, "ti,autosuspend-delay-ms",
1337 &oproc
->autosuspend_delay
);
1339 pm_runtime_set_autosuspend_delay(&pdev
->dev
, oproc
->autosuspend_delay
);
1341 oproc
->fck
= devm_clk_get(&pdev
->dev
, 0);
1342 if (IS_ERR(oproc
->fck
)) {
1343 ret
= PTR_ERR(oproc
->fck
);
1347 ret
= of_reserved_mem_device_init(&pdev
->dev
);
1349 dev_warn(&pdev
->dev
, "device does not have specific CMA pool.\n");
1350 dev_warn(&pdev
->dev
, "Typically this should be provided,\n");
1351 dev_warn(&pdev
->dev
, "only omit if you know what you are doing.\n");
1354 platform_set_drvdata(pdev
, rproc
);
1356 ret
= rproc_add(rproc
);
1363 of_reserved_mem_device_release(&pdev
->dev
);
1369 static int omap_rproc_remove(struct platform_device
*pdev
)
1371 struct rproc
*rproc
= platform_get_drvdata(pdev
);
1375 of_reserved_mem_device_release(&pdev
->dev
);
1380 static const struct dev_pm_ops omap_rproc_pm_ops
= {
1381 SET_SYSTEM_SLEEP_PM_OPS(omap_rproc_suspend
, omap_rproc_resume
)
1382 SET_RUNTIME_PM_OPS(omap_rproc_runtime_suspend
,
1383 omap_rproc_runtime_resume
, NULL
)
1386 static struct platform_driver omap_rproc_driver
= {
1387 .probe
= omap_rproc_probe
,
1388 .remove
= omap_rproc_remove
,
1390 .name
= "omap-rproc",
1391 .pm
= &omap_rproc_pm_ops
,
1392 .of_match_table
= omap_rproc_of_match
,
1396 module_platform_driver(omap_rproc_driver
);
1398 MODULE_LICENSE("GPL v2");
1399 MODULE_DESCRIPTION("OMAP Remote Processor control driver");