pcie.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * arch/arm/mach-dove/pcie.c
  3. *
  4. * PCIe functions for Marvell Dove 88AP510 SoC
  5. *
  6. * This file is licensed under the terms of the GNU General Public
  7. * License version 2. This program is licensed "as is" without any
  8. * warranty of any kind, whether express or implied.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/pci.h>
  12. #include <video/vga.h>
  13. #include <asm/mach/pci.h>
  14. #include <asm/mach/arch.h>
  15. #include <asm/setup.h>
  16. #include <asm/delay.h>
  17. #include <plat/pcie.h>
  18. #include <mach/irqs.h>
  19. #include <mach/bridge-regs.h>
  20. #include <plat/addr-map.h>
  21. #include "common.h"
  22. struct pcie_port {
  23. u8 index;
  24. u8 root_bus_nr;
  25. void __iomem *base;
  26. spinlock_t conf_lock;
  27. char io_space_name[16];
  28. char mem_space_name[16];
  29. struct resource res[2];
  30. };
  31. static struct pcie_port pcie_port[2];
  32. static int num_pcie_ports;
  33. static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
  34. {
  35. struct pcie_port *pp;
  36. if (nr >= num_pcie_ports)
  37. return 0;
  38. pp = &pcie_port[nr];
  39. pp->root_bus_nr = sys->busnr;
  40. /*
  41. * Generic PCIe unit setup.
  42. */
  43. orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
  44. orion_pcie_setup(pp->base);
  45. /*
  46. * IORESOURCE_IO
  47. */
  48. snprintf(pp->io_space_name, sizeof(pp->io_space_name),
  49. "PCIe %d I/O", pp->index);
  50. pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
  51. pp->res[0].name = pp->io_space_name;
  52. if (pp->index == 0) {
  53. pp->res[0].start = DOVE_PCIE0_IO_PHYS_BASE;
  54. pp->res[0].end = pp->res[0].start + DOVE_PCIE0_IO_SIZE - 1;
  55. } else {
  56. pp->res[0].start = DOVE_PCIE1_IO_PHYS_BASE;
  57. pp->res[0].end = pp->res[0].start + DOVE_PCIE1_IO_SIZE - 1;
  58. }
  59. pp->res[0].flags = IORESOURCE_IO;
  60. if (request_resource(&ioport_resource, &pp->res[0]))
  61. panic("Request PCIe IO resource failed\n");
  62. pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
  63. /*
  64. * IORESOURCE_MEM
  65. */
  66. snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
  67. "PCIe %d MEM", pp->index);
  68. pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
  69. pp->res[1].name = pp->mem_space_name;
  70. if (pp->index == 0) {
  71. pp->res[1].start = DOVE_PCIE0_MEM_PHYS_BASE;
  72. pp->res[1].end = pp->res[1].start + DOVE_PCIE0_MEM_SIZE - 1;
  73. } else {
  74. pp->res[1].start = DOVE_PCIE1_MEM_PHYS_BASE;
  75. pp->res[1].end = pp->res[1].start + DOVE_PCIE1_MEM_SIZE - 1;
  76. }
  77. pp->res[1].flags = IORESOURCE_MEM;
  78. if (request_resource(&iomem_resource, &pp->res[1]))
  79. panic("Request PCIe Memory resource failed\n");
  80. pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
  81. return 1;
  82. }
  83. static struct pcie_port *bus_to_port(int bus)
  84. {
  85. int i;
  86. for (i = num_pcie_ports - 1; i >= 0; i--) {
  87. int rbus = pcie_port[i].root_bus_nr;
  88. if (rbus != -1 && rbus <= bus)
  89. break;
  90. }
  91. return i >= 0 ? pcie_port + i : NULL;
  92. }
  93. static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
  94. {
  95. /*
  96. * Don't go out when trying to access nonexisting devices
  97. * on the local bus.
  98. */
  99. if (bus == pp->root_bus_nr && dev > 1)
  100. return 0;
  101. return 1;
  102. }
  103. static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
  104. int size, u32 *val)
  105. {
  106. struct pcie_port *pp = bus_to_port(bus->number);
  107. unsigned long flags;
  108. int ret;
  109. if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
  110. *val = 0xffffffff;
  111. return PCIBIOS_DEVICE_NOT_FOUND;
  112. }
  113. spin_lock_irqsave(&pp->conf_lock, flags);
  114. ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
  115. spin_unlock_irqrestore(&pp->conf_lock, flags);
  116. return ret;
  117. }
  118. static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
  119. int where, int size, u32 val)
  120. {
  121. struct pcie_port *pp = bus_to_port(bus->number);
  122. unsigned long flags;
  123. int ret;
  124. if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
  125. return PCIBIOS_DEVICE_NOT_FOUND;
  126. spin_lock_irqsave(&pp->conf_lock, flags);
  127. ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
  128. spin_unlock_irqrestore(&pp->conf_lock, flags);
  129. return ret;
  130. }
  131. static struct pci_ops pcie_ops = {
  132. .read = pcie_rd_conf,
  133. .write = pcie_wr_conf,
  134. };
  135. static void __devinit rc_pci_fixup(struct pci_dev *dev)
  136. {
  137. /*
  138. * Prevent enumeration of root complex.
  139. */
  140. if (dev->bus->parent == NULL && dev->devfn == 0) {
  141. int i;
  142. for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
  143. dev->resource[i].start = 0;
  144. dev->resource[i].end = 0;
  145. dev->resource[i].flags = 0;
  146. }
  147. }
  148. }
  149. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
  150. static struct pci_bus __init *
  151. dove_pcie_scan_bus(int nr, struct pci_sys_data *sys)
  152. {
  153. struct pci_bus *bus;
  154. if (nr < num_pcie_ports) {
  155. bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
  156. &sys->resources);
  157. } else {
  158. bus = NULL;
  159. BUG();
  160. }
  161. return bus;
  162. }
  163. static int __init dove_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  164. {
  165. struct pcie_port *pp = bus_to_port(dev->bus->number);
  166. return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0;
  167. }
  168. static struct hw_pci dove_pci __initdata = {
  169. .nr_controllers = 2,
  170. .swizzle = pci_std_swizzle,
  171. .setup = dove_pcie_setup,
  172. .scan = dove_pcie_scan_bus,
  173. .map_irq = dove_pcie_map_irq,
  174. };
  175. static void __init add_pcie_port(int index, unsigned long base)
  176. {
  177. printk(KERN_INFO "Dove PCIe port %d: ", index);
  178. if (orion_pcie_link_up((void __iomem *)base)) {
  179. struct pcie_port *pp = &pcie_port[num_pcie_ports++];
  180. printk(KERN_INFO "link up\n");
  181. pp->index = index;
  182. pp->root_bus_nr = -1;
  183. pp->base = (void __iomem *)base;
  184. spin_lock_init(&pp->conf_lock);
  185. memset(pp->res, 0, sizeof(pp->res));
  186. } else {
  187. printk(KERN_INFO "link down, ignoring\n");
  188. }
  189. }
  190. void __init dove_pcie_init(int init_port0, int init_port1)
  191. {
  192. vga_base = DOVE_PCIE0_MEM_PHYS_BASE;
  193. if (init_port0)
  194. add_pcie_port(0, DOVE_PCIE0_VIRT_BASE);
  195. if (init_port1)
  196. add_pcie_port(1, DOVE_PCIE1_VIRT_BASE);
  197. pci_common_init(&dove_pci);
  198. }