pcie.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. * arch/arm/mach-mv78xx0/pcie.c
  3. *
  4. * PCIe functions for Marvell MV78xx0 SoCs
  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 <linux/mbus.h>
  13. #include <asm/irq.h>
  14. #include <asm/mach/pci.h>
  15. #include <plat/pcie.h>
  16. #include "common.h"
  17. struct pcie_port {
  18. u8 maj;
  19. u8 min;
  20. u8 root_bus_nr;
  21. void __iomem *base;
  22. spinlock_t conf_lock;
  23. char io_space_name[16];
  24. char mem_space_name[16];
  25. struct resource res[2];
  26. };
  27. static struct pcie_port pcie_port[8];
  28. static int num_pcie_ports;
  29. static struct resource pcie_io_space;
  30. static struct resource pcie_mem_space;
  31. static void __init mv78xx0_pcie_preinit(void)
  32. {
  33. int i;
  34. u32 size_each;
  35. u32 start;
  36. int win;
  37. pcie_io_space.name = "PCIe I/O Space";
  38. pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
  39. pcie_io_space.end =
  40. MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1;
  41. pcie_io_space.flags = IORESOURCE_IO;
  42. if (request_resource(&iomem_resource, &pcie_io_space))
  43. panic("can't allocate PCIe I/O space");
  44. pcie_mem_space.name = "PCIe MEM Space";
  45. pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE;
  46. pcie_mem_space.end =
  47. MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1;
  48. pcie_mem_space.flags = IORESOURCE_MEM;
  49. if (request_resource(&iomem_resource, &pcie_mem_space))
  50. panic("can't allocate PCIe MEM space");
  51. for (i = 0; i < num_pcie_ports; i++) {
  52. struct pcie_port *pp = pcie_port + i;
  53. snprintf(pp->io_space_name, sizeof(pp->io_space_name),
  54. "PCIe %d.%d I/O", pp->maj, pp->min);
  55. pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
  56. pp->res[0].name = pp->io_space_name;
  57. pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i);
  58. pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1;
  59. pp->res[0].flags = IORESOURCE_IO;
  60. snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
  61. "PCIe %d.%d MEM", pp->maj, pp->min);
  62. pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
  63. pp->res[1].name = pp->mem_space_name;
  64. pp->res[1].flags = IORESOURCE_MEM;
  65. }
  66. switch (num_pcie_ports) {
  67. case 0:
  68. size_each = 0;
  69. break;
  70. case 1:
  71. size_each = 0x30000000;
  72. break;
  73. case 2 ... 3:
  74. size_each = 0x10000000;
  75. break;
  76. case 4 ... 6:
  77. size_each = 0x08000000;
  78. break;
  79. case 7:
  80. size_each = 0x04000000;
  81. break;
  82. default:
  83. panic("invalid number of PCIe ports");
  84. }
  85. start = MV78XX0_PCIE_MEM_PHYS_BASE;
  86. for (i = 0; i < num_pcie_ports; i++) {
  87. struct pcie_port *pp = pcie_port + i;
  88. pp->res[1].start = start;
  89. pp->res[1].end = start + size_each - 1;
  90. start += size_each;
  91. }
  92. for (i = 0; i < num_pcie_ports; i++) {
  93. struct pcie_port *pp = pcie_port + i;
  94. if (request_resource(&pcie_io_space, &pp->res[0]))
  95. panic("can't allocate PCIe I/O sub-space");
  96. if (request_resource(&pcie_mem_space, &pp->res[1]))
  97. panic("can't allocate PCIe MEM sub-space");
  98. }
  99. win = 0;
  100. for (i = 0; i < num_pcie_ports; i++) {
  101. struct pcie_port *pp = pcie_port + i;
  102. mv78xx0_setup_pcie_io_win(win++, pp->res[0].start,
  103. pp->res[0].end - pp->res[0].start + 1,
  104. pp->maj, pp->min);
  105. mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start,
  106. pp->res[1].end - pp->res[1].start + 1,
  107. pp->maj, pp->min);
  108. }
  109. }
  110. static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
  111. {
  112. struct pcie_port *pp;
  113. if (nr >= num_pcie_ports)
  114. return 0;
  115. pp = &pcie_port[nr];
  116. pp->root_bus_nr = sys->busnr;
  117. /*
  118. * Generic PCIe unit setup.
  119. */
  120. orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
  121. orion_pcie_setup(pp->base, &mv78xx0_mbus_dram_info);
  122. sys->resource[0] = &pp->res[0];
  123. sys->resource[1] = &pp->res[1];
  124. sys->resource[2] = NULL;
  125. return 1;
  126. }
  127. static struct pcie_port *bus_to_port(int bus)
  128. {
  129. int i;
  130. for (i = num_pcie_ports - 1; i >= 0; i--) {
  131. int rbus = pcie_port[i].root_bus_nr;
  132. if (rbus != -1 && rbus <= bus)
  133. break;
  134. }
  135. return i >= 0 ? pcie_port + i : NULL;
  136. }
  137. static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
  138. {
  139. /*
  140. * Don't go out when trying to access nonexisting devices
  141. * on the local bus.
  142. */
  143. if (bus == pp->root_bus_nr && dev > 1)
  144. return 0;
  145. return 1;
  146. }
  147. static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
  148. int size, u32 *val)
  149. {
  150. struct pcie_port *pp = bus_to_port(bus->number);
  151. unsigned long flags;
  152. int ret;
  153. if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
  154. *val = 0xffffffff;
  155. return PCIBIOS_DEVICE_NOT_FOUND;
  156. }
  157. spin_lock_irqsave(&pp->conf_lock, flags);
  158. ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
  159. spin_unlock_irqrestore(&pp->conf_lock, flags);
  160. return ret;
  161. }
  162. static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
  163. int where, int size, u32 val)
  164. {
  165. struct pcie_port *pp = bus_to_port(bus->number);
  166. unsigned long flags;
  167. int ret;
  168. if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
  169. return PCIBIOS_DEVICE_NOT_FOUND;
  170. spin_lock_irqsave(&pp->conf_lock, flags);
  171. ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
  172. spin_unlock_irqrestore(&pp->conf_lock, flags);
  173. return ret;
  174. }
  175. static struct pci_ops pcie_ops = {
  176. .read = pcie_rd_conf,
  177. .write = pcie_wr_conf,
  178. };
  179. static void __devinit rc_pci_fixup(struct pci_dev *dev)
  180. {
  181. /*
  182. * Prevent enumeration of root complex.
  183. */
  184. if (dev->bus->parent == NULL && dev->devfn == 0) {
  185. int i;
  186. for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
  187. dev->resource[i].start = 0;
  188. dev->resource[i].end = 0;
  189. dev->resource[i].flags = 0;
  190. }
  191. }
  192. }
  193. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
  194. static struct pci_bus __init *
  195. mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys)
  196. {
  197. struct pci_bus *bus;
  198. if (nr < num_pcie_ports) {
  199. bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
  200. } else {
  201. bus = NULL;
  202. BUG();
  203. }
  204. return bus;
  205. }
  206. static int __init mv78xx0_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  207. {
  208. struct pcie_port *pp = bus_to_port(dev->bus->number);
  209. return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min;
  210. }
  211. static struct hw_pci mv78xx0_pci __initdata = {
  212. .nr_controllers = 8,
  213. .preinit = mv78xx0_pcie_preinit,
  214. .swizzle = pci_std_swizzle,
  215. .setup = mv78xx0_pcie_setup,
  216. .scan = mv78xx0_pcie_scan_bus,
  217. .map_irq = mv78xx0_pcie_map_irq,
  218. };
  219. static void __init add_pcie_port(int maj, int min, unsigned long base)
  220. {
  221. printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min);
  222. if (orion_pcie_link_up((void __iomem *)base)) {
  223. struct pcie_port *pp = &pcie_port[num_pcie_ports++];
  224. printk("link up\n");
  225. pp->maj = maj;
  226. pp->min = min;
  227. pp->root_bus_nr = -1;
  228. pp->base = (void __iomem *)base;
  229. spin_lock_init(&pp->conf_lock);
  230. memset(pp->res, 0, sizeof(pp->res));
  231. } else {
  232. printk("link down, ignoring\n");
  233. }
  234. }
  235. void __init mv78xx0_pcie_init(int init_port0, int init_port1)
  236. {
  237. if (init_port0) {
  238. add_pcie_port(0, 0, PCIE00_VIRT_BASE);
  239. if (!orion_pcie_x4_mode((void __iomem *)PCIE00_VIRT_BASE)) {
  240. add_pcie_port(0, 1, PCIE01_VIRT_BASE);
  241. add_pcie_port(0, 2, PCIE02_VIRT_BASE);
  242. add_pcie_port(0, 3, PCIE03_VIRT_BASE);
  243. }
  244. }
  245. if (init_port1) {
  246. add_pcie_port(1, 0, PCIE10_VIRT_BASE);
  247. if (!orion_pcie_x4_mode((void __iomem *)PCIE10_VIRT_BASE)) {
  248. add_pcie_port(1, 1, PCIE11_VIRT_BASE);
  249. add_pcie_port(1, 2, PCIE12_VIRT_BASE);
  250. add_pcie_port(1, 3, PCIE13_VIRT_BASE);
  251. }
  252. }
  253. pci_common_init(&mv78xx0_pci);
  254. }