pcie.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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 mem_space_name[16];
  28. struct resource res;
  29. };
  30. static struct pcie_port pcie_port[2];
  31. static int num_pcie_ports;
  32. static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
  33. {
  34. struct pcie_port *pp;
  35. if (nr >= num_pcie_ports)
  36. return 0;
  37. pp = &pcie_port[nr];
  38. sys->private_data = pp;
  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. if (pp->index == 0)
  46. pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE0_IO_PHYS_BASE);
  47. else
  48. pci_ioremap_io(sys->busnr * SZ_64K, DOVE_PCIE1_IO_PHYS_BASE);
  49. /*
  50. * IORESOURCE_MEM
  51. */
  52. snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
  53. "PCIe %d MEM", pp->index);
  54. pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
  55. pp->res.name = pp->mem_space_name;
  56. if (pp->index == 0) {
  57. pp->res.start = DOVE_PCIE0_MEM_PHYS_BASE;
  58. pp->res.end = pp->res.start + DOVE_PCIE0_MEM_SIZE - 1;
  59. } else {
  60. pp->res.start = DOVE_PCIE1_MEM_PHYS_BASE;
  61. pp->res.end = pp->res.start + DOVE_PCIE1_MEM_SIZE - 1;
  62. }
  63. pp->res.flags = IORESOURCE_MEM;
  64. if (request_resource(&iomem_resource, &pp->res))
  65. panic("Request PCIe Memory resource failed\n");
  66. pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
  67. return 1;
  68. }
  69. static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
  70. {
  71. /*
  72. * Don't go out when trying to access nonexisting devices
  73. * on the local bus.
  74. */
  75. if (bus == pp->root_bus_nr && dev > 1)
  76. return 0;
  77. return 1;
  78. }
  79. static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
  80. int size, u32 *val)
  81. {
  82. struct pci_sys_data *sys = bus->sysdata;
  83. struct pcie_port *pp = sys->private_data;
  84. unsigned long flags;
  85. int ret;
  86. if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
  87. *val = 0xffffffff;
  88. return PCIBIOS_DEVICE_NOT_FOUND;
  89. }
  90. spin_lock_irqsave(&pp->conf_lock, flags);
  91. ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
  92. spin_unlock_irqrestore(&pp->conf_lock, flags);
  93. return ret;
  94. }
  95. static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
  96. int where, int size, u32 val)
  97. {
  98. struct pci_sys_data *sys = bus->sysdata;
  99. struct pcie_port *pp = sys->private_data;
  100. unsigned long flags;
  101. int ret;
  102. if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
  103. return PCIBIOS_DEVICE_NOT_FOUND;
  104. spin_lock_irqsave(&pp->conf_lock, flags);
  105. ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
  106. spin_unlock_irqrestore(&pp->conf_lock, flags);
  107. return ret;
  108. }
  109. static struct pci_ops pcie_ops = {
  110. .read = pcie_rd_conf,
  111. .write = pcie_wr_conf,
  112. };
  113. static void __devinit rc_pci_fixup(struct pci_dev *dev)
  114. {
  115. /*
  116. * Prevent enumeration of root complex.
  117. */
  118. if (dev->bus->parent == NULL && dev->devfn == 0) {
  119. int i;
  120. for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
  121. dev->resource[i].start = 0;
  122. dev->resource[i].end = 0;
  123. dev->resource[i].flags = 0;
  124. }
  125. }
  126. }
  127. DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
  128. static struct pci_bus __init *
  129. dove_pcie_scan_bus(int nr, struct pci_sys_data *sys)
  130. {
  131. struct pci_bus *bus;
  132. if (nr < num_pcie_ports) {
  133. bus = pci_scan_root_bus(NULL, sys->busnr, &pcie_ops, sys,
  134. &sys->resources);
  135. } else {
  136. bus = NULL;
  137. BUG();
  138. }
  139. return bus;
  140. }
  141. static int __init dove_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
  142. {
  143. struct pci_sys_data *sys = dev->sysdata;
  144. struct pcie_port *pp = sys->private_data;
  145. return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0;
  146. }
  147. static struct hw_pci dove_pci __initdata = {
  148. .nr_controllers = 2,
  149. .setup = dove_pcie_setup,
  150. .scan = dove_pcie_scan_bus,
  151. .map_irq = dove_pcie_map_irq,
  152. };
  153. static void __init add_pcie_port(int index, void __iomem *base)
  154. {
  155. printk(KERN_INFO "Dove PCIe port %d: ", index);
  156. if (orion_pcie_link_up(base)) {
  157. struct pcie_port *pp = &pcie_port[num_pcie_ports++];
  158. printk(KERN_INFO "link up\n");
  159. pp->index = index;
  160. pp->root_bus_nr = -1;
  161. pp->base = base;
  162. spin_lock_init(&pp->conf_lock);
  163. memset(&pp->res, 0, sizeof(pp->res));
  164. } else {
  165. printk(KERN_INFO "link down, ignoring\n");
  166. }
  167. }
  168. void __init dove_pcie_init(int init_port0, int init_port1)
  169. {
  170. vga_base = DOVE_PCIE0_MEM_PHYS_BASE;
  171. if (init_port0)
  172. add_pcie_port(0, DOVE_PCIE0_VIRT_BASE);
  173. if (init_port1)
  174. add_pcie_port(1, DOVE_PCIE1_VIRT_BASE);
  175. pci_common_init(&dove_pci);
  176. }