0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/slab.h>
0010 #include <linux/io.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/pm_runtime.h>
0014 #include <linux/workqueue.h>
0015 #include <linux/of_address.h>
0016 #include <linux/of_reserved_mem.h>
0017 #include <linux/of_gpio.h>
0018 #include <linux/regmap.h>
0019 #include <linux/mfd/syscon.h>
0020 #include <linux/remoteproc.h>
0021 #include <linux/reset.h>
0022
0023 #include "remoteproc_internal.h"
0024
0025 #define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK (SZ_16M - 1)
0026
0027
0028
0029
0030
0031
0032
0033
0034 struct keystone_rproc_mem {
0035 void __iomem *cpu_addr;
0036 phys_addr_t bus_addr;
0037 u32 dev_addr;
0038 size_t size;
0039 };
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 struct keystone_rproc {
0056 struct device *dev;
0057 struct rproc *rproc;
0058 struct keystone_rproc_mem *mem;
0059 int num_mems;
0060 struct regmap *dev_ctrl;
0061 struct reset_control *reset;
0062 u32 boot_offset;
0063 int irq_ring;
0064 int irq_fault;
0065 int kick_gpio;
0066 struct work_struct workqueue;
0067 };
0068
0069
0070 static void keystone_rproc_dsp_reset(struct keystone_rproc *ksproc)
0071 {
0072 reset_control_assert(ksproc->reset);
0073 }
0074
0075
0076 static int keystone_rproc_dsp_boot(struct keystone_rproc *ksproc, u32 boot_addr)
0077 {
0078 int ret;
0079
0080 if (boot_addr & (SZ_1K - 1)) {
0081 dev_err(ksproc->dev, "invalid boot address 0x%x, must be aligned on a 1KB boundary\n",
0082 boot_addr);
0083 return -EINVAL;
0084 }
0085
0086 ret = regmap_write(ksproc->dev_ctrl, ksproc->boot_offset, boot_addr);
0087 if (ret) {
0088 dev_err(ksproc->dev, "regmap_write of boot address failed, status = %d\n",
0089 ret);
0090 return ret;
0091 }
0092
0093 reset_control_deassert(ksproc->reset);
0094
0095 return 0;
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 static irqreturn_t keystone_rproc_exception_interrupt(int irq, void *dev_id)
0110 {
0111 struct keystone_rproc *ksproc = dev_id;
0112
0113 rproc_report_crash(ksproc->rproc, RPROC_FATAL_ERROR);
0114
0115 return IRQ_HANDLED;
0116 }
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 static void handle_event(struct work_struct *work)
0142 {
0143 struct keystone_rproc *ksproc =
0144 container_of(work, struct keystone_rproc, workqueue);
0145
0146 rproc_vq_interrupt(ksproc->rproc, 0);
0147 rproc_vq_interrupt(ksproc->rproc, 1);
0148 }
0149
0150
0151
0152
0153 static irqreturn_t keystone_rproc_vring_interrupt(int irq, void *dev_id)
0154 {
0155 struct keystone_rproc *ksproc = dev_id;
0156
0157 schedule_work(&ksproc->workqueue);
0158
0159 return IRQ_HANDLED;
0160 }
0161
0162
0163
0164
0165
0166
0167
0168
0169 static int keystone_rproc_start(struct rproc *rproc)
0170 {
0171 struct keystone_rproc *ksproc = rproc->priv;
0172 int ret;
0173
0174 INIT_WORK(&ksproc->workqueue, handle_event);
0175
0176 ret = request_irq(ksproc->irq_ring, keystone_rproc_vring_interrupt, 0,
0177 dev_name(ksproc->dev), ksproc);
0178 if (ret) {
0179 dev_err(ksproc->dev, "failed to enable vring interrupt, ret = %d\n",
0180 ret);
0181 goto out;
0182 }
0183
0184 ret = request_irq(ksproc->irq_fault, keystone_rproc_exception_interrupt,
0185 0, dev_name(ksproc->dev), ksproc);
0186 if (ret) {
0187 dev_err(ksproc->dev, "failed to enable exception interrupt, ret = %d\n",
0188 ret);
0189 goto free_vring_irq;
0190 }
0191
0192 ret = keystone_rproc_dsp_boot(ksproc, rproc->bootaddr);
0193 if (ret)
0194 goto free_exc_irq;
0195
0196 return 0;
0197
0198 free_exc_irq:
0199 free_irq(ksproc->irq_fault, ksproc);
0200 free_vring_irq:
0201 free_irq(ksproc->irq_ring, ksproc);
0202 flush_work(&ksproc->workqueue);
0203 out:
0204 return ret;
0205 }
0206
0207
0208
0209
0210
0211
0212
0213 static int keystone_rproc_stop(struct rproc *rproc)
0214 {
0215 struct keystone_rproc *ksproc = rproc->priv;
0216
0217 keystone_rproc_dsp_reset(ksproc);
0218 free_irq(ksproc->irq_fault, ksproc);
0219 free_irq(ksproc->irq_ring, ksproc);
0220 flush_work(&ksproc->workqueue);
0221
0222 return 0;
0223 }
0224
0225
0226
0227
0228
0229
0230
0231 static void keystone_rproc_kick(struct rproc *rproc, int vqid)
0232 {
0233 struct keystone_rproc *ksproc = rproc->priv;
0234
0235 if (WARN_ON(ksproc->kick_gpio < 0))
0236 return;
0237
0238 gpio_set_value(ksproc->kick_gpio, 1);
0239 }
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 static void *keystone_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
0250 {
0251 struct keystone_rproc *ksproc = rproc->priv;
0252 void __iomem *va = NULL;
0253 phys_addr_t bus_addr;
0254 u32 dev_addr, offset;
0255 size_t size;
0256 int i;
0257
0258 if (len == 0)
0259 return NULL;
0260
0261 for (i = 0; i < ksproc->num_mems; i++) {
0262 bus_addr = ksproc->mem[i].bus_addr;
0263 dev_addr = ksproc->mem[i].dev_addr;
0264 size = ksproc->mem[i].size;
0265
0266 if (da < KEYSTONE_RPROC_LOCAL_ADDRESS_MASK) {
0267
0268 if ((da >= dev_addr) &&
0269 ((da + len) <= (dev_addr + size))) {
0270 offset = da - dev_addr;
0271 va = ksproc->mem[i].cpu_addr + offset;
0272 break;
0273 }
0274 } else {
0275
0276 if ((da >= bus_addr) &&
0277 (da + len) <= (bus_addr + size)) {
0278 offset = da - bus_addr;
0279 va = ksproc->mem[i].cpu_addr + offset;
0280 break;
0281 }
0282 }
0283 }
0284
0285 return (__force void *)va;
0286 }
0287
0288 static const struct rproc_ops keystone_rproc_ops = {
0289 .start = keystone_rproc_start,
0290 .stop = keystone_rproc_stop,
0291 .kick = keystone_rproc_kick,
0292 .da_to_va = keystone_rproc_da_to_va,
0293 };
0294
0295 static int keystone_rproc_of_get_memories(struct platform_device *pdev,
0296 struct keystone_rproc *ksproc)
0297 {
0298 static const char * const mem_names[] = {"l2sram", "l1pram", "l1dram"};
0299 struct device *dev = &pdev->dev;
0300 struct resource *res;
0301 int num_mems = 0;
0302 int i;
0303
0304 num_mems = ARRAY_SIZE(mem_names);
0305 ksproc->mem = devm_kcalloc(ksproc->dev, num_mems,
0306 sizeof(*ksproc->mem), GFP_KERNEL);
0307 if (!ksproc->mem)
0308 return -ENOMEM;
0309
0310 for (i = 0; i < num_mems; i++) {
0311 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
0312 mem_names[i]);
0313 ksproc->mem[i].cpu_addr = devm_ioremap_resource(dev, res);
0314 if (IS_ERR(ksproc->mem[i].cpu_addr)) {
0315 dev_err(dev, "failed to parse and map %s memory\n",
0316 mem_names[i]);
0317 return PTR_ERR(ksproc->mem[i].cpu_addr);
0318 }
0319 ksproc->mem[i].bus_addr = res->start;
0320 ksproc->mem[i].dev_addr =
0321 res->start & KEYSTONE_RPROC_LOCAL_ADDRESS_MASK;
0322 ksproc->mem[i].size = resource_size(res);
0323
0324
0325 memset((__force void *)ksproc->mem[i].cpu_addr, 0,
0326 ksproc->mem[i].size);
0327 }
0328 ksproc->num_mems = num_mems;
0329
0330 return 0;
0331 }
0332
0333 static int keystone_rproc_of_get_dev_syscon(struct platform_device *pdev,
0334 struct keystone_rproc *ksproc)
0335 {
0336 struct device_node *np = pdev->dev.of_node;
0337 struct device *dev = &pdev->dev;
0338 int ret;
0339
0340 if (!of_property_read_bool(np, "ti,syscon-dev")) {
0341 dev_err(dev, "ti,syscon-dev property is absent\n");
0342 return -EINVAL;
0343 }
0344
0345 ksproc->dev_ctrl =
0346 syscon_regmap_lookup_by_phandle(np, "ti,syscon-dev");
0347 if (IS_ERR(ksproc->dev_ctrl)) {
0348 ret = PTR_ERR(ksproc->dev_ctrl);
0349 return ret;
0350 }
0351
0352 if (of_property_read_u32_index(np, "ti,syscon-dev", 1,
0353 &ksproc->boot_offset)) {
0354 dev_err(dev, "couldn't read the boot register offset\n");
0355 return -EINVAL;
0356 }
0357
0358 return 0;
0359 }
0360
0361 static int keystone_rproc_probe(struct platform_device *pdev)
0362 {
0363 struct device *dev = &pdev->dev;
0364 struct device_node *np = dev->of_node;
0365 struct keystone_rproc *ksproc;
0366 struct rproc *rproc;
0367 int dsp_id;
0368 char *fw_name = NULL;
0369 char *template = "keystone-dsp%d-fw";
0370 int name_len = 0;
0371 int ret = 0;
0372
0373 if (!np) {
0374 dev_err(dev, "only DT-based devices are supported\n");
0375 return -ENODEV;
0376 }
0377
0378 dsp_id = of_alias_get_id(np, "rproc");
0379 if (dsp_id < 0) {
0380 dev_warn(dev, "device does not have an alias id\n");
0381 return dsp_id;
0382 }
0383
0384
0385 name_len = strlen(template);
0386 fw_name = devm_kzalloc(dev, name_len, GFP_KERNEL);
0387 if (!fw_name)
0388 return -ENOMEM;
0389 snprintf(fw_name, name_len, template, dsp_id);
0390
0391 rproc = rproc_alloc(dev, dev_name(dev), &keystone_rproc_ops, fw_name,
0392 sizeof(*ksproc));
0393 if (!rproc)
0394 return -ENOMEM;
0395
0396 rproc->has_iommu = false;
0397 ksproc = rproc->priv;
0398 ksproc->rproc = rproc;
0399 ksproc->dev = dev;
0400
0401 ret = keystone_rproc_of_get_dev_syscon(pdev, ksproc);
0402 if (ret)
0403 goto free_rproc;
0404
0405 ksproc->reset = devm_reset_control_get_exclusive(dev, NULL);
0406 if (IS_ERR(ksproc->reset)) {
0407 ret = PTR_ERR(ksproc->reset);
0408 goto free_rproc;
0409 }
0410
0411
0412 pm_runtime_enable(dev);
0413 ret = pm_runtime_resume_and_get(dev);
0414 if (ret < 0) {
0415 dev_err(dev, "failed to enable clock, status = %d\n", ret);
0416 goto disable_rpm;
0417 }
0418
0419 ret = keystone_rproc_of_get_memories(pdev, ksproc);
0420 if (ret)
0421 goto disable_clk;
0422
0423 ksproc->irq_ring = platform_get_irq_byname(pdev, "vring");
0424 if (ksproc->irq_ring < 0) {
0425 ret = ksproc->irq_ring;
0426 goto disable_clk;
0427 }
0428
0429 ksproc->irq_fault = platform_get_irq_byname(pdev, "exception");
0430 if (ksproc->irq_fault < 0) {
0431 ret = ksproc->irq_fault;
0432 goto disable_clk;
0433 }
0434
0435 ksproc->kick_gpio = of_get_named_gpio_flags(np, "kick-gpios", 0, NULL);
0436 if (ksproc->kick_gpio < 0) {
0437 ret = ksproc->kick_gpio;
0438 dev_err(dev, "failed to get gpio for virtio kicks, status = %d\n",
0439 ret);
0440 goto disable_clk;
0441 }
0442
0443 if (of_reserved_mem_device_init(dev))
0444 dev_warn(dev, "device does not have specific CMA pool\n");
0445
0446
0447 ret = reset_control_status(ksproc->reset);
0448 if (ret < 0) {
0449 dev_err(dev, "failed to get reset status, status = %d\n", ret);
0450 goto release_mem;
0451 } else if (ret == 0) {
0452 WARN(1, "device is not in reset\n");
0453 keystone_rproc_dsp_reset(ksproc);
0454 }
0455
0456 ret = rproc_add(rproc);
0457 if (ret) {
0458 dev_err(dev, "failed to add register device with remoteproc core, status = %d\n",
0459 ret);
0460 goto release_mem;
0461 }
0462
0463 platform_set_drvdata(pdev, ksproc);
0464
0465 return 0;
0466
0467 release_mem:
0468 of_reserved_mem_device_release(dev);
0469 disable_clk:
0470 pm_runtime_put_sync(dev);
0471 disable_rpm:
0472 pm_runtime_disable(dev);
0473 free_rproc:
0474 rproc_free(rproc);
0475 return ret;
0476 }
0477
0478 static int keystone_rproc_remove(struct platform_device *pdev)
0479 {
0480 struct keystone_rproc *ksproc = platform_get_drvdata(pdev);
0481
0482 rproc_del(ksproc->rproc);
0483 pm_runtime_put_sync(&pdev->dev);
0484 pm_runtime_disable(&pdev->dev);
0485 rproc_free(ksproc->rproc);
0486 of_reserved_mem_device_release(&pdev->dev);
0487
0488 return 0;
0489 }
0490
0491 static const struct of_device_id keystone_rproc_of_match[] = {
0492 { .compatible = "ti,k2hk-dsp", },
0493 { .compatible = "ti,k2l-dsp", },
0494 { .compatible = "ti,k2e-dsp", },
0495 { .compatible = "ti,k2g-dsp", },
0496 { },
0497 };
0498 MODULE_DEVICE_TABLE(of, keystone_rproc_of_match);
0499
0500 static struct platform_driver keystone_rproc_driver = {
0501 .probe = keystone_rproc_probe,
0502 .remove = keystone_rproc_remove,
0503 .driver = {
0504 .name = "keystone-rproc",
0505 .of_match_table = keystone_rproc_of_match,
0506 },
0507 };
0508
0509 module_platform_driver(keystone_rproc_driver);
0510
0511 MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
0512 MODULE_LICENSE("GPL v2");
0513 MODULE_DESCRIPTION("TI Keystone DSP Remoteproc driver");