2 * TI Keystone DSP remoteproc driver
4 * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
16 #include <linux/module.h>
17 #include <linux/slab.h>
19 #include <linux/interrupt.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/workqueue.h>
23 #include <linux/of_address.h>
24 #include <linux/of_reserved_mem.h>
25 #include <linux/of_gpio.h>
26 #include <linux/regmap.h>
27 #include <linux/mfd/syscon.h>
28 #include <linux/remoteproc.h>
29 #include <linux/reset.h>
31 #include "remoteproc_internal.h"
33 #define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK (SZ_16M - 1)
36 * struct keystone_rproc_mem - internal memory structure
37 * @cpu_addr: MPU virtual address of the memory region
38 * @bus_addr: Bus address used to access the memory region
39 * @dev_addr: Device address of the memory region from DSP view
40 * @size: Size of the memory region
42 struct keystone_rproc_mem
{
43 void __iomem
*cpu_addr
;
50 * struct keystone_rproc - keystone remote processor driver structure
51 * @dev: cached device pointer
52 * @rproc: remoteproc device handle
53 * @mem: internal memory regions data
54 * @num_mems: number of internal memory regions
55 * @dev_ctrl: device control regmap handle
56 * @reset: reset control handle
57 * @boot_offset: boot register offset in @dev_ctrl regmap
58 * @irq_ring: irq entry for vring
59 * @irq_fault: irq entry for exception
60 * @kick_gpio: gpio used for virtio kicks
61 * @workqueue: workqueue for processing virtio interrupts
63 struct keystone_rproc
{
66 struct keystone_rproc_mem
*mem
;
68 struct regmap
*dev_ctrl
;
69 struct reset_control
*reset
;
74 struct work_struct workqueue
;
77 /* Put the DSP processor into reset */
78 static void keystone_rproc_dsp_reset(struct keystone_rproc
*ksproc
)
80 reset_control_assert(ksproc
->reset
);
83 /* Configure the boot address and boot the DSP processor */
84 static int keystone_rproc_dsp_boot(struct keystone_rproc
*ksproc
, u32 boot_addr
)
88 if (boot_addr
& (SZ_1K
- 1)) {
89 dev_err(ksproc
->dev
, "invalid boot address 0x%x, must be aligned on a 1KB boundary\n",
94 ret
= regmap_write(ksproc
->dev_ctrl
, ksproc
->boot_offset
, boot_addr
);
96 dev_err(ksproc
->dev
, "regmap_write of boot address failed, status = %d\n",
101 reset_control_deassert(ksproc
->reset
);
107 * Process the remoteproc exceptions
109 * The exception reporting on Keystone DSP remote processors is very simple
110 * compared to the equivalent processors on the OMAP family, it is notified
111 * through a software-designed specific interrupt source in the IPC interrupt
112 * generation register.
114 * This function just invokes the rproc_report_crash to report the exception
115 * to the remoteproc driver core, to trigger a recovery.
117 static irqreturn_t
keystone_rproc_exception_interrupt(int irq
, void *dev_id
)
119 struct keystone_rproc
*ksproc
= dev_id
;
121 rproc_report_crash(ksproc
->rproc
, RPROC_FATAL_ERROR
);
127 * Main virtqueue message workqueue function
129 * This function is executed upon scheduling of the keystone remoteproc
130 * driver's workqueue. The workqueue is scheduled by the vring ISR handler.
132 * There is no payload message indicating the virtqueue index as is the
133 * case with mailbox-based implementations on OMAP family. As such, this
134 * handler processes both the Tx and Rx virtqueue indices on every invocation.
135 * The rproc_vq_interrupt function can detect if there are new unprocessed
136 * messages or not (returns IRQ_NONE vs IRQ_HANDLED), but there is no need
137 * to check for these return values. The index 0 triggering will process all
138 * pending Rx buffers, and the index 1 triggering will process all newly
139 * available Tx buffers and will wakeup any potentially blocked senders.
142 * 1. A payload could be added by using some of the source bits in the
143 * IPC interrupt generation registers, but this would need additional
144 * changes to the overall IPC stack, and currently there are no benefits
145 * of adapting that approach.
146 * 2. The current logic is based on an inherent design assumption of supporting
147 * only 2 vrings, but this can be changed if needed.
149 static void handle_event(struct work_struct
*work
)
151 struct keystone_rproc
*ksproc
=
152 container_of(work
, struct keystone_rproc
, workqueue
);
154 rproc_vq_interrupt(ksproc
->rproc
, 0);
155 rproc_vq_interrupt(ksproc
->rproc
, 1);
159 * Interrupt handler for processing vring kicks from remote processor
161 static irqreturn_t
keystone_rproc_vring_interrupt(int irq
, void *dev_id
)
163 struct keystone_rproc
*ksproc
= dev_id
;
165 schedule_work(&ksproc
->workqueue
);
171 * Power up the DSP remote processor.
173 * This function will be invoked only after the firmware for this rproc
174 * was loaded, parsed successfully, and all of its resource requirements
177 static int keystone_rproc_start(struct rproc
*rproc
)
179 struct keystone_rproc
*ksproc
= rproc
->priv
;
182 INIT_WORK(&ksproc
->workqueue
, handle_event
);
184 ret
= request_irq(ksproc
->irq_ring
, keystone_rproc_vring_interrupt
, 0,
185 dev_name(ksproc
->dev
), ksproc
);
187 dev_err(ksproc
->dev
, "failed to enable vring interrupt, ret = %d\n",
192 ret
= request_irq(ksproc
->irq_fault
, keystone_rproc_exception_interrupt
,
193 0, dev_name(ksproc
->dev
), ksproc
);
195 dev_err(ksproc
->dev
, "failed to enable exception interrupt, ret = %d\n",
200 ret
= keystone_rproc_dsp_boot(ksproc
, rproc
->bootaddr
);
207 free_irq(ksproc
->irq_fault
, ksproc
);
209 free_irq(ksproc
->irq_ring
, ksproc
);
210 flush_work(&ksproc
->workqueue
);
216 * Stop the DSP remote processor.
218 * This function puts the DSP processor into reset, and finishes processing
219 * of any pending messages.
221 static int keystone_rproc_stop(struct rproc
*rproc
)
223 struct keystone_rproc
*ksproc
= rproc
->priv
;
225 keystone_rproc_dsp_reset(ksproc
);
226 free_irq(ksproc
->irq_fault
, ksproc
);
227 free_irq(ksproc
->irq_ring
, ksproc
);
228 flush_work(&ksproc
->workqueue
);
234 * Kick the remote processor to notify about pending unprocessed messages.
235 * The vqid usage is not used and is inconsequential, as the kick is performed
236 * through a simulated GPIO (a bit in an IPC interrupt-triggering register),
237 * the remote processor is expected to process both its Tx and Rx virtqueues.
239 static void keystone_rproc_kick(struct rproc
*rproc
, int vqid
)
241 struct keystone_rproc
*ksproc
= rproc
->priv
;
243 if (WARN_ON(ksproc
->kick_gpio
< 0))
246 gpio_set_value(ksproc
->kick_gpio
, 1);
250 * Custom function to translate a DSP device address (internal RAMs only) to a
251 * kernel virtual address. The DSPs can access their RAMs at either an internal
252 * address visible only from a DSP, or at the SoC-level bus address. Both these
253 * addresses need to be looked through for translation. The translated addresses
254 * can be used either by the remoteproc core for loading (when using kernel
255 * remoteproc loader), or by any rpmsg bus drivers.
257 static void *keystone_rproc_da_to_va(struct rproc
*rproc
, u64 da
, int len
)
259 struct keystone_rproc
*ksproc
= rproc
->priv
;
260 void __iomem
*va
= NULL
;
261 phys_addr_t bus_addr
;
262 u32 dev_addr
, offset
;
269 for (i
= 0; i
< ksproc
->num_mems
; i
++) {
270 bus_addr
= ksproc
->mem
[i
].bus_addr
;
271 dev_addr
= ksproc
->mem
[i
].dev_addr
;
272 size
= ksproc
->mem
[i
].size
;
274 if (da
< KEYSTONE_RPROC_LOCAL_ADDRESS_MASK
) {
275 /* handle DSP-view addresses */
276 if ((da
>= dev_addr
) &&
277 ((da
+ len
) <= (dev_addr
+ size
))) {
278 offset
= da
- dev_addr
;
279 va
= ksproc
->mem
[i
].cpu_addr
+ offset
;
283 /* handle SoC-view addresses */
284 if ((da
>= bus_addr
) &&
285 (da
+ len
) <= (bus_addr
+ size
)) {
286 offset
= da
- bus_addr
;
287 va
= ksproc
->mem
[i
].cpu_addr
+ offset
;
293 return (__force
void *)va
;
296 static const struct rproc_ops keystone_rproc_ops
= {
297 .start
= keystone_rproc_start
,
298 .stop
= keystone_rproc_stop
,
299 .kick
= keystone_rproc_kick
,
300 .da_to_va
= keystone_rproc_da_to_va
,
303 static int keystone_rproc_of_get_memories(struct platform_device
*pdev
,
304 struct keystone_rproc
*ksproc
)
306 static const char * const mem_names
[] = {"l2sram", "l1pram", "l1dram"};
307 struct device
*dev
= &pdev
->dev
;
308 struct resource
*res
;
312 num_mems
= ARRAY_SIZE(mem_names
);
313 ksproc
->mem
= devm_kcalloc(ksproc
->dev
, num_mems
,
314 sizeof(*ksproc
->mem
), GFP_KERNEL
);
318 for (i
= 0; i
< num_mems
; i
++) {
319 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
,
321 ksproc
->mem
[i
].cpu_addr
= devm_ioremap_resource(dev
, res
);
322 if (IS_ERR(ksproc
->mem
[i
].cpu_addr
)) {
323 dev_err(dev
, "failed to parse and map %s memory\n",
325 return PTR_ERR(ksproc
->mem
[i
].cpu_addr
);
327 ksproc
->mem
[i
].bus_addr
= res
->start
;
328 ksproc
->mem
[i
].dev_addr
=
329 res
->start
& KEYSTONE_RPROC_LOCAL_ADDRESS_MASK
;
330 ksproc
->mem
[i
].size
= resource_size(res
);
332 /* zero out memories to start in a pristine state */
333 memset((__force
void *)ksproc
->mem
[i
].cpu_addr
, 0,
334 ksproc
->mem
[i
].size
);
336 ksproc
->num_mems
= num_mems
;
341 static int keystone_rproc_of_get_dev_syscon(struct platform_device
*pdev
,
342 struct keystone_rproc
*ksproc
)
344 struct device_node
*np
= pdev
->dev
.of_node
;
345 struct device
*dev
= &pdev
->dev
;
348 if (!of_property_read_bool(np
, "ti,syscon-dev")) {
349 dev_err(dev
, "ti,syscon-dev property is absent\n");
354 syscon_regmap_lookup_by_phandle(np
, "ti,syscon-dev");
355 if (IS_ERR(ksproc
->dev_ctrl
)) {
356 ret
= PTR_ERR(ksproc
->dev_ctrl
);
360 if (of_property_read_u32_index(np
, "ti,syscon-dev", 1,
361 &ksproc
->boot_offset
)) {
362 dev_err(dev
, "couldn't read the boot register offset\n");
369 static int keystone_rproc_probe(struct platform_device
*pdev
)
371 struct device
*dev
= &pdev
->dev
;
372 struct device_node
*np
= dev
->of_node
;
373 struct keystone_rproc
*ksproc
;
376 char *fw_name
= NULL
;
377 char *template = "keystone-dsp%d-fw";
382 dev_err(dev
, "only DT-based devices are supported\n");
386 dsp_id
= of_alias_get_id(np
, "rproc");
388 dev_warn(dev
, "device does not have an alias id\n");
392 /* construct a custom default fw name - subject to change in future */
393 name_len
= strlen(template); /* assuming a single digit alias */
394 fw_name
= devm_kzalloc(dev
, name_len
, GFP_KERNEL
);
397 snprintf(fw_name
, name_len
, template, dsp_id
);
399 rproc
= rproc_alloc(dev
, dev_name(dev
), &keystone_rproc_ops
, fw_name
,
404 rproc
->has_iommu
= false;
405 ksproc
= rproc
->priv
;
406 ksproc
->rproc
= rproc
;
409 ret
= keystone_rproc_of_get_dev_syscon(pdev
, ksproc
);
413 ksproc
->reset
= devm_reset_control_get_exclusive(dev
, NULL
);
414 if (IS_ERR(ksproc
->reset
)) {
415 ret
= PTR_ERR(ksproc
->reset
);
419 /* enable clock for accessing DSP internal memories */
420 pm_runtime_enable(dev
);
421 ret
= pm_runtime_get_sync(dev
);
423 dev_err(dev
, "failed to enable clock, status = %d\n", ret
);
424 pm_runtime_put_noidle(dev
);
428 ret
= keystone_rproc_of_get_memories(pdev
, ksproc
);
432 ksproc
->irq_ring
= platform_get_irq_byname(pdev
, "vring");
433 if (ksproc
->irq_ring
< 0) {
434 ret
= ksproc
->irq_ring
;
435 dev_err(dev
, "failed to get vring interrupt, status = %d\n",
440 ksproc
->irq_fault
= platform_get_irq_byname(pdev
, "exception");
441 if (ksproc
->irq_fault
< 0) {
442 ret
= ksproc
->irq_fault
;
443 dev_err(dev
, "failed to get exception interrupt, status = %d\n",
448 ksproc
->kick_gpio
= of_get_named_gpio_flags(np
, "kick-gpios", 0, NULL
);
449 if (ksproc
->kick_gpio
< 0) {
450 ret
= ksproc
->kick_gpio
;
451 dev_err(dev
, "failed to get gpio for virtio kicks, status = %d\n",
456 if (of_reserved_mem_device_init(dev
))
457 dev_warn(dev
, "device does not have specific CMA pool\n");
459 /* ensure the DSP is in reset before loading firmware */
460 ret
= reset_control_status(ksproc
->reset
);
462 dev_err(dev
, "failed to get reset status, status = %d\n", ret
);
464 } else if (ret
== 0) {
465 WARN(1, "device is not in reset\n");
466 keystone_rproc_dsp_reset(ksproc
);
469 ret
= rproc_add(rproc
);
471 dev_err(dev
, "failed to add register device with remoteproc core, status = %d\n",
476 platform_set_drvdata(pdev
, ksproc
);
481 of_reserved_mem_device_release(dev
);
483 pm_runtime_put_sync(dev
);
485 pm_runtime_disable(dev
);
491 static int keystone_rproc_remove(struct platform_device
*pdev
)
493 struct keystone_rproc
*ksproc
= platform_get_drvdata(pdev
);
495 rproc_del(ksproc
->rproc
);
496 pm_runtime_put_sync(&pdev
->dev
);
497 pm_runtime_disable(&pdev
->dev
);
498 rproc_free(ksproc
->rproc
);
499 of_reserved_mem_device_release(&pdev
->dev
);
504 static const struct of_device_id keystone_rproc_of_match
[] = {
505 { .compatible
= "ti,k2hk-dsp", },
506 { .compatible
= "ti,k2l-dsp", },
507 { .compatible
= "ti,k2e-dsp", },
508 { .compatible
= "ti,k2g-dsp", },
511 MODULE_DEVICE_TABLE(of
, keystone_rproc_of_match
);
513 static struct platform_driver keystone_rproc_driver
= {
514 .probe
= keystone_rproc_probe
,
515 .remove
= keystone_rproc_remove
,
517 .name
= "keystone-rproc",
518 .of_match_table
= keystone_rproc_of_match
,
522 module_platform_driver(keystone_rproc_driver
);
524 MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
525 MODULE_LICENSE("GPL v2");
526 MODULE_DESCRIPTION("TI Keystone DSP Remoteproc driver");