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
:
514 case RP_MBOX_SUSPEND_CANCEL
:
515 oproc
->suspend_acked
= msg
== RP_MBOX_SUSPEND_ACK
;
516 complete(&oproc
->pm_comp
);
519 if (msg
>= RP_MBOX_READY
&& msg
< RP_MBOX_END_MSG
)
521 if (msg
> oproc
->rproc
->max_notifyid
) {
522 dev_dbg(dev
, "dropping unknown message 0x%x", msg
);
525 /* msg contains the index of the triggered vring */
526 if (rproc_vq_interrupt(oproc
->rproc
, msg
) == IRQ_NONE
)
527 dev_dbg(dev
, "no message was found in vqid %d\n", msg
);
531 /* kick a virtqueue */
532 static void omap_rproc_kick(struct rproc
*rproc
, int vqid
)
534 struct omap_rproc
*oproc
= rproc
->priv
;
535 struct device
*dev
= rproc
->dev
.parent
;
538 /* wake up the rproc before kicking it */
539 ret
= pm_runtime_get_sync(dev
);
540 if (WARN_ON(ret
< 0)) {
541 dev_err(dev
, "pm_runtime_get_sync() failed during kick, ret = %d\n",
543 pm_runtime_put_noidle(dev
);
547 /* send the index of the triggered virtqueue in the mailbox payload */
548 ret
= mbox_send_message(oproc
->mbox
, (void *)vqid
);
550 dev_err(dev
, "failed to send mailbox message, status = %d\n",
553 pm_runtime_mark_last_busy(dev
);
554 pm_runtime_put_autosuspend(dev
);
558 * omap_rproc_write_dsp_boot_addr() - set boot address for DSP remote processor
559 * @rproc: handle of a remote processor
561 * Set boot address for a supported DSP remote processor.
563 * Return: 0 on success, or -EINVAL if boot address is not aligned properly
565 static int omap_rproc_write_dsp_boot_addr(struct rproc
*rproc
)
567 struct device
*dev
= rproc
->dev
.parent
;
568 struct omap_rproc
*oproc
= rproc
->priv
;
569 struct omap_rproc_boot_data
*bdata
= oproc
->boot_data
;
570 u32 offset
= bdata
->boot_reg
;
574 if (rproc
->bootaddr
& (SZ_1K
- 1)) {
575 dev_err(dev
, "invalid boot address 0x%llx, must be aligned on a 1KB boundary\n",
580 value
= rproc
->bootaddr
>> bdata
->boot_reg_shift
;
581 mask
= ~(SZ_1K
- 1) >> bdata
->boot_reg_shift
;
583 return regmap_update_bits(bdata
->syscon
, offset
, mask
, value
);
587 * Power up the remote processor.
589 * This function will be invoked only after the firmware for this rproc
590 * was loaded, parsed successfully, and all of its resource requirements
593 static int omap_rproc_start(struct rproc
*rproc
)
595 struct omap_rproc
*oproc
= rproc
->priv
;
596 struct device
*dev
= rproc
->dev
.parent
;
598 struct mbox_client
*client
= &oproc
->client
;
600 if (oproc
->boot_data
) {
601 ret
= omap_rproc_write_dsp_boot_addr(rproc
);
607 client
->tx_done
= NULL
;
608 client
->rx_callback
= omap_rproc_mbox_callback
;
609 client
->tx_block
= false;
610 client
->knows_txdone
= false;
612 oproc
->mbox
= mbox_request_channel(client
, 0);
613 if (IS_ERR(oproc
->mbox
)) {
615 dev_err(dev
, "mbox_request_channel failed: %ld\n",
616 PTR_ERR(oproc
->mbox
));
621 * Ping the remote processor. this is only for sanity-sake;
622 * there is no functional effect whatsoever.
624 * Note that the reply will _not_ arrive immediately: this message
625 * will wait in the mailbox fifo until the remote processor is booted.
627 ret
= mbox_send_message(oproc
->mbox
, (void *)RP_MBOX_ECHO_REQUEST
);
629 dev_err(dev
, "mbox_send_message failed: %d\n", ret
);
633 ret
= omap_rproc_enable_timers(rproc
, true);
635 dev_err(dev
, "omap_rproc_enable_timers failed: %d\n", ret
);
639 ret
= reset_control_deassert(oproc
->reset
);
641 dev_err(dev
, "reset control deassert failed: %d\n", ret
);
646 * remote processor is up, so update the runtime pm status and
647 * enable the auto-suspend. The device usage count is incremented
648 * manually for balancing it for auto-suspend
650 pm_runtime_set_active(dev
);
651 pm_runtime_use_autosuspend(dev
);
652 pm_runtime_get_noresume(dev
);
653 pm_runtime_enable(dev
);
654 pm_runtime_mark_last_busy(dev
);
655 pm_runtime_put_autosuspend(dev
);
660 omap_rproc_disable_timers(rproc
, true);
662 mbox_free_channel(oproc
->mbox
);
666 /* power off the remote processor */
667 static int omap_rproc_stop(struct rproc
*rproc
)
669 struct device
*dev
= rproc
->dev
.parent
;
670 struct omap_rproc
*oproc
= rproc
->priv
;
674 * cancel any possible scheduled runtime suspend by incrementing
675 * the device usage count, and resuming the device. The remoteproc
676 * also needs to be woken up if suspended, to avoid the remoteproc
677 * OS to continue to remember any context that it has saved, and
678 * avoid potential issues in misindentifying a subsequent device
679 * reboot as a power restore boot
681 ret
= pm_runtime_get_sync(dev
);
683 pm_runtime_put_noidle(dev
);
687 ret
= reset_control_assert(oproc
->reset
);
691 ret
= omap_rproc_disable_timers(rproc
, true);
695 mbox_free_channel(oproc
->mbox
);
698 * update the runtime pm states and status now that the remoteproc
701 pm_runtime_disable(dev
);
702 pm_runtime_dont_use_autosuspend(dev
);
703 pm_runtime_put_noidle(dev
);
704 pm_runtime_set_suspended(dev
);
709 reset_control_deassert(oproc
->reset
);
711 /* schedule the next auto-suspend */
712 pm_runtime_mark_last_busy(dev
);
713 pm_runtime_put_autosuspend(dev
);
718 * omap_rproc_da_to_va() - internal memory translation helper
719 * @rproc: remote processor to apply the address translation for
720 * @da: device address to translate
721 * @len: length of the memory buffer
723 * Custom function implementing the rproc .da_to_va ops to provide address
724 * translation (device address to kernel virtual address) for internal RAMs
725 * present in a DSP or IPU device). The translated addresses can be used
726 * either by the remoteproc core for loading, or by any rpmsg bus drivers.
728 * Return: translated virtual address in kernel memory space on success,
729 * or NULL on failure.
731 static void *omap_rproc_da_to_va(struct rproc
*rproc
, u64 da
, size_t len
)
733 struct omap_rproc
*oproc
= rproc
->priv
;
740 if (!oproc
->num_mems
)
743 for (i
= 0; i
< oproc
->num_mems
; i
++) {
744 if (da
>= oproc
->mem
[i
].dev_addr
&& da
+ len
<=
745 oproc
->mem
[i
].dev_addr
+ oproc
->mem
[i
].size
) {
746 offset
= da
- oproc
->mem
[i
].dev_addr
;
747 /* __force to make sparse happy with type conversion */
748 return (__force
void *)(oproc
->mem
[i
].cpu_addr
+
756 static const struct rproc_ops omap_rproc_ops
= {
757 .start
= omap_rproc_start
,
758 .stop
= omap_rproc_stop
,
759 .kick
= omap_rproc_kick
,
760 .da_to_va
= omap_rproc_da_to_va
,
764 static bool _is_rproc_in_standby(struct omap_rproc
*oproc
)
766 return ti_clk_is_in_standby(oproc
->fck
);
769 /* 1 sec is long enough time to let the remoteproc side suspend the device */
770 #define DEF_SUSPEND_TIMEOUT 1000
771 static int _omap_rproc_suspend(struct rproc
*rproc
, bool auto_suspend
)
773 struct device
*dev
= rproc
->dev
.parent
;
774 struct omap_rproc
*oproc
= rproc
->priv
;
775 unsigned long to
= msecs_to_jiffies(DEF_SUSPEND_TIMEOUT
);
776 unsigned long ta
= jiffies
+ to
;
777 u32 suspend_msg
= auto_suspend
?
778 RP_MBOX_SUSPEND_AUTO
: RP_MBOX_SUSPEND_SYSTEM
;
781 reinit_completion(&oproc
->pm_comp
);
782 oproc
->suspend_acked
= false;
783 ret
= mbox_send_message(oproc
->mbox
, (void *)suspend_msg
);
785 dev_err(dev
, "PM mbox_send_message failed: %d\n", ret
);
789 ret
= wait_for_completion_timeout(&oproc
->pm_comp
, to
);
790 if (!oproc
->suspend_acked
)
794 * The remoteproc side is returning the ACK message before saving the
795 * context, because the context saving is performed within a SYS/BIOS
796 * function, and it cannot have any inter-dependencies against the IPC
797 * layer. Also, as the SYS/BIOS needs to preserve properly the processor
798 * register set, sending this ACK or signalling the completion of the
799 * context save through a shared memory variable can never be the
800 * absolute last thing to be executed on the remoteproc side, and the
801 * MPU cannot use the ACK message as a sync point to put the remoteproc
802 * into reset. The only way to ensure that the remote processor has
803 * completed saving the context is to check that the module has reached
804 * STANDBY state (after saving the context, the SYS/BIOS executes the
805 * appropriate target-specific WFI instruction causing the module to
808 while (!_is_rproc_in_standby(oproc
)) {
809 if (time_after(jiffies
, ta
))
814 ret
= reset_control_assert(oproc
->reset
);
816 dev_err(dev
, "reset assert during suspend failed %d\n", ret
);
820 ret
= omap_rproc_disable_timers(rproc
, false);
822 dev_err(dev
, "disabling timers during suspend failed %d\n",
828 * IOMMUs would have to be disabled specifically for runtime suspend.
829 * They are handled automatically through System PM callbacks for
830 * regular system suspend
833 ret
= omap_iommu_domain_deactivate(rproc
->domain
);
835 dev_err(dev
, "iommu domain deactivate failed %d\n",
844 /* ignore errors on re-enabling code */
845 omap_rproc_enable_timers(rproc
, false);
847 reset_control_deassert(oproc
->reset
);
851 static int _omap_rproc_resume(struct rproc
*rproc
, bool auto_suspend
)
853 struct device
*dev
= rproc
->dev
.parent
;
854 struct omap_rproc
*oproc
= rproc
->priv
;
858 * IOMMUs would have to be enabled specifically for runtime resume.
859 * They would have been already enabled automatically through System
860 * PM callbacks for regular system resume
863 ret
= omap_iommu_domain_activate(rproc
->domain
);
865 dev_err(dev
, "omap_iommu activate failed %d\n", ret
);
870 /* boot address could be lost after suspend, so restore it */
871 if (oproc
->boot_data
) {
872 ret
= omap_rproc_write_dsp_boot_addr(rproc
);
874 dev_err(dev
, "boot address restore failed %d\n", ret
);
879 ret
= omap_rproc_enable_timers(rproc
, false);
881 dev_err(dev
, "enabling timers during resume failed %d\n", ret
);
885 ret
= reset_control_deassert(oproc
->reset
);
887 dev_err(dev
, "reset deassert during resume failed %d\n", ret
);
894 omap_rproc_disable_timers(rproc
, false);
897 omap_iommu_domain_deactivate(rproc
->domain
);
902 static int __maybe_unused
omap_rproc_suspend(struct device
*dev
)
904 struct platform_device
*pdev
= to_platform_device(dev
);
905 struct rproc
*rproc
= platform_get_drvdata(pdev
);
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 platform_device
*pdev
= to_platform_device(dev
);
942 struct rproc
*rproc
= platform_get_drvdata(pdev
);
943 struct omap_rproc
*oproc
= rproc
->priv
;
946 mutex_lock(&rproc
->lock
);
947 if (rproc
->state
== RPROC_OFFLINE
)
950 if (rproc
->state
!= RPROC_SUSPENDED
) {
956 * remoteproc was auto-suspended at the time of system suspend,
957 * so no need to wake-up the processor (leave it in suspended
958 * state, will be woken up during a subsequent runtime_resume)
960 if (!oproc
->need_resume
)
963 ret
= _omap_rproc_resume(rproc
, false);
965 dev_err(dev
, "resume failed %d\n", ret
);
969 oproc
->need_resume
= false;
970 rproc
->state
= RPROC_RUNNING
;
972 pm_runtime_mark_last_busy(dev
);
974 mutex_unlock(&rproc
->lock
);
978 static int omap_rproc_runtime_suspend(struct device
*dev
)
980 struct rproc
*rproc
= dev_get_drvdata(dev
);
981 struct omap_rproc
*oproc
= rproc
->priv
;
984 mutex_lock(&rproc
->lock
);
985 if (rproc
->state
== RPROC_CRASHED
) {
986 dev_dbg(dev
, "rproc cannot be runtime suspended when crashed!\n");
991 if (WARN_ON(rproc
->state
!= RPROC_RUNNING
)) {
992 dev_err(dev
, "rproc cannot be runtime suspended when not running!\n");
998 * do not even attempt suspend if the remote processor is not
999 * idled for runtime auto-suspend
1001 if (!_is_rproc_in_standby(oproc
)) {
1006 ret
= _omap_rproc_suspend(rproc
, true);
1010 rproc
->state
= RPROC_SUSPENDED
;
1011 mutex_unlock(&rproc
->lock
);
1015 pm_runtime_mark_last_busy(dev
);
1017 mutex_unlock(&rproc
->lock
);
1021 static int omap_rproc_runtime_resume(struct device
*dev
)
1023 struct rproc
*rproc
= dev_get_drvdata(dev
);
1026 mutex_lock(&rproc
->lock
);
1027 if (WARN_ON(rproc
->state
!= RPROC_SUSPENDED
)) {
1028 dev_err(dev
, "rproc cannot be runtime resumed if not suspended! state=%d\n",
1034 ret
= _omap_rproc_resume(rproc
, true);
1036 dev_err(dev
, "runtime resume failed %d\n", ret
);
1040 rproc
->state
= RPROC_RUNNING
;
1042 mutex_unlock(&rproc
->lock
);
1045 #endif /* CONFIG_PM */
1047 static const struct omap_rproc_mem_data ipu_mems
[] = {
1048 { .name
= "l2ram", .dev_addr
= 0x20000000 },
1052 static const struct omap_rproc_mem_data dra7_dsp_mems
[] = {
1053 { .name
= "l2ram", .dev_addr
= 0x800000 },
1054 { .name
= "l1pram", .dev_addr
= 0xe00000 },
1055 { .name
= "l1dram", .dev_addr
= 0xf00000 },
1059 static const struct omap_rproc_dev_data omap4_dsp_dev_data
= {
1060 .device_name
= "dsp",
1063 static const struct omap_rproc_dev_data omap4_ipu_dev_data
= {
1064 .device_name
= "ipu",
1068 static const struct omap_rproc_dev_data omap5_dsp_dev_data
= {
1069 .device_name
= "dsp",
1072 static const struct omap_rproc_dev_data omap5_ipu_dev_data
= {
1073 .device_name
= "ipu",
1077 static const struct omap_rproc_dev_data dra7_dsp_dev_data
= {
1078 .device_name
= "dsp",
1079 .mems
= dra7_dsp_mems
,
1082 static const struct omap_rproc_dev_data dra7_ipu_dev_data
= {
1083 .device_name
= "ipu",
1087 static const struct of_device_id omap_rproc_of_match
[] = {
1089 .compatible
= "ti,omap4-dsp",
1090 .data
= &omap4_dsp_dev_data
,
1093 .compatible
= "ti,omap4-ipu",
1094 .data
= &omap4_ipu_dev_data
,
1097 .compatible
= "ti,omap5-dsp",
1098 .data
= &omap5_dsp_dev_data
,
1101 .compatible
= "ti,omap5-ipu",
1102 .data
= &omap5_ipu_dev_data
,
1105 .compatible
= "ti,dra7-dsp",
1106 .data
= &dra7_dsp_dev_data
,
1109 .compatible
= "ti,dra7-ipu",
1110 .data
= &dra7_ipu_dev_data
,
1116 MODULE_DEVICE_TABLE(of
, omap_rproc_of_match
);
1118 static const char *omap_rproc_get_firmware(struct platform_device
*pdev
)
1120 const char *fw_name
;
1123 ret
= of_property_read_string(pdev
->dev
.of_node
, "firmware-name",
1126 return ERR_PTR(ret
);
1131 static int omap_rproc_get_boot_data(struct platform_device
*pdev
,
1132 struct rproc
*rproc
)
1134 struct device_node
*np
= pdev
->dev
.of_node
;
1135 struct omap_rproc
*oproc
= rproc
->priv
;
1136 const struct omap_rproc_dev_data
*data
;
1139 data
= of_device_get_match_data(&pdev
->dev
);
1143 if (!of_property_read_bool(np
, "ti,bootreg"))
1146 oproc
->boot_data
= devm_kzalloc(&pdev
->dev
, sizeof(*oproc
->boot_data
),
1148 if (!oproc
->boot_data
)
1151 oproc
->boot_data
->syscon
=
1152 syscon_regmap_lookup_by_phandle(np
, "ti,bootreg");
1153 if (IS_ERR(oproc
->boot_data
->syscon
)) {
1154 ret
= PTR_ERR(oproc
->boot_data
->syscon
);
1158 if (of_property_read_u32_index(np
, "ti,bootreg", 1,
1159 &oproc
->boot_data
->boot_reg
)) {
1160 dev_err(&pdev
->dev
, "couldn't get the boot register\n");
1164 of_property_read_u32_index(np
, "ti,bootreg", 2,
1165 &oproc
->boot_data
->boot_reg_shift
);
1170 static int omap_rproc_of_get_internal_memories(struct platform_device
*pdev
,
1171 struct rproc
*rproc
)
1173 struct omap_rproc
*oproc
= rproc
->priv
;
1174 struct device
*dev
= &pdev
->dev
;
1175 const struct omap_rproc_dev_data
*data
;
1176 struct resource
*res
;
1180 data
= of_device_get_match_data(dev
);
1187 num_mems
= of_property_count_elems_of_size(dev
->of_node
, "reg",
1190 oproc
->mem
= devm_kcalloc(dev
, num_mems
, sizeof(*oproc
->mem
),
1195 for (i
= 0; data
->mems
[i
].name
; i
++) {
1196 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
1197 data
->mems
[i
].name
);
1199 dev_err(dev
, "no memory defined for %s\n",
1200 data
->mems
[i
].name
);
1203 oproc
->mem
[i
].cpu_addr
= devm_ioremap_resource(dev
, res
);
1204 if (IS_ERR(oproc
->mem
[i
].cpu_addr
)) {
1205 dev_err(dev
, "failed to parse and map %s memory\n",
1206 data
->mems
[i
].name
);
1207 return PTR_ERR(oproc
->mem
[i
].cpu_addr
);
1209 oproc
->mem
[i
].bus_addr
= res
->start
;
1210 oproc
->mem
[i
].dev_addr
= data
->mems
[i
].dev_addr
;
1211 oproc
->mem
[i
].size
= resource_size(res
);
1213 dev_dbg(dev
, "memory %8s: bus addr %pa size 0x%x va %pK da 0x%x\n",
1214 data
->mems
[i
].name
, &oproc
->mem
[i
].bus_addr
,
1215 oproc
->mem
[i
].size
, oproc
->mem
[i
].cpu_addr
,
1216 oproc
->mem
[i
].dev_addr
);
1218 oproc
->num_mems
= num_mems
;
1223 #ifdef CONFIG_OMAP_REMOTEPROC_WATCHDOG
1224 static int omap_rproc_count_wdog_timers(struct device
*dev
)
1226 struct device_node
*np
= dev
->of_node
;
1229 ret
= of_count_phandle_with_args(np
, "ti,watchdog-timers", NULL
);
1231 dev_dbg(dev
, "device does not have watchdog timers, status = %d\n",
1239 static int omap_rproc_count_wdog_timers(struct device
*dev
)
1245 static int omap_rproc_of_get_timers(struct platform_device
*pdev
,
1246 struct rproc
*rproc
)
1248 struct device_node
*np
= pdev
->dev
.of_node
;
1249 struct omap_rproc
*oproc
= rproc
->priv
;
1250 struct device
*dev
= &pdev
->dev
;
1254 * Timer nodes are directly used in client nodes as phandles, so
1255 * retrieve the count using appropriate size
1257 oproc
->num_timers
= of_count_phandle_with_args(np
, "ti,timers", NULL
);
1258 if (oproc
->num_timers
<= 0) {
1259 dev_dbg(dev
, "device does not have timers, status = %d\n",
1261 oproc
->num_timers
= 0;
1264 oproc
->num_wd_timers
= omap_rproc_count_wdog_timers(dev
);
1266 num_timers
= oproc
->num_timers
+ oproc
->num_wd_timers
;
1268 oproc
->timers
= devm_kcalloc(dev
, num_timers
,
1269 sizeof(*oproc
->timers
),
1274 dev_dbg(dev
, "device has %d tick timers and %d watchdog timers\n",
1275 oproc
->num_timers
, oproc
->num_wd_timers
);
1281 static int omap_rproc_probe(struct platform_device
*pdev
)
1283 struct device_node
*np
= pdev
->dev
.of_node
;
1284 struct omap_rproc
*oproc
;
1285 struct rproc
*rproc
;
1286 const char *firmware
;
1288 struct reset_control
*reset
;
1291 dev_err(&pdev
->dev
, "only DT-based devices are supported\n");
1295 reset
= devm_reset_control_array_get_exclusive(&pdev
->dev
);
1297 return PTR_ERR(reset
);
1299 firmware
= omap_rproc_get_firmware(pdev
);
1300 if (IS_ERR(firmware
))
1301 return PTR_ERR(firmware
);
1303 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
1305 dev_err(&pdev
->dev
, "dma_set_coherent_mask: %d\n", ret
);
1309 rproc
= rproc_alloc(&pdev
->dev
, dev_name(&pdev
->dev
), &omap_rproc_ops
,
1310 firmware
, sizeof(*oproc
));
1314 oproc
= rproc
->priv
;
1315 oproc
->rproc
= rproc
;
1316 oproc
->reset
= reset
;
1317 /* All existing OMAP IPU and DSP processors have an MMU */
1318 rproc
->has_iommu
= true;
1320 ret
= omap_rproc_of_get_internal_memories(pdev
, rproc
);
1324 ret
= omap_rproc_get_boot_data(pdev
, rproc
);
1328 ret
= omap_rproc_of_get_timers(pdev
, rproc
);
1332 init_completion(&oproc
->pm_comp
);
1333 oproc
->autosuspend_delay
= DEFAULT_AUTOSUSPEND_DELAY
;
1335 of_property_read_u32(pdev
->dev
.of_node
, "ti,autosuspend-delay-ms",
1336 &oproc
->autosuspend_delay
);
1338 pm_runtime_set_autosuspend_delay(&pdev
->dev
, oproc
->autosuspend_delay
);
1340 oproc
->fck
= devm_clk_get(&pdev
->dev
, 0);
1341 if (IS_ERR(oproc
->fck
)) {
1342 ret
= PTR_ERR(oproc
->fck
);
1346 ret
= of_reserved_mem_device_init(&pdev
->dev
);
1348 dev_warn(&pdev
->dev
, "device does not have specific CMA pool.\n");
1349 dev_warn(&pdev
->dev
, "Typically this should be provided,\n");
1350 dev_warn(&pdev
->dev
, "only omit if you know what you are doing.\n");
1353 platform_set_drvdata(pdev
, rproc
);
1355 ret
= rproc_add(rproc
);
1362 of_reserved_mem_device_release(&pdev
->dev
);
1368 static int omap_rproc_remove(struct platform_device
*pdev
)
1370 struct rproc
*rproc
= platform_get_drvdata(pdev
);
1374 of_reserved_mem_device_release(&pdev
->dev
);
1379 static const struct dev_pm_ops omap_rproc_pm_ops
= {
1380 SET_SYSTEM_SLEEP_PM_OPS(omap_rproc_suspend
, omap_rproc_resume
)
1381 SET_RUNTIME_PM_OPS(omap_rproc_runtime_suspend
,
1382 omap_rproc_runtime_resume
, NULL
)
1385 static struct platform_driver omap_rproc_driver
= {
1386 .probe
= omap_rproc_probe
,
1387 .remove
= omap_rproc_remove
,
1389 .name
= "omap-rproc",
1390 .pm
= &omap_rproc_pm_ops
,
1391 .of_match_table
= omap_rproc_of_match
,
1395 module_platform_driver(omap_rproc_driver
);
1397 MODULE_LICENSE("GPL v2");
1398 MODULE_DESCRIPTION("OMAP Remote Processor control driver");