pci-xlr.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
  3. * reserved.
  4. *
  5. * This software is available to you under a choice of one of two
  6. * licenses. You may choose to be licensed under the terms of the GNU
  7. * General Public License (GPL) Version 2, available from the file
  8. * COPYING in the main directory of this source tree, or the NetLogic
  9. * license below:
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
  23. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
  26. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  29. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  30. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  31. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  32. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <linux/types.h>
  35. #include <linux/pci.h>
  36. #include <linux/kernel.h>
  37. #include <linux/init.h>
  38. #include <linux/msi.h>
  39. #include <linux/mm.h>
  40. #include <linux/irq.h>
  41. #include <linux/irqdesc.h>
  42. #include <linux/console.h>
  43. #include <asm/io.h>
  44. #include <asm/netlogic/interrupt.h>
  45. #include <asm/netlogic/haldefs.h>
  46. #include <asm/netlogic/xlr/msidef.h>
  47. #include <asm/netlogic/xlr/iomap.h>
  48. #include <asm/netlogic/xlr/pic.h>
  49. #include <asm/netlogic/xlr/xlr.h>
  50. static void *pci_config_base;
  51. #define pci_cfg_addr(bus, devfn, off) (((bus) << 16) | ((devfn) << 8) | (off))
  52. /* PCI ops */
  53. static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn,
  54. int where)
  55. {
  56. u32 data;
  57. u32 *cfgaddr;
  58. cfgaddr = (u32 *)(pci_config_base +
  59. pci_cfg_addr(bus->number, devfn, where & ~3));
  60. data = *cfgaddr;
  61. return cpu_to_le32(data);
  62. }
  63. static inline void pci_cfg_write_32bit(struct pci_bus *bus, unsigned int devfn,
  64. int where, u32 data)
  65. {
  66. u32 *cfgaddr;
  67. cfgaddr = (u32 *)(pci_config_base +
  68. pci_cfg_addr(bus->number, devfn, where & ~3));
  69. *cfgaddr = cpu_to_le32(data);
  70. }
  71. static int nlm_pcibios_read(struct pci_bus *bus, unsigned int devfn,
  72. int where, int size, u32 *val)
  73. {
  74. u32 data;
  75. if ((size == 2) && (where & 1))
  76. return PCIBIOS_BAD_REGISTER_NUMBER;
  77. else if ((size == 4) && (where & 3))
  78. return PCIBIOS_BAD_REGISTER_NUMBER;
  79. data = pci_cfg_read_32bit(bus, devfn, where);
  80. if (size == 1)
  81. *val = (data >> ((where & 3) << 3)) & 0xff;
  82. else if (size == 2)
  83. *val = (data >> ((where & 3) << 3)) & 0xffff;
  84. else
  85. *val = data;
  86. return PCIBIOS_SUCCESSFUL;
  87. }
  88. static int nlm_pcibios_write(struct pci_bus *bus, unsigned int devfn,
  89. int where, int size, u32 val)
  90. {
  91. u32 data;
  92. if ((size == 2) && (where & 1))
  93. return PCIBIOS_BAD_REGISTER_NUMBER;
  94. else if ((size == 4) && (where & 3))
  95. return PCIBIOS_BAD_REGISTER_NUMBER;
  96. data = pci_cfg_read_32bit(bus, devfn, where);
  97. if (size == 1)
  98. data = (data & ~(0xff << ((where & 3) << 3))) |
  99. (val << ((where & 3) << 3));
  100. else if (size == 2)
  101. data = (data & ~(0xffff << ((where & 3) << 3))) |
  102. (val << ((where & 3) << 3));
  103. else
  104. data = val;
  105. pci_cfg_write_32bit(bus, devfn, where, data);
  106. return PCIBIOS_SUCCESSFUL;
  107. }
  108. struct pci_ops nlm_pci_ops = {
  109. .read = nlm_pcibios_read,
  110. .write = nlm_pcibios_write
  111. };
  112. static struct resource nlm_pci_mem_resource = {
  113. .name = "XLR PCI MEM",
  114. .start = 0xd0000000UL, /* 256MB PCI mem @ 0xd000_0000 */
  115. .end = 0xdfffffffUL,
  116. .flags = IORESOURCE_MEM,
  117. };
  118. static struct resource nlm_pci_io_resource = {
  119. .name = "XLR IO MEM",
  120. .start = 0x10000000UL, /* 16MB PCI IO @ 0x1000_0000 */
  121. .end = 0x100fffffUL,
  122. .flags = IORESOURCE_IO,
  123. };
  124. struct pci_controller nlm_pci_controller = {
  125. .index = 0,
  126. .pci_ops = &nlm_pci_ops,
  127. .mem_resource = &nlm_pci_mem_resource,
  128. .mem_offset = 0x00000000UL,
  129. .io_resource = &nlm_pci_io_resource,
  130. .io_offset = 0x00000000UL,
  131. };
  132. static int get_irq_vector(const struct pci_dev *dev)
  133. {
  134. if (!nlm_chip_is_xls())
  135. return PIC_PCIX_IRQ; /* for XLR just one IRQ*/
  136. /*
  137. * For XLS PCIe, there is an IRQ per Link, find out which
  138. * link the device is on to assign interrupts
  139. */
  140. if (dev->bus->self == NULL)
  141. return 0;
  142. switch (dev->bus->self->devfn) {
  143. case 0x0:
  144. return PIC_PCIE_LINK0_IRQ;
  145. case 0x8:
  146. return PIC_PCIE_LINK1_IRQ;
  147. case 0x10:
  148. if (nlm_chip_is_xls_b())
  149. return PIC_PCIE_XLSB0_LINK2_IRQ;
  150. else
  151. return PIC_PCIE_LINK2_IRQ;
  152. case 0x18:
  153. if (nlm_chip_is_xls_b())
  154. return PIC_PCIE_XLSB0_LINK3_IRQ;
  155. else
  156. return PIC_PCIE_LINK3_IRQ;
  157. }
  158. WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
  159. return 0;
  160. }
  161. #ifdef CONFIG_PCI_MSI
  162. void destroy_irq(unsigned int irq)
  163. {
  164. /* nothing to do yet */
  165. }
  166. void arch_teardown_msi_irq(unsigned int irq)
  167. {
  168. destroy_irq(irq);
  169. }
  170. int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
  171. {
  172. struct msi_msg msg;
  173. int irq, ret;
  174. irq = get_irq_vector(dev);
  175. if (irq <= 0)
  176. return 1;
  177. msg.address_hi = MSI_ADDR_BASE_HI;
  178. msg.address_lo = MSI_ADDR_BASE_LO |
  179. MSI_ADDR_DEST_MODE_PHYSICAL |
  180. MSI_ADDR_REDIRECTION_CPU;
  181. msg.data = MSI_DATA_TRIGGER_EDGE |
  182. MSI_DATA_LEVEL_ASSERT |
  183. MSI_DATA_DELIVERY_FIXED;
  184. ret = irq_set_msi_desc(irq, desc);
  185. if (ret < 0) {
  186. destroy_irq(irq);
  187. return ret;
  188. }
  189. write_msi_msg(irq, &msg);
  190. return 0;
  191. }
  192. #endif
  193. /* Extra ACK needed for XLR on chip PCI controller */
  194. static void xlr_pci_ack(struct irq_data *d)
  195. {
  196. uint64_t pcibase = nlm_mmio_base(NETLOGIC_IO_PCIX_OFFSET);
  197. nlm_read_reg(pcibase, (0x140 >> 2));
  198. }
  199. /* Extra ACK needed for XLS on chip PCIe controller */
  200. static void xls_pcie_ack(struct irq_data *d)
  201. {
  202. uint64_t pciebase_le = nlm_mmio_base(NETLOGIC_IO_PCIE_1_OFFSET);
  203. switch (d->irq) {
  204. case PIC_PCIE_LINK0_IRQ:
  205. nlm_write_reg(pciebase_le, (0x90 >> 2), 0xffffffff);
  206. break;
  207. case PIC_PCIE_LINK1_IRQ:
  208. nlm_write_reg(pciebase_le, (0x94 >> 2), 0xffffffff);
  209. break;
  210. case PIC_PCIE_LINK2_IRQ:
  211. nlm_write_reg(pciebase_le, (0x190 >> 2), 0xffffffff);
  212. break;
  213. case PIC_PCIE_LINK3_IRQ:
  214. nlm_write_reg(pciebase_le, (0x194 >> 2), 0xffffffff);
  215. break;
  216. }
  217. }
  218. /* For XLS B silicon, the 3,4 PCI interrupts are different */
  219. static void xls_pcie_ack_b(struct irq_data *d)
  220. {
  221. uint64_t pciebase_le = nlm_mmio_base(NETLOGIC_IO_PCIE_1_OFFSET);
  222. switch (d->irq) {
  223. case PIC_PCIE_LINK0_IRQ:
  224. nlm_write_reg(pciebase_le, (0x90 >> 2), 0xffffffff);
  225. break;
  226. case PIC_PCIE_LINK1_IRQ:
  227. nlm_write_reg(pciebase_le, (0x94 >> 2), 0xffffffff);
  228. break;
  229. case PIC_PCIE_XLSB0_LINK2_IRQ:
  230. nlm_write_reg(pciebase_le, (0x190 >> 2), 0xffffffff);
  231. break;
  232. case PIC_PCIE_XLSB0_LINK3_IRQ:
  233. nlm_write_reg(pciebase_le, (0x194 >> 2), 0xffffffff);
  234. break;
  235. }
  236. }
  237. int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  238. {
  239. return get_irq_vector(dev);
  240. }
  241. /* Do platform specific device initialization at pci_enable_device() time */
  242. int pcibios_plat_dev_init(struct pci_dev *dev)
  243. {
  244. return 0;
  245. }
  246. static int __init pcibios_init(void)
  247. {
  248. /* PSB assigns PCI resources */
  249. pci_set_flags(PCI_PROBE_ONLY);
  250. pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20);
  251. /* Extend IO port for memory mapped io */
  252. ioport_resource.start = 0;
  253. ioport_resource.end = ~0;
  254. set_io_port_base(CKSEG1);
  255. nlm_pci_controller.io_map_base = CKSEG1;
  256. pr_info("Registering XLR/XLS PCIX/PCIE Controller.\n");
  257. register_pci_controller(&nlm_pci_controller);
  258. /*
  259. * For PCI interrupts, we need to ack the PCI controller too, overload
  260. * irq handler data to do this
  261. */
  262. if (nlm_chip_is_xls()) {
  263. if (nlm_chip_is_xls_b()) {
  264. irq_set_handler_data(PIC_PCIE_LINK0_IRQ,
  265. xls_pcie_ack_b);
  266. irq_set_handler_data(PIC_PCIE_LINK1_IRQ,
  267. xls_pcie_ack_b);
  268. irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ,
  269. xls_pcie_ack_b);
  270. irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ,
  271. xls_pcie_ack_b);
  272. } else {
  273. irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack);
  274. irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack);
  275. irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack);
  276. irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack);
  277. }
  278. } else {
  279. /* XLR PCI controller ACK */
  280. irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack);
  281. }
  282. return 0;
  283. }
  284. arch_initcall(pcibios_init);
  285. struct pci_fixup pcibios_fixups[] = {
  286. {0}
  287. };