pci-malta.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
  4. * All rights reserved.
  5. * Authors: Carsten Langgaard <[email protected]>
  6. * Maciej W. Rozycki <[email protected]>
  7. *
  8. * Copyright (C) 2004 by Ralf Baechle ([email protected])
  9. *
  10. * MIPS boards specific PCI support.
  11. */
  12. #include <linux/types.h>
  13. #include <linux/pci.h>
  14. #include <linux/kernel.h>
  15. #include <linux/init.h>
  16. #include <asm/gt64120.h>
  17. #include <asm/mips-cps.h>
  18. #include <asm/mips-boards/generic.h>
  19. #include <asm/mips-boards/bonito64.h>
  20. #include <asm/mips-boards/msc01_pci.h>
  21. static struct resource bonito64_mem_resource = {
  22. .name = "Bonito PCI MEM",
  23. .flags = IORESOURCE_MEM,
  24. };
  25. static struct resource bonito64_io_resource = {
  26. .name = "Bonito PCI I/O",
  27. .start = 0x00000000UL,
  28. .end = 0x000fffffUL,
  29. .flags = IORESOURCE_IO,
  30. };
  31. static struct resource gt64120_mem_resource = {
  32. .name = "GT-64120 PCI MEM",
  33. .flags = IORESOURCE_MEM,
  34. };
  35. static struct resource gt64120_io_resource = {
  36. .name = "GT-64120 PCI I/O",
  37. .flags = IORESOURCE_IO,
  38. };
  39. static struct resource msc_mem_resource = {
  40. .name = "MSC PCI MEM",
  41. .flags = IORESOURCE_MEM,
  42. };
  43. static struct resource msc_io_resource = {
  44. .name = "MSC PCI I/O",
  45. .flags = IORESOURCE_IO,
  46. };
  47. extern struct pci_ops bonito64_pci_ops;
  48. extern struct pci_ops gt64xxx_pci0_ops;
  49. extern struct pci_ops msc_pci_ops;
  50. static struct pci_controller bonito64_controller = {
  51. .pci_ops = &bonito64_pci_ops,
  52. .io_resource = &bonito64_io_resource,
  53. .mem_resource = &bonito64_mem_resource,
  54. .io_offset = 0x00000000UL,
  55. };
  56. static struct pci_controller gt64120_controller = {
  57. .pci_ops = &gt64xxx_pci0_ops,
  58. .io_resource = &gt64120_io_resource,
  59. .mem_resource = &gt64120_mem_resource,
  60. };
  61. static struct pci_controller msc_controller = {
  62. .pci_ops = &msc_pci_ops,
  63. .io_resource = &msc_io_resource,
  64. .mem_resource = &msc_mem_resource,
  65. };
  66. void __init mips_pcibios_init(void)
  67. {
  68. struct pci_controller *controller;
  69. resource_size_t start, end, map, start1, end1, map1, map2, map3, mask;
  70. switch (mips_revision_sconid) {
  71. case MIPS_REVISION_SCON_GT64120:
  72. /*
  73. * Due to a bug in the Galileo system controller, we need
  74. * to setup the PCI BAR for the Galileo internal registers.
  75. * This should be done in the bios/bootprom and will be
  76. * fixed in a later revision of YAMON (the MIPS boards
  77. * boot prom).
  78. */
  79. GT_WRITE(GT_PCI0_CFGADDR_OFS,
  80. (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
  81. (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
  82. (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
  83. ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
  84. GT_PCI0_CFGADDR_CONFIGEN_BIT);
  85. /* Perform the write */
  86. GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
  87. /* Set up resource ranges from the controller's registers. */
  88. start = GT_READ(GT_PCI0M0LD_OFS);
  89. end = GT_READ(GT_PCI0M0HD_OFS);
  90. map = GT_READ(GT_PCI0M0REMAP_OFS);
  91. end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
  92. start1 = GT_READ(GT_PCI0M1LD_OFS);
  93. end1 = GT_READ(GT_PCI0M1HD_OFS);
  94. map1 = GT_READ(GT_PCI0M1REMAP_OFS);
  95. end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
  96. /* Cannot support multiple windows, use the wider. */
  97. if (end1 - start1 > end - start) {
  98. start = start1;
  99. end = end1;
  100. map = map1;
  101. }
  102. mask = ~(start ^ end);
  103. /* We don't support remapping with a discontiguous mask. */
  104. BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
  105. mask != ~((mask & -mask) - 1));
  106. gt64120_mem_resource.start = start;
  107. gt64120_mem_resource.end = end;
  108. gt64120_controller.mem_offset = (start & mask) - (map & mask);
  109. /* Addresses are 36-bit, so do shifts in the destinations. */
  110. gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
  111. gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
  112. gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
  113. gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
  114. start = GT_READ(GT_PCI0IOLD_OFS);
  115. end = GT_READ(GT_PCI0IOHD_OFS);
  116. map = GT_READ(GT_PCI0IOREMAP_OFS);
  117. end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
  118. mask = ~(start ^ end);
  119. /* We don't support remapping with a discontiguous mask. */
  120. BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
  121. mask != ~((mask & -mask) - 1));
  122. gt64120_io_resource.start = map & mask;
  123. gt64120_io_resource.end = (map & mask) | ~mask;
  124. gt64120_controller.io_offset = 0;
  125. /* Addresses are 36-bit, so do shifts in the destinations. */
  126. gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
  127. gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
  128. gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
  129. controller = &gt64120_controller;
  130. break;
  131. case MIPS_REVISION_SCON_BONITO:
  132. /* Set up resource ranges from the controller's registers. */
  133. map = BONITO_PCIMAP;
  134. map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
  135. BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
  136. map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
  137. BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
  138. map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
  139. BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
  140. /* Combine as many adjacent windows as possible. */
  141. map = map1;
  142. start = BONITO_PCILO0_BASE;
  143. end = 1;
  144. if (map3 == map2 + 1) {
  145. map = map2;
  146. start = BONITO_PCILO1_BASE;
  147. end++;
  148. }
  149. if (map2 == map1 + 1) {
  150. map = map1;
  151. start = BONITO_PCILO0_BASE;
  152. end++;
  153. }
  154. bonito64_mem_resource.start = start;
  155. bonito64_mem_resource.end = start +
  156. BONITO_PCIMAP_WINBASE(end) - 1;
  157. bonito64_controller.mem_offset = start -
  158. BONITO_PCIMAP_WINBASE(map);
  159. controller = &bonito64_controller;
  160. break;
  161. case MIPS_REVISION_SCON_SOCIT:
  162. case MIPS_REVISION_SCON_ROCIT:
  163. case MIPS_REVISION_SCON_SOCITSC:
  164. case MIPS_REVISION_SCON_SOCITSCP:
  165. /* Set up resource ranges from the controller's registers. */
  166. MSC_READ(MSC01_PCI_SC2PMBASL, start);
  167. MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
  168. MSC_READ(MSC01_PCI_SC2PMMAPL, map);
  169. msc_mem_resource.start = start & mask;
  170. msc_mem_resource.end = (start & mask) | ~mask;
  171. msc_controller.mem_offset = (start & mask) - (map & mask);
  172. if (mips_cps_numiocu(0)) {
  173. write_gcr_reg0_base(start);
  174. write_gcr_reg0_mask(mask |
  175. CM_GCR_REGn_MASK_CMTGT_IOCU0);
  176. }
  177. MSC_READ(MSC01_PCI_SC2PIOBASL, start);
  178. MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
  179. MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
  180. msc_io_resource.start = map & mask;
  181. msc_io_resource.end = (map & mask) | ~mask;
  182. msc_controller.io_offset = 0;
  183. ioport_resource.end = ~mask;
  184. if (mips_cps_numiocu(0)) {
  185. write_gcr_reg1_base(start);
  186. write_gcr_reg1_mask(mask |
  187. CM_GCR_REGn_MASK_CMTGT_IOCU0);
  188. }
  189. /* If ranges overlap I/O takes precedence. */
  190. start = start & mask;
  191. end = start | ~mask;
  192. if ((start >= msc_mem_resource.start &&
  193. start <= msc_mem_resource.end) ||
  194. (end >= msc_mem_resource.start &&
  195. end <= msc_mem_resource.end)) {
  196. /* Use the larger space. */
  197. start = max(start, msc_mem_resource.start);
  198. end = min(end, msc_mem_resource.end);
  199. if (start - msc_mem_resource.start >=
  200. msc_mem_resource.end - end)
  201. msc_mem_resource.end = start - 1;
  202. else
  203. msc_mem_resource.start = end + 1;
  204. }
  205. controller = &msc_controller;
  206. break;
  207. default:
  208. return;
  209. }
  210. /* PIIX4 ACPI starts at 0x1000 */
  211. if (controller->io_resource->start < 0x00001000UL)
  212. controller->io_resource->start = 0x00001000UL;
  213. iomem_resource.end &= 0xfffffffffULL; /* 64 GB */
  214. ioport_resource.end = controller->io_resource->end;
  215. controller->io_map_base = mips_io_port_base;
  216. register_pci_controller(controller);
  217. }