axon_msi.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /*
  2. * Copyright 2007, Michael Ellerman, IBM Corporation.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. */
  9. #include <linux/interrupt.h>
  10. #include <linux/irq.h>
  11. #include <linux/kernel.h>
  12. #include <linux/pci.h>
  13. #include <linux/msi.h>
  14. #include <linux/of_platform.h>
  15. #include <linux/debugfs.h>
  16. #include <asm/dcr.h>
  17. #include <asm/machdep.h>
  18. #include <asm/prom.h>
  19. /*
  20. * MSIC registers, specified as offsets from dcr_base
  21. */
  22. #define MSIC_CTRL_REG 0x0
  23. /* Base Address registers specify FIFO location in BE memory */
  24. #define MSIC_BASE_ADDR_HI_REG 0x3
  25. #define MSIC_BASE_ADDR_LO_REG 0x4
  26. /* Hold the read/write offsets into the FIFO */
  27. #define MSIC_READ_OFFSET_REG 0x5
  28. #define MSIC_WRITE_OFFSET_REG 0x6
  29. /* MSIC control register flags */
  30. #define MSIC_CTRL_ENABLE 0x0001
  31. #define MSIC_CTRL_FIFO_FULL_ENABLE 0x0002
  32. #define MSIC_CTRL_IRQ_ENABLE 0x0008
  33. #define MSIC_CTRL_FULL_STOP_ENABLE 0x0010
  34. /*
  35. * The MSIC can be configured to use a FIFO of 32KB, 64KB, 128KB or 256KB.
  36. * Currently we're using a 64KB FIFO size.
  37. */
  38. #define MSIC_FIFO_SIZE_SHIFT 16
  39. #define MSIC_FIFO_SIZE_BYTES (1 << MSIC_FIFO_SIZE_SHIFT)
  40. /*
  41. * To configure the FIFO size as (1 << n) bytes, we write (n - 15) into bits
  42. * 8-9 of the MSIC control reg.
  43. */
  44. #define MSIC_CTRL_FIFO_SIZE (((MSIC_FIFO_SIZE_SHIFT - 15) << 8) & 0x300)
  45. /*
  46. * We need to mask the read/write offsets to make sure they stay within
  47. * the bounds of the FIFO. Also they should always be 16-byte aligned.
  48. */
  49. #define MSIC_FIFO_SIZE_MASK ((MSIC_FIFO_SIZE_BYTES - 1) & ~0xFu)
  50. /* Each entry in the FIFO is 16 bytes, the first 4 bytes hold the irq # */
  51. #define MSIC_FIFO_ENTRY_SIZE 0x10
  52. struct axon_msic {
  53. struct irq_host *irq_host;
  54. __le32 *fifo_virt;
  55. dma_addr_t fifo_phys;
  56. dcr_host_t dcr_host;
  57. u32 read_offset;
  58. #ifdef DEBUG
  59. u32 __iomem *trigger;
  60. #endif
  61. };
  62. #ifdef DEBUG
  63. void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic);
  64. #else
  65. static inline void axon_msi_debug_setup(struct device_node *dn,
  66. struct axon_msic *msic) { }
  67. #endif
  68. static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
  69. {
  70. pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
  71. dcr_write(msic->dcr_host, dcr_n, val);
  72. }
  73. static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
  74. {
  75. struct axon_msic *msic = get_irq_data(irq);
  76. u32 write_offset, msi;
  77. int idx;
  78. write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG);
  79. pr_debug("axon_msi: original write_offset 0x%x\n", write_offset);
  80. /* write_offset doesn't wrap properly, so we have to mask it */
  81. write_offset &= MSIC_FIFO_SIZE_MASK;
  82. while (msic->read_offset != write_offset) {
  83. idx = msic->read_offset / sizeof(__le32);
  84. msi = le32_to_cpu(msic->fifo_virt[idx]);
  85. msi &= 0xFFFF;
  86. pr_debug("axon_msi: woff %x roff %x msi %x\n",
  87. write_offset, msic->read_offset, msi);
  88. msic->read_offset += MSIC_FIFO_ENTRY_SIZE;
  89. msic->read_offset &= MSIC_FIFO_SIZE_MASK;
  90. if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host)
  91. generic_handle_irq(msi);
  92. else
  93. pr_debug("axon_msi: invalid irq 0x%x!\n", msi);
  94. }
  95. desc->chip->eoi(irq);
  96. }
  97. static struct axon_msic *find_msi_translator(struct pci_dev *dev)
  98. {
  99. struct irq_host *irq_host;
  100. struct device_node *dn, *tmp;
  101. const phandle *ph;
  102. struct axon_msic *msic = NULL;
  103. dn = of_node_get(pci_device_to_OF_node(dev));
  104. if (!dn) {
  105. dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n");
  106. return NULL;
  107. }
  108. for (; dn; dn = of_get_next_parent(dn)) {
  109. ph = of_get_property(dn, "msi-translator", NULL);
  110. if (ph)
  111. break;
  112. }
  113. if (!ph) {
  114. dev_dbg(&dev->dev,
  115. "axon_msi: no msi-translator property found\n");
  116. goto out_error;
  117. }
  118. tmp = dn;
  119. dn = of_find_node_by_phandle(*ph);
  120. of_node_put(tmp);
  121. if (!dn) {
  122. dev_dbg(&dev->dev,
  123. "axon_msi: msi-translator doesn't point to a node\n");
  124. goto out_error;
  125. }
  126. irq_host = irq_find_host(dn);
  127. if (!irq_host) {
  128. dev_dbg(&dev->dev, "axon_msi: no irq_host found for node %s\n",
  129. dn->full_name);
  130. goto out_error;
  131. }
  132. msic = irq_host->host_data;
  133. out_error:
  134. of_node_put(dn);
  135. return msic;
  136. }
  137. static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type)
  138. {
  139. if (!find_msi_translator(dev))
  140. return -ENODEV;
  141. return 0;
  142. }
  143. static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
  144. {
  145. struct device_node *dn;
  146. struct msi_desc *entry;
  147. int len;
  148. const u32 *prop;
  149. dn = of_node_get(pci_device_to_OF_node(dev));
  150. if (!dn) {
  151. dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n");
  152. return -ENODEV;
  153. }
  154. entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
  155. for (; dn; dn = of_get_next_parent(dn)) {
  156. if (entry->msi_attrib.is_64) {
  157. prop = of_get_property(dn, "msi-address-64", &len);
  158. if (prop)
  159. break;
  160. }
  161. prop = of_get_property(dn, "msi-address-32", &len);
  162. if (prop)
  163. break;
  164. }
  165. if (!prop) {
  166. dev_dbg(&dev->dev,
  167. "axon_msi: no msi-address-(32|64) properties found\n");
  168. return -ENOENT;
  169. }
  170. switch (len) {
  171. case 8:
  172. msg->address_hi = prop[0];
  173. msg->address_lo = prop[1];
  174. break;
  175. case 4:
  176. msg->address_hi = 0;
  177. msg->address_lo = prop[0];
  178. break;
  179. default:
  180. dev_dbg(&dev->dev,
  181. "axon_msi: malformed msi-address-(32|64) property\n");
  182. of_node_put(dn);
  183. return -EINVAL;
  184. }
  185. of_node_put(dn);
  186. return 0;
  187. }
  188. static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
  189. {
  190. unsigned int virq, rc;
  191. struct msi_desc *entry;
  192. struct msi_msg msg;
  193. struct axon_msic *msic;
  194. msic = find_msi_translator(dev);
  195. if (!msic)
  196. return -ENODEV;
  197. rc = setup_msi_msg_address(dev, &msg);
  198. if (rc)
  199. return rc;
  200. /* We rely on being able to stash a virq in a u16 */
  201. BUILD_BUG_ON(NR_IRQS > 65536);
  202. list_for_each_entry(entry, &dev->msi_list, list) {
  203. virq = irq_create_direct_mapping(msic->irq_host);
  204. if (virq == NO_IRQ) {
  205. dev_warn(&dev->dev,
  206. "axon_msi: virq allocation failed!\n");
  207. return -1;
  208. }
  209. dev_dbg(&dev->dev, "axon_msi: allocated virq 0x%x\n", virq);
  210. set_irq_msi(virq, entry);
  211. msg.data = virq;
  212. write_msi_msg(virq, &msg);
  213. }
  214. return 0;
  215. }
  216. static void axon_msi_teardown_msi_irqs(struct pci_dev *dev)
  217. {
  218. struct msi_desc *entry;
  219. dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n");
  220. list_for_each_entry(entry, &dev->msi_list, list) {
  221. if (entry->irq == NO_IRQ)
  222. continue;
  223. set_irq_msi(entry->irq, NULL);
  224. irq_dispose_mapping(entry->irq);
  225. }
  226. }
  227. static struct irq_chip msic_irq_chip = {
  228. .mask = mask_msi_irq,
  229. .unmask = unmask_msi_irq,
  230. .shutdown = unmask_msi_irq,
  231. .typename = "AXON-MSI",
  232. };
  233. static int msic_host_map(struct irq_host *h, unsigned int virq,
  234. irq_hw_number_t hw)
  235. {
  236. set_irq_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq);
  237. return 0;
  238. }
  239. static struct irq_host_ops msic_host_ops = {
  240. .map = msic_host_map,
  241. };
  242. static int axon_msi_shutdown(struct of_device *device)
  243. {
  244. struct axon_msic *msic = device->dev.platform_data;
  245. u32 tmp;
  246. pr_debug("axon_msi: disabling %s\n",
  247. msic->irq_host->of_node->full_name);
  248. tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
  249. tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
  250. msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
  251. return 0;
  252. }
  253. static int axon_msi_probe(struct of_device *device,
  254. const struct of_device_id *device_id)
  255. {
  256. struct device_node *dn = device->node;
  257. struct axon_msic *msic;
  258. unsigned int virq;
  259. int dcr_base, dcr_len;
  260. pr_debug("axon_msi: setting up dn %s\n", dn->full_name);
  261. msic = kzalloc(sizeof(struct axon_msic), GFP_KERNEL);
  262. if (!msic) {
  263. printk(KERN_ERR "axon_msi: couldn't allocate msic for %s\n",
  264. dn->full_name);
  265. goto out;
  266. }
  267. dcr_base = dcr_resource_start(dn, 0);
  268. dcr_len = dcr_resource_len(dn, 0);
  269. if (dcr_base == 0 || dcr_len == 0) {
  270. printk(KERN_ERR
  271. "axon_msi: couldn't parse dcr properties on %s\n",
  272. dn->full_name);
  273. goto out;
  274. }
  275. msic->dcr_host = dcr_map(dn, dcr_base, dcr_len);
  276. if (!DCR_MAP_OK(msic->dcr_host)) {
  277. printk(KERN_ERR "axon_msi: dcr_map failed for %s\n",
  278. dn->full_name);
  279. goto out_free_msic;
  280. }
  281. msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES,
  282. &msic->fifo_phys, GFP_KERNEL);
  283. if (!msic->fifo_virt) {
  284. printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n",
  285. dn->full_name);
  286. goto out_free_msic;
  287. }
  288. virq = irq_of_parse_and_map(dn, 0);
  289. if (virq == NO_IRQ) {
  290. printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n",
  291. dn->full_name);
  292. goto out_free_fifo;
  293. }
  294. msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP,
  295. NR_IRQS, &msic_host_ops, 0);
  296. if (!msic->irq_host) {
  297. printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n",
  298. dn->full_name);
  299. goto out_free_fifo;
  300. }
  301. msic->irq_host->host_data = msic;
  302. set_irq_data(virq, msic);
  303. set_irq_chained_handler(virq, axon_msi_cascade);
  304. pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
  305. /* Enable the MSIC hardware */
  306. msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32);
  307. msic_dcr_write(msic, MSIC_BASE_ADDR_LO_REG,
  308. msic->fifo_phys & 0xFFFFFFFF);
  309. msic_dcr_write(msic, MSIC_CTRL_REG,
  310. MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE |
  311. MSIC_CTRL_FIFO_SIZE);
  312. device->dev.platform_data = msic;
  313. ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
  314. ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
  315. ppc_md.msi_check_device = axon_msi_check_device;
  316. axon_msi_debug_setup(dn, msic);
  317. printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name);
  318. return 0;
  319. out_free_fifo:
  320. dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt,
  321. msic->fifo_phys);
  322. out_free_msic:
  323. kfree(msic);
  324. out:
  325. return -1;
  326. }
  327. static const struct of_device_id axon_msi_device_id[] = {
  328. {
  329. .compatible = "ibm,axon-msic"
  330. },
  331. {}
  332. };
  333. static struct of_platform_driver axon_msi_driver = {
  334. .match_table = axon_msi_device_id,
  335. .probe = axon_msi_probe,
  336. .shutdown = axon_msi_shutdown,
  337. .driver = {
  338. .name = "axon-msi"
  339. },
  340. };
  341. static int __init axon_msi_init(void)
  342. {
  343. return of_register_platform_driver(&axon_msi_driver);
  344. }
  345. subsys_initcall(axon_msi_init);
  346. #ifdef DEBUG
  347. static int msic_set(void *data, u64 val)
  348. {
  349. struct axon_msic *msic = data;
  350. out_le32(msic->trigger, val);
  351. return 0;
  352. }
  353. static int msic_get(void *data, u64 *val)
  354. {
  355. *val = 0;
  356. return 0;
  357. }
  358. DEFINE_SIMPLE_ATTRIBUTE(fops_msic, msic_get, msic_set, "%llu\n");
  359. void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic)
  360. {
  361. char name[8];
  362. u64 addr;
  363. addr = of_translate_address(dn, of_get_property(dn, "reg", NULL));
  364. if (addr == OF_BAD_ADDR) {
  365. pr_debug("axon_msi: couldn't translate reg property\n");
  366. return;
  367. }
  368. msic->trigger = ioremap(addr, 0x4);
  369. if (!msic->trigger) {
  370. pr_debug("axon_msi: ioremap failed\n");
  371. return;
  372. }
  373. snprintf(name, sizeof(name), "msic_%d", of_node_to_nid(dn));
  374. if (!debugfs_create_file(name, 0600, powerpc_debugfs_root,
  375. msic, &fops_msic)) {
  376. pr_debug("axon_msi: debugfs_create_file failed!\n");
  377. return;
  378. }
  379. }
  380. #endif /* DEBUG */