ppc4xx_pci.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*
  2. * PCI / PCI-X / PCI-Express support for 4xx parts
  3. *
  4. * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
  5. *
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/pci.h>
  9. #include <linux/init.h>
  10. #include <linux/of.h>
  11. #include <asm/io.h>
  12. #include <asm/pci-bridge.h>
  13. #include <asm/machdep.h>
  14. #include "ppc4xx_pci.h"
  15. static int dma_offset_set;
  16. /* Move that to a useable header */
  17. extern unsigned long total_memory;
  18. static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
  19. void __iomem *reg,
  20. struct resource *res)
  21. {
  22. u64 size;
  23. const u32 *ranges;
  24. int rlen;
  25. int pna = of_n_addr_cells(hose->dn);
  26. int np = pna + 5;
  27. /* Default */
  28. res->start = 0;
  29. res->end = size = 0x80000000;
  30. res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
  31. /* Get dma-ranges property */
  32. ranges = of_get_property(hose->dn, "dma-ranges", &rlen);
  33. if (ranges == NULL)
  34. goto out;
  35. /* Walk it */
  36. while ((rlen -= np * 4) >= 0) {
  37. u32 pci_space = ranges[0];
  38. u64 pci_addr = of_read_number(ranges + 1, 2);
  39. u64 cpu_addr = of_translate_dma_address(hose->dn, ranges + 3);
  40. size = of_read_number(ranges + pna + 3, 2);
  41. ranges += np;
  42. if (cpu_addr == OF_BAD_ADDR || size == 0)
  43. continue;
  44. /* We only care about memory */
  45. if ((pci_space & 0x03000000) != 0x02000000)
  46. continue;
  47. /* We currently only support memory at 0, and pci_addr
  48. * within 32 bits space
  49. */
  50. if (cpu_addr != 0 || pci_addr > 0xffffffff) {
  51. printk(KERN_WARNING "%s: Ignored unsupported dma range"
  52. " 0x%016llx...0x%016llx -> 0x%016llx\n",
  53. hose->dn->full_name,
  54. pci_addr, pci_addr + size - 1, cpu_addr);
  55. continue;
  56. }
  57. /* Check if not prefetchable */
  58. if (!(pci_space & 0x40000000))
  59. res->flags &= ~IORESOURCE_PREFETCH;
  60. /* Use that */
  61. res->start = pci_addr;
  62. #ifndef CONFIG_RESOURCES_64BIT
  63. /* Beware of 32 bits resources */
  64. if ((pci_addr + size) > 0x100000000ull)
  65. res->end = 0xffffffff;
  66. else
  67. #endif
  68. res->end = res->start + size - 1;
  69. break;
  70. }
  71. /* We only support one global DMA offset */
  72. if (dma_offset_set && pci_dram_offset != res->start) {
  73. printk(KERN_ERR "%s: dma-ranges(s) mismatch\n",
  74. hose->dn->full_name);
  75. return -ENXIO;
  76. }
  77. /* Check that we can fit all of memory as we don't support
  78. * DMA bounce buffers
  79. */
  80. if (size < total_memory) {
  81. printk(KERN_ERR "%s: dma-ranges too small "
  82. "(size=%llx total_memory=%lx)\n",
  83. hose->dn->full_name, size, total_memory);
  84. return -ENXIO;
  85. }
  86. /* Check we are a power of 2 size and that base is a multiple of size*/
  87. if (!is_power_of_2(size) ||
  88. (res->start & (size - 1)) != 0) {
  89. printk(KERN_ERR "%s: dma-ranges unaligned\n",
  90. hose->dn->full_name);
  91. return -ENXIO;
  92. }
  93. /* Check that we are fully contained within 32 bits space */
  94. if (res->end > 0xffffffff) {
  95. printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n",
  96. hose->dn->full_name);
  97. return -ENXIO;
  98. }
  99. out:
  100. dma_offset_set = 1;
  101. pci_dram_offset = res->start;
  102. printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n",
  103. pci_dram_offset);
  104. return 0;
  105. }
  106. /*
  107. * 4xx PCI 2.x part
  108. */
  109. static void __init ppc4xx_probe_pci_bridge(struct device_node *np)
  110. {
  111. /* NYI */
  112. }
  113. /*
  114. * 4xx PCI-X part
  115. */
  116. static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
  117. void __iomem *reg)
  118. {
  119. u32 lah, lal, pciah, pcial, sa;
  120. int i, j;
  121. /* Setup outbound memory windows */
  122. for (i = j = 0; i < 3; i++) {
  123. struct resource *res = &hose->mem_resources[i];
  124. /* we only care about memory windows */
  125. if (!(res->flags & IORESOURCE_MEM))
  126. continue;
  127. if (j > 1) {
  128. printk(KERN_WARNING "%s: Too many ranges\n",
  129. hose->dn->full_name);
  130. break;
  131. }
  132. /* Calculate register values */
  133. #ifdef CONFIG_PTE_64BIT
  134. lah = res->start >> 32;
  135. lal = res->start & 0xffffffffu;
  136. pciah = (res->start - hose->pci_mem_offset) >> 32;
  137. pcial = (res->start - hose->pci_mem_offset) & 0xffffffffu;
  138. #else
  139. lah = pciah = 0;
  140. lal = res->start;
  141. pcial = res->start - hose->pci_mem_offset;
  142. #endif
  143. sa = res->end + 1 - res->start;
  144. if (!is_power_of_2(sa) || sa < 0x100000 ||
  145. sa > 0xffffffffu) {
  146. printk(KERN_WARNING "%s: Resource out of range\n",
  147. hose->dn->full_name);
  148. continue;
  149. }
  150. sa = (0xffffffffu << ilog2(sa)) | 0x1;
  151. /* Program register values */
  152. if (j == 0) {
  153. writel(lah, reg + PCIX0_POM0LAH);
  154. writel(lal, reg + PCIX0_POM0LAL);
  155. writel(pciah, reg + PCIX0_POM0PCIAH);
  156. writel(pcial, reg + PCIX0_POM0PCIAL);
  157. writel(sa, reg + PCIX0_POM0SA);
  158. } else {
  159. writel(lah, reg + PCIX0_POM1LAH);
  160. writel(lal, reg + PCIX0_POM1LAL);
  161. writel(pciah, reg + PCIX0_POM1PCIAH);
  162. writel(pcial, reg + PCIX0_POM1PCIAL);
  163. writel(sa, reg + PCIX0_POM1SA);
  164. }
  165. j++;
  166. }
  167. }
  168. static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose,
  169. void __iomem *reg,
  170. const struct resource *res,
  171. int big_pim,
  172. int enable_msi_hole)
  173. {
  174. resource_size_t size = res->end - res->start + 1;
  175. u32 sa;
  176. /* RAM is always at 0 */
  177. writel(0x00000000, reg + PCIX0_PIM0LAH);
  178. writel(0x00000000, reg + PCIX0_PIM0LAL);
  179. /* Calculate window size */
  180. sa = (0xffffffffu << ilog2(size)) | 1;
  181. sa |= 0x1;
  182. if (res->flags & IORESOURCE_PREFETCH)
  183. sa |= 0x2;
  184. if (enable_msi_hole)
  185. sa |= 0x4;
  186. writel(sa, reg + PCIX0_PIM0SA);
  187. if (big_pim)
  188. writel(0xffffffff, reg + PCIX0_PIM0SAH);
  189. /* Map on PCI side */
  190. writel(0x00000000, reg + PCIX0_BAR0H);
  191. writel(res->start, reg + PCIX0_BAR0L);
  192. writew(0x0006, reg + PCIX0_COMMAND);
  193. }
  194. static void __init ppc4xx_probe_pcix_bridge(struct device_node *np)
  195. {
  196. struct resource rsrc_cfg;
  197. struct resource rsrc_reg;
  198. struct resource dma_window;
  199. struct pci_controller *hose = NULL;
  200. void __iomem *reg = NULL;
  201. const int *bus_range;
  202. int big_pim = 0, msi = 0, primary = 0;
  203. /* Fetch config space registers address */
  204. if (of_address_to_resource(np, 0, &rsrc_cfg)) {
  205. printk(KERN_ERR "%s:Can't get PCI-X config register base !",
  206. np->full_name);
  207. return;
  208. }
  209. /* Fetch host bridge internal registers address */
  210. if (of_address_to_resource(np, 3, &rsrc_reg)) {
  211. printk(KERN_ERR "%s: Can't get PCI-X internal register base !",
  212. np->full_name);
  213. return;
  214. }
  215. /* Check if it supports large PIMs (440GX) */
  216. if (of_get_property(np, "large-inbound-windows", NULL))
  217. big_pim = 1;
  218. /* Check if we should enable MSIs inbound hole */
  219. if (of_get_property(np, "enable-msi-hole", NULL))
  220. msi = 1;
  221. /* Check if primary bridge */
  222. if (of_get_property(np, "primary", NULL))
  223. primary = 1;
  224. /* Get bus range if any */
  225. bus_range = of_get_property(np, "bus-range", NULL);
  226. /* Map registers */
  227. reg = ioremap(rsrc_reg.start, rsrc_reg.end + 1 - rsrc_reg.start);
  228. if (reg == NULL) {
  229. printk(KERN_ERR "%s: Can't map registers !", np->full_name);
  230. goto fail;
  231. }
  232. /* Allocate the host controller data structure */
  233. hose = pcibios_alloc_controller(np);
  234. if (!hose)
  235. goto fail;
  236. hose->first_busno = bus_range ? bus_range[0] : 0x0;
  237. hose->last_busno = bus_range ? bus_range[1] : 0xff;
  238. /* Setup config space */
  239. setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0);
  240. /* Disable all windows */
  241. writel(0, reg + PCIX0_POM0SA);
  242. writel(0, reg + PCIX0_POM1SA);
  243. writel(0, reg + PCIX0_POM2SA);
  244. writel(0, reg + PCIX0_PIM0SA);
  245. writel(0, reg + PCIX0_PIM1SA);
  246. writel(0, reg + PCIX0_PIM2SA);
  247. if (big_pim) {
  248. writel(0, reg + PCIX0_PIM0SAH);
  249. writel(0, reg + PCIX0_PIM2SAH);
  250. }
  251. /* Parse outbound mapping resources */
  252. pci_process_bridge_OF_ranges(hose, np, primary);
  253. /* Parse inbound mapping resources */
  254. if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0)
  255. goto fail;
  256. /* Configure outbound ranges POMs */
  257. ppc4xx_configure_pcix_POMs(hose, reg);
  258. /* Configure inbound ranges PIMs */
  259. ppc4xx_configure_pcix_PIMs(hose, reg, &dma_window, big_pim, msi);
  260. /* We don't need the registers anymore */
  261. iounmap(reg);
  262. return;
  263. fail:
  264. if (hose)
  265. pcibios_free_controller(hose);
  266. if (reg)
  267. iounmap(reg);
  268. }
  269. /*
  270. * 4xx PCI-Express part
  271. */
  272. static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
  273. {
  274. /* NYI */
  275. }
  276. static int __init ppc4xx_pci_find_bridges(void)
  277. {
  278. struct device_node *np;
  279. for_each_compatible_node(np, NULL, "ibm,plb-pciex")
  280. ppc4xx_probe_pciex_bridge(np);
  281. for_each_compatible_node(np, NULL, "ibm,plb-pcix")
  282. ppc4xx_probe_pcix_bridge(np);
  283. for_each_compatible_node(np, NULL, "ibm,plb-pci")
  284. ppc4xx_probe_pci_bridge(np);
  285. return 0;
  286. }
  287. arch_initcall(ppc4xx_pci_find_bridges);