axon_msi.c 9.6 KB

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