• Home
  • Raw
  • Download

Lines Matching +full:dsp +full:- +full:gpio

2  * TI Keystone DSP remoteproc driver
4 * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
33 #define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK (SZ_16M - 1)
36 * struct keystone_rproc_mem - internal memory structure
39 * @dev_addr: Device address of the memory region from DSP view
50 * struct keystone_rproc - keystone remote processor driver structure
60 * @kick_gpio: gpio used for virtio kicks
77 /* Put the DSP processor into reset */
80 reset_control_assert(ksproc->reset); in keystone_rproc_dsp_reset()
83 /* Configure the boot address and boot the DSP processor */
88 if (boot_addr & (SZ_1K - 1)) { in keystone_rproc_dsp_boot()
89 dev_err(ksproc->dev, "invalid boot address 0x%x, must be aligned on a 1KB boundary\n", in keystone_rproc_dsp_boot()
91 return -EINVAL; in keystone_rproc_dsp_boot()
94 ret = regmap_write(ksproc->dev_ctrl, ksproc->boot_offset, boot_addr); in keystone_rproc_dsp_boot()
96 dev_err(ksproc->dev, "regmap_write of boot address failed, status = %d\n", in keystone_rproc_dsp_boot()
101 reset_control_deassert(ksproc->reset); in keystone_rproc_dsp_boot()
109 * The exception reporting on Keystone DSP remote processors is very simple
111 * through a software-designed specific interrupt source in the IPC interrupt
121 rproc_report_crash(ksproc->rproc, RPROC_FATAL_ERROR); in keystone_rproc_exception_interrupt()
133 * case with mailbox-based implementations on OMAP family. As such, this
154 rproc_vq_interrupt(ksproc->rproc, 0); in handle_event()
155 rproc_vq_interrupt(ksproc->rproc, 1); in handle_event()
165 schedule_work(&ksproc->workqueue); in keystone_rproc_vring_interrupt()
171 * Power up the DSP remote processor.
179 struct keystone_rproc *ksproc = rproc->priv; in keystone_rproc_start()
182 INIT_WORK(&ksproc->workqueue, handle_event); in keystone_rproc_start()
184 ret = request_irq(ksproc->irq_ring, keystone_rproc_vring_interrupt, 0, in keystone_rproc_start()
185 dev_name(ksproc->dev), ksproc); in keystone_rproc_start()
187 dev_err(ksproc->dev, "failed to enable vring interrupt, ret = %d\n", in keystone_rproc_start()
192 ret = request_irq(ksproc->irq_fault, keystone_rproc_exception_interrupt, in keystone_rproc_start()
193 0, dev_name(ksproc->dev), ksproc); in keystone_rproc_start()
195 dev_err(ksproc->dev, "failed to enable exception interrupt, ret = %d\n", in keystone_rproc_start()
200 ret = keystone_rproc_dsp_boot(ksproc, rproc->bootaddr); in keystone_rproc_start()
207 free_irq(ksproc->irq_fault, ksproc); in keystone_rproc_start()
209 free_irq(ksproc->irq_ring, ksproc); in keystone_rproc_start()
210 flush_work(&ksproc->workqueue); in keystone_rproc_start()
216 * Stop the DSP remote processor.
218 * This function puts the DSP processor into reset, and finishes processing
223 struct keystone_rproc *ksproc = rproc->priv; in keystone_rproc_stop()
226 free_irq(ksproc->irq_fault, ksproc); in keystone_rproc_stop()
227 free_irq(ksproc->irq_ring, ksproc); in keystone_rproc_stop()
228 flush_work(&ksproc->workqueue); in keystone_rproc_stop()
236 * through a simulated GPIO (a bit in an IPC interrupt-triggering register),
241 struct keystone_rproc *ksproc = rproc->priv; in keystone_rproc_kick()
243 if (WARN_ON(ksproc->kick_gpio < 0)) in keystone_rproc_kick()
246 gpio_set_value(ksproc->kick_gpio, 1); in keystone_rproc_kick()
250 * Custom function to translate a DSP device address (internal RAMs only) to a
252 * address visible only from a DSP, or at the SoC-level bus address. Both these
259 struct keystone_rproc *ksproc = rproc->priv; in keystone_rproc_da_to_va()
269 for (i = 0; i < ksproc->num_mems; i++) { in keystone_rproc_da_to_va()
270 bus_addr = ksproc->mem[i].bus_addr; in keystone_rproc_da_to_va()
271 dev_addr = ksproc->mem[i].dev_addr; in keystone_rproc_da_to_va()
272 size = ksproc->mem[i].size; in keystone_rproc_da_to_va()
275 /* handle DSP-view addresses */ in keystone_rproc_da_to_va()
278 offset = da - dev_addr; in keystone_rproc_da_to_va()
279 va = ksproc->mem[i].cpu_addr + offset; in keystone_rproc_da_to_va()
283 /* handle SoC-view addresses */ in keystone_rproc_da_to_va()
286 offset = da - bus_addr; in keystone_rproc_da_to_va()
287 va = ksproc->mem[i].cpu_addr + offset; in keystone_rproc_da_to_va()
307 struct device *dev = &pdev->dev; in keystone_rproc_of_get_memories()
313 ksproc->mem = devm_kcalloc(ksproc->dev, num_mems, in keystone_rproc_of_get_memories()
314 sizeof(*ksproc->mem), GFP_KERNEL); in keystone_rproc_of_get_memories()
315 if (!ksproc->mem) in keystone_rproc_of_get_memories()
316 return -ENOMEM; in keystone_rproc_of_get_memories()
321 ksproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res); in keystone_rproc_of_get_memories()
322 if (IS_ERR(ksproc->mem[i].cpu_addr)) { in keystone_rproc_of_get_memories()
325 return PTR_ERR(ksproc->mem[i].cpu_addr); in keystone_rproc_of_get_memories()
327 ksproc->mem[i].bus_addr = res->start; in keystone_rproc_of_get_memories()
328 ksproc->mem[i].dev_addr = in keystone_rproc_of_get_memories()
329 res->start & KEYSTONE_RPROC_LOCAL_ADDRESS_MASK; in keystone_rproc_of_get_memories()
330 ksproc->mem[i].size = resource_size(res); in keystone_rproc_of_get_memories()
333 memset((__force void *)ksproc->mem[i].cpu_addr, 0, in keystone_rproc_of_get_memories()
334 ksproc->mem[i].size); in keystone_rproc_of_get_memories()
336 ksproc->num_mems = num_mems; in keystone_rproc_of_get_memories()
344 struct device_node *np = pdev->dev.of_node; in keystone_rproc_of_get_dev_syscon()
345 struct device *dev = &pdev->dev; in keystone_rproc_of_get_dev_syscon()
348 if (!of_property_read_bool(np, "ti,syscon-dev")) { in keystone_rproc_of_get_dev_syscon()
349 dev_err(dev, "ti,syscon-dev property is absent\n"); in keystone_rproc_of_get_dev_syscon()
350 return -EINVAL; in keystone_rproc_of_get_dev_syscon()
353 ksproc->dev_ctrl = in keystone_rproc_of_get_dev_syscon()
354 syscon_regmap_lookup_by_phandle(np, "ti,syscon-dev"); in keystone_rproc_of_get_dev_syscon()
355 if (IS_ERR(ksproc->dev_ctrl)) { in keystone_rproc_of_get_dev_syscon()
356 ret = PTR_ERR(ksproc->dev_ctrl); in keystone_rproc_of_get_dev_syscon()
360 if (of_property_read_u32_index(np, "ti,syscon-dev", 1, in keystone_rproc_of_get_dev_syscon()
361 &ksproc->boot_offset)) { in keystone_rproc_of_get_dev_syscon()
363 return -EINVAL; in keystone_rproc_of_get_dev_syscon()
371 struct device *dev = &pdev->dev; in keystone_rproc_probe()
372 struct device_node *np = dev->of_node; in keystone_rproc_probe()
377 char *template = "keystone-dsp%d-fw"; in keystone_rproc_probe()
382 dev_err(dev, "only DT-based devices are supported\n"); in keystone_rproc_probe()
383 return -ENODEV; in keystone_rproc_probe()
392 /* construct a custom default fw name - subject to change in future */ in keystone_rproc_probe()
396 return -ENOMEM; in keystone_rproc_probe()
402 return -ENOMEM; in keystone_rproc_probe()
404 rproc->has_iommu = false; in keystone_rproc_probe()
405 ksproc = rproc->priv; in keystone_rproc_probe()
406 ksproc->rproc = rproc; in keystone_rproc_probe()
407 ksproc->dev = dev; in keystone_rproc_probe()
413 ksproc->reset = devm_reset_control_get_exclusive(dev, NULL); in keystone_rproc_probe()
414 if (IS_ERR(ksproc->reset)) { in keystone_rproc_probe()
415 ret = PTR_ERR(ksproc->reset); in keystone_rproc_probe()
419 /* enable clock for accessing DSP internal memories */ in keystone_rproc_probe()
432 ksproc->irq_ring = platform_get_irq_byname(pdev, "vring"); in keystone_rproc_probe()
433 if (ksproc->irq_ring < 0) { in keystone_rproc_probe()
434 ret = ksproc->irq_ring; in keystone_rproc_probe()
440 ksproc->irq_fault = platform_get_irq_byname(pdev, "exception"); in keystone_rproc_probe()
441 if (ksproc->irq_fault < 0) { in keystone_rproc_probe()
442 ret = ksproc->irq_fault; in keystone_rproc_probe()
448 ksproc->kick_gpio = of_get_named_gpio_flags(np, "kick-gpios", 0, NULL); in keystone_rproc_probe()
449 if (ksproc->kick_gpio < 0) { in keystone_rproc_probe()
450 ret = ksproc->kick_gpio; in keystone_rproc_probe()
451 dev_err(dev, "failed to get gpio for virtio kicks, status = %d\n", in keystone_rproc_probe()
459 /* ensure the DSP is in reset before loading firmware */ in keystone_rproc_probe()
460 ret = reset_control_status(ksproc->reset); in keystone_rproc_probe()
495 rproc_del(ksproc->rproc); in keystone_rproc_remove()
496 pm_runtime_put_sync(&pdev->dev); in keystone_rproc_remove()
497 pm_runtime_disable(&pdev->dev); in keystone_rproc_remove()
498 rproc_free(ksproc->rproc); in keystone_rproc_remove()
499 of_reserved_mem_device_release(&pdev->dev); in keystone_rproc_remove()
505 { .compatible = "ti,k2hk-dsp", },
506 { .compatible = "ti,k2l-dsp", },
507 { .compatible = "ti,k2e-dsp", },
508 { .compatible = "ti,k2g-dsp", },
517 .name = "keystone-rproc",
524 MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
526 MODULE_DESCRIPTION("TI Keystone DSP Remoteproc driver");