1
2 /*
3 * arch/ppc/kernel/mpc10x_common.c
4 *
5 * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
6 * Mem ctlr, EPIC, etc.
7 *
8 * Author: Mark A. Greer
9 * mgreer@mvista.com
10 *
11 * Copyright 2001 MontaVista Software Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19 /*
20 * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs ***
21 */
22
23 #include <linux/kernel.h>
24 #include <linux/init.h>
25 #include <linux/pci.h>
26 #include <linux/slab.h>
27
28 #include <asm/byteorder.h>
29 #include <asm/io.h>
30 #include <asm/irq.h>
31 #include <asm/uaccess.h>
32 #include <asm/machdep.h>
33 #include <asm/pci-bridge.h>
34 #include <asm/open_pic.h>
35 #include <asm/mpc10x.h>
36
37
38 /* Set resources to match bridge memory map */
39 void __init
mpc10x_bridge_set_resources(int map,struct pci_controller * hose)40 mpc10x_bridge_set_resources(int map, struct pci_controller *hose)
41 {
42
43 switch (map) {
44 case MPC10X_MEM_MAP_A:
45 pci_init_resource(&hose->io_resource,
46 0x00000000,
47 0x3f7fffff,
48 IORESOURCE_IO,
49 "PCI host bridge");
50
51 pci_init_resource (&hose->mem_resources[0],
52 0xc0000000,
53 0xfeffffff,
54 IORESOURCE_MEM,
55 "PCI host bridge");
56 break;
57 case MPC10X_MEM_MAP_B:
58 pci_init_resource(&hose->io_resource,
59 0x00000000,
60 0x00bfffff,
61 IORESOURCE_IO,
62 "PCI host bridge");
63
64 pci_init_resource (&hose->mem_resources[0],
65 0x80000000,
66 0xfcffffff,
67 IORESOURCE_MEM,
68 "PCI host bridge");
69 break;
70 default:
71 printk("mpc10x_bridge_set_resources: "
72 "Invalid map specified\n");
73 if (ppc_md.progress)
74 ppc_md.progress("mpc10x:exit1", 0x100);
75 }
76 }
77 /*
78 * Do some initialization and put the EUMB registers at the specified address
79 * (also map the EPIC registers into virtual space--OpenPIC_Addr will be set).
80 *
81 * The EPIC is not on the 106, only the 8240 and 107.
82 */
83 int __init
mpc10x_bridge_init(struct pci_controller * hose,uint current_map,uint new_map,uint phys_eumb_base)84 mpc10x_bridge_init(struct pci_controller *hose,
85 uint current_map,
86 uint new_map,
87 uint phys_eumb_base)
88 {
89 int host_bridge, picr1, picr1_bit;
90 ulong pci_config_addr, pci_config_data;
91 u_char pir, byte;
92
93 if (ppc_md.progress) ppc_md.progress("mpc10x:enter", 0x100);
94
95 /* Set up for current map so we can get at config regs */
96 switch (current_map) {
97 case MPC10X_MEM_MAP_A:
98 setup_indirect_pci(hose,
99 MPC10X_MAPA_CNFG_ADDR,
100 MPC10X_MAPA_CNFG_DATA);
101 break;
102 case MPC10X_MEM_MAP_B:
103 setup_indirect_pci(hose,
104 MPC10X_MAPB_CNFG_ADDR,
105 MPC10X_MAPB_CNFG_DATA);
106 break;
107 default:
108 printk("mpc10x_bridge_init: %s\n",
109 "Invalid current map specified");
110 if (ppc_md.progress)
111 ppc_md.progress("mpc10x:exit1", 0x100);
112 return -1;
113 }
114
115 /* Make sure its a supported bridge */
116 early_read_config_dword(hose,
117 0,
118 PCI_DEVFN(0,0),
119 PCI_VENDOR_ID,
120 &host_bridge);
121
122 switch (host_bridge) {
123 case MPC10X_BRIDGE_106:
124 case MPC10X_BRIDGE_8240:
125 case MPC10X_BRIDGE_107:
126 case MPC10X_BRIDGE_8245:
127 break;
128 default:
129 if (ppc_md.progress)
130 ppc_md.progress("mpc10x:exit2", 0x100);
131 return -1;
132 }
133
134 switch (new_map) {
135 case MPC10X_MEM_MAP_A:
136 MPC10X_SETUP_HOSE(hose, A);
137 pci_config_addr = MPC10X_MAPA_CNFG_ADDR;
138 pci_config_data = MPC10X_MAPA_CNFG_DATA;
139 picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_A;
140 break;
141 case MPC10X_MEM_MAP_B:
142 MPC10X_SETUP_HOSE(hose, B);
143 pci_config_addr = MPC10X_MAPB_CNFG_ADDR;
144 pci_config_data = MPC10X_MAPB_CNFG_DATA;
145 picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_B;
146 break;
147 default:
148 printk("mpc10x_bridge_init: %s\n",
149 "Invalid new map specified");
150 if (ppc_md.progress)
151 ppc_md.progress("mpc10x:exit3", 0x100);
152 return -1;
153 }
154
155 /* Make bridge use the 'new_map', if not already usng it */
156 if (current_map != new_map) {
157 early_read_config_dword(hose,
158 0,
159 PCI_DEVFN(0,0),
160 MPC10X_CFG_PICR1_REG,
161 &picr1);
162
163 picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) |
164 picr1_bit;
165
166 early_write_config_dword(hose,
167 0,
168 PCI_DEVFN(0,0),
169 MPC10X_CFG_PICR1_REG,
170 picr1);
171
172 asm volatile("sync");
173
174 /* Undo old mappings & map in new cfg data/addr regs */
175 iounmap((void *)hose->cfg_addr);
176 iounmap((void *)hose->cfg_data);
177
178 setup_indirect_pci(hose,
179 pci_config_addr,
180 pci_config_data);
181 }
182
183 /* Setup resources to match map */
184 mpc10x_bridge_set_resources(new_map, hose);
185
186 /*
187 * Want processor accesses of 0xFDxxxxxx to be mapped
188 * to PCI memory space at 0x00000000. Do not want
189 * host bridge to respond to PCI memory accesses of
190 * 0xFDxxxxxx. Do not want host bridge to respond
191 * to PCI memory addresses 0xFD000000-0xFDFFFFFF;
192 * want processor accesses from 0x000A0000-0x000BFFFF
193 * to be forwarded to system memory.
194 *
195 * Only valid if not in agent mode and using MAP B.
196 */
197 if (new_map == MPC10X_MEM_MAP_B) {
198 early_read_config_byte(hose,
199 0,
200 PCI_DEVFN(0,0),
201 MPC10X_CFG_MAPB_OPTIONS_REG,
202 &byte);
203
204 byte &= ~(MPC10X_CFG_MAPB_OPTIONS_PFAE |
205 MPC10X_CFG_MAPB_OPTIONS_PCICH |
206 MPC10X_CFG_MAPB_OPTIONS_PROCCH);
207
208 if (host_bridge != MPC10X_BRIDGE_106) {
209 byte |= MPC10X_CFG_MAPB_OPTIONS_CFAE;
210 }
211
212 early_write_config_byte(hose,
213 0,
214 PCI_DEVFN(0,0),
215 MPC10X_CFG_MAPB_OPTIONS_REG,
216 byte);
217 }
218
219 if (host_bridge != MPC10X_BRIDGE_106) {
220 early_read_config_byte(hose,
221 0,
222 PCI_DEVFN(0,0),
223 MPC10X_CFG_PIR_REG,
224 &pir);
225
226 if (pir != MPC10X_CFG_PIR_HOST_BRIDGE) {
227 printk("Host bridge in Agent mode\n");
228 /* Read or Set LMBAR & PCSRBAR? */
229 }
230
231 /* Set base addr of the 8240/107 EUMB. */
232 early_write_config_dword(hose,
233 0,
234 PCI_DEVFN(0,0),
235 MPC10X_CFG_EUMBBAR,
236 phys_eumb_base);
237
238 /* Map EPIC register part of EUMB into vitual memory */
239 OpenPIC_Addr =
240 ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET,
241 MPC10X_EUMB_EPIC_SIZE);
242 }
243
244 #ifdef CONFIG_MPC10X_STORE_GATHERING
245 mpc10x_enable_store_gathering(hose);
246 #else
247 mpc10x_disable_store_gathering(hose);
248 #endif
249
250 if (ppc_md.progress) ppc_md.progress("mpc10x:exit", 0x100);
251 return 0;
252 }
253
254 /*
255 * Need to make our own PCI config space access macros because
256 * mpc10x_get_mem_size() is called before the data structures are set up for
257 * the 'early_xxx' and 'indirect_xxx' routines to work.
258 * Assumes bus 0.
259 */
260 #define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr))
261 #define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val))
262
263 #define MPC10X_PCI_OP(rw, size, type, op, mask) \
264 static void \
265 mpc10x_##rw##_config_##size(uint *cfg_addr, uint *cfg_data, int devfn, int offset, type val) \
266 { \
267 out_be32(cfg_addr, \
268 ((offset & 0xfc) << 24) | (devfn << 16) \
269 | (0 << 8) | 0x80); \
270 MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \
271 return; \
272 }
273
274 MPC10X_PCI_OP(read, byte, u8 *, in_8, 3)
275 MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0)
276 #if 0 /* Not used */
277 MPC10X_PCI_OP(write, byte, u8, out_8, 3)
278 MPC10X_PCI_OP(read, word, u16 *, in_le16, 2)
279 MPC10X_PCI_OP(write, word, u16, out_le16, 2)
280 MPC10X_PCI_OP(write, dword, u32, out_le32, 0)
281 #endif
282
283 /*
284 * Read the memory controller registers to determine the amount of memory in
285 * the system. This assumes that the firmware has correctly set up the memory
286 * controller registers.
287 */
288 unsigned long __init
mpc10x_get_mem_size(uint mem_map)289 mpc10x_get_mem_size(uint mem_map)
290 {
291 uint *config_addr, *config_data, val;
292 ulong start, end, total, offset;
293 int i;
294 u_char bank_enables;
295
296 switch (mem_map) {
297 case MPC10X_MEM_MAP_A:
298 config_addr = (uint *)MPC10X_MAPA_CNFG_ADDR;
299 config_data = (uint *)MPC10X_MAPA_CNFG_DATA;
300 break;
301 case MPC10X_MEM_MAP_B:
302 config_addr = (uint *)MPC10X_MAPB_CNFG_ADDR;
303 config_data = (uint *)MPC10X_MAPB_CNFG_DATA;
304 break;
305 default:
306 return 0;
307 }
308
309 mpc10x_read_config_byte(config_addr,
310 config_data,
311 PCI_DEVFN(0,0),
312 MPC10X_MCTLR_MEM_BANK_ENABLES,
313 &bank_enables);
314
315 total = 0;
316
317 for (i=0; i<8; i++) {
318 if (bank_enables & (1 << i)) {
319 offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0);
320 mpc10x_read_config_dword(config_addr,
321 config_data,
322 PCI_DEVFN(0,0),
323 offset,
324 &val);
325 start = (val >> ((i & 3) << 3)) & 0xff;
326
327 offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0);
328 mpc10x_read_config_dword(config_addr,
329 config_data,
330 PCI_DEVFN(0,0),
331 offset,
332 &val);
333 val = (val >> ((i & 3) << 3)) & 0x03;
334 start = (val << 28) | (start << 20);
335
336 offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0);
337 mpc10x_read_config_dword(config_addr,
338 config_data,
339 PCI_DEVFN(0,0),
340 offset,
341 &val);
342 end = (val >> ((i & 3) << 3)) & 0xff;
343
344 offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0);
345 mpc10x_read_config_dword(config_addr,
346 config_data,
347 PCI_DEVFN(0,0),
348 offset,
349 &val);
350 val = (val >> ((i & 3) << 3)) & 0x03;
351 end = (val << 28) | (end << 20) | 0xfffff;
352
353 total += (end - start + 1);
354 }
355 }
356
357 return total;
358 }
359
360 int __init
mpc10x_enable_store_gathering(struct pci_controller * hose)361 mpc10x_enable_store_gathering(struct pci_controller *hose)
362 {
363 uint picr1;
364
365 early_read_config_dword(hose,
366 0,
367 PCI_DEVFN(0,0),
368 MPC10X_CFG_PICR1_REG,
369 &picr1);
370
371 picr1 |= MPC10X_CFG_PICR1_ST_GATH_EN;
372
373 early_write_config_dword(hose,
374 0,
375 PCI_DEVFN(0,0),
376 MPC10X_CFG_PICR1_REG,
377 picr1);
378
379 return 0;
380 }
381
382 int __init
mpc10x_disable_store_gathering(struct pci_controller * hose)383 mpc10x_disable_store_gathering(struct pci_controller *hose)
384 {
385 uint picr1;
386
387 early_read_config_dword(hose,
388 0,
389 PCI_DEVFN(0,0),
390 MPC10X_CFG_PICR1_REG,
391 &picr1);
392
393 picr1 &= ~MPC10X_CFG_PICR1_ST_GATH_EN;
394
395 early_write_config_dword(hose,
396 0,
397 PCI_DEVFN(0,0),
398 MPC10X_CFG_PICR1_REG,
399 picr1);
400
401 return 0;
402 }
403