1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h>
19#include <linux/remoteproc.h>
20#include <linux/interrupt.h>
21#include <linux/of_address.h>
22#include <linux/of_irq.h>
23#include <linux/of_reserved_mem.h>
24#include <linux/smp.h>
25#include <linux/irqchip/arm-gic.h>
26#include <asm/outercache.h>
27#include <linux/slab.h>
28#include <linux/cpu.h>
29#include <linux/genalloc.h>
30#include <../../arch/arm/mach-zynq/common.h>
31
32#include "remoteproc_internal.h"
33
34#define MAX_NUM_VRINGS 2
35#define NOTIFYID_ANY (-1)
36
37#define MAX_ON_CHIP_MEMS 32
38
39
40struct irq_list {
41 int irq;
42 struct list_head list;
43};
44
45
46struct ipi_info {
47 u32 irq;
48 u32 notifyid;
49 bool pending;
50};
51
52
53
54
55
56
57struct zynq_mem_res {
58 struct resource res;
59 struct list_head node;
60};
61
62
63
64
65
66
67
68
69struct zynq_rproc_pdata {
70 struct irq_list irqs;
71 struct rproc *rproc;
72 struct ipi_info ipis[MAX_NUM_VRINGS];
73 struct list_head fw_mems;
74};
75
76static bool autoboot __read_mostly;
77
78
79static struct rproc *rproc;
80static struct work_struct workqueue;
81
82static void handle_event(struct work_struct *work)
83{
84 struct zynq_rproc_pdata *local = rproc->priv;
85
86 if (rproc_vq_interrupt(local->rproc, local->ipis[0].notifyid) ==
87 IRQ_NONE)
88 dev_dbg(rproc->dev.parent, "no message found in vqid 0\n");
89}
90
91static void ipi_kick(void)
92{
93 dev_dbg(rproc->dev.parent, "KICK Linux because of pending message\n");
94 schedule_work(&workqueue);
95}
96
97static void kick_pending_ipi(struct rproc *rproc)
98{
99 struct zynq_rproc_pdata *local = rproc->priv;
100 int i;
101
102 for (i = 0; i < MAX_NUM_VRINGS; i++) {
103
104 if (local->ipis[i].pending) {
105 gic_raise_softirq(cpumask_of(1),
106 local->ipis[i].irq);
107 local->ipis[i].pending = false;
108 }
109 }
110}
111
112static int zynq_rproc_start(struct rproc *rproc)
113{
114 struct device *dev = rproc->dev.parent;
115 int ret;
116
117 dev_dbg(dev, "%s\n", __func__);
118 INIT_WORK(&workqueue, handle_event);
119
120 ret = cpu_down(1);
121
122 if (ret && (ret != -EBUSY)) {
123 dev_err(dev, "Can't release cpu1\n");
124 return ret;
125 }
126
127 ret = zynq_cpun_start(rproc->bootaddr, 1);
128
129 kick_pending_ipi(rproc);
130
131 return ret;
132}
133
134
135static void zynq_rproc_kick(struct rproc *rproc, int vqid)
136{
137 struct device *dev = rproc->dev.parent;
138 struct zynq_rproc_pdata *local = rproc->priv;
139 struct rproc_vdev *rvdev, *rvtmp;
140 int i;
141
142 dev_dbg(dev, "KICK Firmware to start send messages vqid %d\n", vqid);
143
144 list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) {
145 for (i = 0; i < MAX_NUM_VRINGS; i++) {
146 struct rproc_vring *rvring = &rvdev->vring[i];
147
148
149 if (rvring->notifyid == vqid) {
150 local->ipis[i].notifyid = vqid;
151
152
153
154 if (rproc->state == RPROC_RUNNING)
155 gic_raise_softirq(cpumask_of(1),
156 local->ipis[i].irq);
157 else
158 local->ipis[i].pending = true;
159 }
160 }
161 }
162}
163
164
165static int zynq_rproc_stop(struct rproc *rproc)
166{
167 int ret;
168 struct device *dev = rproc->dev.parent;
169
170 dev_dbg(rproc->dev.parent, "%s\n", __func__);
171
172
173 ret = cpu_up(1);
174 if (ret)
175 dev_err(dev, "Can't power on cpu1 %d\n", ret);
176
177 return 0;
178}
179
180static int zynq_parse_fw(struct rproc *rproc, const struct firmware *fw)
181{
182 int num_mems, i, ret;
183 struct device *dev = rproc->dev.parent;
184 struct device_node *np = dev->of_node;
185 struct rproc_mem_entry *mem;
186
187 num_mems = of_count_phandle_with_args(np, "memory-region", NULL);
188 if (num_mems <= 0)
189 return 0;
190 for (i = 0; i < num_mems; i++) {
191 struct device_node *node;
192 struct reserved_mem *rmem;
193
194 node = of_parse_phandle(np, "memory-region", i);
195 rmem = of_reserved_mem_lookup(node);
196 if (!rmem) {
197 dev_err(dev, "unable to acquire memory-region\n");
198 return -EINVAL;
199 }
200 if (strstr(node->name, "vdev") &&
201 strstr(node->name, "buffer")) {
202
203 mem = rproc_mem_entry_init(dev, NULL,
204 (dma_addr_t)rmem->base,
205 rmem->size, rmem->base,
206 NULL, NULL,
207 node->name);
208 if (!mem) {
209 dev_err(dev,
210 "unable to initialize memory-region %s \n",
211 node->name);
212 return -ENOMEM;
213 }
214 rproc_add_carveout(rproc, mem);
215 } else if (strstr(node->name, "vdev") &&
216 strstr(node->name, "vring")) {
217
218 mem = rproc_mem_entry_init(dev, NULL,
219 (dma_addr_t)rmem->base,
220 rmem->size, rmem->base,
221 NULL, NULL,
222 node->name);
223 mem->va = devm_ioremap_wc(dev, rmem->base, rmem->size);
224 if (!mem->va)
225 return -ENOMEM;
226 if (!mem) {
227 dev_err(dev,
228 "unable to initialize memory-region %s\n",
229 node->name);
230 return -ENOMEM;
231 }
232 rproc_add_carveout(rproc, mem);
233 } else {
234 mem = rproc_of_resm_mem_entry_init(dev, i,
235 rmem->size,
236 rmem->base,
237 node->name);
238 if (!mem) {
239 dev_err(dev,
240 "unable to initialize memory-region %s \n",
241 node->name);
242 return -ENOMEM;
243 }
244 mem->va = devm_ioremap_wc(dev, rmem->base, rmem->size);
245 if (!mem->va)
246 return -ENOMEM;
247
248 rproc_add_carveout(rproc, mem);
249 }
250 }
251
252 ret = rproc_elf_load_rsc_table(rproc, fw);
253 if (ret == -EINVAL)
254 ret = 0;
255 return ret;
256}
257
258static struct rproc_ops zynq_rproc_ops = {
259 .start = zynq_rproc_start,
260 .stop = zynq_rproc_stop,
261 .load = rproc_elf_load_segments,
262 .parse_fw = zynq_parse_fw,
263 .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
264 .get_boot_addr = rproc_elf_get_boot_addr,
265 .kick = zynq_rproc_kick,
266};
267
268
269static irqreturn_t zynq_remoteproc_interrupt(int irq, void *dev_id)
270{
271 struct device *dev = dev_id;
272
273 dev_err(dev, "GIC IRQ %d is not forwarded correctly\n", irq);
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 gic_set_cpu(1, irq);
289 return IRQ_HANDLED;
290}
291
292static void clear_irq(struct rproc *rproc)
293{
294 struct list_head *pos, *q;
295 struct irq_list *tmp;
296 struct zynq_rproc_pdata *local = rproc->priv;
297
298 dev_info(rproc->dev.parent, "Deleting the irq_list\n");
299 list_for_each_safe(pos, q, &local->irqs.list) {
300 tmp = list_entry(pos, struct irq_list, list);
301 free_irq(tmp->irq, rproc->dev.parent);
302 gic_set_cpu(0, tmp->irq);
303 list_del(pos);
304 kfree(tmp);
305 }
306}
307
308static int zynq_remoteproc_probe(struct platform_device *pdev)
309{
310 int ret = 0;
311 struct irq_list *tmp;
312 int count = 0;
313 struct zynq_rproc_pdata *local;
314
315 rproc = rproc_alloc(&pdev->dev, dev_name(&pdev->dev),
316 &zynq_rproc_ops, NULL,
317 sizeof(struct zynq_rproc_pdata));
318 if (!rproc) {
319 dev_err(&pdev->dev, "rproc allocation failed\n");
320 ret = -ENOMEM;
321 return ret;
322 }
323 local = rproc->priv;
324 local->rproc = rproc;
325
326 platform_set_drvdata(pdev, rproc);
327
328 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
329 if (ret) {
330 dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret);
331 goto dma_mask_fault;
332 }
333
334
335 INIT_LIST_HEAD(&local->irqs.list);
336
337
338 while (1) {
339 int irq;
340
341 irq = platform_get_irq(pdev, count++);
342 if (irq == -ENXIO || irq == -EINVAL)
343 break;
344
345 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
346 if (!tmp) {
347 ret = -ENOMEM;
348 goto irq_fault;
349 }
350
351 tmp->irq = irq;
352
353 dev_dbg(&pdev->dev, "%d: Alloc irq: %d\n", count, tmp->irq);
354
355
356
357
358 ret = request_irq(tmp->irq, zynq_remoteproc_interrupt, 0,
359 dev_name(&pdev->dev), &pdev->dev);
360 if (ret) {
361 dev_err(&pdev->dev, "IRQ %d already allocated\n",
362 tmp->irq);
363 goto irq_fault;
364 }
365
366
367
368
369
370
371
372 gic_set_cpu(1, tmp->irq);
373 list_add(&tmp->list, &local->irqs.list);
374 }
375
376
377
378 ret = of_property_read_u32(pdev->dev.of_node, "vring0",
379 &local->ipis[0].irq);
380 if (ret < 0) {
381 dev_err(&pdev->dev, "unable to read property");
382 goto irq_fault;
383 }
384
385 ret = set_ipi_handler(local->ipis[0].irq, ipi_kick,
386 "Firmware kick");
387 if (ret) {
388 dev_err(&pdev->dev, "IPI handler already registered\n");
389 goto irq_fault;
390 }
391
392
393 ret = of_property_read_u32(pdev->dev.of_node, "vring1",
394 &local->ipis[1].irq);
395 if (ret < 0) {
396 dev_err(&pdev->dev, "unable to read property");
397 goto ipi_fault;
398 }
399
400 rproc->auto_boot = autoboot;
401
402 ret = rproc_add(local->rproc);
403 if (ret) {
404 dev_err(&pdev->dev, "rproc registration failed\n");
405 goto ipi_fault;
406 }
407
408 return 0;
409
410ipi_fault:
411 clear_ipi_handler(local->ipis[0].irq);
412
413irq_fault:
414 clear_irq(rproc);
415
416dma_mask_fault:
417 rproc_free(rproc);
418
419 return ret;
420}
421
422static int zynq_remoteproc_remove(struct platform_device *pdev)
423{
424 struct rproc *rproc = platform_get_drvdata(pdev);
425 struct zynq_rproc_pdata *local = rproc->priv;
426
427 dev_info(&pdev->dev, "%s\n", __func__);
428
429 rproc_del(rproc);
430
431 clear_ipi_handler(local->ipis[0].irq);
432 clear_irq(rproc);
433
434 of_reserved_mem_device_release(&pdev->dev);
435 rproc_free(rproc);
436
437 return 0;
438}
439
440
441static const struct of_device_id zynq_remoteproc_match[] = {
442 { .compatible = "xlnx,zynq_remoteproc", },
443 { },
444};
445MODULE_DEVICE_TABLE(of, zynq_remoteproc_match);
446
447static struct platform_driver zynq_remoteproc_driver = {
448 .probe = zynq_remoteproc_probe,
449 .remove = zynq_remoteproc_remove,
450 .driver = {
451 .name = "zynq_remoteproc",
452 .of_match_table = zynq_remoteproc_match,
453 },
454};
455module_platform_driver(zynq_remoteproc_driver);
456
457module_param_named(autoboot, autoboot, bool, 0444);
458MODULE_PARM_DESC(autoboot,
459 "enable | disable autoboot. (default: false)");
460
461MODULE_AUTHOR("Michal Simek <monstr@monstr.eu");
462MODULE_LICENSE("GPL v2");
463MODULE_DESCRIPTION("Zynq remote processor control driver");
464