mpc52xx_pci.c 5.5 KB

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