2 * arch/ppc/syslib/mpc10x_common.c
4 * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
7 * Author: Mark A. Greer
10 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
17 * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs ***
20 #include <linux/kernel.h>
21 #include <linux/init.h>
22 #include <linux/pci.h>
23 #include <linux/slab.h>
25 #include <asm/byteorder.h>
28 #include <asm/uaccess.h>
29 #include <asm/machdep.h>
30 #include <asm/pci-bridge.h>
31 #include <asm/open_pic.h>
32 #include <asm/mpc10x.h>
35 /* Set resources to match bridge memory map */
37 mpc10x_bridge_set_resources(int map, struct pci_controller *hose)
41 case MPC10X_MEM_MAP_A:
42 pci_init_resource(&hose->io_resource,
48 pci_init_resource (&hose->mem_resources[0],
54 case MPC10X_MEM_MAP_B:
55 pci_init_resource(&hose->io_resource,
61 pci_init_resource (&hose->mem_resources[0],
68 printk("mpc10x_bridge_set_resources: "
69 "Invalid map specified\n");
71 ppc_md.progress("mpc10x:exit1", 0x100);
75 * Do some initialization and put the EUMB registers at the specified address
76 * (also map the EPIC registers into virtual space--OpenPIC_Addr will be set).
78 * The EPIC is not on the 106, only the 8240 and 107.
81 mpc10x_bridge_init(struct pci_controller *hose,
86 int host_bridge, picr1, picr1_bit;
87 ulong pci_config_addr, pci_config_data;
90 if (ppc_md.progress) ppc_md.progress("mpc10x:enter", 0x100);
92 /* Set up for current map so we can get at config regs */
93 switch (current_map) {
94 case MPC10X_MEM_MAP_A:
95 setup_indirect_pci(hose,
96 MPC10X_MAPA_CNFG_ADDR,
97 MPC10X_MAPA_CNFG_DATA);
99 case MPC10X_MEM_MAP_B:
100 setup_indirect_pci(hose,
101 MPC10X_MAPB_CNFG_ADDR,
102 MPC10X_MAPB_CNFG_DATA);
105 printk("mpc10x_bridge_init: %s\n",
106 "Invalid current map specified");
108 ppc_md.progress("mpc10x:exit1", 0x100);
112 /* Make sure it's a supported bridge */
113 early_read_config_dword(hose,
119 switch (host_bridge) {
120 case MPC10X_BRIDGE_106:
121 case MPC10X_BRIDGE_8240:
122 case MPC10X_BRIDGE_107:
123 case MPC10X_BRIDGE_8245:
127 ppc_md.progress("mpc10x:exit2", 0x100);
132 case MPC10X_MEM_MAP_A:
133 MPC10X_SETUP_HOSE(hose, A);
134 pci_config_addr = MPC10X_MAPA_CNFG_ADDR;
135 pci_config_data = MPC10X_MAPA_CNFG_DATA;
136 picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_A;
138 case MPC10X_MEM_MAP_B:
139 MPC10X_SETUP_HOSE(hose, B);
140 pci_config_addr = MPC10X_MAPB_CNFG_ADDR;
141 pci_config_data = MPC10X_MAPB_CNFG_DATA;
142 picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_B;
145 printk("mpc10x_bridge_init: %s\n",
146 "Invalid new map specified");
148 ppc_md.progress("mpc10x:exit3", 0x100);
152 /* Make bridge use the 'new_map', if not already usng it */
153 if (current_map != new_map) {
154 early_read_config_dword(hose,
157 MPC10X_CFG_PICR1_REG,
160 picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) |
163 early_write_config_dword(hose,
166 MPC10X_CFG_PICR1_REG,
169 asm volatile("sync");
171 /* Undo old mappings & map in new cfg data/addr regs */
172 iounmap((void *)hose->cfg_addr);
173 iounmap((void *)hose->cfg_data);
175 setup_indirect_pci(hose,
180 /* Setup resources to match map */
181 mpc10x_bridge_set_resources(new_map, hose);
184 * Want processor accesses of 0xFDxxxxxx to be mapped
185 * to PCI memory space at 0x00000000. Do not want
186 * host bridge to respond to PCI memory accesses of
187 * 0xFDxxxxxx. Do not want host bridge to respond
188 * to PCI memory addresses 0xFD000000-0xFDFFFFFF;
189 * want processor accesses from 0x000A0000-0x000BFFFF
190 * to be forwarded to system memory.
192 * Only valid if not in agent mode and using MAP B.
194 if (new_map == MPC10X_MEM_MAP_B) {
195 early_read_config_byte(hose,
198 MPC10X_CFG_MAPB_OPTIONS_REG,
201 byte &= ~(MPC10X_CFG_MAPB_OPTIONS_PFAE |
202 MPC10X_CFG_MAPB_OPTIONS_PCICH |
203 MPC10X_CFG_MAPB_OPTIONS_PROCCH);
205 if (host_bridge != MPC10X_BRIDGE_106) {
206 byte |= MPC10X_CFG_MAPB_OPTIONS_CFAE;
209 early_write_config_byte(hose,
212 MPC10X_CFG_MAPB_OPTIONS_REG,
216 if (host_bridge != MPC10X_BRIDGE_106) {
217 early_read_config_byte(hose,
223 if (pir != MPC10X_CFG_PIR_HOST_BRIDGE) {
224 printk("Host bridge in Agent mode\n");
225 /* Read or Set LMBAR & PCSRBAR? */
228 /* Set base addr of the 8240/107 EUMB. */
229 early_write_config_dword(hose,
235 /* Map EPIC register part of EUMB into vitual memory */
237 ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET,
238 MPC10X_EUMB_EPIC_SIZE);
241 #ifdef CONFIG_MPC10X_STORE_GATHERING
242 mpc10x_enable_store_gathering(hose);
244 mpc10x_disable_store_gathering(hose);
247 if (ppc_md.progress) ppc_md.progress("mpc10x:exit", 0x100);
252 * Need to make our own PCI config space access macros because
253 * mpc10x_get_mem_size() is called before the data structures are set up for
254 * the 'early_xxx' and 'indirect_xxx' routines to work.
257 #define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr))
258 #define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val))
260 #define MPC10X_PCI_OP(rw, size, type, op, mask) \
262 mpc10x_##rw##_config_##size(uint *cfg_addr, uint *cfg_data, int devfn, int offset, type val) \
265 ((offset & 0xfc) << 24) | (devfn << 16) \
266 | (0 << 8) | 0x80); \
267 MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \
271 MPC10X_PCI_OP(read, byte, u8 *, in_8, 3)
272 MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0)
274 MPC10X_PCI_OP(write, byte, u8, out_8, 3)
275 MPC10X_PCI_OP(read, word, u16 *, in_le16, 2)
276 MPC10X_PCI_OP(write, word, u16, out_le16, 2)
277 MPC10X_PCI_OP(write, dword, u32, out_le32, 0)
281 * Read the memory controller registers to determine the amount of memory in
282 * the system. This assumes that the firmware has correctly set up the memory
283 * controller registers.
286 mpc10x_get_mem_size(uint mem_map)
288 uint *config_addr, *config_data, val;
289 ulong start, end, total, offset;
294 case MPC10X_MEM_MAP_A:
295 config_addr = (uint *)MPC10X_MAPA_CNFG_ADDR;
296 config_data = (uint *)MPC10X_MAPA_CNFG_DATA;
298 case MPC10X_MEM_MAP_B:
299 config_addr = (uint *)MPC10X_MAPB_CNFG_ADDR;
300 config_data = (uint *)MPC10X_MAPB_CNFG_DATA;
306 mpc10x_read_config_byte(config_addr,
309 MPC10X_MCTLR_MEM_BANK_ENABLES,
314 for (i=0; i<8; i++) {
315 if (bank_enables & (1 << i)) {
316 offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0);
317 mpc10x_read_config_dword(config_addr,
322 start = (val >> ((i & 3) << 3)) & 0xff;
324 offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0);
325 mpc10x_read_config_dword(config_addr,
330 val = (val >> ((i & 3) << 3)) & 0x03;
331 start = (val << 28) | (start << 20);
333 offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0);
334 mpc10x_read_config_dword(config_addr,
339 end = (val >> ((i & 3) << 3)) & 0xff;
341 offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0);
342 mpc10x_read_config_dword(config_addr,
347 val = (val >> ((i & 3) << 3)) & 0x03;
348 end = (val << 28) | (end << 20) | 0xfffff;
350 total += (end - start + 1);
358 mpc10x_enable_store_gathering(struct pci_controller *hose)
362 early_read_config_dword(hose,
365 MPC10X_CFG_PICR1_REG,
368 picr1 |= MPC10X_CFG_PICR1_ST_GATH_EN;
370 early_write_config_dword(hose,
373 MPC10X_CFG_PICR1_REG,
380 mpc10x_disable_store_gathering(struct pci_controller *hose)
384 early_read_config_dword(hose,
387 MPC10X_CFG_PICR1_REG,
390 picr1 &= ~MPC10X_CFG_PICR1_ST_GATH_EN;
392 early_write_config_dword(hose,
395 MPC10X_CFG_PICR1_REG,