pcie.c 7.5 KB

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