Lines Matching +full:keystone +full:- +full:gpio

1 // SPDX-License-Identifier: GPL-2.0-only
3 * TI Keystone DSP remoteproc driver
5 * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
17 #include <linux/gpio/consumer.h>
25 #define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK (SZ_16M - 1)
28 * struct keystone_rproc_mem - internal memory structure
42 * struct keystone_rproc - keystone remote processor driver structure
52 * @kick_gpio: gpio used for virtio kicks
72 reset_control_assert(ksproc->reset); in keystone_rproc_dsp_reset()
80 if (boot_addr & (SZ_1K - 1)) { in keystone_rproc_dsp_boot()
81 dev_err(ksproc->dev, "invalid boot address 0x%x, must be aligned on a 1KB boundary\n", in keystone_rproc_dsp_boot()
83 return -EINVAL; in keystone_rproc_dsp_boot()
86 ret = regmap_write(ksproc->dev_ctrl, ksproc->boot_offset, boot_addr); in keystone_rproc_dsp_boot()
88 dev_err(ksproc->dev, "regmap_write of boot address failed, status = %d\n", in keystone_rproc_dsp_boot()
93 reset_control_deassert(ksproc->reset); in keystone_rproc_dsp_boot()
101 * The exception reporting on Keystone DSP remote processors is very simple
103 * through a software-designed specific interrupt source in the IPC interrupt
113 rproc_report_crash(ksproc->rproc, RPROC_FATAL_ERROR); in keystone_rproc_exception_interrupt()
121 * This function is executed upon scheduling of the keystone remoteproc
125 * case with mailbox-based implementations on OMAP family. As such, this
146 rproc_vq_interrupt(ksproc->rproc, 0); in handle_event()
147 rproc_vq_interrupt(ksproc->rproc, 1); in handle_event()
157 schedule_work(&ksproc->workqueue); in keystone_rproc_vring_interrupt()
171 struct keystone_rproc *ksproc = rproc->priv; in keystone_rproc_start()
174 INIT_WORK(&ksproc->workqueue, handle_event); in keystone_rproc_start()
176 ret = request_irq(ksproc->irq_ring, keystone_rproc_vring_interrupt, 0, in keystone_rproc_start()
177 dev_name(ksproc->dev), ksproc); in keystone_rproc_start()
179 dev_err(ksproc->dev, "failed to enable vring interrupt, ret = %d\n", in keystone_rproc_start()
184 ret = request_irq(ksproc->irq_fault, keystone_rproc_exception_interrupt, in keystone_rproc_start()
185 0, dev_name(ksproc->dev), ksproc); in keystone_rproc_start()
187 dev_err(ksproc->dev, "failed to enable exception interrupt, ret = %d\n", in keystone_rproc_start()
192 ret = keystone_rproc_dsp_boot(ksproc, rproc->bootaddr); in keystone_rproc_start()
199 free_irq(ksproc->irq_fault, ksproc); in keystone_rproc_start()
201 free_irq(ksproc->irq_ring, ksproc); in keystone_rproc_start()
202 flush_work(&ksproc->workqueue); in keystone_rproc_start()
215 struct keystone_rproc *ksproc = rproc->priv; in keystone_rproc_stop()
218 free_irq(ksproc->irq_fault, ksproc); in keystone_rproc_stop()
219 free_irq(ksproc->irq_ring, ksproc); in keystone_rproc_stop()
220 flush_work(&ksproc->workqueue); in keystone_rproc_stop()
228 * through a simulated GPIO (a bit in an IPC interrupt-triggering register),
233 struct keystone_rproc *ksproc = rproc->priv; in keystone_rproc_kick()
235 if (!ksproc->kick_gpio) in keystone_rproc_kick()
238 gpiod_set_value(ksproc->kick_gpio, 1); in keystone_rproc_kick()
244 * address visible only from a DSP, or at the SoC-level bus address. Both these
251 struct keystone_rproc *ksproc = rproc->priv; in keystone_rproc_da_to_va()
261 for (i = 0; i < ksproc->num_mems; i++) { in keystone_rproc_da_to_va()
262 bus_addr = ksproc->mem[i].bus_addr; in keystone_rproc_da_to_va()
263 dev_addr = ksproc->mem[i].dev_addr; in keystone_rproc_da_to_va()
264 size = ksproc->mem[i].size; in keystone_rproc_da_to_va()
267 /* handle DSP-view addresses */ in keystone_rproc_da_to_va()
270 offset = da - dev_addr; in keystone_rproc_da_to_va()
271 va = ksproc->mem[i].cpu_addr + offset; in keystone_rproc_da_to_va()
275 /* handle SoC-view addresses */ in keystone_rproc_da_to_va()
278 offset = da - bus_addr; in keystone_rproc_da_to_va()
279 va = ksproc->mem[i].cpu_addr + offset; in keystone_rproc_da_to_va()
299 struct device *dev = &pdev->dev; in keystone_rproc_of_get_memories()
305 ksproc->mem = devm_kcalloc(ksproc->dev, num_mems, in keystone_rproc_of_get_memories()
306 sizeof(*ksproc->mem), GFP_KERNEL); in keystone_rproc_of_get_memories()
307 if (!ksproc->mem) in keystone_rproc_of_get_memories()
308 return -ENOMEM; in keystone_rproc_of_get_memories()
313 ksproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res); in keystone_rproc_of_get_memories()
314 if (IS_ERR(ksproc->mem[i].cpu_addr)) { in keystone_rproc_of_get_memories()
317 return PTR_ERR(ksproc->mem[i].cpu_addr); in keystone_rproc_of_get_memories()
319 ksproc->mem[i].bus_addr = res->start; in keystone_rproc_of_get_memories()
320 ksproc->mem[i].dev_addr = in keystone_rproc_of_get_memories()
321 res->start & KEYSTONE_RPROC_LOCAL_ADDRESS_MASK; in keystone_rproc_of_get_memories()
322 ksproc->mem[i].size = resource_size(res); in keystone_rproc_of_get_memories()
325 memset((__force void *)ksproc->mem[i].cpu_addr, 0, in keystone_rproc_of_get_memories()
326 ksproc->mem[i].size); in keystone_rproc_of_get_memories()
328 ksproc->num_mems = num_mems; in keystone_rproc_of_get_memories()
336 struct device_node *np = pdev->dev.of_node; in keystone_rproc_of_get_dev_syscon()
337 struct device *dev = &pdev->dev; in keystone_rproc_of_get_dev_syscon()
339 if (!of_property_read_bool(np, "ti,syscon-dev")) { in keystone_rproc_of_get_dev_syscon()
340 dev_err(dev, "ti,syscon-dev property is absent\n"); in keystone_rproc_of_get_dev_syscon()
341 return -EINVAL; in keystone_rproc_of_get_dev_syscon()
344 ksproc->dev_ctrl = syscon_regmap_lookup_by_phandle_args(np, "ti,syscon-dev", in keystone_rproc_of_get_dev_syscon()
345 1, &ksproc->boot_offset); in keystone_rproc_of_get_dev_syscon()
346 if (IS_ERR(ksproc->dev_ctrl)) in keystone_rproc_of_get_dev_syscon()
347 return PTR_ERR(ksproc->dev_ctrl); in keystone_rproc_of_get_dev_syscon()
354 struct device *dev = &pdev->dev; in keystone_rproc_probe()
355 struct device_node *np = dev->of_node; in keystone_rproc_probe()
363 dev_err(dev, "only DT-based devices are supported\n"); in keystone_rproc_probe()
364 return -ENODEV; in keystone_rproc_probe()
373 /* construct a custom default fw name - subject to change in future */ in keystone_rproc_probe()
374 fw_name = devm_kasprintf(dev, GFP_KERNEL, "keystone-dsp%d-fw", dsp_id); in keystone_rproc_probe()
376 return -ENOMEM; in keystone_rproc_probe()
381 return -ENOMEM; in keystone_rproc_probe()
383 rproc->has_iommu = false; in keystone_rproc_probe()
384 ksproc = rproc->priv; in keystone_rproc_probe()
385 ksproc->rproc = rproc; in keystone_rproc_probe()
386 ksproc->dev = dev; in keystone_rproc_probe()
392 ksproc->reset = devm_reset_control_get_exclusive(dev, NULL); in keystone_rproc_probe()
393 if (IS_ERR(ksproc->reset)) in keystone_rproc_probe()
394 return PTR_ERR(ksproc->reset); in keystone_rproc_probe()
408 ksproc->irq_ring = platform_get_irq_byname(pdev, "vring"); in keystone_rproc_probe()
409 if (ksproc->irq_ring < 0) { in keystone_rproc_probe()
410 ret = ksproc->irq_ring; in keystone_rproc_probe()
414 ksproc->irq_fault = platform_get_irq_byname(pdev, "exception"); in keystone_rproc_probe()
415 if (ksproc->irq_fault < 0) { in keystone_rproc_probe()
416 ret = ksproc->irq_fault; in keystone_rproc_probe()
420 ksproc->kick_gpio = gpiod_get(dev, "kick", GPIOD_ASIS); in keystone_rproc_probe()
421 ret = PTR_ERR_OR_ZERO(ksproc->kick_gpio); in keystone_rproc_probe()
423 dev_err(dev, "failed to get gpio for virtio kicks, status = %d\n", in keystone_rproc_probe()
432 ret = reset_control_status(ksproc->reset); in keystone_rproc_probe()
454 gpiod_put(ksproc->kick_gpio); in keystone_rproc_probe()
466 rproc_del(ksproc->rproc); in keystone_rproc_remove()
467 gpiod_put(ksproc->kick_gpio); in keystone_rproc_remove()
468 pm_runtime_put_sync(&pdev->dev); in keystone_rproc_remove()
469 pm_runtime_disable(&pdev->dev); in keystone_rproc_remove()
470 of_reserved_mem_device_release(&pdev->dev); in keystone_rproc_remove()
474 { .compatible = "ti,k2hk-dsp", },
475 { .compatible = "ti,k2l-dsp", },
476 { .compatible = "ti,k2e-dsp", },
477 { .compatible = "ti,k2g-dsp", },
486 .name = "keystone-rproc",
493 MODULE_AUTHOR("Suman Anna <s-[email protected]>");
495 MODULE_DESCRIPTION("TI Keystone DSP Remoteproc driver");