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/module.h>
14 #include <linux/of_device.h>
15 #include <linux/pruss_driver.h>
16 #include <linux/remoteproc.h>
18 #include "remoteproc_internal.h"
19 #include "pru_rproc.h"
21 /* PRU_ICSS_PRU_CTRL registers */
22 #define PRU_CTRL_CTRL 0x0000
23 #define PRU_CTRL_STS 0x0004
24 #define PRU_CTRL_WAKEUP_EN 0x0008
25 #define PRU_CTRL_CYCLE 0x000C
26 #define PRU_CTRL_STALL 0x0010
27 #define PRU_CTRL_CTBIR0 0x0020
28 #define PRU_CTRL_CTBIR1 0x0024
29 #define PRU_CTRL_CTPPR0 0x0028
30 #define PRU_CTRL_CTPPR1 0x002C
32 /* CTRL register bit-fields */
33 #define CTRL_CTRL_SOFT_RST_N BIT(0)
34 #define CTRL_CTRL_EN BIT(1)
35 #define CTRL_CTRL_SLEEPING BIT(2)
36 #define CTRL_CTRL_CTR_EN BIT(3)
37 #define CTRL_CTRL_SINGLE_STEP BIT(8)
38 #define CTRL_CTRL_RUNSTATE BIT(15)
40 /* PRU_ICSS_PRU_DEBUG registers */
41 #define PRU_DEBUG_GPREG(x) (0x0000 + (x) * 4)
42 #define PRU_DEBUG_CT_REG(x) (0x0080 + (x) * 4)
44 /* PRU Core IRAM address masks */
45 #define PRU0_IRAM_ADDR_MASK 0x34000
46 #define PRU1_IRAM_ADDR_MASK 0x38000
48 /**
49 * enum pru_iomem - PRU core memory/register range identifiers
50 */
51 enum pru_iomem {
52 PRU_IOMEM_IRAM = 0,
53 PRU_IOMEM_CTRL,
54 PRU_IOMEM_DEBUG,
55 PRU_IOMEM_MAX,
56 };
58 /**
59 * struct pru_rproc - PRU remoteproc structure
60 * @id: id of the PRU core within the PRUSS
61 * @pruss: back-reference to parent PRUSS structure
62 * @rproc: remoteproc pointer for this PRU core
63 * @mem_regions: data for each of the PRU memory regions
64 * @intc_config: PRU INTC configuration data
65 * @iram_da: device address of Instruction RAM for this PRU
66 * @pdram_da: device address of primary Data RAM for this PRU
67 * @sdram_da: device address of secondary Data RAM for this PRU
68 * @shrdram_da: device address of shared Data RAM
69 * @fw_name: name of firmware image used during loading
70 * @dbg_single_step: debug state variable to set PRU into single step mode
71 * @dbg_continuous: debug state variable to restore PRU execution mode
72 */
73 struct pru_rproc {
74 int id;
75 struct pruss *pruss;
76 struct rproc *rproc;
77 struct pruss_mem_region mem_regions[PRU_IOMEM_MAX];
78 struct pruss_intc_config intc_config;
79 u32 iram_da;
80 u32 pdram_da;
81 u32 sdram_da;
82 u32 shrdram_da;
83 const char *fw_name;
84 u32 dbg_single_step;
85 u32 dbg_continuous;
86 };
88 static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, int len);
90 static inline u32 pru_control_read_reg(struct pru_rproc *pru, unsigned int reg)
91 {
92 return readl_relaxed(pru->mem_regions[PRU_IOMEM_CTRL].va + reg);
93 }
95 static inline
96 void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val)
97 {
98 writel_relaxed(val, pru->mem_regions[PRU_IOMEM_CTRL].va + reg);
99 }
101 static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg)
102 {
103 return readl_relaxed(pru->mem_regions[PRU_IOMEM_DEBUG].va + reg);
104 }
106 static inline
107 void pru_debug_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val)
108 {
109 writel_relaxed(val, pru->mem_regions[PRU_IOMEM_DEBUG].va + reg);
110 }
112 static int regs_show(struct seq_file *s, void *data)
113 {
114 struct rproc *rproc = s->private;
115 struct pru_rproc *pru = rproc->priv;
116 int i, nregs = 32;
117 u32 pru_sts;
118 int pru_is_running;
120 seq_puts(s, "============== Control Registers ==============\n");
121 seq_printf(s, "CTRL := 0x%08x\n",
122 pru_control_read_reg(pru, PRU_CTRL_CTRL));
123 pru_sts = pru_control_read_reg(pru, PRU_CTRL_STS);
124 seq_printf(s, "STS (PC) := 0x%08x (0x%08x)\n", pru_sts, pru_sts << 2);
125 seq_printf(s, "WAKEUP_EN := 0x%08x\n",
126 pru_control_read_reg(pru, PRU_CTRL_WAKEUP_EN));
127 seq_printf(s, "CYCLE := 0x%08x\n",
128 pru_control_read_reg(pru, PRU_CTRL_CYCLE));
129 seq_printf(s, "STALL := 0x%08x\n",
130 pru_control_read_reg(pru, PRU_CTRL_STALL));
131 seq_printf(s, "CTBIR0 := 0x%08x\n",
132 pru_control_read_reg(pru, PRU_CTRL_CTBIR0));
133 seq_printf(s, "CTBIR1 := 0x%08x\n",
134 pru_control_read_reg(pru, PRU_CTRL_CTBIR1));
135 seq_printf(s, "CTPPR0 := 0x%08x\n",
136 pru_control_read_reg(pru, PRU_CTRL_CTPPR0));
137 seq_printf(s, "CTPPR1 := 0x%08x\n",
138 pru_control_read_reg(pru, PRU_CTRL_CTPPR1));
140 seq_puts(s, "=============== Debug Registers ===============\n");
141 pru_is_running = pru_control_read_reg(pru, PRU_CTRL_CTRL) &
142 CTRL_CTRL_RUNSTATE;
143 if (pru_is_running) {
144 seq_puts(s, "PRU is executing, cannot print/access debug registers.\n");
145 return 0;
146 }
148 for (i = 0; i < nregs; i++) {
149 seq_printf(s, "GPREG%-2d := 0x%08x\tCT_REG%-2d := 0x%08x\n",
150 i, pru_debug_read_reg(pru, PRU_DEBUG_GPREG(i)),
151 i, pru_debug_read_reg(pru, PRU_DEBUG_CT_REG(i)));
152 }
154 return 0;
155 }
157 DEFINE_SHOW_ATTRIBUTE(regs);
159 /*
160 * Control PRU single-step mode
161 *
162 * This is a debug helper function used for controlling the single-step
163 * mode of the PRU. The PRU Debug registers are not accessible when the
164 * PRU is in RUNNING state.
165 *
166 * Writing a non-zero value sets the PRU into single-step mode irrespective
167 * of its previous state. The PRU mode is saved only on the first set into
168 * a single-step mode. Writing a zero value will restore the PRU into its
169 * original mode.
170 */
171 static int pru_rproc_debug_ss_set(void *data, u64 val)
172 {
173 struct rproc *rproc = data;
174 struct pru_rproc *pru = rproc->priv;
175 u32 reg_val;
177 val = val ? 1 : 0;
178 if (!val && !pru->dbg_single_step)
179 return 0;
181 reg_val = pru_control_read_reg(pru, PRU_CTRL_CTRL);
183 if (val && !pru->dbg_single_step)
184 pru->dbg_continuous = reg_val;
186 if (val)
187 reg_val |= CTRL_CTRL_SINGLE_STEP | CTRL_CTRL_EN;
188 else
189 reg_val = pru->dbg_continuous;
191 pru->dbg_single_step = val;
192 pru_control_write_reg(pru, PRU_CTRL_CTRL, reg_val);
194 return 0;
195 }
197 static int pru_rproc_debug_ss_get(void *data, u64 *val)
198 {
199 struct rproc *rproc = data;
200 struct pru_rproc *pru = rproc->priv;
202 *val = pru->dbg_single_step;
204 return 0;
205 }
206 DEFINE_SIMPLE_ATTRIBUTE(pru_rproc_debug_ss_fops, pru_rproc_debug_ss_get,
207 pru_rproc_debug_ss_set, "%llu\n");
209 /*
210 * Create PRU-specific debugfs entries
211 *
212 * The entries are created only if the parent remoteproc debugfs directory
213 * exists, and will be cleaned up by the remoteproc core.
214 */
215 static void pru_rproc_create_debug_entries(struct rproc *rproc)
216 {
217 if (!rproc->dbg_dir)
218 return;
220 debugfs_create_file("regs", 0400, rproc->dbg_dir,
221 rproc, ®s_fops);
222 debugfs_create_file("single_step", 0600, rproc->dbg_dir,
223 rproc, &pru_rproc_debug_ss_fops);
224 }
226 /* start a PRU core */
227 static int pru_rproc_start(struct rproc *rproc)
228 {
229 struct device *dev = &rproc->dev;
230 struct pru_rproc *pru = rproc->priv;
231 u32 val;
233 dev_dbg(dev, "starting PRU%d: entry-point = 0x%x\n",
234 pru->id, (rproc->bootaddr >> 2));
236 val = CTRL_CTRL_EN | ((rproc->bootaddr >> 2) << 16);
237 pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
239 return 0;
240 }
242 /* stop/disable a PRU core */
243 static int pru_rproc_stop(struct rproc *rproc)
244 {
245 struct device *dev = &rproc->dev;
246 struct pru_rproc *pru = rproc->priv;
247 u32 val;
249 dev_dbg(dev, "stopping PRU%d\n", pru->id);
251 val = pru_control_read_reg(pru, PRU_CTRL_CTRL);
252 val &= ~CTRL_CTRL_EN;
253 pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
255 /* undo INTC config */
256 pruss_intc_unconfigure(pru->pruss, &pru->intc_config);
258 return 0;
259 }
261 /*
262 * parse the custom PRU interrupt map resource and configure the INTC
263 * appropriately
264 */
265 static int pru_handle_vendor_intrmap(struct rproc *rproc,
266 struct fw_rsc_vendor *rsc)
267 {
268 struct device *dev = rproc->dev.parent;
269 struct pru_rproc *pru = rproc->priv;
270 struct pruss *pruss = pru->pruss;
271 struct pruss_event_chnl *event_chnl_map;
272 struct fw_rsc_pruss_intrmap *intr_rsc =
273 (struct fw_rsc_pruss_intrmap *)rsc->data;
274 int i, ret;
275 s8 sys_evt, chnl, intr_no;
277 dev_dbg(dev, "version %d event_chnl_map_size %d event_chnl_map_addr 0x%x\n",
278 rsc->u.st.st_ver, intr_rsc->event_chnl_map_size,
279 intr_rsc->event_chnl_map_addr);
281 if (rsc->u.st.st_ver != 0) {
282 dev_err(dev, "only PRU interrupt resource version 0 supported\n");
283 return -EINVAL;
284 }
286 if (intr_rsc->event_chnl_map_size < 0 ||
287 intr_rsc->event_chnl_map_size >= MAX_PRU_SYS_EVENTS) {
288 dev_err(dev, "PRU interrupt resource has more events than present on hardware\n");
289 return -EINVAL;
290 }
292 /*
293 * XXX: The event_chnl_map_addr mapping is currently a pointer in device
294 * memory, evaluate if this needs to be directly in firmware file.
295 */
296 event_chnl_map = pru_d_da_to_va(pru, intr_rsc->event_chnl_map_addr,
297 intr_rsc->event_chnl_map_size *
298 sizeof(*event_chnl_map));
299 if (!event_chnl_map) {
300 dev_err(dev, "PRU interrupt resource has inadequate event_chnl_map configuration\n");
301 return -EINVAL;
302 }
304 /* init intc_config to defaults */
305 for (i = 0; i < ARRAY_SIZE(pru->intc_config.sysev_to_ch); i++)
306 pru->intc_config.sysev_to_ch[i] = -1;
308 for (i = 0; i < ARRAY_SIZE(pru->intc_config.ch_to_host); i++)
309 pru->intc_config.ch_to_host[i] = -1;
311 /* parse and fill in system event to interrupt channel mapping */
312 for (i = 0; i < intr_rsc->event_chnl_map_size; i++) {
313 sys_evt = event_chnl_map[i].event;
314 chnl = event_chnl_map[i].chnl;
316 if (sys_evt < 0 || sys_evt >= MAX_PRU_SYS_EVENTS) {
317 dev_err(dev, "[%d] bad sys event %d\n", i, sys_evt);
318 return -EINVAL;
319 }
320 if (chnl < 0 || chnl >= MAX_PRU_CHANNELS) {
321 dev_err(dev, "[%d] bad channel value %d\n", i, chnl);
322 return -EINVAL;
323 }
325 pru->intc_config.sysev_to_ch[sys_evt] = chnl;
326 dev_dbg(dev, "sysevt-to-ch[%d] -> %d\n", sys_evt, chnl);
327 }
329 /* parse and handle interrupt channel-to-host interrupt mapping */
330 for (i = 0; i < MAX_PRU_CHANNELS; i++) {
331 intr_no = intr_rsc->chnl_host_intr_map[i];
332 if (intr_no < 0) {
333 dev_dbg(dev, "skip intr mapping for chnl %d\n", i);
334 continue;
335 }
337 if (intr_no >= MAX_PRU_HOST_INT) {
338 dev_err(dev, "bad intr mapping for chnl %d, intr_no %d\n",
339 i, intr_no);
340 return -EINVAL;
341 }
343 pru->intc_config.ch_to_host[i] = intr_no;
344 dev_dbg(dev, "chnl-to-host[%d] -> %d\n", i, intr_no);
345 }
347 ret = pruss_intc_configure(pruss, &pru->intc_config);
348 if (ret)
349 dev_err(dev, "failed to configure pruss intc %d\n", ret);
351 return ret;
352 }
354 /* PRU-specific vendor resource handler */
355 static int pru_rproc_handle_vendor_rsc(struct rproc *rproc,
356 struct fw_rsc_vendor *rsc)
357 {
358 struct device *dev = rproc->dev.parent;
359 int ret = -EINVAL;
361 switch (rsc->u.st.st_type) {
362 case PRUSS_RSC_INTRS:
363 ret = pru_handle_vendor_intrmap(rproc, rsc);
364 break;
365 default:
366 dev_err(dev, "%s: cannot handle unknown type %d\n", __func__,
367 rsc->u.st.st_type);
368 }
370 return ret;
371 }
373 /*
374 * Convert PRU device address (data spaces only) to kernel virtual address
375 *
376 * Each PRU has access to all data memories within the PRUSS, accessible at
377 * different ranges. So, look through both its primary and secondary Data
378 * RAMs as well as any shared Data RAM to convert a PRU device address to
379 * kernel virtual address. Data RAM0 is primary Data RAM for PRU0 and Data
380 * RAM1 is primary Data RAM for PRU1.
381 */
382 static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, int len)
383 {
384 struct pruss_mem_region dram0, dram1, shrd_ram;
385 struct pruss *pruss = pru->pruss;
386 u32 offset;
387 void *va = NULL;
389 if (len <= 0)
390 return NULL;
392 dram0 = pruss->mem_regions[PRUSS_MEM_DRAM0];
393 dram1 = pruss->mem_regions[PRUSS_MEM_DRAM1];
394 /* PRU1 has its local RAM addresses reversed */
395 if (pru->id == 1)
396 swap(dram0, dram1);
397 shrd_ram = pruss->mem_regions[PRUSS_MEM_SHRD_RAM2];
399 if (da >= pru->pdram_da && da + len <= pru->pdram_da + dram0.size) {
400 offset = da - pru->pdram_da;
401 va = (__force void *)(dram0.va + offset);
402 } else if (da >= pru->sdram_da &&
403 da + len <= pru->sdram_da + dram1.size) {
404 offset = da - pru->sdram_da;
405 va = (__force void *)(dram1.va + offset);
406 } else if (da >= pru->shrdram_da &&
407 da + len <= pru->shrdram_da + shrd_ram.size) {
408 offset = da - pru->shrdram_da;
409 va = (__force void *)(shrd_ram.va + offset);
410 }
412 return va;
413 }
415 /*
416 * Convert PRU device address (instruction space) to kernel virtual address
417 *
418 * A PRU does not have an unified address space. Each PRU has its very own
419 * private Instruction RAM, and its device address is identical to that of
420 * its primary Data RAM device address.
421 */
422 static void *pru_i_da_to_va(struct pru_rproc *pru, u32 da, int len)
423 {
424 u32 offset;
425 void *va = NULL;
427 if (len <= 0)
428 return NULL;
430 if (da >= pru->iram_da &&
431 da + len <= pru->iram_da + pru->mem_regions[PRU_IOMEM_IRAM].size) {
432 offset = da - pru->iram_da;
433 va = (__force void *)(pru->mem_regions[PRU_IOMEM_IRAM].va +
434 offset);
435 }
437 return va;
438 }
440 /* PRU-specific address translator */
441 static void *pru_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
442 {
443 struct pru_rproc *pru = rproc->priv;
444 void *va;
445 u32 exec_flag;
447 exec_flag = ((flags & RPROC_FLAGS_ELF_SHDR) ? flags & SHF_EXECINSTR :
448 ((flags & RPROC_FLAGS_ELF_PHDR) ? flags & PF_X : 0));
450 if (exec_flag)
451 va = pru_i_da_to_va(pru, da, len);
452 else
453 va = pru_d_da_to_va(pru, da, len);
455 return va;
456 }
458 static struct rproc_ops pru_rproc_ops = {
459 .start = pru_rproc_start,
460 .stop = pru_rproc_stop,
461 .handle_vendor_rsc = pru_rproc_handle_vendor_rsc,
462 .da_to_va = pru_da_to_va,
463 };
465 /*
466 * compute PRU id based on the IRAM addresses. The PRU IRAMs are
467 * always at a particular offset within the PRUSS address space.
468 * The other alternative is to use static data for each core (not a
469 * hardware property to define it in DT), and the id can always be
470 * computated using this inherent address logic.
471 */
472 static int pru_rproc_set_id(struct pru_rproc *pru)
473 {
474 int ret = 0;
475 u32 mask1 = PRU0_IRAM_ADDR_MASK;
476 u32 mask2 = PRU1_IRAM_ADDR_MASK;
478 if ((pru->mem_regions[PRU_IOMEM_IRAM].pa & mask1) == mask1)
479 pru->id = 0;
480 else if ((pru->mem_regions[PRU_IOMEM_IRAM].pa & mask2) == mask2)
481 pru->id = 1;
482 else
483 ret = -EINVAL;
485 return ret;
486 }
488 static int pru_rproc_probe(struct platform_device *pdev)
489 {
490 struct device *dev = &pdev->dev;
491 struct device_node *np = dev->of_node;
492 struct platform_device *ppdev = to_platform_device(dev->parent);
493 struct pru_rproc *pru;
494 const char *fw_name;
495 struct rproc *rproc = NULL;
496 struct resource *res;
497 int i, ret;
498 const char *mem_names[PRU_IOMEM_MAX] = { "iram", "control", "debug" };
500 if (!np) {
501 dev_err(dev, "Non-DT platform device not supported\n");
502 return -ENODEV;
503 }
505 ret = of_property_read_string(np, "firmware-name", &fw_name);
506 if (ret) {
507 dev_err(dev, "unable to retrieve firmware-name %d\n", ret);
508 return ret;
509 }
511 rproc = rproc_alloc(dev, pdev->name, &pru_rproc_ops, fw_name,
512 sizeof(*pru));
513 if (!rproc) {
514 dev_err(dev, "rproc_alloc failed\n");
515 return -ENOMEM;
516 }
517 /* error recovery is not supported for PRUs */
518 rproc->recovery_disabled = true;
520 /*
521 * rproc_add will auto-boot the processor normally, but this is
522 * not desired with PRU client driven boot-flow methodology. A PRU
523 * application/client driver will boot the corresponding PRU
524 * remote-processor as part of its state machine either through
525 * the remoteproc sysfs interface or through the equivalent kernel API
526 */
527 rproc->auto_boot = false;
529 pru = rproc->priv;
530 pru->pruss = platform_get_drvdata(ppdev);
531 pru->rproc = rproc;
532 pru->fw_name = fw_name;
534 /* XXX: get this from match data if different in the future */
535 pru->iram_da = 0;
536 pru->pdram_da = 0;
537 pru->sdram_da = 0x2000;
538 pru->shrdram_da = 0x10000;
540 for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
541 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
542 mem_names[i]);
543 pru->mem_regions[i].va = devm_ioremap_resource(dev, res);
544 if (IS_ERR(pru->mem_regions[i].va)) {
545 dev_err(dev, "failed to parse and map memory resource %d %s\n",
546 i, mem_names[i]);
547 ret = PTR_ERR(pru->mem_regions[i].va);
548 goto free_rproc;
549 }
550 pru->mem_regions[i].pa = res->start;
551 pru->mem_regions[i].size = resource_size(res);
553 dev_dbg(dev, "memory %8s: pa %pa size 0x%zx va %p\n",
554 mem_names[i], &pru->mem_regions[i].pa,
555 pru->mem_regions[i].size, pru->mem_regions[i].va);
556 }
558 ret = pru_rproc_set_id(pru);
559 if (ret < 0)
560 goto free_rproc;
562 platform_set_drvdata(pdev, rproc);
564 ret = rproc_add(pru->rproc);
565 if (ret) {
566 dev_err(dev, "rproc_add failed: %d\n", ret);
567 goto free_rproc;
568 }
570 pru_rproc_create_debug_entries(rproc);
572 dev_info(dev, "PRU rproc node %s probed successfully\n", np->full_name);
574 return 0;
576 free_rproc:
577 rproc_free(rproc);
578 return ret;
579 }
581 static int pru_rproc_remove(struct platform_device *pdev)
582 {
583 struct device *dev = &pdev->dev;
584 struct rproc *rproc = platform_get_drvdata(pdev);
586 dev_info(dev, "%s: removing rproc %s\n", __func__, rproc->name);
588 rproc_del(rproc);
589 rproc_free(rproc);
591 return 0;
592 }
594 static const struct of_device_id pru_rproc_match[] = {
595 { .compatible = "ti,am3356-pru", },
596 { .compatible = "ti,am4376-pru", },
597 { .compatible = "ti,am5728-pru", },
598 {},
599 };
600 MODULE_DEVICE_TABLE(of, pru_rproc_match);
602 static struct platform_driver pru_rproc_driver = {
603 .driver = {
604 .name = "pru-rproc",
605 .of_match_table = pru_rproc_match,
606 .suppress_bind_attrs = true,
607 },
608 .probe = pru_rproc_probe,
609 .remove = pru_rproc_remove,
610 };
611 module_platform_driver(pru_rproc_driver);
613 MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
614 MODULE_DESCRIPTION("PRU-ICSS Remote Processor Driver");
615 MODULE_LICENSE("GPL v2");