mpc52xx_pci.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * arch/ppc/syslib/mpc52xx_pci.c
  3. *
  4. * PCI code for the Freescale MPC52xx embedded CPU.
  5. *
  6. *
  7. * Maintainer : Sylvain Munaut <tnt@246tNt.com>
  8. *
  9. * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
  10. *
  11. * This file is licensed under the terms of the GNU General Public License
  12. * version 2. This program is licensed "as is" without any warranty of any
  13. * kind, whether express or implied.
  14. */
  15. #include <linux/config.h>
  16. #include <asm/pci.h>
  17. #include <asm/mpc52xx.h>
  18. #include "mpc52xx_pci.h"
  19. #include <asm/delay.h>
  20. static int
  21. mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
  22. int offset, int len, u32 *val)
  23. {
  24. struct pci_controller *hose = bus->sysdata;
  25. u32 value;
  26. if (ppc_md.pci_exclude_device)
  27. if (ppc_md.pci_exclude_device(bus->number, devfn))
  28. return PCIBIOS_DEVICE_NOT_FOUND;
  29. out_be32(hose->cfg_addr,
  30. (1 << 31) |
  31. ((bus->number - hose->bus_offset) << 16) |
  32. (devfn << 8) |
  33. (offset & 0xfc));
  34. value = in_le32(hose->cfg_data);
  35. if (len != 4) {
  36. value >>= ((offset & 0x3) << 3);
  37. value &= 0xffffffff >> (32 - (len << 3));
  38. }
  39. *val = value;
  40. out_be32(hose->cfg_addr, 0);
  41. return PCIBIOS_SUCCESSFUL;
  42. }
  43. static int
  44. mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
  45. int offset, int len, u32 val)
  46. {
  47. struct pci_controller *hose = bus->sysdata;
  48. u32 value, mask;
  49. if (ppc_md.pci_exclude_device)
  50. if (ppc_md.pci_exclude_device(bus->number, devfn))
  51. return PCIBIOS_DEVICE_NOT_FOUND;
  52. out_be32(hose->cfg_addr,
  53. (1 << 31) |
  54. ((bus->number - hose->bus_offset) << 16) |
  55. (devfn << 8) |
  56. (offset & 0xfc));
  57. if (len != 4) {
  58. value = in_le32(hose->cfg_data);
  59. offset = (offset & 0x3) << 3;
  60. mask = (0xffffffff >> (32 - (len << 3)));
  61. mask <<= offset;
  62. value &= ~mask;
  63. val = value | ((val << offset) & mask);
  64. }
  65. out_le32(hose->cfg_data, val);
  66. out_be32(hose->cfg_addr, 0);
  67. return PCIBIOS_SUCCESSFUL;
  68. }
  69. static struct pci_ops mpc52xx_pci_ops = {
  70. .read = mpc52xx_pci_read_config,
  71. .write = mpc52xx_pci_write_config
  72. };
  73. static void __init
  74. mpc52xx_pci_setup(struct mpc52xx_pci __iomem *pci_regs)
  75. {
  76. /* Setup control regs */
  77. /* Nothing to do afaik */
  78. /* Setup windows */
  79. out_be32(&pci_regs->iw0btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
  80. MPC52xx_PCI_MEM_START + MPC52xx_PCI_MEM_OFFSET,
  81. MPC52xx_PCI_MEM_START,
  82. MPC52xx_PCI_MEM_SIZE ));
  83. out_be32(&pci_regs->iw1btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
  84. MPC52xx_PCI_MMIO_START + MPC52xx_PCI_MEM_OFFSET,
  85. MPC52xx_PCI_MMIO_START,
  86. MPC52xx_PCI_MMIO_SIZE ));
  87. out_be32(&pci_regs->iw2btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
  88. MPC52xx_PCI_IO_BASE,
  89. MPC52xx_PCI_IO_START,
  90. MPC52xx_PCI_IO_SIZE ));
  91. out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(
  92. ( MPC52xx_PCI_IWCR_ENABLE | /* iw0btar */
  93. MPC52xx_PCI_IWCR_READ_MULTI |
  94. MPC52xx_PCI_IWCR_MEM ),
  95. ( MPC52xx_PCI_IWCR_ENABLE | /* iw1btar */
  96. MPC52xx_PCI_IWCR_READ |
  97. MPC52xx_PCI_IWCR_MEM ),
  98. ( MPC52xx_PCI_IWCR_ENABLE | /* iw2btar */
  99. MPC52xx_PCI_IWCR_IO )
  100. ));
  101. out_be32(&pci_regs->tbatr0,
  102. MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
  103. out_be32(&pci_regs->tbatr1,
  104. MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
  105. out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
  106. /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
  107. /* Not necessary and can be a bad thing if for example the bootloader
  108. is displaying a splash screen or ... Just left here for
  109. documentation purpose if anyone need it */
  110. #if 0
  111. u32 tmp;
  112. tmp = in_be32(&pci_regs->gscr);
  113. out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
  114. udelay(50);
  115. out_be32(&pci_regs->gscr, tmp);
  116. #endif
  117. }
  118. static void __init
  119. mpc52xx_pci_fixup_resources(struct pci_dev *dev)
  120. {
  121. int i;
  122. /* We don't rely on boot loader for PCI and resets all
  123. devices */
  124. for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
  125. struct resource *res = &dev->resource[i];
  126. if (res->end > res->start) { /* Only valid resources */
  127. res->end -= res->start;
  128. res->start = 0;
  129. res->flags |= IORESOURCE_UNSET;
  130. }
  131. }
  132. /* The PCI Host bridge of MPC52xx has a prefetch memory resource
  133. fixed to 1Gb. Doesn't fit in the resource system so we remove it */
  134. if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
  135. (dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200) ) {
  136. struct resource *res = &dev->resource[1];
  137. res->start = res->end = res->flags = 0;
  138. }
  139. }
  140. void __init
  141. mpc52xx_find_bridges(void)
  142. {
  143. struct mpc52xx_pci __iomem *pci_regs;
  144. struct pci_controller *hose;
  145. pci_assign_all_busses = 1;
  146. pci_regs = ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET), MPC52xx_PCI_SIZE);
  147. if (!pci_regs)
  148. return;
  149. hose = pcibios_alloc_controller();
  150. if (!hose) {
  151. iounmap(pci_regs);
  152. return;
  153. }
  154. ppc_md.pci_swizzle = common_swizzle;
  155. ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
  156. hose->first_busno = 0;
  157. hose->last_busno = 0xff;
  158. hose->bus_offset = 0;
  159. hose->ops = &mpc52xx_pci_ops;
  160. mpc52xx_pci_setup(pci_regs);
  161. hose->pci_mem_offset = MPC52xx_PCI_MEM_OFFSET;
  162. hose->io_base_virt = ioremap(MPC52xx_PCI_IO_BASE, MPC52xx_PCI_IO_SIZE);
  163. isa_io_base = (unsigned long) hose->io_base_virt;
  164. hose->cfg_addr = &pci_regs->car;
  165. hose->cfg_data = hose->io_base_virt;
  166. /* Setup resources */
  167. pci_init_resource(&hose->mem_resources[0],
  168. MPC52xx_PCI_MEM_START,
  169. MPC52xx_PCI_MEM_STOP,
  170. IORESOURCE_MEM|IORESOURCE_PREFETCH,
  171. "PCI prefetchable memory");
  172. pci_init_resource(&hose->mem_resources[1],
  173. MPC52xx_PCI_MMIO_START,
  174. MPC52xx_PCI_MMIO_STOP,
  175. IORESOURCE_MEM,
  176. "PCI memory");
  177. pci_init_resource(&hose->io_resource,
  178. MPC52xx_PCI_IO_START,
  179. MPC52xx_PCI_IO_STOP,
  180. IORESOURCE_IO,
  181. "PCI I/O");
  182. }