]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - rpmsg/rpmsg.git/blob - drivers/remoteproc/pru_rproc.c
remoteproc/pru: Introduce new vendor interrupt resource for K3 AM65x SoCs
[rpmsg/rpmsg.git] / drivers / remoteproc / pru_rproc.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PRU-ICSS remoteproc driver for various TI SoCs
4  *
5  * Copyright (C) 2014-2019 Texas Instruments Incorporated - http://www.ti.com/
6  *      Suman Anna <s-anna@ti.com>
7  *      Andrew F. Davis <afd@ti.com>
8  */
10 #include <linux/bitops.h>
11 #include <linux/debugfs.h>
12 #include <linux/interrupt.h>
13 #include <linux/mailbox_client.h>
14 #include <linux/module.h>
15 #include <linux/of_device.h>
16 #include <linux/omap-mailbox.h>
17 #include <linux/pruss.h>
18 #include <linux/pruss_driver.h>
19 #include <linux/remoteproc.h>
21 #include "remoteproc_internal.h"
22 #include "pru_rproc.h"
24 /* PRU_ICSS_PRU_CTRL registers */
25 #define PRU_CTRL_CTRL           0x0000
26 #define PRU_CTRL_STS            0x0004
27 #define PRU_CTRL_WAKEUP_EN      0x0008
28 #define PRU_CTRL_CYCLE          0x000C
29 #define PRU_CTRL_STALL          0x0010
30 #define PRU_CTRL_CTBIR0         0x0020
31 #define PRU_CTRL_CTBIR1         0x0024
32 #define PRU_CTRL_CTPPR0         0x0028
33 #define PRU_CTRL_CTPPR1         0x002C
35 /* CTRL register bit-fields */
36 #define CTRL_CTRL_SOFT_RST_N    BIT(0)
37 #define CTRL_CTRL_EN            BIT(1)
38 #define CTRL_CTRL_SLEEPING      BIT(2)
39 #define CTRL_CTRL_CTR_EN        BIT(3)
40 #define CTRL_CTRL_SINGLE_STEP   BIT(8)
41 #define CTRL_CTRL_RUNSTATE      BIT(15)
43 /* PRU_ICSS_PRU_DEBUG registers */
44 #define PRU_DEBUG_GPREG(x)      (0x0000 + (x) * 4)
45 #define PRU_DEBUG_CT_REG(x)     (0x0080 + (x) * 4)
47 /* PRU Core IRAM address masks */
48 #define PRU0_IRAM_ADDR_MASK     0x34000
49 #define PRU1_IRAM_ADDR_MASK     0x38000
51 /**
52  * enum pru_iomem - PRU core memory/register range identifiers
53  */
54 enum pru_iomem {
55         PRU_IOMEM_IRAM = 0,
56         PRU_IOMEM_CTRL,
57         PRU_IOMEM_DEBUG,
58         PRU_IOMEM_MAX,
59 };
61 /**
62  * struct pru_rproc - PRU remoteproc structure
63  * @id: id of the PRU core within the PRUSS
64  * @pruss: back-reference to parent PRUSS structure
65  * @rproc: remoteproc pointer for this PRU core
66  * @client_np: client device node
67  * @mbox: mailbox channel handle used for vring signalling with MPU
68  * @client: mailbox client to request the mailbox channel
69  * @irq_ring: IRQ number to use for processing vring buffers
70  * @irq_kick: IRQ number to use to perform virtio kick
71  * @mem_regions: data for each of the PRU memory regions
72  * @intc_config: PRU INTC configuration data
73  * @rmw_lock: lock for read, modify, write operations on registers
74  * @iram_da: device address of Instruction RAM for this PRU
75  * @pdram_da: device address of primary Data RAM for this PRU
76  * @sdram_da: device address of secondary Data RAM for this PRU
77  * @shrdram_da: device address of shared Data RAM
78  * @fw_name: name of firmware image used during loading
79  * @dt_irqs: number of irqs configured from DT
80  * @gpmux_save: saved value for gpmux config
81  * @lock: mutex to protect client usage
82  * @dbg_single_step: debug state variable to set PRU into single step mode
83  * @dbg_continuous: debug state variable to restore PRU execution mode
84  * @fw_has_intc_rsc: boolean flag to indicate INTC config through firmware
85  */
86 struct pru_rproc {
87         int id;
88         struct pruss *pruss;
89         struct rproc *rproc;
90         struct device_node *client_np;
91         struct mbox_chan *mbox;
92         struct mbox_client client;
93         int irq_vring;
94         int irq_kick;
95         struct pruss_mem_region mem_regions[PRU_IOMEM_MAX];
96         struct pruss_intc_config intc_config;
97         spinlock_t rmw_lock; /* register access lock */
98         u32 iram_da;
99         u32 pdram_da;
100         u32 sdram_da;
101         u32 shrdram_da;
102         const char *fw_name;
103         int dt_irqs;
104         u8 gpmux_save;
105         struct mutex lock; /* client access lock */
106         u32 dbg_single_step;
107         u32 dbg_continuous;
108         unsigned int fw_has_intc_rsc : 1;
109 };
111 static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, int len);
113 static inline u32 pru_control_read_reg(struct pru_rproc *pru, unsigned int reg)
115         return readl_relaxed(pru->mem_regions[PRU_IOMEM_CTRL].va + reg);
118 static inline
119 void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val)
121         writel_relaxed(val, pru->mem_regions[PRU_IOMEM_CTRL].va + reg);
124 static inline
125 void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg,
126                          u32 mask, u32 set)
128         u32 val;
129         unsigned long flags;
131         spin_lock_irqsave(&pru->rmw_lock, flags);
133         val = pru_control_read_reg(pru, reg);
134         val &= ~mask;
135         val |= (set & mask);
136         pru_control_write_reg(pru, reg, val);
138         spin_unlock_irqrestore(&pru->rmw_lock, flags);
141 /**
142  * pru_rproc_set_firmware() - set firmware for a pru core
143  * @rproc: the rproc instance of the PRU
144  * @fw_name: the new firmware name, or NULL if default is desired
145  */
146 static int pru_rproc_set_firmware(struct rproc *rproc, const char *fw_name)
148         struct pru_rproc *pru = rproc->priv;
150         if (!fw_name)
151                 fw_name = pru->fw_name;
153         return rproc_set_firmware(rproc, fw_name);
156 static int pru_rproc_intc_dt_config(struct pru_rproc *pru, int index)
158         struct device *dev = &pru->rproc->dev;
159         struct device_node *np = pru->client_np;
160         struct property *prop;
161         const char *prop_name = "ti,pru-interrupt-map";
162         int ret = 0, i;
163         int dt_irqs;
164         u32 *arr;
165         bool has_irqs = false;
167         prop = of_find_property(np, prop_name, NULL);
168         if (!prop)
169                 return 0;
171         dt_irqs = of_property_count_u32_elems(np, prop_name);
172         if (dt_irqs <= 0 || dt_irqs % 4) {
173                 dev_err(dev, "bad interrupt map data %d, expected multiple of 4\n",
174                         dt_irqs);
175                 return -EINVAL;
176         }
178         arr = kmalloc_array(dt_irqs, sizeof(u32), GFP_KERNEL);
179         if (!arr)
180                 return -ENOMEM;
182         ret = of_property_read_u32_array(np, prop_name, arr, dt_irqs);
183         if (ret) {
184                 dev_err(dev, "failed to read pru irq map: %d\n", ret);
185                 goto out;
186         }
188         for (i = 0; i < ARRAY_SIZE(pru->intc_config.sysev_to_ch); i++)
189                 pru->intc_config.sysev_to_ch[i] = -1;
191         for (i = 0; i < ARRAY_SIZE(pru->intc_config.ch_to_host); i++)
192                 pru->intc_config.ch_to_host[i] = -1;
194         for (i = 0; i < dt_irqs; i += 4) {
195                 if (arr[i] != index)
196                         continue;
198                 if (arr[i + 1] < 0 ||
199                     arr[i + 1] >= MAX_PRU_SYS_EVENTS) {
200                         dev_err(dev, "bad sys event %d\n", arr[i + 1]);
201                         ret = -EINVAL;
202                         goto out;
203                 }
205                 if (arr[i + 2] < 0 ||
206                     arr[i + 2] >= MAX_PRU_CHANNELS) {
207                         dev_err(dev, "bad channel %d\n", arr[i + 2]);
208                         ret = -EINVAL;
209                         goto out;
210                 }
212                 if (arr[i + 3] < 0 ||
213                     arr[i + 3] >= MAX_PRU_HOST_INT) {
214                         dev_err(dev, "bad irq %d\n", arr[i + 3]);
215                         ret = -EINVAL;
216                         goto out;
217                 }
219                 pru->intc_config.sysev_to_ch[arr[i + 1]] = arr[i + 2];
220                 dev_dbg(dev, "sysevt-to-ch[%d] -> %d\n", arr[i + 1],
221                         arr[i + 2]);
223                 pru->intc_config.ch_to_host[arr[i + 2]] = arr[i + 3];
224                 dev_dbg(dev, "chnl-to-host[%d] -> %d\n", arr[i + 2],
225                         arr[i + 3]);
227                 has_irqs = true;
228         }
230         /*
231          * The property "ti,pru-interrupt-map" is used in a consumer node, but
232          * need not necessarily have data for all referenced PRUs. Provide a
233          * fallback to get the interrupt data from firmware for PRUs ith no
234          * interrupt data.
235          */
236         if (!has_irqs) {
237                 dev_dbg(dev, "no DT irqs, falling back to firmware intc rsc mode\n");
238                 goto out;
239         }
241         pru->dt_irqs = dt_irqs;
242         ret = pruss_intc_configure(pru->pruss, &pru->intc_config);
243         if (ret) {
244                 dev_err(dev, "failed to configure intc %d\n", ret);
245                 pru->dt_irqs = 0;
246         }
248 out:
249         kfree(arr);
251         return ret;
254 static struct rproc *__pru_rproc_get(struct device_node *np, int index)
256         struct device_node *rproc_np = NULL;
257         struct platform_device *pdev;
258         struct rproc *rproc;
260         rproc_np = of_parse_phandle(np, "prus", index);
261         if (!rproc_np || !of_device_is_available(rproc_np))
262                 return ERR_PTR(-ENODEV);
264         pdev = of_find_device_by_node(rproc_np);
265         of_node_put(rproc_np);
267         if (!pdev)
268                 /* probably PRU not yet probed */
269                 return ERR_PTR(-EPROBE_DEFER);
271         /* TODO: replace the crude string based check to make sure it is PRU */
272         if (!strstr(dev_name(&pdev->dev), "pru")) {
273                 put_device(&pdev->dev);
274                 return ERR_PTR(-ENODEV);
275         }
277         rproc = platform_get_drvdata(pdev);
278         put_device(&pdev->dev);
279         if (!rproc)
280                 return ERR_PTR(-EPROBE_DEFER);
282         get_device(&rproc->dev);
284         return rproc;
287 /**
288  * pru_rproc_get() - get the PRU rproc instance from a device node
289  * @np: the user/client device node
290  * @index: index to use for the prus property
291  *
292  * This function looks through a client device node's "prus" property at index
293  * @index and returns the rproc handle for a valid PRU remote processor if
294  * found. The function allows only one user to own the PRU rproc resource at
295  * a time. Caller must call pru_rproc_put() when done with using the rproc,
296  * not required if the function returns a failure.
297  *
298  * Returns the rproc handle on success, and an ERR_PTR on failure using one
299  * of the following error values
300  *    -ENODEV if device is not found
301  *    -EBUSY if PRU is already acquired by anyone
302  *    -EPROBE_DEFER is PRU device is not probed yet
303  */
304 struct rproc *pru_rproc_get(struct device_node *np, int index)
306         struct rproc *rproc;
307         struct pru_rproc *pru;
308         const char *fw_name;
309         struct device *dev;
310         int ret;
311         u32 mux;
313         rproc = __pru_rproc_get(np, index);
314         if (IS_ERR(rproc))
315                 return rproc;
317         pru = rproc->priv;
318         dev = &rproc->dev;
320         mutex_lock(&pru->lock);
322         if (pru->client_np) {
323                 mutex_unlock(&pru->lock);
324                 put_device(&rproc->dev);
325                 return ERR_PTR(-EBUSY);
326         }
328         pru->client_np = np;
329         rproc->deny_sysfs_ops = 1;
331         mutex_unlock(&pru->lock);
333         ret = pruss_cfg_get_gpmux(pru->pruss, pru->id, &pru->gpmux_save);
334         if (ret) {
335                 dev_err(dev, "failed to get cfg gpmux: %d\n", ret);
336                 goto err;
337         }
339         ret = of_property_read_u32_index(np, "ti,pruss-gp-mux-sel", index,
340                                          &mux);
341         if (!ret) {
342                 ret = pruss_cfg_set_gpmux(pru->pruss, pru->id, mux);
343                 if (ret) {
344                         dev_err(dev, "failed to set cfg gpmux: %d\n", ret);
345                         goto err;
346                 }
347         }
349         ret = of_property_read_string_index(np, "firmware-name", index,
350                                             &fw_name);
351         if (!ret) {
352                 ret = pru_rproc_set_firmware(rproc, fw_name);
353                 if (ret) {
354                         dev_err(dev, "failed to set firmware: %d\n", ret);
355                         goto err;
356                 }
357         }
359         ret = pru_rproc_intc_dt_config(pru, index);
360         if (ret)
361                 goto err;
363         return rproc;
365 err:
366         pru_rproc_put(rproc);
367         return ERR_PTR(ret);
369 EXPORT_SYMBOL_GPL(pru_rproc_get);
371 /**
372  * pru_rproc_put() - release the PRU rproc resource
373  * @rproc: the rproc resource to release
374  *
375  * Releases the PRU rproc resource and makes it available to other
376  * users.
377  */
378 void pru_rproc_put(struct rproc *rproc)
380         struct pru_rproc *pru;
382         if (IS_ERR_OR_NULL(rproc))
383                 return;
385         /* TODO: replace the crude string based check to make sure it is PRU */
386         if (!strstr(dev_name(rproc->dev.parent), "pru"))
387                 return;
389         pru = rproc->priv;
390         if (!pru->client_np)
391                 return;
393         pruss_cfg_set_gpmux(pru->pruss, pru->id, pru->gpmux_save);
395         if (pru->dt_irqs)
396                 pruss_intc_unconfigure(pru->pruss, &pru->intc_config);
398         pru_rproc_set_firmware(rproc, NULL);
400         mutex_lock(&pru->lock);
401         pru->client_np = NULL;
402         rproc->deny_sysfs_ops = 0;
403         mutex_unlock(&pru->lock);
405         put_device(&rproc->dev);
407 EXPORT_SYMBOL_GPL(pru_rproc_put);
409 /**
410  * pru_rproc_get_id() - get PRU id from a previously acquired PRU remoteproc
411  * @rproc: the rproc instance of the PRU
412  *
413  * Returns the PRU id of the PRU remote processor that has been acquired through
414  * a pru_rproc_get(), or a negative value on error
415  */
416 enum pruss_pru_id pru_rproc_get_id(struct rproc *rproc)
418         struct pru_rproc *pru;
420         if (IS_ERR_OR_NULL(rproc) || !rproc->dev.parent)
421                 return -EINVAL;
423         /* TODO: replace the crude string based check to make sure it is PRU */
424         if (!strstr(dev_name(rproc->dev.parent), "pru"))
425                 return -EINVAL;
427         pru = rproc->priv;
428         return pru->id;
430 EXPORT_SYMBOL_GPL(pru_rproc_get_id);
432 /**
433  * pru_rproc_set_ctable() - set the constant table index for the PRU
434  * @rproc: the rproc instance of the PRU
435  * @c: constant table index to set
436  * @addr: physical address to set it to
437  */
438 int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr)
440         struct pru_rproc *pru = rproc->priv;
441         unsigned int reg;
442         u32 mask, set;
443         u16 idx;
444         u16 idx_mask;
446         /* pointer is 16 bit and index is 8-bit so mask out the rest */
447         idx_mask = (c >= PRU_C28) ? 0xFFFF : 0xFF;
449         /* ctable uses bit 8 and upwards only */
450         idx = (addr >> 8) & idx_mask;
452         /* configurable ctable (i.e. C24) starts at PRU_CTRL_CTBIR0 */
453         reg = PRU_CTRL_CTBIR0 + 4 * (c >> 1);
454         mask = idx_mask << (16 * (c & 1));
455         set = idx << (16 * (c & 1));
457         pru_control_set_reg(pru, reg, mask, set);
459         return 0;
461 EXPORT_SYMBOL_GPL(pru_rproc_set_ctable);
463 static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg)
465         return readl_relaxed(pru->mem_regions[PRU_IOMEM_DEBUG].va + reg);
468 static inline
469 void pru_debug_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val)
471         writel_relaxed(val, pru->mem_regions[PRU_IOMEM_DEBUG].va + reg);
474 static int regs_show(struct seq_file *s, void *data)
476         struct rproc *rproc = s->private;
477         struct pru_rproc *pru = rproc->priv;
478         int i, nregs = 32;
479         u32 pru_sts;
480         int pru_is_running;
482         seq_puts(s, "============== Control Registers ==============\n");
483         seq_printf(s, "CTRL      := 0x%08x\n",
484                    pru_control_read_reg(pru, PRU_CTRL_CTRL));
485         pru_sts = pru_control_read_reg(pru, PRU_CTRL_STS);
486         seq_printf(s, "STS (PC)  := 0x%08x (0x%08x)\n", pru_sts, pru_sts << 2);
487         seq_printf(s, "WAKEUP_EN := 0x%08x\n",
488                    pru_control_read_reg(pru, PRU_CTRL_WAKEUP_EN));
489         seq_printf(s, "CYCLE     := 0x%08x\n",
490                    pru_control_read_reg(pru, PRU_CTRL_CYCLE));
491         seq_printf(s, "STALL     := 0x%08x\n",
492                    pru_control_read_reg(pru, PRU_CTRL_STALL));
493         seq_printf(s, "CTBIR0    := 0x%08x\n",
494                    pru_control_read_reg(pru, PRU_CTRL_CTBIR0));
495         seq_printf(s, "CTBIR1    := 0x%08x\n",
496                    pru_control_read_reg(pru, PRU_CTRL_CTBIR1));
497         seq_printf(s, "CTPPR0    := 0x%08x\n",
498                    pru_control_read_reg(pru, PRU_CTRL_CTPPR0));
499         seq_printf(s, "CTPPR1    := 0x%08x\n",
500                    pru_control_read_reg(pru, PRU_CTRL_CTPPR1));
502         seq_puts(s, "=============== Debug Registers ===============\n");
503         pru_is_running = pru_control_read_reg(pru, PRU_CTRL_CTRL) &
504                                 CTRL_CTRL_RUNSTATE;
505         if (pru_is_running) {
506                 seq_puts(s, "PRU is executing, cannot print/access debug registers.\n");
507                 return 0;
508         }
510         for (i = 0; i < nregs; i++) {
511                 seq_printf(s, "GPREG%-2d := 0x%08x\tCT_REG%-2d := 0x%08x\n",
512                            i, pru_debug_read_reg(pru, PRU_DEBUG_GPREG(i)),
513                            i, pru_debug_read_reg(pru, PRU_DEBUG_CT_REG(i)));
514         }
516         return 0;
519 DEFINE_SHOW_ATTRIBUTE(regs);
521 /*
522  * Control PRU single-step mode
523  *
524  * This is a debug helper function used for controlling the single-step
525  * mode of the PRU. The PRU Debug registers are not accessible when the
526  * PRU is in RUNNING state.
527  *
528  * Writing a non-zero value sets the PRU into single-step mode irrespective
529  * of its previous state. The PRU mode is saved only on the first set into
530  * a single-step mode. Writing a zero value will restore the PRU into its
531  * original mode.
532  */
533 static int pru_rproc_debug_ss_set(void *data, u64 val)
535         struct rproc *rproc = data;
536         struct pru_rproc *pru = rproc->priv;
537         u32 reg_val;
539         val = val ? 1 : 0;
540         if (!val && !pru->dbg_single_step)
541                 return 0;
543         reg_val = pru_control_read_reg(pru, PRU_CTRL_CTRL);
545         if (val && !pru->dbg_single_step)
546                 pru->dbg_continuous = reg_val;
548         if (val)
549                 reg_val |= CTRL_CTRL_SINGLE_STEP | CTRL_CTRL_EN;
550         else
551                 reg_val = pru->dbg_continuous;
553         pru->dbg_single_step = val;
554         pru_control_write_reg(pru, PRU_CTRL_CTRL, reg_val);
556         return 0;
559 static int pru_rproc_debug_ss_get(void *data, u64 *val)
561         struct rproc *rproc = data;
562         struct pru_rproc *pru = rproc->priv;
564         *val = pru->dbg_single_step;
566         return 0;
568 DEFINE_SIMPLE_ATTRIBUTE(pru_rproc_debug_ss_fops, pru_rproc_debug_ss_get,
569                         pru_rproc_debug_ss_set, "%llu\n");
571 /*
572  * Create PRU-specific debugfs entries
573  *
574  * The entries are created only if the parent remoteproc debugfs directory
575  * exists, and will be cleaned up by the remoteproc core.
576  */
577 static void pru_rproc_create_debug_entries(struct rproc *rproc)
579         if (!rproc->dbg_dir)
580                 return;
582         debugfs_create_file("regs", 0400, rproc->dbg_dir,
583                             rproc, &regs_fops);
584         debugfs_create_file("single_step", 0600, rproc->dbg_dir,
585                             rproc, &pru_rproc_debug_ss_fops);
588 /**
589  * pru_rproc_mbox_callback() - inbound mailbox message handler
590  * @client: mailbox client pointer used for requesting the mailbox channel
591  * @data: mailbox payload
592  *
593  * This handler is invoked by omap's mailbox driver whenever a mailbox
594  * message is received. Usually, the mailbox payload simply contains
595  * the index of the virtqueue that is kicked by the PRU remote processor,
596  * and we let remoteproc core handle it.
597  *
598  * In addition to virtqueue indices, we might also have some out-of-band
599  * values that indicates different events. Those values are deliberately
600  * very big so they don't coincide with virtqueue indices.
601  */
602 static void pru_rproc_mbox_callback(struct mbox_client *client, void *data)
604         struct pru_rproc *pru = container_of(client, struct pru_rproc, client);
605         struct device *dev = &pru->rproc->dev;
606         u32 msg = to_omap_mbox_msg(data);
608         dev_dbg(dev, "mbox msg: 0x%x\n", msg);
610         /* msg contains the index of the triggered vring */
611         if (rproc_vq_interrupt(pru->rproc, msg) == IRQ_NONE)
612                 dev_dbg(dev, "no message was found in vqid %d\n", msg);
615 /**
616  * pru_rproc_vring_interrupt() - interrupt handler for processing vrings
617  * @irq: irq number associated with the PRU event MPU is listening on
618  * @data: interrupt handler data, will be a PRU rproc structure
619  *
620  * This handler is used by the PRU remoteproc driver when using PRU system
621  * events for processing the virtqueues. Unlike the mailbox IP, there is
622  * no payload associated with an interrupt, so either a unique event is
623  * used for each virtqueue kick, or a both virtqueues are processed on
624  * a single event. The latter is chosen to conserve the usable PRU system
625  * events.
626  */
627 static irqreturn_t pru_rproc_vring_interrupt(int irq, void *data)
629         struct pru_rproc *pru = data;
631         dev_dbg(&pru->rproc->dev, "got vring irq\n");
633         /* process incoming buffers on both the Rx and Tx vrings */
634         rproc_vq_interrupt(pru->rproc, 0);
635         rproc_vq_interrupt(pru->rproc, 1);
637         return IRQ_HANDLED;
640 /* kick a virtqueue */
641 static void pru_rproc_kick(struct rproc *rproc, int vq_id)
643         struct device *dev = &rproc->dev;
644         struct pru_rproc *pru = rproc->priv;
645         int ret;
646         mbox_msg_t msg = (mbox_msg_t)vq_id;
648         dev_dbg(dev, "kicking vqid %d on PRU%d\n", vq_id, pru->id);
650         if (pru->irq_kick > 0) {
651                 ret = pruss_intc_trigger(pru->irq_kick);
652                 if (ret < 0)
653                         dev_err(dev, "pruss_intc_trigger failed: %d\n", ret);
654         } else if (pru->mbox) {
655                 /*
656                  * send the index of the triggered virtqueue in the mailbox
657                  * payload
658                  */
659                 ret = mbox_send_message(pru->mbox, (void *)msg);
660                 if (ret < 0)
661                         dev_err(dev, "mbox_send_message failed: %d\n", ret);
662         }
665 /* start a PRU core */
666 static int pru_rproc_start(struct rproc *rproc)
668         struct device *dev = &rproc->dev;
669         struct pru_rproc *pru = rproc->priv;
670         u32 val;
671         int ret;
673         dev_dbg(dev, "starting PRU%d: entry-point = 0x%x\n",
674                 pru->id, (rproc->bootaddr >> 2));
676         if (!list_empty(&pru->rproc->rvdevs)) {
677                 if (!pru->mbox && (pru->irq_vring <= 0 || pru->irq_kick <= 0)) {
678                         dev_err(dev, "virtio vring interrupt mechanisms are not provided\n");
679                         ret = -EINVAL;
680                         goto fail;
681                 }
683                 if (!pru->mbox && pru->irq_vring > 0) {
684                         ret = request_threaded_irq(pru->irq_vring, NULL,
685                                                    pru_rproc_vring_interrupt,
686                                                    IRQF_ONESHOT, dev_name(dev),
687                                                    pru);
688                         if (ret) {
689                                 dev_err(dev, "failed to enable vring interrupt, ret = %d\n",
690                                         ret);
691                                 goto fail;
692                         }
693                 }
694         }
696         val = CTRL_CTRL_EN | ((rproc->bootaddr >> 2) << 16);
697         pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
699         return 0;
701 fail:
702         if (!pru->dt_irqs && pru->fw_has_intc_rsc)
703                 pruss_intc_unconfigure(pru->pruss, &pru->intc_config);
704         return ret;
707 /* stop/disable a PRU core */
708 static int pru_rproc_stop(struct rproc *rproc)
710         struct device *dev = &rproc->dev;
711         struct pru_rproc *pru = rproc->priv;
712         u32 val;
714         dev_dbg(dev, "stopping PRU%d\n", pru->id);
716         val = pru_control_read_reg(pru, PRU_CTRL_CTRL);
717         val &= ~CTRL_CTRL_EN;
718         pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
720         if (!list_empty(&pru->rproc->rvdevs) &&
721             !pru->mbox && pru->irq_vring > 0)
722                 free_irq(pru->irq_vring, pru);
724         /* undo INTC config */
725         if (!pru->dt_irqs && pru->fw_has_intc_rsc)
726                 pruss_intc_unconfigure(pru->pruss, &pru->intc_config);
728         return 0;
731 /*
732  * parse the custom PRU interrupt map resource and configure the INTC
733  * appropriately
734  */
735 static int pru_handle_vendor_intrmap(struct rproc *rproc,
736                                      struct fw_rsc_vendor *rsc)
738         struct device *dev = rproc->dev.parent;
739         struct pru_rproc *pru = rproc->priv;
740         struct pruss *pruss = pru->pruss;
741         struct pruss_event_chnl *event_chnl_map;
742         struct fw_rsc_pruss_intrmap *intr_rsc0;
743         struct fw_rsc_pruss_intrmap_k3 *intr_rsc1;
744         int i, ret;
745         u32 event_chnl_map_da, event_chnl_map_size;
746         s8 sys_evt, chnl, intr_no;
747         s8 *chnl_host_intr_map;
748         u8 max_system_events, max_pru_channels, max_pru_host_ints;
750         if (rsc->u.st.st_ver != 0 && rsc->u.st.st_ver != 1) {
751                 dev_err(dev, "only PRU interrupt resource versions 0 and 1 are supported\n");
752                 return -EINVAL;
753         }
755         if (!rsc->u.st.st_ver) {
756                 intr_rsc0 = (struct fw_rsc_pruss_intrmap *)rsc->data;
757                 event_chnl_map_da = intr_rsc0->event_chnl_map_addr;
758                 event_chnl_map_size = intr_rsc0->event_chnl_map_size;
759                 chnl_host_intr_map = intr_rsc0->chnl_host_intr_map;
760                 max_system_events = MAX_PRU_SYS_EVENTS;
761                 max_pru_channels = MAX_PRU_CHANNELS;
762                 max_pru_host_ints = MAX_PRU_HOST_INT;
764                 dev_dbg(dev, "version %d event_chnl_map_size %d event_chnl_map_da 0x%x\n",
765                         rsc->u.st.st_ver, intr_rsc0->event_chnl_map_size,
766                         event_chnl_map_da);
767         } else {
768                 intr_rsc1 = (struct fw_rsc_pruss_intrmap_k3 *)rsc->data;
769                 event_chnl_map_da = intr_rsc1->event_chnl_map_addr;
770                 event_chnl_map_size = intr_rsc1->event_chnl_map_size;
771                 chnl_host_intr_map = intr_rsc1->chnl_host_intr_map;
772                 max_system_events = MAX_PRU_SYS_EVENTS_K3;
773                 max_pru_channels = MAX_PRU_CHANNELS_K3;
774                 max_pru_host_ints = MAX_PRU_HOST_INT_K3;
776                 dev_dbg(dev, "version %d event_chnl_map_size %d event_chnl_map_da 0x%x\n",
777                         rsc->u.st.st_ver, intr_rsc1->event_chnl_map_size,
778                         event_chnl_map_da);
779         }
781         if (event_chnl_map_size < 0 ||
782             event_chnl_map_size >= max_system_events) {
783                 dev_err(dev, "PRU interrupt resource has more events than present on hardware\n");
784                 return -EINVAL;
785         }
787         /*
788          * XXX: The event_chnl_map_addr mapping is currently a pointer in device
789          * memory, evaluate if this needs to be directly in firmware file.
790          */
791         event_chnl_map = pru_d_da_to_va(pru, event_chnl_map_da,
792                                         event_chnl_map_size *
793                                         sizeof(*event_chnl_map));
794         if (!event_chnl_map) {
795                 dev_err(dev, "PRU interrupt resource has inadequate event_chnl_map configuration\n");
796                 return -EINVAL;
797         }
799         /* init intc_config to defaults */
800         for (i = 0; i < ARRAY_SIZE(pru->intc_config.sysev_to_ch); i++)
801                 pru->intc_config.sysev_to_ch[i] = -1;
803         for (i = 0; i < ARRAY_SIZE(pru->intc_config.ch_to_host); i++)
804                 pru->intc_config.ch_to_host[i] = -1;
806         /* parse and fill in system event to interrupt channel mapping */
807         for (i = 0; i < event_chnl_map_size; i++) {
808                 sys_evt = event_chnl_map[i].event;
809                 chnl = event_chnl_map[i].chnl;
811                 if (sys_evt < 0 || sys_evt >= max_system_events) {
812                         dev_err(dev, "[%d] bad sys event %d\n", i, sys_evt);
813                         return -EINVAL;
814                 }
815                 if (chnl < 0 || chnl >= max_pru_channels) {
816                         dev_err(dev, "[%d] bad channel value %d\n", i, chnl);
817                         return -EINVAL;
818                 }
820                 pru->intc_config.sysev_to_ch[sys_evt] = chnl;
821                 dev_dbg(dev, "sysevt-to-ch[%d] -> %d\n", sys_evt, chnl);
822         }
824         /* parse and handle interrupt channel-to-host interrupt mapping */
825         for (i = 0; i < max_pru_channels; i++) {
826                 intr_no = chnl_host_intr_map[i];
827                 if (intr_no < 0) {
828                         dev_dbg(dev, "skip intr mapping for chnl %d\n", i);
829                         continue;
830                 }
832                 if (intr_no >= max_pru_host_ints) {
833                         dev_err(dev, "bad intr mapping for chnl %d, intr_no %d\n",
834                                 i, intr_no);
835                         return -EINVAL;
836                 }
838                 pru->intc_config.ch_to_host[i] = intr_no;
839                 dev_dbg(dev, "chnl-to-host[%d] -> %d\n", i, intr_no);
840         }
842         pru->fw_has_intc_rsc = 1;
844         ret = pruss_intc_configure(pruss, &pru->intc_config);
845         if (ret)
846                 dev_err(dev, "failed to configure pruss intc %d\n", ret);
848         return ret;
851 /* PRU-specific vendor resource handler */
852 static int pru_rproc_handle_vendor_rsc(struct rproc *rproc,
853                                        struct fw_rsc_vendor *rsc)
855         struct device *dev = rproc->dev.parent;
856         struct pru_rproc *pru = rproc->priv;
857         int ret = 0;
859         switch (rsc->u.st.st_type) {
860         case PRUSS_RSC_INTRS:
861                 if (!pru->dt_irqs)
862                         ret = pru_handle_vendor_intrmap(rproc, rsc);
863                 break;
864         default:
865                 dev_err(dev, "%s: cannot handle unknown type %d\n", __func__,
866                         rsc->u.st.st_type);
867                 ret = -EINVAL;
868         }
870         return ret;
873 /*
874  * Convert PRU device address (data spaces only) to kernel virtual address
875  *
876  * Each PRU has access to all data memories within the PRUSS, accessible at
877  * different ranges. So, look through both its primary and secondary Data
878  * RAMs as well as any shared Data RAM to convert a PRU device address to
879  * kernel virtual address. Data RAM0 is primary Data RAM for PRU0 and Data
880  * RAM1 is primary Data RAM for PRU1.
881  */
882 static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, int len)
884         struct pruss_mem_region dram0, dram1, shrd_ram;
885         struct pruss *pruss = pru->pruss;
886         u32 offset;
887         void *va = NULL;
889         if (len <= 0)
890                 return NULL;
892         dram0 = pruss->mem_regions[PRUSS_MEM_DRAM0];
893         dram1 = pruss->mem_regions[PRUSS_MEM_DRAM1];
894         /* PRU1 has its local RAM addresses reversed */
895         if (pru->id == 1)
896                 swap(dram0, dram1);
897         shrd_ram = pruss->mem_regions[PRUSS_MEM_SHRD_RAM2];
899         if (da >= pru->pdram_da && da + len <= pru->pdram_da + dram0.size) {
900                 offset = da - pru->pdram_da;
901                 va = (__force void *)(dram0.va + offset);
902         } else if (da >= pru->sdram_da &&
903                    da + len <= pru->sdram_da + dram1.size) {
904                 offset = da - pru->sdram_da;
905                 va = (__force void *)(dram1.va + offset);
906         } else if (da >= pru->shrdram_da &&
907                    da + len <= pru->shrdram_da + shrd_ram.size) {
908                 offset = da - pru->shrdram_da;
909                 va = (__force void *)(shrd_ram.va + offset);
910         }
912         return va;
915 /*
916  * Convert PRU device address (instruction space) to kernel virtual address
917  *
918  * A PRU does not have an unified address space. Each PRU has its very own
919  * private Instruction RAM, and its device address is identical to that of
920  * its primary Data RAM device address.
921  */
922 static void *pru_i_da_to_va(struct pru_rproc *pru, u32 da, int len)
924         u32 offset;
925         void *va = NULL;
927         if (len <= 0)
928                 return NULL;
930         if (da >= pru->iram_da &&
931             da + len <= pru->iram_da + pru->mem_regions[PRU_IOMEM_IRAM].size) {
932                 offset = da - pru->iram_da;
933                 va = (__force void *)(pru->mem_regions[PRU_IOMEM_IRAM].va +
934                                       offset);
935         }
937         return va;
940 /* PRU-specific address translator */
941 static void *pru_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
943         struct pru_rproc *pru = rproc->priv;
944         void *va;
945         u32 exec_flag;
947         exec_flag = ((flags & RPROC_FLAGS_ELF_SHDR) ? flags & SHF_EXECINSTR :
948                      ((flags & RPROC_FLAGS_ELF_PHDR) ? flags & PF_X : 0));
950         if (exec_flag)
951                 va = pru_i_da_to_va(pru, da, len);
952         else
953                 va = pru_d_da_to_va(pru, da, len);
955         return va;
958 static struct rproc_ops pru_rproc_ops = {
959         .start                  = pru_rproc_start,
960         .stop                   = pru_rproc_stop,
961         .kick                   = pru_rproc_kick,
962         .handle_vendor_rsc      = pru_rproc_handle_vendor_rsc,
963         .da_to_va               = pru_da_to_va,
964 };
966 /*
967  * compute PRU id based on the IRAM addresses. The PRU IRAMs are
968  * always at a particular offset within the PRUSS address space.
969  * The other alternative is to use static data for each core (not a
970  * hardware property to define it in DT), and the id can always be
971  * computated using this inherent address logic.
972  */
973 static int pru_rproc_set_id(struct pru_rproc *pru)
975         int ret = 0;
976         u32 mask1 = PRU0_IRAM_ADDR_MASK;
977         u32 mask2 = PRU1_IRAM_ADDR_MASK;
979         if ((pru->mem_regions[PRU_IOMEM_IRAM].pa & mask1) == mask1)
980                 pru->id = PRUSS_PRU0;
981         else if ((pru->mem_regions[PRU_IOMEM_IRAM].pa & mask2) == mask2)
982                 pru->id = PRUSS_PRU1;
983         else
984                 ret = -EINVAL;
986         return ret;
989 static int pru_rproc_probe(struct platform_device *pdev)
991         struct device *dev = &pdev->dev;
992         struct device_node *np = dev->of_node;
993         struct platform_device *ppdev = to_platform_device(dev->parent);
994         struct pru_rproc *pru;
995         const char *fw_name;
996         struct rproc *rproc = NULL;
997         struct mbox_client *client;
998         struct resource *res;
999         int i, ret;
1000         const char *mem_names[PRU_IOMEM_MAX] = { "iram", "control", "debug" };
1002         if (!np) {
1003                 dev_err(dev, "Non-DT platform device not supported\n");
1004                 return -ENODEV;
1005         }
1007         ret = of_property_read_string(np, "firmware-name", &fw_name);
1008         if (ret) {
1009                 dev_err(dev, "unable to retrieve firmware-name %d\n", ret);
1010                 return ret;
1011         }
1013         rproc = rproc_alloc(dev, pdev->name, &pru_rproc_ops, fw_name,
1014                             sizeof(*pru));
1015         if (!rproc) {
1016                 dev_err(dev, "rproc_alloc failed\n");
1017                 return -ENOMEM;
1018         }
1019         /* error recovery is not supported for PRUs */
1020         rproc->recovery_disabled = true;
1022         /*
1023          * rproc_add will auto-boot the processor normally, but this is
1024          * not desired with PRU client driven boot-flow methodology. A PRU
1025          * application/client driver will boot the corresponding PRU
1026          * remote-processor as part of its state machine either through
1027          * the remoteproc sysfs interface or through the equivalent kernel API
1028          */
1029         rproc->auto_boot = false;
1031         pru = rproc->priv;
1032         pru->pruss = platform_get_drvdata(ppdev);
1033         pru->rproc = rproc;
1034         pru->fw_name = fw_name;
1035         spin_lock_init(&pru->rmw_lock);
1036         mutex_init(&pru->lock);
1038         /* XXX: get this from match data if different in the future */
1039         pru->iram_da = 0;
1040         pru->pdram_da = 0;
1041         pru->sdram_da = 0x2000;
1042         pru->shrdram_da = 0x10000;
1044         for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
1045                 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1046                                                    mem_names[i]);
1047                 pru->mem_regions[i].va = devm_ioremap_resource(dev, res);
1048                 if (IS_ERR(pru->mem_regions[i].va)) {
1049                         dev_err(dev, "failed to parse and map memory resource %d %s\n",
1050                                 i, mem_names[i]);
1051                         ret = PTR_ERR(pru->mem_regions[i].va);
1052                         goto free_rproc;
1053                 }
1054                 pru->mem_regions[i].pa = res->start;
1055                 pru->mem_regions[i].size = resource_size(res);
1057                 dev_dbg(dev, "memory %8s: pa %pa size 0x%zx va %p\n",
1058                         mem_names[i], &pru->mem_regions[i].pa,
1059                         pru->mem_regions[i].size, pru->mem_regions[i].va);
1060         }
1062         ret = pru_rproc_set_id(pru);
1063         if (ret < 0)
1064                 goto free_rproc;
1066         platform_set_drvdata(pdev, rproc);
1068         /* get optional vring and kick interrupts for supporting virtio rpmsg */
1069         pru->irq_vring = platform_get_irq_byname(pdev, "vring");
1070         if (pru->irq_vring <= 0) {
1071                 ret = pru->irq_vring;
1072                 if (ret == -EPROBE_DEFER)
1073                         goto free_rproc;
1074                 dev_dbg(dev, "unable to get vring interrupt, status = %d\n",
1075                         ret);
1076         }
1078         pru->irq_kick = platform_get_irq_byname(pdev, "kick");
1079         if (pru->irq_kick <= 0) {
1080                 ret = pru->irq_kick;
1081                 if (ret == -EPROBE_DEFER)
1082                         goto free_rproc;
1083                 dev_dbg(dev, "unable to get kick interrupt, status = %d\n",
1084                         ret);
1085         }
1087         /*
1088          * get optional mailbox for virtio rpmsg signalling if vring and kick
1089          * interrupts are not specified for OMAP architecture based SoCs
1090          */
1091         if (pru->irq_vring <= 0 && pru->irq_kick <= 0 &&
1092             !of_device_is_compatible(np, "ti,k2g-pru")) {
1093                 client = &pru->client;
1094                 client->dev = dev;
1095                 client->tx_done = NULL;
1096                 client->rx_callback = pru_rproc_mbox_callback;
1097                 client->tx_block = false;
1098                 client->knows_txdone = false;
1099                 pru->mbox = mbox_request_channel(client, 0);
1100                 if (IS_ERR(pru->mbox)) {
1101                         ret = PTR_ERR(pru->mbox);
1102                         pru->mbox = NULL;
1103                         dev_dbg(dev, "unable to get mailbox channel, status = %d\n",
1104                                 ret);
1105                 }
1106         }
1108         ret = rproc_add(pru->rproc);
1109         if (ret) {
1110                 dev_err(dev, "rproc_add failed: %d\n", ret);
1111                 goto put_mbox;
1112         }
1114         pru_rproc_create_debug_entries(rproc);
1116         dev_info(dev, "PRU rproc node %s probed successfully\n", np->full_name);
1118         return 0;
1120 put_mbox:
1121         mbox_free_channel(pru->mbox);
1122 free_rproc:
1123         rproc_free(rproc);
1124         return ret;
1127 static int pru_rproc_remove(struct platform_device *pdev)
1129         struct device *dev = &pdev->dev;
1130         struct rproc *rproc = platform_get_drvdata(pdev);
1131         struct pru_rproc *pru = rproc->priv;
1133         dev_info(dev, "%s: removing rproc %s\n", __func__, rproc->name);
1135         mbox_free_channel(pru->mbox);
1137         rproc_del(rproc);
1138         rproc_free(rproc);
1140         return 0;
1143 static const struct of_device_id pru_rproc_match[] = {
1144         { .compatible = "ti,am3356-pru", },
1145         { .compatible = "ti,am4376-pru", },
1146         { .compatible = "ti,am5728-pru", },
1147         { .compatible = "ti,k2g-pru",    },
1148         {},
1149 };
1150 MODULE_DEVICE_TABLE(of, pru_rproc_match);
1152 static struct platform_driver pru_rproc_driver = {
1153         .driver = {
1154                 .name   = "pru-rproc",
1155                 .of_match_table = pru_rproc_match,
1156                 .suppress_bind_attrs = true,
1157         },
1158         .probe  = pru_rproc_probe,
1159         .remove = pru_rproc_remove,
1160 };
1161 module_platform_driver(pru_rproc_driver);
1163 MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
1164 MODULE_DESCRIPTION("PRU-ICSS Remote Processor Driver");
1165 MODULE_LICENSE("GPL v2");