2 * arch/ppc/syslib/mpc52xx_pci.c
4 * PCI code for the Freescale MPC52xx embedded CPU.
7 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
9 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
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.
16 #include <linux/config.h>
20 #include <asm/mpc52xx.h>
21 #include "mpc52xx_pci.h"
23 #include <asm/delay.h>
27 mpc52xx_pci_read_config(struct pci_bus
*bus
, unsigned int devfn
,
28 int offset
, int len
, u32
*val
)
30 struct pci_controller
*hose
= bus
->sysdata
;
33 if (ppc_md
.pci_exclude_device
)
34 if (ppc_md
.pci_exclude_device(bus
->number
, devfn
))
35 return PCIBIOS_DEVICE_NOT_FOUND
;
37 out_be32(hose
->cfg_addr
,
39 ((bus
->number
- hose
->bus_offset
) << 16) |
43 value
= in_le32(hose
->cfg_data
);
46 value
>>= ((offset
& 0x3) << 3);
47 value
&= 0xffffffff >> (32 - (len
<< 3));
52 out_be32(hose
->cfg_addr
, 0);
54 return PCIBIOS_SUCCESSFUL
;
58 mpc52xx_pci_write_config(struct pci_bus
*bus
, unsigned int devfn
,
59 int offset
, int len
, u32 val
)
61 struct pci_controller
*hose
= bus
->sysdata
;
64 if (ppc_md
.pci_exclude_device
)
65 if (ppc_md
.pci_exclude_device(bus
->number
, devfn
))
66 return PCIBIOS_DEVICE_NOT_FOUND
;
68 out_be32(hose
->cfg_addr
,
70 ((bus
->number
- hose
->bus_offset
) << 16) |
75 value
= in_le32(hose
->cfg_data
);
77 offset
= (offset
& 0x3) << 3;
78 mask
= (0xffffffff >> (32 - (len
<< 3)));
82 val
= value
| ((val
<< offset
) & mask
);
85 out_le32(hose
->cfg_data
, val
);
87 out_be32(hose
->cfg_addr
, 0);
89 return PCIBIOS_SUCCESSFUL
;
92 static struct pci_ops mpc52xx_pci_ops
= {
93 .read
= mpc52xx_pci_read_config
,
94 .write
= mpc52xx_pci_write_config
99 mpc52xx_pci_setup(struct mpc52xx_pci __iomem
*pci_regs
)
102 /* Setup control regs */
103 /* Nothing to do afaik */
106 out_be32(&pci_regs
->iw0btar
, MPC52xx_PCI_IWBTAR_TRANSLATION(
107 MPC52xx_PCI_MEM_START
+ MPC52xx_PCI_MEM_OFFSET
,
108 MPC52xx_PCI_MEM_START
,
109 MPC52xx_PCI_MEM_SIZE
));
111 out_be32(&pci_regs
->iw1btar
, MPC52xx_PCI_IWBTAR_TRANSLATION(
112 MPC52xx_PCI_MMIO_START
+ MPC52xx_PCI_MEM_OFFSET
,
113 MPC52xx_PCI_MMIO_START
,
114 MPC52xx_PCI_MMIO_SIZE
));
116 out_be32(&pci_regs
->iw2btar
, MPC52xx_PCI_IWBTAR_TRANSLATION(
118 MPC52xx_PCI_IO_START
,
119 MPC52xx_PCI_IO_SIZE
));
121 out_be32(&pci_regs
->iwcr
, MPC52xx_PCI_IWCR_PACK(
122 ( MPC52xx_PCI_IWCR_ENABLE
| /* iw0btar */
123 MPC52xx_PCI_IWCR_READ_MULTI
|
124 MPC52xx_PCI_IWCR_MEM
),
125 ( MPC52xx_PCI_IWCR_ENABLE
| /* iw1btar */
126 MPC52xx_PCI_IWCR_READ
|
127 MPC52xx_PCI_IWCR_MEM
),
128 ( MPC52xx_PCI_IWCR_ENABLE
| /* iw2btar */
129 MPC52xx_PCI_IWCR_IO
)
133 out_be32(&pci_regs
->tbatr0
,
134 MPC52xx_PCI_TBATR_ENABLE
| MPC52xx_PCI_TARGET_IO
);
135 out_be32(&pci_regs
->tbatr1
,
136 MPC52xx_PCI_TBATR_ENABLE
| MPC52xx_PCI_TARGET_MEM
);
138 out_be32(&pci_regs
->tcr
, MPC52xx_PCI_TCR_LD
);
140 /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
141 /* Not necessary and can be a bad thing if for example the bootloader
142 is displaying a splash screen or ... Just left here for
143 documentation purpose if anyone need it */
146 tmp
= in_be32(&pci_regs
->gscr
);
147 out_be32(&pci_regs
->gscr
, tmp
| MPC52xx_PCI_GSCR_PR
);
149 out_be32(&pci_regs
->gscr
, tmp
);
154 mpc52xx_pci_fixup_resources(struct pci_dev
*dev
)
158 /* We don't rely on boot loader for PCI and resets all
160 for (i
= 0; i
< DEVICE_COUNT_RESOURCE
; i
++) {
161 struct resource
*res
= &dev
->resource
[i
];
162 if (res
->end
> res
->start
) { /* Only valid resources */
163 res
->end
-= res
->start
;
165 res
->flags
|= IORESOURCE_UNSET
;
169 /* The PCI Host bridge of MPC52xx has a prefetch memory resource
170 fixed to 1Gb. Doesn't fit in the resource system so we remove it */
171 if ( (dev
->vendor
== PCI_VENDOR_ID_MOTOROLA
) &&
172 (dev
->device
== PCI_DEVICE_ID_MOTOROLA_MPC5200
) ) {
173 struct resource
*res
= &dev
->resource
[1];
174 res
->start
= res
->end
= res
->flags
= 0;
179 mpc52xx_find_bridges(void)
181 struct mpc52xx_pci __iomem
*pci_regs
;
182 struct pci_controller
*hose
;
184 pci_assign_all_busses
= 1;
186 pci_regs
= ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET
), MPC52xx_PCI_SIZE
);
190 hose
= pcibios_alloc_controller();
196 ppc_md
.pci_swizzle
= common_swizzle
;
197 ppc_md
.pcibios_fixup_resources
= mpc52xx_pci_fixup_resources
;
199 hose
->first_busno
= 0;
200 hose
->last_busno
= 0xff;
201 hose
->bus_offset
= 0;
202 hose
->ops
= &mpc52xx_pci_ops
;
204 mpc52xx_pci_setup(pci_regs
);
206 hose
->pci_mem_offset
= MPC52xx_PCI_MEM_OFFSET
;
208 hose
->io_base_virt
= ioremap(MPC52xx_PCI_IO_BASE
, MPC52xx_PCI_IO_SIZE
);
209 isa_io_base
= (unsigned long) hose
->io_base_virt
;
211 hose
->cfg_addr
= &pci_regs
->car
;
212 hose
->cfg_data
= hose
->io_base_virt
;
214 /* Setup resources */
215 pci_init_resource(&hose
->mem_resources
[0],
216 MPC52xx_PCI_MEM_START
,
217 MPC52xx_PCI_MEM_STOP
,
218 IORESOURCE_MEM
|IORESOURCE_PREFETCH
,
219 "PCI prefetchable memory");
221 pci_init_resource(&hose
->mem_resources
[1],
222 MPC52xx_PCI_MMIO_START
,
223 MPC52xx_PCI_MMIO_STOP
,
227 pci_init_resource(&hose
->io_resource
,
228 MPC52xx_PCI_IO_START
,