pru_rproc.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. /*
  2. * PRU-ICSS remoteproc driver for various TI SoCs
  3. *
  4. * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/
  5. * Suman Anna <s-anna@ti.com>
  6. * Andrew F. Davis <afd@ti.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * version 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. */
  17. #include <linux/bitops.h>
  18. #include <linux/debugfs.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/mailbox_client.h>
  21. #include <linux/module.h>
  22. #include <linux/of_device.h>
  23. #include <linux/remoteproc.h>
  24. #include <linux/pruss.h>
  25. #include "remoteproc_internal.h"
  26. #include "pruss.h"
  27. #include "pru_rproc.h"
  28. /* PRU_ICSS_PRU_CTRL registers */
  29. #define PRU_CTRL_CTRL 0x0000
  30. #define PRU_CTRL_STS 0x0004
  31. #define PRU_CTRL_WAKEUP_EN 0x0008
  32. #define PRU_CTRL_CYCLE 0x000C
  33. #define PRU_CTRL_STALL 0x0010
  34. #define PRU_CTRL_CTBIR0 0x0020
  35. #define PRU_CTRL_CTBIR1 0x0024
  36. #define PRU_CTRL_CTPPR0 0x0028
  37. #define PRU_CTRL_CTPPR1 0x002C
  38. /* CTRL register bit-fields */
  39. #define CTRL_CTRL_SOFT_RST_N BIT(0)
  40. #define CTRL_CTRL_EN BIT(1)
  41. #define CTRL_CTRL_SLEEPING BIT(2)
  42. #define CTRL_CTRL_CTR_EN BIT(3)
  43. #define CTRL_CTRL_SINGLE_STEP BIT(8)
  44. #define CTRL_CTRL_RUNSTATE BIT(15)
  45. /* PRU_ICSS_PRU_DEBUG registers */
  46. #define PRU_DEBUG_GPREG(x) (0x0000 + (x) * 4)
  47. #define PRU_DEBUG_CT_REG(x) (0x0080 + (x) * 4)
  48. /**
  49. * enum pru_mem - PRU core memory range identifiers
  50. */
  51. enum pru_mem {
  52. PRU_MEM_IRAM = 0,
  53. PRU_MEM_CTRL,
  54. PRU_MEM_DEBUG,
  55. PRU_MEM_MAX,
  56. };
  57. /**
  58. * struct pru_private_data - PRU core private data
  59. * @id: PRU index
  60. * @fw_name: firmware name to be used for the PRU core
  61. */
  62. struct pru_private_data {
  63. u32 id;
  64. const char *fw_name;
  65. };
  66. /**
  67. * struct pru_match_private_data - private data to handle multiple instances
  68. * @device_name: device name of the PRU processor core instance
  69. * @priv_data: PRU driver private data for this PRU processor core instance
  70. */
  71. struct pru_match_private_data {
  72. const char *device_name;
  73. struct pru_private_data *priv_data;
  74. };
  75. /**
  76. * struct pru_rproc - PRU remoteproc structure
  77. * @id: id of the PRU core within the PRUSS
  78. * @pruss: back-reference to parent PRUSS structure
  79. * @rproc: remoteproc pointer for this PRU core
  80. * @mbox: mailbox channel handle used for vring signalling with MPU
  81. * @client: mailbox client to request the mailbox channel
  82. * @irq_ring: IRQ number to use for processing vring buffers
  83. * @irq_kick: IRQ number to use to perform virtio kick
  84. * @mem_regions: data for each of the PRU memory regions
  85. * @intc_config: PRU INTC configuration data
  86. * @rmw_lock: lock for read, modify, write operations on registers
  87. * @iram_da: device address of Instruction RAM for this PRU
  88. * @pdram_da: device address of primary Data RAM for this PRU
  89. * @sdram_da: device address of secondary Data RAM for this PRU
  90. * @shrdram_da: device address of shared Data RAM
  91. * @fw_name: name of firmware image used during loading
  92. * @dbg_single_step: debug state variable to set PRU into single step mode
  93. * @dbg_continuous: debug state variable to restore PRU execution mode
  94. */
  95. struct pru_rproc {
  96. int id;
  97. struct pruss *pruss;
  98. struct rproc *rproc;
  99. struct mbox_chan *mbox;
  100. struct mbox_client client;
  101. int irq_vring;
  102. int irq_kick;
  103. struct pruss_mem_region mem_regions[PRU_MEM_MAX];
  104. struct pruss_intc_config intc_config;
  105. spinlock_t rmw_lock; /* register access lock */
  106. u32 iram_da;
  107. u32 pdram_da;
  108. u32 sdram_da;
  109. u32 shrdram_da;
  110. const char *fw_name;
  111. u32 dbg_single_step;
  112. u32 dbg_continuous;
  113. };
  114. static inline u32 pru_control_read_reg(struct pru_rproc *pru, unsigned int reg)
  115. {
  116. return readl_relaxed(pru->mem_regions[PRU_MEM_CTRL].va + reg);
  117. }
  118. static inline
  119. void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val)
  120. {
  121. writel_relaxed(val, pru->mem_regions[PRU_MEM_CTRL].va + reg);
  122. }
  123. static inline
  124. void pru_control_set_reg(struct pru_rproc *pru, unsigned int reg,
  125. u32 mask, u32 set)
  126. {
  127. u32 val;
  128. unsigned long flags;
  129. spin_lock_irqsave(&pru->rmw_lock, flags);
  130. val = pru_control_read_reg(pru, reg);
  131. val &= ~mask;
  132. val |= (set & mask);
  133. pru_control_write_reg(pru, reg, val);
  134. spin_unlock_irqrestore(&pru->rmw_lock, flags);
  135. }
  136. /**
  137. * pru_rproc_set_ctable() - set the constant table index for the PRU
  138. * @rproc: the rproc instance of the PRU
  139. * @c: constant table index to set
  140. * @addr: physical address to set it to
  141. */
  142. int pru_rproc_set_ctable(struct rproc *rproc, enum pru_ctable_idx c, u32 addr)
  143. {
  144. struct pru_rproc *pru = rproc->priv;
  145. unsigned int reg;
  146. u32 mask, set;
  147. u16 idx;
  148. u16 idx_mask;
  149. /* pointer is 16 bit and index is 8-bit so mask out the rest */
  150. idx_mask = (c >= PRU_C28) ? 0xFFFF : 0xFF;
  151. /* ctable uses bit 8 and upwards only */
  152. idx = (addr >> 8) & idx_mask;
  153. /* configurable ctable (i.e. C24) starts at PRU_CTRL_CTBIR0 */
  154. reg = PRU_CTRL_CTBIR0 + 4 * (c >> 1);
  155. mask = idx_mask << (16 * (c & 1));
  156. set = idx << (16 * (c & 1));
  157. pru_control_set_reg(pru, reg, mask, set);
  158. return 0;
  159. }
  160. EXPORT_SYMBOL_GPL(pru_rproc_set_ctable);
  161. static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg)
  162. {
  163. return readl_relaxed(pru->mem_regions[PRU_MEM_DEBUG].va + reg);
  164. }
  165. static inline
  166. void pru_debug_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val)
  167. {
  168. writel_relaxed(val, pru->mem_regions[PRU_MEM_DEBUG].va + reg);
  169. }
  170. /*
  171. * Convert PRU device address (data spaces only) to kernel virtual address
  172. *
  173. * Each PRU has access to all data memories within the PRUSS, accessible at
  174. * different ranges. So, look through both its primary and secondary Data
  175. * RAMs as well as any shared Data RAM to convert a PRU device address to
  176. * kernel virtual address. Data RAM0 is primary Data RAM for PRU0 and Data
  177. * RAM1 is primary Data RAM for PRU1.
  178. */
  179. static void *pru_d_da_to_va(struct pru_rproc *pru, u32 da, int len)
  180. {
  181. struct pruss_mem_region dram0, dram1, shrd_ram;
  182. struct pruss *pruss = pru->pruss;
  183. u32 offset;
  184. void *va = NULL;
  185. if (len <= 0)
  186. return NULL;
  187. dram0 = pruss->mem_regions[PRUSS_MEM_DRAM0];
  188. dram1 = pruss->mem_regions[PRUSS_MEM_DRAM1];
  189. /* PRU1 has its local RAM addresses reversed */
  190. if (pru->id == 1)
  191. swap(dram0, dram1);
  192. shrd_ram = pruss->mem_regions[PRUSS_MEM_SHRD_RAM2];
  193. if (da >= pru->pdram_da && da + len <= pru->pdram_da + dram0.size) {
  194. offset = da - pru->pdram_da;
  195. va = (__force void *)(dram0.va + offset);
  196. } else if (da >= pru->sdram_da &&
  197. da + len <= pru->sdram_da + dram1.size) {
  198. offset = da - pru->sdram_da;
  199. va = (__force void *)(dram1.va + offset);
  200. } else if (da >= pru->shrdram_da &&
  201. da + len <= pru->shrdram_da + shrd_ram.size) {
  202. offset = da - pru->shrdram_da;
  203. va = (__force void *)(shrd_ram.va + offset);
  204. }
  205. return va;
  206. }
  207. /*
  208. * Convert PRU device address (instruction space) to kernel virtual address
  209. *
  210. * A PRU does not have an unified address space. Each PRU has its very own
  211. * private Instruction RAM, and its device address is identical to that of
  212. * its primary Data RAM device address.
  213. */
  214. static void *pru_i_da_to_va(struct pru_rproc *pru, u32 da, int len)
  215. {
  216. u32 offset;
  217. void *va = NULL;
  218. if (len <= 0)
  219. return NULL;
  220. if (da >= pru->iram_da &&
  221. da + len <= pru->iram_da + pru->mem_regions[PRU_MEM_IRAM].size) {
  222. offset = da - pru->iram_da;
  223. va = (__force void *)(pru->mem_regions[PRU_MEM_IRAM].va +
  224. offset);
  225. }
  226. return va;
  227. }
  228. static int pru_rproc_debug_read_regs(struct seq_file *s, void *data)
  229. {
  230. struct rproc *rproc = s->private;
  231. struct pru_rproc *pru = rproc->priv;
  232. int i, nregs = 32;
  233. u32 pru_sts;
  234. int pru_is_running;
  235. seq_puts(s, "============== Control Registers ==============\n");
  236. seq_printf(s, "CTRL := 0x%08x\n",
  237. pru_control_read_reg(pru, PRU_CTRL_CTRL));
  238. pru_sts = pru_control_read_reg(pru, PRU_CTRL_STS);
  239. seq_printf(s, "STS (PC) := 0x%08x (0x%08x)\n", pru_sts, pru_sts << 2);
  240. seq_printf(s, "WAKEUP_EN := 0x%08x\n",
  241. pru_control_read_reg(pru, PRU_CTRL_WAKEUP_EN));
  242. seq_printf(s, "CYCLE := 0x%08x\n",
  243. pru_control_read_reg(pru, PRU_CTRL_CYCLE));
  244. seq_printf(s, "STALL := 0x%08x\n",
  245. pru_control_read_reg(pru, PRU_CTRL_STALL));
  246. seq_printf(s, "CTBIR0 := 0x%08x\n",
  247. pru_control_read_reg(pru, PRU_CTRL_CTBIR0));
  248. seq_printf(s, "CTBIR1 := 0x%08x\n",
  249. pru_control_read_reg(pru, PRU_CTRL_CTBIR1));
  250. seq_printf(s, "CTPPR0 := 0x%08x\n",
  251. pru_control_read_reg(pru, PRU_CTRL_CTPPR0));
  252. seq_printf(s, "CTPPR1 := 0x%08x\n",
  253. pru_control_read_reg(pru, PRU_CTRL_CTPPR1));
  254. seq_puts(s, "=============== Debug Registers ===============\n");
  255. pru_is_running = pru_control_read_reg(pru, PRU_CTRL_CTRL) &
  256. CTRL_CTRL_RUNSTATE;
  257. if (pru_is_running) {
  258. seq_puts(s, "PRU is executing, cannot print/access debug registers.\n");
  259. return 0;
  260. }
  261. for (i = 0; i < nregs; i++) {
  262. seq_printf(s, "GPREG%-2d := 0x%08x\tCT_REG%-2d := 0x%08x\n",
  263. i, pru_debug_read_reg(pru, PRU_DEBUG_GPREG(i)),
  264. i, pru_debug_read_reg(pru, PRU_DEBUG_CT_REG(i)));
  265. }
  266. return 0;
  267. }
  268. static int pru_rproc_debug_regs_open(struct inode *inode, struct file *file)
  269. {
  270. return single_open(file, pru_rproc_debug_read_regs, inode->i_private);
  271. }
  272. static const struct file_operations pru_rproc_debug_regs_ops = {
  273. .open = pru_rproc_debug_regs_open,
  274. .read = seq_read,
  275. .llseek = seq_lseek,
  276. .release = single_release,
  277. };
  278. /*
  279. * Control PRU single-step mode
  280. *
  281. * This is a debug helper function used for controlling the single-step
  282. * mode of the PRU. The PRU Debug registers are not accessible when the
  283. * PRU is in RUNNING state.
  284. *
  285. * Writing a non-zero value sets the PRU into single-step mode irrespective
  286. * of its previous state. The PRU mode is saved only on the first set into
  287. * a single-step mode. Writing a non-zero value will restore the PRU into
  288. * its original mode.
  289. */
  290. static int pru_rproc_debug_ss_set(void *data, u64 val)
  291. {
  292. struct rproc *rproc = data;
  293. struct pru_rproc *pru = rproc->priv;
  294. u32 reg_val;
  295. val = val ? 1 : 0;
  296. if (!val && !pru->dbg_single_step)
  297. return 0;
  298. reg_val = pru_control_read_reg(pru, PRU_CTRL_CTRL);
  299. if (val && !pru->dbg_single_step)
  300. pru->dbg_continuous = reg_val;
  301. if (val)
  302. reg_val |= CTRL_CTRL_SINGLE_STEP | CTRL_CTRL_EN;
  303. else
  304. reg_val = pru->dbg_continuous;
  305. pru->dbg_single_step = val;
  306. pru_control_write_reg(pru, PRU_CTRL_CTRL, reg_val);
  307. return 0;
  308. }
  309. static int pru_rproc_debug_ss_get(void *data, u64 *val)
  310. {
  311. struct rproc *rproc = data;
  312. struct pru_rproc *pru = rproc->priv;
  313. *val = pru->dbg_single_step;
  314. return 0;
  315. }
  316. DEFINE_SIMPLE_ATTRIBUTE(pru_rproc_debug_ss_fops, pru_rproc_debug_ss_get,
  317. pru_rproc_debug_ss_set, "%llu\n");
  318. /*
  319. * Create PRU-specific debugfs entries
  320. *
  321. * The entries are created only if the parent remoteproc debugfs directory
  322. * exists, and will be cleaned up by the remoteproc core.
  323. */
  324. static void pru_rproc_create_debug_entries(struct rproc *rproc)
  325. {
  326. if (!rproc->dbg_dir)
  327. return;
  328. debugfs_create_file("regs", 0400, rproc->dbg_dir,
  329. rproc, &pru_rproc_debug_regs_ops);
  330. debugfs_create_file("single_step", 0600, rproc->dbg_dir,
  331. rproc, &pru_rproc_debug_ss_fops);
  332. }
  333. /**
  334. * pru_rproc_mbox_callback() - inbound mailbox message handler
  335. * @client: mailbox client pointer used for requesting the mailbox channel
  336. * @data: mailbox payload
  337. *
  338. * This handler is invoked by omap's mailbox driver whenever a mailbox
  339. * message is received. Usually, the mailbox payload simply contains
  340. * the index of the virtqueue that is kicked by the PRU remote processor,
  341. * and we let remoteproc core handle it.
  342. *
  343. * In addition to virtqueue indices, we might also have some out-of-band
  344. * values that indicates different events. Those values are deliberately
  345. * very big so they don't coincide with virtqueue indices.
  346. */
  347. static void pru_rproc_mbox_callback(struct mbox_client *client, void *data)
  348. {
  349. struct pru_rproc *pru = container_of(client, struct pru_rproc, client);
  350. struct device *dev = &pru->rproc->dev;
  351. u32 msg = (u32)data;
  352. dev_dbg(dev, "mbox msg: 0x%x\n", msg);
  353. /* msg contains the index of the triggered vring */
  354. if (rproc_vq_interrupt(pru->rproc, msg) == IRQ_NONE)
  355. dev_dbg(dev, "no message was found in vqid %d\n", msg);
  356. }
  357. /**
  358. * pru_rproc_vring_interrupt() - interrupt handler for processing vrings
  359. * @irq: irq number associated with the PRU event MPU is listening on
  360. * @data: interrupt handler data, will be a PRU rproc structure
  361. *
  362. * This handler is used by the PRU remoteproc driver when using PRU system
  363. * events for processing the virtqueues. Unlike the mailbox IP, there is
  364. * no payload associated with an interrupt, so either a unique event is
  365. * used for each virtqueue kick, or a both virtqueues are processed on
  366. * a single event. The latter is chosen to conserve the usable PRU system
  367. * events.
  368. */
  369. static irqreturn_t pru_rproc_vring_interrupt(int irq, void *data)
  370. {
  371. struct pru_rproc *pru = data;
  372. dev_dbg(&pru->rproc->dev, "got vring irq\n");
  373. /* process incoming buffers on both the Rx and Tx vrings */
  374. rproc_vq_interrupt(pru->rproc, 0);
  375. rproc_vq_interrupt(pru->rproc, 1);
  376. return IRQ_HANDLED;
  377. }
  378. /* kick a virtqueue */
  379. static void pru_rproc_kick(struct rproc *rproc, int vq_id)
  380. {
  381. struct device *dev = &rproc->dev;
  382. struct pru_rproc *pru = rproc->priv;
  383. int ret;
  384. dev_dbg(dev, "kicking vqid %d on PRU%d\n", vq_id, pru->id);
  385. if (pru->mbox) {
  386. /*
  387. * send the index of the triggered virtqueue in the mailbox
  388. * payload
  389. */
  390. ret = mbox_send_message(pru->mbox, (void *)vq_id);
  391. if (ret < 0)
  392. dev_err(dev, "mbox_send_message failed: %d\n", ret);
  393. } else if (pru->irq_kick > 0) {
  394. ret = pruss_intc_trigger(pru->irq_kick);
  395. if (ret < 0)
  396. dev_err(dev, "pruss_intc_trigger failed: %d\n", ret);
  397. }
  398. }
  399. /* start a PRU core */
  400. static int pru_rproc_start(struct rproc *rproc)
  401. {
  402. struct device *dev = &rproc->dev;
  403. struct pru_rproc *pru = rproc->priv;
  404. u32 val;
  405. int ret;
  406. dev_dbg(dev, "starting PRU%d: entry-point = 0x%x\n",
  407. pru->id, (rproc->bootaddr >> 2));
  408. if (!list_empty(&pru->rproc->rvdevs)) {
  409. if (!pru->mbox && (pru->irq_vring <= 0 || pru->irq_kick <= 0)) {
  410. dev_err(dev, "virtio vring interrupt mechanisms are not provided\n");
  411. ret = -EINVAL;
  412. goto fail;
  413. }
  414. if (!pru->mbox && pru->irq_vring > 0) {
  415. ret = request_threaded_irq(pru->irq_vring, NULL,
  416. pru_rproc_vring_interrupt,
  417. IRQF_ONESHOT, dev_name(dev),
  418. pru);
  419. if (ret) {
  420. dev_err(dev, "failed to enable vring interrupt, ret = %d\n",
  421. ret);
  422. goto fail;
  423. }
  424. }
  425. }
  426. val = CTRL_CTRL_EN | ((rproc->bootaddr >> 2) << 16);
  427. pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
  428. return 0;
  429. fail:
  430. pruss_intc_unconfigure(pru->pruss, &pru->intc_config);
  431. return ret;
  432. }
  433. /* stop/disable a PRU core */
  434. static int pru_rproc_stop(struct rproc *rproc)
  435. {
  436. struct device *dev = &rproc->dev;
  437. struct pru_rproc *pru = rproc->priv;
  438. u32 val;
  439. dev_dbg(dev, "stopping PRU%d\n", pru->id);
  440. val = pru_control_read_reg(pru, PRU_CTRL_CTRL);
  441. val &= ~CTRL_CTRL_EN;
  442. pru_control_write_reg(pru, PRU_CTRL_CTRL, val);
  443. if (!list_empty(&pru->rproc->rvdevs) &&
  444. !pru->mbox && pru->irq_vring > 0)
  445. free_irq(pru->irq_vring, pru);
  446. /* undo INTC config */
  447. pruss_intc_unconfigure(pru->pruss, &pru->intc_config);
  448. return 0;
  449. }
  450. /*
  451. * parse the custom interrupt map resource and configure the INTC
  452. * appropriately
  453. */
  454. static int pru_handle_custom_intrmap(struct rproc *rproc,
  455. struct fw_rsc_custom_intrmap *intr_rsc)
  456. {
  457. struct device *dev = rproc->dev.parent;
  458. struct pru_rproc *pru = rproc->priv;
  459. struct pruss *pruss = pru->pruss;
  460. struct pruss_event_chnl *event_chnl_map;
  461. int i, ret;
  462. s8 sys_evt, chnl, intr_no;
  463. dev_dbg(dev, "version %d event_chnl_map_size %d event_chnl_map %p\n",
  464. intr_rsc->version, intr_rsc->event_chnl_map_size,
  465. intr_rsc->event_chnl_map);
  466. if (intr_rsc->version != 0) {
  467. dev_err(dev, "only custom ints resource version 0 supported\n");
  468. return -EINVAL;
  469. }
  470. if (intr_rsc->event_chnl_map_size < 0 ||
  471. intr_rsc->event_chnl_map_size >= MAX_PRU_SYS_EVENTS) {
  472. dev_err(dev, "custom ints resource has more events than present on hardware\n");
  473. return -EINVAL;
  474. }
  475. /*
  476. * XXX: The event_chnl_map mapping is currently a pointer in device
  477. * memory, evaluate if this needs to be directly in firmware file.
  478. */
  479. event_chnl_map = pru_d_da_to_va(pru, (u32)intr_rsc->event_chnl_map,
  480. intr_rsc->event_chnl_map_size *
  481. sizeof(*event_chnl_map));
  482. if (!event_chnl_map) {
  483. dev_err(dev, "custom ints resource has inadequate event_chnl_map configuration\n");
  484. return -EINVAL;
  485. }
  486. /* init intc_config to defaults */
  487. for (i = 0; i < ARRAY_SIZE(pru->intc_config.sysev_to_ch); i++)
  488. pru->intc_config.sysev_to_ch[i] = -1;
  489. for (i = 0; i < ARRAY_SIZE(pru->intc_config.ch_to_host); i++)
  490. pru->intc_config.ch_to_host[i] = -1;
  491. /* parse and fill in system event to interrupt channel mapping */
  492. for (i = 0; i < intr_rsc->event_chnl_map_size; i++) {
  493. sys_evt = event_chnl_map[i].event;
  494. chnl = event_chnl_map[i].chnl;
  495. if (sys_evt < 0 || sys_evt >= MAX_PRU_SYS_EVENTS) {
  496. dev_err(dev, "[%d] bad sys event %d\n", i, sys_evt);
  497. return -EINVAL;
  498. }
  499. if (chnl < 0 || chnl >= MAX_PRU_CHANNELS) {
  500. dev_err(dev, "[%d] bad channel value %d\n", i, chnl);
  501. return -EINVAL;
  502. }
  503. pru->intc_config.sysev_to_ch[sys_evt] = chnl;
  504. dev_dbg(dev, "sysevt-to-ch[%d] -> %d\n", sys_evt, chnl);
  505. }
  506. /* parse and handle interrupt channel-to-host interrupt mapping */
  507. for (i = 0; i < MAX_PRU_CHANNELS; i++) {
  508. intr_no = intr_rsc->chnl_host_intr_map[i];
  509. if (intr_no < 0) {
  510. dev_dbg(dev, "skip intr mapping for chnl %d\n", i);
  511. continue;
  512. }
  513. if (intr_no >= MAX_PRU_HOST_INT) {
  514. dev_err(dev, "bad intr mapping for chnl %d, intr_no %d\n",
  515. i, intr_no);
  516. return -EINVAL;
  517. }
  518. pru->intc_config.ch_to_host[i] = intr_no;
  519. dev_dbg(dev, "chnl-to-host[%d] -> %d\n", i, intr_no);
  520. }
  521. ret = pruss_intc_configure(pruss, &pru->intc_config);
  522. if (ret)
  523. dev_err(dev, "failed to configure pruss intc %d\n", ret);
  524. return ret;
  525. }
  526. /* PRU-specific post loading custom resource handler */
  527. static int pru_rproc_handle_custom_rsc(struct rproc *rproc,
  528. struct fw_rsc_custom *rsc)
  529. {
  530. struct device *dev = rproc->dev.parent;
  531. int ret = -EINVAL;
  532. switch (rsc->sub_type) {
  533. case PRUSS_RSC_INTRS:
  534. ret = pru_handle_custom_intrmap(rproc,
  535. (struct fw_rsc_custom_intrmap *)
  536. rsc->data);
  537. break;
  538. default:
  539. dev_err(dev, "%s: handling unknown type %d\n", __func__,
  540. rsc->sub_type);
  541. }
  542. return ret;
  543. }
  544. /* PRU-specific address translator */
  545. static void *pru_da_to_va(struct rproc *rproc, u64 da, int len, u32 flags)
  546. {
  547. struct pru_rproc *pru = rproc->priv;
  548. void *va;
  549. u32 exec_flag;
  550. exec_flag = ((flags & RPROC_FLAGS_ELF_SHDR) ? flags & SHF_EXECINSTR :
  551. ((flags & RPROC_FLAGS_ELF_PHDR) ? flags & PF_X : 0));
  552. if (exec_flag)
  553. va = pru_i_da_to_va(pru, da, len);
  554. else
  555. va = pru_d_da_to_va(pru, da, len);
  556. return va;
  557. }
  558. static struct rproc_ops pru_rproc_ops = {
  559. .start = pru_rproc_start,
  560. .stop = pru_rproc_stop,
  561. .kick = pru_rproc_kick,
  562. .handle_custom_rsc = pru_rproc_handle_custom_rsc,
  563. .da_to_va = pru_da_to_va,
  564. };
  565. static const struct of_device_id pru_rproc_match[];
  566. static const struct pru_private_data *pru_rproc_get_private_data(
  567. struct platform_device *pdev)
  568. {
  569. const struct pru_match_private_data *data;
  570. const struct of_device_id *match;
  571. match = of_match_device(pru_rproc_match, &pdev->dev);
  572. if (!match)
  573. return ERR_PTR(-ENODEV);
  574. for (data = match->data; data && data->device_name; data++) {
  575. if (!strcmp(dev_name(&pdev->dev), data->device_name))
  576. return data->priv_data;
  577. }
  578. return NULL;
  579. }
  580. static int pru_rproc_probe(struct platform_device *pdev)
  581. {
  582. struct device *dev = &pdev->dev;
  583. struct device_node *np = dev->of_node;
  584. struct platform_device *ppdev = to_platform_device(dev->parent);
  585. struct pru_rproc *pru;
  586. const struct pru_private_data *pdata;
  587. struct rproc *rproc = NULL;
  588. struct mbox_client *client;
  589. struct resource *res;
  590. int i, ret;
  591. const char *mem_names[PRU_MEM_MAX] = { "iram", "control", "debug" };
  592. u32 mux_sel;
  593. if (!np) {
  594. dev_err(dev, "Non-DT platform device not supported\n");
  595. return -ENODEV;
  596. }
  597. pdata = pru_rproc_get_private_data(pdev);
  598. if (IS_ERR_OR_NULL(pdata) || !pdata->fw_name) {
  599. dev_err(dev, "missing or incomplete PRU-private data\n");
  600. return -ENODEV;
  601. }
  602. rproc = rproc_alloc(dev, pdev->name, &pru_rproc_ops, pdata->fw_name,
  603. sizeof(*pru));
  604. if (!rproc) {
  605. dev_err(dev, "rproc_alloc failed\n");
  606. return -ENOMEM;
  607. }
  608. /* error recovery is not supported for PRUs */
  609. rproc->recovery_disabled = true;
  610. /*
  611. * rproc_add will auto-boot the processor normally, but this is
  612. * not desired with PRU client driven boot-flow methodoly. A PRU
  613. * application/client driver will boot the corresponding PRU
  614. * remote-processor as part of its state machine either through
  615. * the remoteproc sysfs interface or through the equivalent kernel API
  616. */
  617. rproc->auto_boot = false;
  618. pru = rproc->priv;
  619. pru->id = pdata->id;
  620. pru->pruss = platform_get_drvdata(ppdev);
  621. pru->rproc = rproc;
  622. pru->fw_name = pdata->fw_name;
  623. spin_lock_init(&pru->rmw_lock);
  624. /* XXX: get this from match data if different in the future */
  625. pru->iram_da = 0;
  626. pru->pdram_da = 0;
  627. pru->sdram_da = 0x2000;
  628. pru->shrdram_da = 0x10000;
  629. for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
  630. res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
  631. mem_names[i]);
  632. pru->mem_regions[i].va = devm_ioremap_resource(dev, res);
  633. if (IS_ERR(pru->mem_regions[i].va)) {
  634. dev_err(dev, "failed to parse and map memory resource %d %s\n",
  635. i, mem_names[i]);
  636. ret = PTR_ERR(pru->mem_regions[i].va);
  637. goto free_rproc;
  638. }
  639. pru->mem_regions[i].pa = res->start;
  640. pru->mem_regions[i].size = resource_size(res);
  641. dev_dbg(dev, "memory %8s: pa %pa size 0x%x va %p\n",
  642. mem_names[i], &pru->mem_regions[i].pa,
  643. pru->mem_regions[i].size, pru->mem_regions[i].va);
  644. }
  645. platform_set_drvdata(pdev, rproc);
  646. client = &pru->client;
  647. client->dev = dev;
  648. client->tx_done = NULL;
  649. client->rx_callback = pru_rproc_mbox_callback;
  650. client->tx_block = false;
  651. client->knows_txdone = false;
  652. pru->mbox = mbox_request_channel(client, 0);
  653. if (IS_ERR(pru->mbox)) {
  654. ret = PTR_ERR(pru->mbox);
  655. pru->mbox = NULL;
  656. dev_dbg(dev, "mbox_request_channel failed: %d\n", ret);
  657. }
  658. pru->irq_vring = platform_get_irq_byname(pdev, "vring");
  659. if (pru->irq_vring <= 0) {
  660. ret = pru->irq_vring;
  661. if (ret == -EPROBE_DEFER)
  662. goto free_rproc;
  663. dev_dbg(dev, "unable to get vring interrupt, status = %d\n",
  664. ret);
  665. }
  666. pru->irq_kick = platform_get_irq_byname(pdev, "kick");
  667. if (pru->irq_kick <= 0) {
  668. ret = pru->irq_kick;
  669. if (ret == -EPROBE_DEFER)
  670. goto free_rproc;
  671. dev_dbg(dev, "unable to get kick interrupt, status = %d\n",
  672. ret);
  673. }
  674. if (pru->mbox && (pru->irq_vring > 0 || pru->irq_kick > 0))
  675. dev_warn(dev, "both mailbox and vring/kick system events defined\n");
  676. ret = rproc_add(pru->rproc);
  677. if (ret) {
  678. dev_err(dev, "rproc_add failed: %d\n", ret);
  679. goto put_mbox;
  680. }
  681. if ((of_machine_is_compatible("ti,am5718-idk") ||
  682. of_machine_is_compatible("ti,k2g-ice")) &&
  683. !of_property_read_u32(np, "ti,pruss-gp-mux-sel", &mux_sel)) {
  684. if (mux_sel < PRUSS_GP_MUX_SEL_GP ||
  685. mux_sel >= PRUSS_GP_MUX_MAX) {
  686. dev_err(dev, "invalid gp_mux_sel %d\n", mux_sel);
  687. ret = -EINVAL;
  688. goto del_rproc;
  689. }
  690. ret = pruss_cfg_set_gpmux(pru->pruss, pru->id, mux_sel);
  691. if (ret)
  692. goto del_rproc;
  693. }
  694. pru_rproc_create_debug_entries(rproc);
  695. dev_info(dev, "PRU rproc node %s probed successfully\n", np->full_name);
  696. return 0;
  697. del_rproc:
  698. rproc_del(rproc);
  699. put_mbox:
  700. mbox_free_channel(pru->mbox);
  701. free_rproc:
  702. rproc_free(rproc);
  703. return ret;
  704. }
  705. static int pru_rproc_remove(struct platform_device *pdev)
  706. {
  707. struct device *dev = &pdev->dev;
  708. struct rproc *rproc = platform_get_drvdata(pdev);
  709. struct pru_rproc *pru = rproc->priv;
  710. dev_info(dev, "%s: removing rproc %s\n", __func__, rproc->name);
  711. mbox_free_channel(pru->mbox);
  712. if ((of_machine_is_compatible("ti,am5718-idk") ||
  713. of_machine_is_compatible("ti,k2g-ice")))
  714. pruss_cfg_set_gpmux(pru->pruss, pru->id, PRUSS_GP_MUX_SEL_GP);
  715. rproc_del(rproc);
  716. rproc_free(rproc);
  717. return 0;
  718. }
  719. /* AM33xx PRU core-specific private data */
  720. static struct pru_private_data am335x_pru0_rproc_pdata = {
  721. .id = 0,
  722. .fw_name = "am335x-pru0-fw",
  723. };
  724. static struct pru_private_data am335x_pru1_rproc_pdata = {
  725. .id = 1,
  726. .fw_name = "am335x-pru1-fw",
  727. };
  728. /* AM437x PRUSS1 PRU core-specific private data */
  729. static struct pru_private_data am437x_pru1_0_rproc_pdata = {
  730. .id = 0,
  731. .fw_name = "am437x-pru1_0-fw",
  732. };
  733. static struct pru_private_data am437x_pru1_1_rproc_pdata = {
  734. .id = 1,
  735. .fw_name = "am437x-pru1_1-fw",
  736. };
  737. /* AM437x PRUSS0 PRU core-specific private data */
  738. static struct pru_private_data am437x_pru0_0_rproc_pdata = {
  739. .id = 0,
  740. .fw_name = "am437x-pru0_0-fw",
  741. };
  742. static struct pru_private_data am437x_pru0_1_rproc_pdata = {
  743. .id = 1,
  744. .fw_name = "am437x-pru0_1-fw",
  745. };
  746. /* AM57xx PRUSS1 PRU core-specific private data */
  747. static struct pru_private_data am57xx_pru1_0_rproc_pdata = {
  748. .id = 0,
  749. .fw_name = "am57xx-pru1_0-fw",
  750. };
  751. static struct pru_private_data am57xx_pru1_1_rproc_pdata = {
  752. .id = 1,
  753. .fw_name = "am57xx-pru1_1-fw",
  754. };
  755. /* AM57xx PRUSS2 PRU core-specific private data */
  756. static struct pru_private_data am57xx_pru2_0_rproc_pdata = {
  757. .id = 0,
  758. .fw_name = "am57xx-pru2_0-fw",
  759. };
  760. static struct pru_private_data am57xx_pru2_1_rproc_pdata = {
  761. .id = 1,
  762. .fw_name = "am57xx-pru2_1-fw",
  763. };
  764. /* 66AK2G PRUSS0 PRU core-specific private data */
  765. static struct pru_private_data k2g_pru0_0_rproc_pdata = {
  766. .id = 0,
  767. .fw_name = "k2g-pru0_0-fw",
  768. };
  769. static struct pru_private_data k2g_pru0_1_rproc_pdata = {
  770. .id = 1,
  771. .fw_name = "k2g-pru0_1-fw",
  772. };
  773. static struct pru_private_data k2g_pru1_0_rproc_pdata = {
  774. .id = 0,
  775. .fw_name = "k2g-pru1_0-fw",
  776. };
  777. static struct pru_private_data k2g_pru1_1_rproc_pdata = {
  778. .id = 1,
  779. .fw_name = "k2g-pru1_1-fw",
  780. };
  781. /* AM33xx SoC-specific PRU Device data */
  782. static struct pru_match_private_data am335x_pru_match_data[] = {
  783. {
  784. .device_name = "4a334000.pru0",
  785. .priv_data = &am335x_pru0_rproc_pdata,
  786. },
  787. {
  788. .device_name = "4a338000.pru1",
  789. .priv_data = &am335x_pru1_rproc_pdata,
  790. },
  791. {
  792. /* sentinel */
  793. },
  794. };
  795. /* AM43xx SoC-specific PRU Device data */
  796. static struct pru_match_private_data am437x_pru_match_data[] = {
  797. {
  798. .device_name = "54434000.pru0",
  799. .priv_data = &am437x_pru1_0_rproc_pdata,
  800. },
  801. {
  802. .device_name = "54438000.pru1",
  803. .priv_data = &am437x_pru1_1_rproc_pdata,
  804. },
  805. {
  806. .device_name = "54474000.pru0",
  807. .priv_data = &am437x_pru0_0_rproc_pdata,
  808. },
  809. {
  810. .device_name = "54478000.pru1",
  811. .priv_data = &am437x_pru0_1_rproc_pdata,
  812. },
  813. {
  814. /* sentinel */
  815. },
  816. };
  817. /* AM57xx SoC-specific PRU Device data */
  818. static struct pru_match_private_data am57xx_pru_match_data[] = {
  819. {
  820. .device_name = "4b234000.pru0",
  821. .priv_data = &am57xx_pru1_0_rproc_pdata,
  822. },
  823. {
  824. .device_name = "4b238000.pru1",
  825. .priv_data = &am57xx_pru1_1_rproc_pdata,
  826. },
  827. {
  828. .device_name = "4b2b4000.pru0",
  829. .priv_data = &am57xx_pru2_0_rproc_pdata,
  830. },
  831. {
  832. .device_name = "4b2b8000.pru1",
  833. .priv_data = &am57xx_pru2_1_rproc_pdata,
  834. },
  835. {
  836. /* sentinel */
  837. },
  838. };
  839. /* 66AK2G SoC-specific PRU Device data */
  840. static struct pru_match_private_data k2g_pru_match_data[] = {
  841. {
  842. .device_name = "20ab4000.pru0",
  843. .priv_data = &k2g_pru0_0_rproc_pdata,
  844. },
  845. {
  846. .device_name = "20ab8000.pru1",
  847. .priv_data = &k2g_pru0_1_rproc_pdata,
  848. },
  849. {
  850. .device_name = "20af4000.pru0",
  851. .priv_data = &k2g_pru1_0_rproc_pdata,
  852. },
  853. {
  854. .device_name = "20af8000.pru1",
  855. .priv_data = &k2g_pru1_1_rproc_pdata,
  856. },
  857. {
  858. /* sentinel */
  859. },
  860. };
  861. static const struct of_device_id pru_rproc_match[] = {
  862. { .compatible = "ti,am3356-pru", .data = am335x_pru_match_data, },
  863. { .compatible = "ti,am4376-pru", .data = am437x_pru_match_data, },
  864. { .compatible = "ti,am5728-pru", .data = am57xx_pru_match_data, },
  865. { .compatible = "ti,k2g-pru", .data = k2g_pru_match_data, },
  866. {},
  867. };
  868. MODULE_DEVICE_TABLE(of, pru_rproc_match);
  869. static struct platform_driver pru_rproc_driver = {
  870. .driver = {
  871. .name = "pru-rproc",
  872. .of_match_table = pru_rproc_match,
  873. .suppress_bind_attrs = true,
  874. },
  875. .probe = pru_rproc_probe,
  876. .remove = pru_rproc_remove,
  877. };
  878. module_platform_driver(pru_rproc_driver);
  879. MODULE_AUTHOR("Suman Anna <s-anna@ti.com>");
  880. MODULE_DESCRIPTION("PRU-ICSS Remote Processor Driver");
  881. MODULE_LICENSE("GPL v2");