This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / ppc / syslib / mv64x60.c
1 /*
2  * arch/ppc/syslib/mv64x60.c
3  * 
4  * Common routines for the Marvell/Galileo Discovery line of host bridges
5  * (e.g, gt64260 and mv64360).
6  *
7  * Author: Mark A. Greer <mgreer@mvista.com>
8  *         Rabeeh Khoury <rabeeh@galileo.co.il>
9  *
10  * 2001-2002 (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
13  * or implied.
14  */
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/pci.h>
18 #include <linux/slab.h>
19 #include <linux/module.h>
20 #include <linux/string.h>
21
22 #include <asm/byteorder.h>
23 #include <asm/io.h>
24 #include <asm/irq.h>
25 #include <asm/uaccess.h>
26 #include <asm/machdep.h>
27 #include <asm/pci-bridge.h>
28 #include <asm/mv64x60.h>
29 #include <asm/delay.h>
30 #include <asm/ocp.h>
31
32
33 #undef  DEBUG
34
35 #ifdef  DEBUG
36 #define DBG(x...) printk(x)
37 #else
38 #define DBG(x...)
39 #endif  /* DEBUG */
40
41
42 static u32 mv64x60_mask(u32 val, u32 num_bits);
43 static u32 mv64x60_shift_left(u32 val, u32 num_bits);
44 static u32 mv64x60_shift_right(u32 val, u32 num_bits);
45 static void mv64x60_early_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si);
46 static int mv64x60_get_type(mv64x60_handle_t *bh);
47 static int mv64x60_setup_for_chip(mv64x60_handle_t *bh);
48 static void mv64x60_get_mem_windows(mv64x60_handle_t *bh,
49         u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
50 static u32 mv64x60_calc_mem_size(mv64x60_handle_t *bh,
51         u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
52 static void mv64x60_config_cpu2mem_windows(mv64x60_handle_t *bh,
53         mv64x60_setup_info_t *si, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
54 static void mv64x60_config_cpu2pci_windows(mv64x60_handle_t *bh,
55         mv64x60_setup_info_t *si);
56 static void mv64x60_set_cpu2pci_window(mv64x60_handle_t *bh,
57         mv64x60_pci_info_t *pi, u32 *win_tab, u32 *remap_tab);
58 static void mv64x60_config_pci2mem_windows(mv64x60_handle_t *bh,
59         mv64x60_setup_info_t *si, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
60 static void mv64x60_alloc_hoses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si);
61 static void mv64x60_init_hoses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si);
62 static void mv64x60_init_resources(struct pci_controller *hose,
63         mv64x60_pci_info_t *pi, u32 io_base);
64 static void mv64x60_set_pci_params(struct pci_controller *hose,
65         mv64x60_pci_info_t *pi);
66 static void mv64x60_enumerate_buses(mv64x60_handle_t *bh,
67         mv64x60_setup_info_t *si);
68 static int mv64x60_pci_exclude_device(u8 bus, u8 devfn);
69 static void mv64x60_fixup_ocp(struct ocp_device *, void *arg);
70
71 static u32 gt64260_translate_size(u32 base, u32 size, u32 num_bits);
72 static u32 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits);
73 static void gt64260_set_pci2mem_window(struct pci_controller *hose,
74         u32 window, u32 base);
75 static u32 gt64260_is_enabled_32bit(mv64x60_handle_t *bh, u32 window);
76 static void gt64260_enable_window_32bit(mv64x60_handle_t *bh, u32 window);
77 static void gt64260_disable_window_32bit(mv64x60_handle_t *bh, u32 window);
78 static void gt64260_enable_window_64bit(mv64x60_handle_t *bh, u32 window);
79 static void gt64260_disable_window_64bit(mv64x60_handle_t *bh, u32 window);
80 static void gt64260_disable_all_windows(mv64x60_handle_t *bh,
81                                         mv64x60_setup_info_t *si);
82 static void gt64260a_chip_specific_init(mv64x60_handle_t *bh,
83         mv64x60_setup_info_t *si);
84 static void gt64260b_chip_specific_init(mv64x60_handle_t *bh,
85         mv64x60_setup_info_t *si);
86
87 static u32 mv64360_translate_size(u32 base_addr, u32 size, u32 num_bits);
88 static u32 mv64360_untranslate_size(u32 base_addr, u32 size, u32 num_bits);
89 static void mv64360_set_pci2mem_window(struct pci_controller *hose,
90         u32 window, u32 base);
91 static u32 mv64360_is_enabled_32bit(mv64x60_handle_t *bh, u32 window);
92 static void mv64360_enable_window_32bit(mv64x60_handle_t *bh, u32 window);
93 static void mv64360_disable_window_32bit(mv64x60_handle_t *bh, u32 window);
94 static void mv64360_enable_window_64bit(mv64x60_handle_t *bh, u32 window);
95 static void mv64360_disable_window_64bit(mv64x60_handle_t *bh, u32 window);
96 static void mv64360_disable_all_windows(mv64x60_handle_t *bh,
97                                         mv64x60_setup_info_t *si);
98 static void mv64360_chip_specific_init(mv64x60_handle_t *bh,
99         mv64x60_setup_info_t *si);
100 static void mv64460_chip_specific_init(mv64x60_handle_t *bh,
101         mv64x60_setup_info_t *si);
102
103
104 u8      mv64x60_pci_exclude_bridge = TRUE;
105
106 spinlock_t mv64x60_lock = SPIN_LOCK_UNLOCKED;
107 spinlock_t mv64x60_rmw_lock = SPIN_LOCK_UNLOCKED;
108
109 static mv64x60_32bit_window_t gt64260_32bit_windows[] __initdata = {
110         /* CPU->MEM Windows */
111         [MV64x60_CPU2MEM_0_WIN] = {
112                 .base_reg               = MV64x60_CPU2MEM_0_BASE,
113                 .size_reg               = MV64x60_CPU2MEM_0_SIZE,
114                 .base_bits              = 12,
115                 .size_bits              = 12,
116                 .get_from_field         = mv64x60_shift_left,
117                 .map_to_field           = mv64x60_shift_right,
118                 .extra                  = 0 },
119         [MV64x60_CPU2MEM_1_WIN] = {
120                 .base_reg               = MV64x60_CPU2MEM_1_BASE,
121                 .size_reg               = MV64x60_CPU2MEM_1_SIZE,
122                 .base_bits              = 12,
123                 .size_bits              = 12,
124                 .get_from_field         = mv64x60_shift_left,
125                 .map_to_field           = mv64x60_shift_right,
126                 .extra                  = 0 },
127         [MV64x60_CPU2MEM_2_WIN] = {
128                 .base_reg               = MV64x60_CPU2MEM_2_BASE,
129                 .size_reg               = MV64x60_CPU2MEM_2_SIZE,
130                 .base_bits              = 12,
131                 .size_bits              = 12,
132                 .get_from_field         = mv64x60_shift_left,
133                 .map_to_field           = mv64x60_shift_right,
134                 .extra                  = 0 },
135         [MV64x60_CPU2MEM_3_WIN] = {
136                 .base_reg               = MV64x60_CPU2MEM_3_BASE,
137                 .size_reg               = MV64x60_CPU2MEM_3_SIZE,
138                 .base_bits              = 12,
139                 .size_bits              = 12,
140                 .get_from_field         = mv64x60_shift_left,
141                 .map_to_field           = mv64x60_shift_right,
142                 .extra                  = 0 },
143         /* CPU->Device Windows */
144         [MV64x60_CPU2DEV_0_WIN] = {
145                 .base_reg               = MV64x60_CPU2DEV_0_BASE,
146                 .size_reg               = MV64x60_CPU2DEV_0_SIZE,
147                 .base_bits              = 12,
148                 .size_bits              = 12,
149                 .get_from_field         = mv64x60_shift_left,
150                 .map_to_field           = mv64x60_shift_right,
151                 .extra                  = 0 },
152         [MV64x60_CPU2DEV_1_WIN] = {
153                 .base_reg               = MV64x60_CPU2DEV_1_BASE,
154                 .size_reg               = MV64x60_CPU2DEV_1_SIZE,
155                 .base_bits              = 12,
156                 .size_bits              = 12,
157                 .get_from_field         = mv64x60_shift_left,
158                 .map_to_field           = mv64x60_shift_right,
159                 .extra                  = 0 },
160         [MV64x60_CPU2DEV_2_WIN] = {
161                 .base_reg               = MV64x60_CPU2DEV_2_BASE,
162                 .size_reg               = MV64x60_CPU2DEV_2_SIZE,
163                 .base_bits              = 12,
164                 .size_bits              = 12,
165                 .get_from_field         = mv64x60_shift_left,
166                 .map_to_field           = mv64x60_shift_right,
167                 .extra                  = 0 },
168         [MV64x60_CPU2DEV_3_WIN] = {
169                 .base_reg               = MV64x60_CPU2DEV_3_BASE,
170                 .size_reg               = MV64x60_CPU2DEV_3_SIZE,
171                 .base_bits              = 12,
172                 .size_bits              = 12,
173                 .get_from_field         = mv64x60_shift_left,
174                 .map_to_field           = mv64x60_shift_right,
175                 .extra                  = 0 },
176         /* CPU->Boot Window */
177         [MV64x60_CPU2BOOT_WIN] = {
178                 .base_reg               = MV64x60_CPU2BOOT_0_BASE,
179                 .size_reg               = MV64x60_CPU2BOOT_0_SIZE,
180                 .base_bits              = 12,
181                 .size_bits              = 12,
182                 .get_from_field         = mv64x60_shift_left,
183                 .map_to_field           = mv64x60_shift_right,
184                 .extra                  = 0 },
185         /* CPU->PCI 0 Windows */
186         [MV64x60_CPU2PCI0_IO_WIN] = {
187                 .base_reg               = MV64x60_CPU2PCI0_IO_BASE,
188                 .size_reg               = MV64x60_CPU2PCI0_IO_SIZE,
189                 .base_bits              = 12,
190                 .size_bits              = 12,
191                 .get_from_field         = mv64x60_shift_left,
192                 .map_to_field           = mv64x60_shift_right,
193                 .extra                  = 0 },
194         [MV64x60_CPU2PCI0_MEM_0_WIN] = {
195                 .base_reg               = MV64x60_CPU2PCI0_MEM_0_BASE,
196                 .size_reg               = MV64x60_CPU2PCI0_MEM_0_SIZE,
197                 .base_bits              = 12,
198                 .size_bits              = 12,
199                 .get_from_field         = mv64x60_shift_left,
200                 .map_to_field           = mv64x60_shift_right,
201                 .extra                  = 0 },
202         [MV64x60_CPU2PCI0_MEM_1_WIN] = {
203                 .base_reg               = MV64x60_CPU2PCI0_MEM_1_BASE,
204                 .size_reg               = MV64x60_CPU2PCI0_MEM_1_SIZE,
205                 .base_bits              = 12,
206                 .size_bits              = 12,
207                 .get_from_field         = mv64x60_shift_left,
208                 .map_to_field           = mv64x60_shift_right,
209                 .extra                  = 0 },
210         [MV64x60_CPU2PCI0_MEM_2_WIN] = {
211                 .base_reg               = MV64x60_CPU2PCI0_MEM_2_BASE,
212                 .size_reg               = MV64x60_CPU2PCI0_MEM_2_SIZE,
213                 .base_bits              = 12,
214                 .size_bits              = 12,
215                 .get_from_field         = mv64x60_shift_left,
216                 .map_to_field           = mv64x60_shift_right,
217                 .extra                  = 0 },
218         [MV64x60_CPU2PCI0_MEM_3_WIN] = {
219                 .base_reg               = MV64x60_CPU2PCI0_MEM_3_BASE,
220                 .size_reg               = MV64x60_CPU2PCI0_MEM_3_SIZE,
221                 .base_bits              = 12,
222                 .size_bits              = 12,
223                 .get_from_field         = mv64x60_shift_left,
224                 .map_to_field           = mv64x60_shift_right,
225                 .extra                  = 0 },
226         /* CPU->PCI 1 Windows */
227         [MV64x60_CPU2PCI1_IO_WIN] = {
228                 .base_reg               = MV64x60_CPU2PCI1_IO_BASE,
229                 .size_reg               = MV64x60_CPU2PCI1_IO_SIZE,
230                 .base_bits              = 12,
231                 .size_bits              = 12,
232                 .get_from_field         = mv64x60_shift_left,
233                 .map_to_field           = mv64x60_shift_right,
234                 .extra                  = 0 },
235         [MV64x60_CPU2PCI1_MEM_0_WIN] = {
236                 .base_reg               = MV64x60_CPU2PCI1_MEM_0_BASE,
237                 .size_reg               = MV64x60_CPU2PCI1_MEM_0_SIZE,
238                 .base_bits              = 12,
239                 .size_bits              = 12,
240                 .get_from_field         = mv64x60_shift_left,
241                 .map_to_field           = mv64x60_shift_right,
242                 .extra                  = 0 },
243         [MV64x60_CPU2PCI1_MEM_1_WIN] = {
244                 .base_reg               = MV64x60_CPU2PCI1_MEM_1_BASE,
245                 .size_reg               = MV64x60_CPU2PCI1_MEM_1_SIZE,
246                 .base_bits              = 12,
247                 .size_bits              = 12,
248                 .get_from_field         = mv64x60_shift_left,
249                 .map_to_field           = mv64x60_shift_right,
250                 .extra                  = 0 },
251         [MV64x60_CPU2PCI1_MEM_2_WIN] = {
252                 .base_reg               = MV64x60_CPU2PCI1_MEM_2_BASE,
253                 .size_reg               = MV64x60_CPU2PCI1_MEM_2_SIZE,
254                 .base_bits              = 12,
255                 .size_bits              = 12,
256                 .get_from_field         = mv64x60_shift_left,
257                 .map_to_field           = mv64x60_shift_right,
258                 .extra                  = 0 },
259         [MV64x60_CPU2PCI1_MEM_3_WIN] = {
260                 .base_reg               = MV64x60_CPU2PCI1_MEM_3_BASE,
261                 .size_reg               = MV64x60_CPU2PCI1_MEM_3_SIZE,
262                 .base_bits              = 12,
263                 .size_bits              = 12,
264                 .get_from_field         = mv64x60_shift_left,
265                 .map_to_field           = mv64x60_shift_right,
266                 .extra                  = 0 },
267         /* CPU->SRAM Window (64260 has no integrated SRAM) */
268         /* CPU->PCI 0 Remap I/O Window */
269         [MV64x60_CPU2PCI0_IO_REMAP_WIN] = {
270                 .base_reg               = MV64x60_CPU2PCI0_IO_REMAP,
271                 .size_reg               = 0,
272                 .base_bits              = 12,
273                 .size_bits              = 0,
274                 .get_from_field         = mv64x60_shift_left,
275                 .map_to_field           = mv64x60_shift_right,
276                 .extra                  = 0 },
277         /* CPU->PCI 1 Remap I/O Window */
278         [MV64x60_CPU2PCI1_IO_REMAP_WIN] = {
279                 .base_reg               = MV64x60_CPU2PCI1_IO_REMAP,
280                 .size_reg               = 0,
281                 .base_bits              = 12,
282                 .size_bits              = 0,
283                 .get_from_field         = mv64x60_shift_left,
284                 .map_to_field           = mv64x60_shift_right,
285                 .extra                  = 0 },
286         /* CPU Memory Protection Windows */
287         [MV64x60_CPU_PROT_0_WIN] = {
288                 .base_reg               = MV64x60_CPU_PROT_BASE_0,
289                 .size_reg               = MV64x60_CPU_PROT_SIZE_0,
290                 .base_bits              = 12,
291                 .size_bits              = 12,
292                 .get_from_field         = mv64x60_shift_left,
293                 .map_to_field           = mv64x60_shift_right,
294                 .extra                  = 0 },
295         [MV64x60_CPU_PROT_1_WIN] = {
296                 .base_reg               = MV64x60_CPU_PROT_BASE_1,
297                 .size_reg               = MV64x60_CPU_PROT_SIZE_1,
298                 .base_bits              = 12,
299                 .size_bits              = 12,
300                 .get_from_field         = mv64x60_shift_left,
301                 .map_to_field           = mv64x60_shift_right,
302                 .extra                  = 0 },
303         [MV64x60_CPU_PROT_2_WIN] = {
304                 .base_reg               = MV64x60_CPU_PROT_BASE_2,
305                 .size_reg               = MV64x60_CPU_PROT_SIZE_2,
306                 .base_bits              = 12,
307                 .size_bits              = 12,
308                 .get_from_field         = mv64x60_shift_left,
309                 .map_to_field           = mv64x60_shift_right,
310                 .extra                  = 0 },
311         [MV64x60_CPU_PROT_3_WIN] = {
312                 .base_reg               = MV64x60_CPU_PROT_BASE_3,
313                 .size_reg               = MV64x60_CPU_PROT_SIZE_3,
314                 .base_bits              = 12,
315                 .size_bits              = 12,
316                 .get_from_field         = mv64x60_shift_left,
317                 .map_to_field           = mv64x60_shift_right,
318                 .extra                  = 0 },
319         /* CPU Snoop Windows */
320         [MV64x60_CPU_SNOOP_0_WIN] = {
321                 .base_reg               = GT64260_CPU_SNOOP_BASE_0,
322                 .size_reg               = GT64260_CPU_SNOOP_SIZE_0,
323                 .base_bits              = 12,
324                 .size_bits              = 12,
325                 .get_from_field         = mv64x60_shift_left,
326                 .map_to_field           = mv64x60_shift_right,
327                 .extra                  = 0 },
328         [MV64x60_CPU_SNOOP_1_WIN] = {
329                 .base_reg               = GT64260_CPU_SNOOP_BASE_1,
330                 .size_reg               = GT64260_CPU_SNOOP_SIZE_1,
331                 .base_bits              = 12,
332                 .size_bits              = 12,
333                 .get_from_field         = mv64x60_shift_left,
334                 .map_to_field           = mv64x60_shift_right,
335                 .extra                  = 0 },
336         [MV64x60_CPU_SNOOP_2_WIN] = {
337                 .base_reg               = GT64260_CPU_SNOOP_BASE_2,
338                 .size_reg               = GT64260_CPU_SNOOP_SIZE_2,
339                 .base_bits              = 12,
340                 .size_bits              = 12,
341                 .get_from_field         = mv64x60_shift_left,
342                 .map_to_field           = mv64x60_shift_right,
343                 .extra                  = 0 },
344         [MV64x60_CPU_SNOOP_3_WIN] = {
345                 .base_reg               = GT64260_CPU_SNOOP_BASE_3,
346                 .size_reg               = GT64260_CPU_SNOOP_SIZE_3,
347                 .base_bits              = 12,
348                 .size_bits              = 12,
349                 .get_from_field         = mv64x60_shift_left,
350                 .map_to_field           = mv64x60_shift_right,
351                 .extra                  = 0 },
352         /* PCI 0->System Memory Remap Windows */
353         [MV64x60_PCI02MEM_REMAP_0_WIN] = {
354                 .base_reg               = MV64x60_PCI0_SLAVE_MEM_0_REMAP,
355                 .size_reg               = 0,
356                 .base_bits              = 20,
357                 .size_bits              = 0,
358                 .get_from_field         = mv64x60_mask,
359                 .map_to_field           = mv64x60_mask,
360                 .extra                  = 0 },
361         [MV64x60_PCI02MEM_REMAP_1_WIN] = {
362                 .base_reg               = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
363                 .size_reg               = 0,
364                 .base_bits              = 20,
365                 .size_bits              = 0,
366                 .get_from_field         = mv64x60_mask,
367                 .map_to_field           = mv64x60_mask,
368                 .extra                  = 0 },
369         [MV64x60_PCI02MEM_REMAP_2_WIN] = {
370                 .base_reg               = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
371                 .size_reg               = 0,
372                 .base_bits              = 20,
373                 .size_bits              = 0,
374                 .get_from_field         = mv64x60_mask,
375                 .map_to_field           = mv64x60_mask,
376                 .extra                  = 0 },
377         [MV64x60_PCI02MEM_REMAP_3_WIN] = {
378                 .base_reg               = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
379                 .size_reg               = 0,
380                 .base_bits              = 20,
381                 .size_bits              = 0,
382                 .get_from_field         = mv64x60_mask,
383                 .map_to_field           = mv64x60_mask,
384                 .extra                  = 0 },
385         /* PCI 1->System Memory Remap Windows */
386         [MV64x60_PCI12MEM_REMAP_0_WIN] = {
387                 .base_reg               = MV64x60_PCI1_SLAVE_MEM_0_REMAP,
388                 .size_reg               = 0,
389                 .base_bits              = 20,
390                 .size_bits              = 0,
391                 .get_from_field         = mv64x60_mask,
392                 .map_to_field           = mv64x60_mask,
393                 .extra                  = 0 },
394         [MV64x60_PCI12MEM_REMAP_1_WIN] = {
395                 .base_reg               = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
396                 .size_reg               = 0,
397                 .base_bits              = 20,
398                 .size_bits              = 0,
399                 .get_from_field         = mv64x60_mask,
400                 .map_to_field           = mv64x60_mask,
401                 .extra                  = 0 },
402         [MV64x60_PCI12MEM_REMAP_2_WIN] = {
403                 .base_reg               = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
404                 .size_reg               = 0,
405                 .base_bits              = 20,
406                 .size_bits              = 0,
407                 .get_from_field         = mv64x60_mask,
408                 .map_to_field           = mv64x60_mask,
409                 .extra                  = 0 },
410         [MV64x60_PCI12MEM_REMAP_3_WIN] = {
411                 .base_reg               = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
412                 .size_reg               = 0,
413                 .base_bits              = 20,
414                 .size_bits              = 0,
415                 .get_from_field         = mv64x60_mask,
416                 .map_to_field           = mv64x60_mask,
417                 .extra                  = 0 },
418 };
419
420 static mv64x60_64bit_window_t gt64260_64bit_windows[] __initdata = {
421         /* CPU->PCI 0 MEM Remap Windows */
422         [MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = {
423                 .base_hi_reg            = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
424                 .base_lo_reg            = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
425                 .size_reg               = 0,
426                 .base_lo_bits           = 12,
427                 .size_bits              = 0,
428                 .get_from_field         = mv64x60_shift_left,
429                 .map_to_field           = mv64x60_shift_right,
430                 .extra                  = 0 },
431         [MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = {
432                 .base_hi_reg            = MV64x60_CPU2PCI0_MEM_1_REMAP_HI,
433                 .base_lo_reg            = MV64x60_CPU2PCI0_MEM_1_REMAP_LO,
434                 .size_reg               = 0,
435                 .base_lo_bits           = 12,
436                 .size_bits              = 0,
437                 .get_from_field         = mv64x60_shift_left,
438                 .map_to_field           = mv64x60_shift_right,
439                 .extra                  = 0 },
440         [MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = {
441                 .base_hi_reg            = MV64x60_CPU2PCI0_MEM_2_REMAP_HI,
442                 .base_lo_reg            = MV64x60_CPU2PCI0_MEM_2_REMAP_LO,
443                 .size_reg               = 0,
444                 .base_lo_bits           = 12,
445                 .size_bits              = 0,
446                 .get_from_field         = mv64x60_shift_left,
447                 .map_to_field           = mv64x60_shift_right,
448                 .extra                  = 0 },
449         [MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = {
450                 .base_hi_reg            = MV64x60_CPU2PCI0_MEM_3_REMAP_HI,
451                 .base_lo_reg            = MV64x60_CPU2PCI0_MEM_3_REMAP_LO,
452                 .size_reg               = 0,
453                 .base_lo_bits           = 12,
454                 .size_bits              = 0,
455                 .get_from_field         = mv64x60_shift_left,
456                 .map_to_field           = mv64x60_shift_right,
457                 .extra                  = 0 },
458         /* CPU->PCI 1 MEM Remap Windows */
459         [MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = {
460                 .base_hi_reg            = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
461                 .base_lo_reg            = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
462                 .size_reg               = 0,
463                 .base_lo_bits           = 12,
464                 .size_bits              = 0,
465                 .get_from_field         = mv64x60_shift_left,
466                 .map_to_field           = mv64x60_shift_right,
467                 .extra                  = 0 },
468         [MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = {
469                 .base_hi_reg            = MV64x60_CPU2PCI1_MEM_1_REMAP_HI,
470                 .base_lo_reg            = MV64x60_CPU2PCI1_MEM_1_REMAP_LO,
471                 .size_reg               = 0,
472                 .base_lo_bits           = 12,
473                 .size_bits              = 0,
474                 .get_from_field         = mv64x60_shift_left,
475                 .map_to_field           = mv64x60_shift_right,
476                 .extra                  = 0 },
477         [MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = {
478                 .base_hi_reg            = MV64x60_CPU2PCI1_MEM_2_REMAP_HI,
479                 .base_lo_reg            = MV64x60_CPU2PCI1_MEM_2_REMAP_LO,
480                 .size_reg               = 0,
481                 .base_lo_bits           = 12,
482                 .size_bits              = 0,
483                 .get_from_field         = mv64x60_shift_left,
484                 .map_to_field           = mv64x60_shift_right,
485                 .extra                  = 0 },
486         [MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = {
487                 .base_hi_reg            = MV64x60_CPU2PCI1_MEM_3_REMAP_HI,
488                 .base_lo_reg            = MV64x60_CPU2PCI1_MEM_3_REMAP_LO,
489                 .size_reg               = 0,
490                 .base_lo_bits           = 12,
491                 .size_bits              = 0,
492                 .get_from_field         = mv64x60_shift_left,
493                 .map_to_field           = mv64x60_shift_right,
494                 .extra                  = 0 },
495         /* PCI 0->MEM Access Control Windows */
496         [MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = {
497                 .base_hi_reg            = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
498                 .base_lo_reg            = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
499                 .size_reg               = MV64x60_PCI0_ACC_CNTL_0_SIZE,
500                 .base_lo_bits           = 12,
501                 .size_bits              = 12,
502                 .get_from_field         = mv64x60_shift_left,
503                 .map_to_field           = mv64x60_shift_right,
504                 .extra                  = 0 },
505         [MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = {
506                 .base_hi_reg            = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
507                 .base_lo_reg            = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
508                 .size_reg               = MV64x60_PCI0_ACC_CNTL_1_SIZE,
509                 .base_lo_bits           = 12,
510                 .size_bits              = 12,
511                 .get_from_field         = mv64x60_shift_left,
512                 .map_to_field           = mv64x60_shift_right,
513                 .extra                  = 0 },
514         [MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = {
515                 .base_hi_reg            = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
516                 .base_lo_reg            = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
517                 .size_reg               = MV64x60_PCI0_ACC_CNTL_2_SIZE,
518                 .base_lo_bits           = 12,
519                 .size_bits              = 12,
520                 .get_from_field         = mv64x60_shift_left,
521                 .map_to_field           = mv64x60_shift_right,
522                 .extra                  = 0 },
523         [MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = {
524                 .base_hi_reg            = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
525                 .base_lo_reg            = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
526                 .size_reg               = MV64x60_PCI0_ACC_CNTL_3_SIZE,
527                 .base_lo_bits           = 12,
528                 .size_bits              = 12,
529                 .get_from_field         = mv64x60_shift_left,
530                 .map_to_field           = mv64x60_shift_right,
531                 .extra                  = 0 },
532         /* PCI 1->MEM Access Control Windows */
533         [MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = {
534                 .base_hi_reg            = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
535                 .base_lo_reg            = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
536                 .size_reg               = MV64x60_PCI1_ACC_CNTL_0_SIZE,
537                 .base_lo_bits           = 12,
538                 .size_bits              = 12,
539                 .get_from_field         = mv64x60_shift_left,
540                 .map_to_field           = mv64x60_shift_right,
541                 .extra                  = 0 },
542         [MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = {
543                 .base_hi_reg            = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
544                 .base_lo_reg            = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
545                 .size_reg               = MV64x60_PCI1_ACC_CNTL_1_SIZE,
546                 .base_lo_bits           = 12,
547                 .size_bits              = 12,
548                 .get_from_field         = mv64x60_shift_left,
549                 .map_to_field           = mv64x60_shift_right,
550                 .extra                  = 0 },
551         [MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = {
552                 .base_hi_reg            = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
553                 .base_lo_reg            = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
554                 .size_reg               = MV64x60_PCI1_ACC_CNTL_2_SIZE,
555                 .base_lo_bits           = 12,
556                 .size_bits              = 12,
557                 .get_from_field         = mv64x60_shift_left,
558                 .map_to_field           = mv64x60_shift_right,
559                 .extra                  = 0 },
560         [MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = {
561                 .base_hi_reg            = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
562                 .base_lo_reg            = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
563                 .size_reg               = MV64x60_PCI1_ACC_CNTL_3_SIZE,
564                 .base_lo_bits           = 12,
565                 .size_bits              = 12,
566                 .get_from_field         = mv64x60_shift_left,
567                 .map_to_field           = mv64x60_shift_right,
568                 .extra                  = 0 },
569         /* PCI 0->MEM Snoop Windows */
570         [MV64x60_PCI02MEM_SNOOP_0_WIN] = {
571                 .base_hi_reg            = GT64260_PCI0_SNOOP_0_BASE_HI,
572                 .base_lo_reg            = GT64260_PCI0_SNOOP_0_BASE_LO,
573                 .size_reg               = GT64260_PCI0_SNOOP_0_SIZE,
574                 .base_lo_bits           = 12,
575                 .size_bits              = 12,
576                 .get_from_field         = mv64x60_shift_left,
577                 .map_to_field           = mv64x60_shift_right,
578                 .extra                  = 0 },
579         [MV64x60_PCI02MEM_SNOOP_1_WIN] = {
580                 .base_hi_reg            = GT64260_PCI0_SNOOP_1_BASE_HI,
581                 .base_lo_reg            = GT64260_PCI0_SNOOP_1_BASE_LO,
582                 .size_reg               = GT64260_PCI0_SNOOP_1_SIZE,
583                 .base_lo_bits           = 12,
584                 .size_bits              = 12,
585                 .get_from_field         = mv64x60_shift_left,
586                 .map_to_field           = mv64x60_shift_right,
587                 .extra                  = 0 },
588         [MV64x60_PCI02MEM_SNOOP_2_WIN] = {
589                 .base_hi_reg            = GT64260_PCI0_SNOOP_2_BASE_HI,
590                 .base_lo_reg            = GT64260_PCI0_SNOOP_2_BASE_LO,
591                 .size_reg               = GT64260_PCI0_SNOOP_2_SIZE,
592                 .base_lo_bits           = 12,
593                 .size_bits              = 12,
594                 .get_from_field         = mv64x60_shift_left,
595                 .map_to_field           = mv64x60_shift_right,
596                 .extra                  = 0 },
597         [MV64x60_PCI02MEM_SNOOP_3_WIN] = {
598                 .base_hi_reg            = GT64260_PCI0_SNOOP_3_BASE_HI,
599                 .base_lo_reg            = GT64260_PCI0_SNOOP_3_BASE_LO,
600                 .size_reg               = GT64260_PCI0_SNOOP_3_SIZE,
601                 .base_lo_bits           = 12,
602                 .size_bits              = 12,
603                 .get_from_field         = mv64x60_shift_left,
604                 .map_to_field           = mv64x60_shift_right,
605                 .extra                  = 0 },
606         /* PCI 1->MEM Snoop Windows */
607         [MV64x60_PCI12MEM_SNOOP_0_WIN] = {
608                 .base_hi_reg            = GT64260_PCI1_SNOOP_0_BASE_HI,
609                 .base_lo_reg            = GT64260_PCI1_SNOOP_0_BASE_LO,
610                 .size_reg               = GT64260_PCI1_SNOOP_0_SIZE,
611                 .base_lo_bits           = 12,
612                 .size_bits              = 12,
613                 .get_from_field         = mv64x60_shift_left,
614                 .map_to_field           = mv64x60_shift_right,
615                 .extra                  = 0 },
616         [MV64x60_PCI12MEM_SNOOP_1_WIN] = {
617                 .base_hi_reg            = GT64260_PCI1_SNOOP_1_BASE_HI,
618                 .base_lo_reg            = GT64260_PCI1_SNOOP_1_BASE_LO,
619                 .size_reg               = GT64260_PCI1_SNOOP_1_SIZE,
620                 .base_lo_bits           = 12,
621                 .size_bits              = 12,
622                 .get_from_field         = mv64x60_shift_left,
623                 .map_to_field           = mv64x60_shift_right,
624                 .extra                  = 0 },
625         [MV64x60_PCI12MEM_SNOOP_2_WIN] = {
626                 .base_hi_reg            = GT64260_PCI1_SNOOP_2_BASE_HI,
627                 .base_lo_reg            = GT64260_PCI1_SNOOP_2_BASE_LO,
628                 .size_reg               = GT64260_PCI1_SNOOP_2_SIZE,
629                 .base_lo_bits           = 12,
630                 .size_bits              = 12,
631                 .get_from_field         = mv64x60_shift_left,
632                 .map_to_field           = mv64x60_shift_right,
633                 .extra                  = 0 },
634         [MV64x60_PCI12MEM_SNOOP_3_WIN] = {
635                 .base_hi_reg            = GT64260_PCI1_SNOOP_3_BASE_HI,
636                 .base_lo_reg            = GT64260_PCI1_SNOOP_3_BASE_LO,
637                 .size_reg               = GT64260_PCI1_SNOOP_3_SIZE,
638                 .base_lo_bits           = 12,
639                 .size_bits              = 12,
640                 .get_from_field         = mv64x60_shift_left,
641                 .map_to_field           = mv64x60_shift_right,
642                 .extra                  = 0 },
643 };
644
645 static mv64x60_chip_info_t gt64260a_ci __initdata = {
646         .translate_size         = gt64260_translate_size,
647         .untranslate_size       = gt64260_untranslate_size,
648         .set_pci2mem_window     = gt64260_set_pci2mem_window,
649         .is_enabled_32bit       = gt64260_is_enabled_32bit,
650         .enable_window_32bit    = gt64260_enable_window_32bit,
651         .disable_window_32bit   = gt64260_disable_window_32bit,
652         .enable_window_64bit    = gt64260_enable_window_64bit,
653         .disable_window_64bit   = gt64260_disable_window_64bit,
654         .disable_all_windows    = gt64260_disable_all_windows,
655         .chip_specific_init     = gt64260a_chip_specific_init,
656         .window_tab_32bit       = gt64260_32bit_windows,
657         .window_tab_64bit       = gt64260_64bit_windows,
658 };
659
660 static mv64x60_chip_info_t gt64260b_ci __initdata = {
661         .translate_size         = gt64260_translate_size,
662         .untranslate_size       = gt64260_untranslate_size,
663         .set_pci2mem_window     = gt64260_set_pci2mem_window,
664         .is_enabled_32bit       = gt64260_is_enabled_32bit,
665         .enable_window_32bit    = gt64260_enable_window_32bit,
666         .disable_window_32bit   = gt64260_disable_window_32bit,
667         .enable_window_64bit    = gt64260_enable_window_64bit,
668         .disable_window_64bit   = gt64260_disable_window_64bit,
669         .disable_all_windows    = gt64260_disable_all_windows,
670         .chip_specific_init     = gt64260b_chip_specific_init,
671         .window_tab_32bit       = gt64260_32bit_windows,
672         .window_tab_64bit       = gt64260_64bit_windows,
673 };
674
675
676 static mv64x60_32bit_window_t mv64360_32bit_windows[] __initdata = {
677         /* CPU->MEM Windows */
678         [MV64x60_CPU2MEM_0_WIN] = {
679                 .base_reg               = MV64x60_CPU2MEM_0_BASE,
680                 .size_reg               = MV64x60_CPU2MEM_0_SIZE,
681                 .base_bits              = 16,
682                 .size_bits              = 16,
683                 .get_from_field         = mv64x60_shift_left,
684                 .map_to_field           = mv64x60_shift_right,
685                 .extra                  = 0 },
686         [MV64x60_CPU2MEM_1_WIN] = {
687                 .base_reg               = MV64x60_CPU2MEM_1_BASE,
688                 .size_reg               = MV64x60_CPU2MEM_1_SIZE,
689                 .base_bits              = 16,
690                 .size_bits              = 16,
691                 .get_from_field         = mv64x60_shift_left,
692                 .map_to_field           = mv64x60_shift_right,
693                 .extra                  = 1 },
694         [MV64x60_CPU2MEM_2_WIN] = {
695                 .base_reg               = MV64x60_CPU2MEM_2_BASE,
696                 .size_reg               = MV64x60_CPU2MEM_2_SIZE,
697                 .base_bits              = 16,
698                 .size_bits              = 16,
699                 .get_from_field         = mv64x60_shift_left,
700                 .map_to_field           = mv64x60_shift_right,
701                 .extra                  = 2 },
702         [MV64x60_CPU2MEM_3_WIN] = {
703                 .base_reg               = MV64x60_CPU2MEM_3_BASE,
704                 .size_reg               = MV64x60_CPU2MEM_3_SIZE,
705                 .base_bits              = 16,
706                 .size_bits              = 16,
707                 .get_from_field         = mv64x60_shift_left,
708                 .map_to_field           = mv64x60_shift_right,
709                 .extra                  = 3 },
710         /* CPU->Device Windows */
711         [MV64x60_CPU2DEV_0_WIN] = {
712                 .base_reg               = MV64x60_CPU2DEV_0_BASE,
713                 .size_reg               = MV64x60_CPU2DEV_0_SIZE,
714                 .base_bits              = 16,
715                 .size_bits              = 16,
716                 .get_from_field         = mv64x60_shift_left,
717                 .map_to_field           = mv64x60_shift_right,
718                 .extra                  = 4 },
719         [MV64x60_CPU2DEV_1_WIN] = {
720                 .base_reg               = MV64x60_CPU2DEV_1_BASE,
721                 .size_reg               = MV64x60_CPU2DEV_1_SIZE,
722                 .base_bits              = 16,
723                 .size_bits              = 16,
724                 .get_from_field         = mv64x60_shift_left,
725                 .map_to_field           = mv64x60_shift_right,
726                 .extra                  = 5 },
727         [MV64x60_CPU2DEV_2_WIN] = {
728                 .base_reg               = MV64x60_CPU2DEV_2_BASE,
729                 .size_reg               = MV64x60_CPU2DEV_2_SIZE,
730                 .base_bits              = 16,
731                 .size_bits              = 16,
732                 .get_from_field         = mv64x60_shift_left,
733                 .map_to_field           = mv64x60_shift_right,
734                 .extra                  = 6 },
735         [MV64x60_CPU2DEV_3_WIN] = {
736                 .base_reg               = MV64x60_CPU2DEV_3_BASE,
737                 .size_reg               = MV64x60_CPU2DEV_3_SIZE,
738                 .base_bits              = 16,
739                 .size_bits              = 16,
740                 .get_from_field         = mv64x60_shift_left,
741                 .map_to_field           = mv64x60_shift_right,
742                 .extra                  = 7 },
743         /* CPU->Boot Window */
744         [MV64x60_CPU2BOOT_WIN] = {
745                 .base_reg               = MV64x60_CPU2BOOT_0_BASE,
746                 .size_reg               = MV64x60_CPU2BOOT_0_SIZE,
747                 .base_bits              = 16,
748                 .size_bits              = 16,
749                 .get_from_field         = mv64x60_shift_left,
750                 .map_to_field           = mv64x60_shift_right,
751                 .extra                  = 8 },
752         /* CPU->PCI 0 Windows */
753         [MV64x60_CPU2PCI0_IO_WIN] = {
754                 .base_reg               = MV64x60_CPU2PCI0_IO_BASE,
755                 .size_reg               = MV64x60_CPU2PCI0_IO_SIZE,
756                 .base_bits              = 16,
757                 .size_bits              = 16,
758                 .get_from_field         = mv64x60_shift_left,
759                 .map_to_field           = mv64x60_shift_right,
760                 .extra                  = 9 },
761         [MV64x60_CPU2PCI0_MEM_0_WIN] = {
762                 .base_reg               = MV64x60_CPU2PCI0_MEM_0_BASE,
763                 .size_reg               = MV64x60_CPU2PCI0_MEM_0_SIZE,
764                 .base_bits              = 16,
765                 .size_bits              = 16,
766                 .get_from_field         = mv64x60_shift_left,
767                 .map_to_field           = mv64x60_shift_right,
768                 .extra                  = 10 },
769         [MV64x60_CPU2PCI0_MEM_1_WIN] = {
770                 .base_reg               = MV64x60_CPU2PCI0_MEM_1_BASE,
771                 .size_reg               = MV64x60_CPU2PCI0_MEM_1_SIZE,
772                 .base_bits              = 16,
773                 .size_bits              = 16,
774                 .get_from_field         = mv64x60_shift_left,
775                 .map_to_field           = mv64x60_shift_right,
776                 .extra                  = 11 },
777         [MV64x60_CPU2PCI0_MEM_2_WIN] = {
778                 .base_reg               = MV64x60_CPU2PCI0_MEM_2_BASE,
779                 .size_reg               = MV64x60_CPU2PCI0_MEM_2_SIZE,
780                 .base_bits              = 16,
781                 .size_bits              = 16,
782                 .get_from_field         = mv64x60_shift_left,
783                 .map_to_field           = mv64x60_shift_right,
784                 .extra                  = 12 },
785         [MV64x60_CPU2PCI0_MEM_3_WIN] = {
786                 .base_reg               = MV64x60_CPU2PCI0_MEM_3_BASE,
787                 .size_reg               = MV64x60_CPU2PCI0_MEM_3_SIZE,
788                 .base_bits              = 16,
789                 .size_bits              = 16,
790                 .get_from_field         = mv64x60_shift_left,
791                 .map_to_field           = mv64x60_shift_right,
792                 .extra                  = 13 },
793         /* CPU->PCI 1 Windows */
794         [MV64x60_CPU2PCI1_IO_WIN] = {
795                 .base_reg               = MV64x60_CPU2PCI1_IO_BASE,
796                 .size_reg               = MV64x60_CPU2PCI1_IO_SIZE,
797                 .base_bits              = 16,
798                 .size_bits              = 16,
799                 .get_from_field         = mv64x60_shift_left,
800                 .map_to_field           = mv64x60_shift_right,
801                 .extra                  = 14 },
802         [MV64x60_CPU2PCI1_MEM_0_WIN] = {
803                 .base_reg               = MV64x60_CPU2PCI1_MEM_0_BASE,
804                 .size_reg               = MV64x60_CPU2PCI1_MEM_0_SIZE,
805                 .base_bits              = 16,
806                 .size_bits              = 16,
807                 .get_from_field         = mv64x60_shift_left,
808                 .map_to_field           = mv64x60_shift_right,
809                 .extra                  = 15 },
810         [MV64x60_CPU2PCI1_MEM_1_WIN] = {
811                 .base_reg               = MV64x60_CPU2PCI1_MEM_1_BASE,
812                 .size_reg               = MV64x60_CPU2PCI1_MEM_1_SIZE,
813                 .base_bits              = 16,
814                 .size_bits              = 16,
815                 .get_from_field         = mv64x60_shift_left,
816                 .map_to_field           = mv64x60_shift_right,
817                 .extra                  = 16 },
818         [MV64x60_CPU2PCI1_MEM_2_WIN] = {
819                 .base_reg               = MV64x60_CPU2PCI1_MEM_2_BASE,
820                 .size_reg               = MV64x60_CPU2PCI1_MEM_2_SIZE,
821                 .base_bits              = 16,
822                 .size_bits              = 16,
823                 .get_from_field         = mv64x60_shift_left,
824                 .map_to_field           = mv64x60_shift_right,
825                 .extra                  = 17 },
826         [MV64x60_CPU2PCI1_MEM_3_WIN] = {
827                 .base_reg               = MV64x60_CPU2PCI1_MEM_3_BASE,
828                 .size_reg               = MV64x60_CPU2PCI1_MEM_3_SIZE,
829                 .base_bits              = 16,
830                 .size_bits              = 16,
831                 .get_from_field         = mv64x60_shift_left,
832                 .map_to_field           = mv64x60_shift_right,
833                 .extra                  = 18 },
834         /* CPU->SRAM Window */
835         [MV64x60_CPU2SRAM_WIN] = {
836                 .base_reg               = MV64360_CPU2SRAM_BASE,
837                 .size_reg               = 0,
838                 .base_bits              = 16,
839                 .size_bits              = 0,
840                 .get_from_field         = mv64x60_shift_left,
841                 .map_to_field           = mv64x60_shift_right,
842                 .extra                  = 19 },
843         /* CPU->PCI 0 Remap I/O Window */
844         [MV64x60_CPU2PCI0_IO_REMAP_WIN] = {
845                 .base_reg               = MV64x60_CPU2PCI0_IO_REMAP,
846                 .size_reg               = 0,
847                 .base_bits              = 16,
848                 .size_bits              = 0,
849                 .get_from_field         = mv64x60_shift_left,
850                 .map_to_field           = mv64x60_shift_right,
851                 .extra                  = 0 },
852         /* CPU->PCI 1 Remap I/O Window */
853         [MV64x60_CPU2PCI1_IO_REMAP_WIN] = {
854                 .base_reg               = MV64x60_CPU2PCI1_IO_REMAP,
855                 .size_reg               = 0,
856                 .base_bits              = 16,
857                 .size_bits              = 0,
858                 .get_from_field         = mv64x60_shift_left,
859                 .map_to_field           = mv64x60_shift_right,
860                 .extra                  = 0 },
861         /* CPU Memory Protection Windows */
862         [MV64x60_CPU_PROT_0_WIN] = {
863                 .base_reg               = MV64x60_CPU_PROT_BASE_0,
864                 .size_reg               = MV64x60_CPU_PROT_SIZE_0,
865                 .base_bits              = 16,
866                 .size_bits              = 16,
867                 .get_from_field         = mv64x60_shift_left,
868                 .map_to_field           = mv64x60_shift_right,
869                 .extra                  = 0x80000000 | 31 },
870         [MV64x60_CPU_PROT_1_WIN] = {
871                 .base_reg               = MV64x60_CPU_PROT_BASE_1,
872                 .size_reg               = MV64x60_CPU_PROT_SIZE_1,
873                 .base_bits              = 16,
874                 .size_bits              = 16,
875                 .get_from_field         = mv64x60_shift_left,
876                 .map_to_field           = mv64x60_shift_right,
877                 .extra                  = 0x80000000 | 31 },
878         [MV64x60_CPU_PROT_2_WIN] = {
879                 .base_reg               = MV64x60_CPU_PROT_BASE_2,
880                 .size_reg               = MV64x60_CPU_PROT_SIZE_2,
881                 .base_bits              = 16,
882                 .size_bits              = 16,
883                 .get_from_field         = mv64x60_shift_left,
884                 .map_to_field           = mv64x60_shift_right,
885                 .extra                  = 0x80000000 | 31 },
886         [MV64x60_CPU_PROT_3_WIN] = {
887                 .base_reg               = MV64x60_CPU_PROT_BASE_3,
888                 .size_reg               = MV64x60_CPU_PROT_SIZE_3,
889                 .base_bits              = 16,
890                 .size_bits              = 16,
891                 .get_from_field         = mv64x60_shift_left,
892                 .map_to_field           = mv64x60_shift_right,
893                 .extra                  = 0x80000000 | 31 },
894         /* CPU Snoop Windows -- don't exist on 64360 */
895         /* PCI 0->System Memory Remap Windows */
896         [MV64x60_PCI02MEM_REMAP_0_WIN] = {
897                 .base_reg               = MV64x60_PCI0_SLAVE_MEM_0_REMAP,
898                 .size_reg               = 0,
899                 .base_bits              = 16,
900                 .size_bits              = 0,
901                 .get_from_field         = mv64x60_mask,
902                 .map_to_field           = mv64x60_mask,
903                 .extra                  = 0 },
904         [MV64x60_PCI02MEM_REMAP_1_WIN] = {
905                 .base_reg               = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
906                 .size_reg               = 0,
907                 .base_bits              = 16,
908                 .size_bits              = 0,
909                 .get_from_field         = mv64x60_mask,
910                 .map_to_field           = mv64x60_mask,
911                 .extra                  = 0 },
912         [MV64x60_PCI02MEM_REMAP_2_WIN] = {
913                 .base_reg               = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
914                 .size_reg               = 0,
915                 .base_bits              = 16,
916                 .size_bits              = 0,
917                 .get_from_field         = mv64x60_mask,
918                 .map_to_field           = mv64x60_mask,
919                 .extra                  = 0 },
920         [MV64x60_PCI02MEM_REMAP_3_WIN] = {
921                 .base_reg               = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
922                 .size_reg               = 0,
923                 .base_bits              = 16,
924                 .size_bits              = 0,
925                 .get_from_field         = mv64x60_mask,
926                 .map_to_field           = mv64x60_mask,
927                 .extra                  = 0 },
928         /* PCI 1->System Memory Remap Windows */
929         [MV64x60_PCI12MEM_REMAP_0_WIN] = {
930                 .base_reg               = MV64x60_PCI1_SLAVE_MEM_0_REMAP,
931                 .size_reg               = 0,
932                 .base_bits              = 16,
933                 .size_bits              = 0,
934                 .get_from_field         = mv64x60_mask,
935                 .map_to_field           = mv64x60_mask,
936                 .extra                  = 0 },
937         [MV64x60_PCI12MEM_REMAP_1_WIN] = {
938                 .base_reg               = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
939                 .size_reg               = 0,
940                 .base_bits              = 16,
941                 .size_bits              = 0,
942                 .get_from_field         = mv64x60_mask,
943                 .map_to_field           = mv64x60_mask,
944                 .extra                  = 0 },
945         [MV64x60_PCI12MEM_REMAP_2_WIN] = {
946                 .base_reg               = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
947                 .size_reg               = 0,
948                 .base_bits              = 16,
949                 .size_bits              = 0,
950                 .get_from_field         = mv64x60_mask,
951                 .map_to_field           = mv64x60_mask,
952                 .extra                  = 0 },
953         [MV64x60_PCI12MEM_REMAP_3_WIN] = {
954                 .base_reg               = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
955                 .size_reg               = 0,
956                 .base_bits              = 16,
957                 .size_bits              = 0,
958                 .get_from_field         = mv64x60_mask,
959                 .map_to_field           = mv64x60_mask,
960                 .extra                  = 0 },
961 };
962
963 static mv64x60_64bit_window_t mv64360_64bit_windows[MV64x60_64BIT_WIN_COUNT]
964                                                                 __initdata = {
965         /* CPU->PCI 0 MEM Remap Windows */
966         [MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = {
967                 .base_hi_reg            = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
968                 .base_lo_reg            = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
969                 .size_reg               = 0,
970                 .base_lo_bits           = 16,
971                 .size_bits              = 0,
972                 .get_from_field         = mv64x60_shift_left,
973                 .map_to_field           = mv64x60_shift_right,
974                 .extra                  = 0 },
975         [MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = {
976                 .base_hi_reg            = MV64x60_CPU2PCI0_MEM_1_REMAP_HI,
977                 .base_lo_reg            = MV64x60_CPU2PCI0_MEM_1_REMAP_LO,
978                 .size_reg               = 0,
979                 .base_lo_bits           = 16,
980                 .size_bits              = 0,
981                 .get_from_field         = mv64x60_shift_left,
982                 .map_to_field           = mv64x60_shift_right,
983                 .extra                  = 0 },
984         [MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = {
985                 .base_hi_reg            = MV64x60_CPU2PCI0_MEM_2_REMAP_HI,
986                 .base_lo_reg            = MV64x60_CPU2PCI0_MEM_2_REMAP_LO,
987                 .size_reg               = 0,
988                 .base_lo_bits           = 16,
989                 .size_bits              = 0,
990                 .get_from_field         = mv64x60_shift_left,
991                 .map_to_field           = mv64x60_shift_right,
992                 .extra                  = 0 },
993         [MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = {
994                 .base_hi_reg            = MV64x60_CPU2PCI0_MEM_3_REMAP_HI,
995                 .base_lo_reg            = MV64x60_CPU2PCI0_MEM_3_REMAP_LO,
996                 .size_reg               = 0,
997                 .base_lo_bits           = 16,
998                 .size_bits              = 0,
999                 .get_from_field         = mv64x60_shift_left,
1000                 .map_to_field           = mv64x60_shift_right,
1001                 .extra                  = 0 },
1002         /* CPU->PCI 1 MEM Remap Windows */
1003         [MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = {
1004                 .base_hi_reg            = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
1005                 .base_lo_reg            = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
1006                 .size_reg               = 0,
1007                 .base_lo_bits           = 16,
1008                 .size_bits              = 0,
1009                 .get_from_field         = mv64x60_shift_left,
1010                 .map_to_field           = mv64x60_shift_right,
1011                 .extra                  = 0 },
1012         [MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = {
1013                 .base_hi_reg            = MV64x60_CPU2PCI1_MEM_1_REMAP_HI,
1014                 .base_lo_reg            = MV64x60_CPU2PCI1_MEM_1_REMAP_LO,
1015                 .size_reg               = 0,
1016                 .base_lo_bits           = 16,
1017                 .size_bits              = 0,
1018                 .get_from_field         = mv64x60_shift_left,
1019                 .map_to_field           = mv64x60_shift_right,
1020                 .extra                  = 0 },
1021         [MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = {
1022                 .base_hi_reg            = MV64x60_CPU2PCI1_MEM_2_REMAP_HI,
1023                 .base_lo_reg            = MV64x60_CPU2PCI1_MEM_2_REMAP_LO,
1024                 .size_reg               = 0,
1025                 .base_lo_bits           = 16,
1026                 .size_bits              = 0,
1027                 .get_from_field         = mv64x60_shift_left,
1028                 .map_to_field           = mv64x60_shift_right,
1029                 .extra                  = 0 },
1030         [MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = {
1031                 .base_hi_reg            = MV64x60_CPU2PCI1_MEM_3_REMAP_HI,
1032                 .base_lo_reg            = MV64x60_CPU2PCI1_MEM_3_REMAP_LO,
1033                 .size_reg               = 0,
1034                 .base_lo_bits           = 16,
1035                 .size_bits              = 0,
1036                 .get_from_field         = mv64x60_shift_left,
1037                 .map_to_field           = mv64x60_shift_right,
1038                 .extra                  = 0 },
1039         /* PCI 0->MEM Access Control Windows */
1040         [MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = {
1041                 .base_hi_reg            = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
1042                 .base_lo_reg            = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
1043                 .size_reg               = MV64x60_PCI0_ACC_CNTL_0_SIZE,
1044                 .base_lo_bits           = 20,
1045                 .size_bits              = 20,
1046                 .get_from_field         = mv64x60_mask,
1047                 .map_to_field           = mv64x60_mask,
1048                 .extra                  = 0x80000000 | 0 },
1049         [MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = {
1050                 .base_hi_reg            = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
1051                 .base_lo_reg            = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
1052                 .size_reg               = MV64x60_PCI0_ACC_CNTL_1_SIZE,
1053                 .base_lo_bits           = 20,
1054                 .size_bits              = 20,
1055                 .get_from_field         = mv64x60_mask,
1056                 .map_to_field           = mv64x60_mask,
1057                 .extra                  = 0x80000000 | 0 },
1058         [MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = {
1059                 .base_hi_reg            = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
1060                 .base_lo_reg            = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
1061                 .size_reg               = MV64x60_PCI0_ACC_CNTL_2_SIZE,
1062                 .base_lo_bits           = 20,
1063                 .size_bits              = 20,
1064                 .get_from_field         = mv64x60_mask,
1065                 .map_to_field           = mv64x60_mask,
1066                 .extra                  = 0x80000000 | 0 },
1067         [MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = {
1068                 .base_hi_reg            = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
1069                 .base_lo_reg            = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
1070                 .size_reg               = MV64x60_PCI0_ACC_CNTL_3_SIZE,
1071                 .base_lo_bits           = 20,
1072                 .size_bits              = 20,
1073                 .get_from_field         = mv64x60_mask,
1074                 .map_to_field           = mv64x60_mask,
1075                 .extra                  = 0x80000000 | 0 },
1076         /* PCI 1->MEM Access Control Windows */
1077         [MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = {
1078                 .base_hi_reg            = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
1079                 .base_lo_reg            = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
1080                 .size_reg               = MV64x60_PCI1_ACC_CNTL_0_SIZE,
1081                 .base_lo_bits           = 20,
1082                 .size_bits              = 20,
1083                 .get_from_field         = mv64x60_mask,
1084                 .map_to_field           = mv64x60_mask,
1085                 .extra                  = 0x80000000 | 0 },
1086         [MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = {
1087                 .base_hi_reg            = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
1088                 .base_lo_reg            = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
1089                 .size_reg               = MV64x60_PCI1_ACC_CNTL_1_SIZE,
1090                 .base_lo_bits           = 20,
1091                 .size_bits              = 20,
1092                 .get_from_field         = mv64x60_mask,
1093                 .map_to_field           = mv64x60_mask,
1094                 .extra                  = 0x80000000 | 0 },
1095         [MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = {
1096                 .base_hi_reg            = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
1097                 .base_lo_reg            = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
1098                 .size_reg               = MV64x60_PCI1_ACC_CNTL_2_SIZE,
1099                 .base_lo_bits           = 20,
1100                 .size_bits              = 20,
1101                 .get_from_field         = mv64x60_mask,
1102                 .map_to_field           = mv64x60_mask,
1103                 .extra                  = 0x80000000 | 0 },
1104         [MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = {
1105                 .base_hi_reg            = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
1106                 .base_lo_reg            = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
1107                 .size_reg               = MV64x60_PCI1_ACC_CNTL_3_SIZE,
1108                 .base_lo_bits           = 20,
1109                 .size_bits              = 20,
1110                 .get_from_field         = mv64x60_mask,
1111                 .map_to_field           = mv64x60_mask,
1112                 .extra                  = 0x80000000 | 0 },
1113         /* PCI 0->MEM Snoop Windows -- don't exist on 64360 */
1114         /* PCI 1->MEM Snoop Windows -- don't exist on 64360 */
1115 };
1116
1117 static mv64x60_chip_info_t mv64360_ci __initdata = {
1118         .translate_size         = mv64360_translate_size,
1119         .untranslate_size       = mv64360_untranslate_size,
1120         .set_pci2mem_window     = mv64360_set_pci2mem_window,
1121         .is_enabled_32bit       = mv64360_is_enabled_32bit,
1122         .enable_window_32bit    = mv64360_enable_window_32bit,
1123         .disable_window_32bit   = mv64360_disable_window_32bit,
1124         .enable_window_64bit    = mv64360_enable_window_64bit,
1125         .disable_window_64bit   = mv64360_disable_window_64bit,
1126         .disable_all_windows    = mv64360_disable_all_windows,
1127         .chip_specific_init     = mv64360_chip_specific_init,
1128         .window_tab_32bit       = mv64360_32bit_windows,
1129         .window_tab_64bit       = mv64360_64bit_windows,
1130 };
1131
1132 static mv64x60_chip_info_t mv64460_ci __initdata = {
1133         .translate_size         = mv64360_translate_size,
1134         .untranslate_size       = mv64360_untranslate_size,
1135         .set_pci2mem_window     = mv64360_set_pci2mem_window,
1136         .is_enabled_32bit       = mv64360_is_enabled_32bit,
1137         .enable_window_32bit    = mv64360_enable_window_32bit,
1138         .disable_window_32bit   = mv64360_disable_window_32bit,
1139         .enable_window_64bit    = mv64360_enable_window_64bit,
1140         .disable_window_64bit   = mv64360_disable_window_64bit,
1141         .disable_all_windows    = mv64360_disable_all_windows,
1142         .chip_specific_init     = mv64460_chip_specific_init,
1143         .window_tab_32bit       = mv64360_32bit_windows,
1144         .window_tab_64bit       = mv64360_64bit_windows,
1145 };
1146
1147
1148 /*
1149  *****************************************************************************
1150  *
1151  *      Bridge Initialization Routines
1152  *
1153  *****************************************************************************
1154  */
1155 /*
1156  * mv64x60_init()
1157  *
1158  * Initialze the bridge based on setting passed in via 'si'.  The bridge
1159  * handle, 'bh', will be set so that it can be used to make subsequent
1160  * calls to routines in this file.
1161  */
1162 int __init
1163 mv64x60_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
1164 {
1165         u32     mem_windows[MV64x60_CPU2MEM_WINDOWS][2];
1166         int     rc = 0;
1167
1168         if (ppc_md.progress)
1169                 ppc_md.progress("mv64x60_init: Enter", 0x0);
1170
1171         mv64x60_early_init(bh, si);
1172         mv64x60_alloc_hoses(bh, si); /* Allocate pci hose structures */
1173         if (mv64x60_get_type(bh))
1174                 return -1;
1175
1176         if (mv64x60_setup_for_chip(bh) != 0) {
1177                 iounmap((void *)bh->v_base);
1178
1179                 if (ppc_md.progress)
1180                         ppc_md.progress("mv64x60_init: Exit--error", 0x0);
1181                 return -1;
1182         }
1183
1184         bh->ci->disable_all_windows(bh, si); /* Disable windows except mem ctlr */
1185         mv64x60_config_cpu2pci_windows(bh, si); /* Init CPU->PCI windows */
1186         mv64x60_get_mem_windows(bh, mem_windows); /* Read mem ctlr regs */
1187         mv64x60_config_cpu2mem_windows(bh, si, mem_windows); /* CPU->MEM setup*/
1188         mv64x60_config_pci2mem_windows(bh, si, mem_windows); /* PCI->Sys MEM */
1189         mv64x60_init_hoses(bh, si); /* Init hose structs & PCI params */
1190         bh->ci->chip_specific_init(bh, si);
1191         mv64x60_enumerate_buses(bh, si); /* Enumerate PCI buses */
1192         ocp_for_each_device(mv64x60_fixup_ocp, (void *)bh);
1193
1194         if (ppc_md.progress)
1195                 ppc_md.progress("mv64x60_init: Exit", 0x0);
1196
1197         return rc;
1198 } /* mv64x60_init() */
1199
1200 /*
1201  *****************************************************************************
1202  *
1203  *      Pre-Bridge-Init Routines (Externally Visible)
1204  *
1205  *****************************************************************************
1206  */
1207 /*
1208  * mv64x60_get_mem_size()
1209  *
1210  * Calculate the amount of memory that the memory controller is set up for.
1211  * This should only be used by board-specific code if there is no other
1212  * way to determine the amount of memory in the system.
1213  */
1214 u32 __init
1215 mv64x60_get_mem_size(u32 bridge_base, u32 chip_type)
1216 {
1217         mv64x60_handle_t        bh;
1218         u32                     mem_windows[MV64x60_CPU2MEM_WINDOWS][2];
1219
1220         memset(&bh, 0, sizeof(bh));
1221
1222         bh.type = chip_type;
1223         bh.p_base = bridge_base;
1224         bh.v_base = bridge_base;
1225
1226         (void)mv64x60_setup_for_chip(&bh);
1227         mv64x60_get_mem_windows(&bh, mem_windows);
1228         return mv64x60_calc_mem_size(&bh, mem_windows);
1229 }
1230
1231 /*
1232  *****************************************************************************
1233  *
1234  *      Window Config Routines (Externally Visible)
1235  *
1236  *****************************************************************************
1237  */
1238 /*
1239  * mv64x60_get_32bit_window()
1240  *
1241  * Determine the base address and size of a 32-bit window on the bridge.
1242  */
1243 void __init
1244 mv64x60_get_32bit_window(mv64x60_handle_t *bh, u32 window, u32 *base, u32 *size)
1245 {
1246         u32     val, base_reg, size_reg, base_bits, size_bits;
1247         u32     (*get_from_field)(u32 val, u32 num_bits);
1248
1249         base_reg  = bh->ci->window_tab_32bit[window].base_reg;
1250
1251         if (base_reg != 0) {
1252                 size_reg  = bh->ci->window_tab_32bit[window].size_reg;
1253                 base_bits = bh->ci->window_tab_32bit[window].base_bits;
1254                 size_bits = bh->ci->window_tab_32bit[window].size_bits;
1255                 get_from_field= bh->ci->window_tab_32bit[window].get_from_field;
1256
1257                 val = mv64x60_read(bh, base_reg);
1258                 *base = get_from_field(val, base_bits);
1259
1260                 if (size_reg != 0) {
1261                         val = mv64x60_read(bh, size_reg);
1262                         val = get_from_field(val, size_bits);
1263                         *size = bh->ci->untranslate_size(*base, val, size_bits);
1264                 }
1265                 else {
1266                         *size = 0;
1267                 }
1268         }
1269         else {
1270                 *base = 0;
1271                 *size = 0;
1272         }
1273
1274         DBG("get 32bit window: %d, base: 0x%x, size: 0x%x\n",
1275                 window, *base, *size);
1276
1277         return;
1278 }
1279
1280 /*
1281  * mv64x60_set_32bit_window()
1282  *
1283  * Set the base address and size of a 32-bit window on the bridge.
1284  */
1285 void __init
1286 mv64x60_set_32bit_window(mv64x60_handle_t *bh, u32 window, u32 base, u32 size,
1287                                                                 u32 other_bits)
1288 {
1289         u32     val, base_reg, size_reg, base_bits, size_bits;
1290         u32     (*map_to_field)(u32 val, u32 num_bits);
1291
1292         DBG("set 32bit window: %d, base: 0x%x, size: 0x%x, other: 0x%x\n",
1293                 window, base, size, other_bits);
1294
1295         base_reg  = bh->ci->window_tab_32bit[window].base_reg;
1296
1297         if (base_reg != 0) {
1298                 size_reg  = bh->ci->window_tab_32bit[window].size_reg;
1299                 base_bits = bh->ci->window_tab_32bit[window].base_bits;
1300                 size_bits = bh->ci->window_tab_32bit[window].size_bits;
1301                 map_to_field = bh->ci->window_tab_32bit[window].map_to_field;
1302
1303                 val = map_to_field(base, base_bits) | other_bits;
1304                 mv64x60_write(bh, base_reg, val);
1305
1306                 if (size_reg != 0) {
1307                         val = bh->ci->translate_size(base, size, size_bits);
1308                         val = map_to_field(val, size_bits);
1309                         mv64x60_write(bh, size_reg, val);
1310                 }
1311                 (void)mv64x60_read(bh, base_reg); /* Flush FIFO */
1312         }
1313
1314         return;
1315 }
1316
1317 /*
1318  * mv64x60_get_64bit_window()
1319  *
1320  * Determine the base address and size of a 64-bit window on the bridge.
1321  */
1322 void __init
1323 mv64x60_get_64bit_window(mv64x60_handle_t *bh, u32 window, u32 *base_hi,
1324                                                         u32 *base_lo, u32 *size)
1325 {
1326         u32     val, base_lo_reg, size_reg, base_lo_bits, size_bits;
1327         u32     (*get_from_field)(u32 val, u32 num_bits);
1328
1329         base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;
1330
1331         if (base_lo_reg != 0) {
1332                 size_reg = bh->ci->window_tab_64bit[window].size_reg;
1333                 base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;
1334                 size_bits = bh->ci->window_tab_64bit[window].size_bits;
1335                 get_from_field= bh->ci->window_tab_64bit[window].get_from_field;
1336
1337                 *base_hi = mv64x60_read(bh, 
1338                         bh->ci->window_tab_64bit[window].base_hi_reg);
1339
1340                 val = mv64x60_read(bh, base_lo_reg);
1341                 *base_lo = get_from_field(val, base_lo_bits);
1342
1343                 if (size_reg != 0) {
1344                         val = mv64x60_read(bh, size_reg);
1345                         val = get_from_field(val, size_bits);
1346                         *size = bh->ci->untranslate_size(*base_lo, val,
1347                                                                 size_bits);
1348                 }
1349                 else {
1350                         *size = 0;
1351                 }
1352         }
1353         else {
1354                 *base_hi = 0;
1355                 *base_lo = 0;
1356                 *size = 0;
1357         }
1358
1359         DBG("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, size: 0x%x\n",
1360                 window, *base_hi, *base_lo, *size);
1361
1362         return;
1363 }
1364
1365 /*
1366  * mv64x60_set_64bit_window()
1367  *
1368  * Set the base address and size of a 64-bit window on the bridge.
1369  */
1370 void __init
1371 mv64x60_set_64bit_window(mv64x60_handle_t *bh, u32 window,
1372                         u32 base_hi, u32 base_lo, u32 size, u32 other_bits)
1373 {
1374         u32     val, base_lo_reg, size_reg, base_lo_bits, size_bits;
1375         u32     (*map_to_field)(u32 val, u32 num_bits);
1376
1377         DBG("set 64bit window: %d, base hi: 0x%x, base lo: 0x%x, " \
1378                 "size: 0x%x, other: 0x%x\n",
1379                 window, base_hi, base_lo, size, other_bits);
1380
1381         base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;
1382
1383         if (base_lo_reg != 0) {
1384                 size_reg = bh->ci->window_tab_64bit[window].size_reg;
1385                 base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;
1386                 size_bits = bh->ci->window_tab_64bit[window].size_bits;
1387                 map_to_field = bh->ci->window_tab_64bit[window].map_to_field;
1388
1389                 mv64x60_write(bh, bh->ci->window_tab_64bit[window].base_hi_reg,
1390                         base_hi);
1391
1392                 val = map_to_field(base_lo, base_lo_bits) | other_bits;
1393                 mv64x60_write(bh, base_lo_reg, val);
1394
1395                 if (size_reg != 0) {
1396                         val = bh->ci->translate_size(base_lo, size, size_bits);
1397                         val = map_to_field(val, size_bits);
1398                         mv64x60_write(bh, size_reg, val);
1399                 }
1400
1401                 (void)mv64x60_read(bh, base_lo_reg); /* Flush FIFO */
1402         }
1403
1404         return;
1405 }
1406
1407 /*
1408  * mv64x60_mask()
1409  *
1410  * Take the high-order 'num_bits' of 'val' & mask off low bits.
1411  */
1412 static u32 __init
1413 mv64x60_mask(u32 val, u32 num_bits)
1414 {
1415         DBG("mask val: 0x%x, num_bits: %d == 0x%x\n", val,
1416                 num_bits, val & (0xffffffff << (32 - num_bits)));
1417
1418         return val & (0xffffffff << (32 - num_bits));
1419 }
1420
1421 /*
1422  * mv64x60_mask_shift_left()
1423  *
1424  * Take the low-order 'num_bits' of 'val', shift left to align at bit 31 (MSB).
1425  */
1426 static u32 __init
1427 mv64x60_shift_left(u32 val, u32 num_bits)
1428 {
1429         DBG("shift left val: 0x%x, num_bits: %d == 0x%x\n", val,
1430                 num_bits, val << (32 - num_bits));
1431
1432         return val << (32 - num_bits);
1433 }
1434
1435 /*
1436  * mv64x60_shift_right()
1437  *
1438  * Take the high-order 'num_bits' of 'val', shift right to align at bit 0 (LSB).
1439  */
1440 static u32 __init
1441 mv64x60_shift_right(u32 val, u32 num_bits)
1442 {
1443         DBG("shift right val: 0x%x, num_bits: %d == 0x%x\n", val, num_bits,
1444                 val >> (32 - num_bits));
1445
1446         return val >> (32 - num_bits);
1447 }
1448
1449 /*
1450  *****************************************************************************
1451  *
1452  *      Early Init Routines
1453  *
1454  *****************************************************************************
1455  */
1456 /*
1457  * mv64x60_early_init()
1458  *
1459  * Do some bridge work that must take place before we start messing with
1460  * the bridge for real.
1461  */
1462 static void __init
1463 mv64x60_early_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
1464 {
1465         memset(bh, 0, sizeof(*bh));
1466
1467         bh->p_base = si->phys_reg_base;
1468         bh->v_base = (u32)ioremap(bh->p_base, MV64x60_INTERNAL_SPACE_SIZE);
1469         bh->base_irq = si->base_irq;
1470
1471         /* Bit 12 MUST be 0; set bit 27--don't auto-update cpu remap regs */
1472         mv64x60_clr_bits(bh, MV64x60_CPU_CONFIG, (1<<12));
1473         mv64x60_set_bits(bh, MV64x60_CPU_CONFIG, (1<<27));
1474
1475         /*
1476          * Turn off timer/counters.  Not turning off watchdog timer because
1477          * can't read its reg on the 64260A so don't know if we'll be enabling
1478          * or disabling.
1479          */
1480         mv64x60_clr_bits(bh, MV64x60_TIMR_CNTR_0_3_CNTL,
1481                         ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
1482
1483 #ifdef  CONFIG_GT64260
1484         mv64x60_clr_bits(bh, GT64260_TIMR_CNTR_4_7_CNTL,
1485                         ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
1486 #endif
1487
1488 #if 0
1489 XXXX Put in PCI_x_RETRY adjustment XXXX
1490 #endif
1491
1492         return;
1493 }
1494
1495 /*
1496  *****************************************************************************
1497  *
1498  *      Chip Identification Routines
1499  *
1500  *****************************************************************************
1501  */
1502 /*
1503  * mv64x60_get_type()
1504  *
1505  * Determine the type of bridge chip we have.
1506  */
1507 static int __init mv64x60_get_type(struct mv64x60_handle *bh)
1508 {
1509         struct pci_controller *hose = bh->hose_a;
1510         int pcidev;
1511         int devfn;
1512         u16 val;
1513         u8 save_exclude;
1514
1515         pcidev = (mv64x60_read(bh, MV64x60_PCI0_P2P_CONFIG) >> 24) & 0xf;
1516         devfn = PCI_DEVFN(pcidev, 0); 
1517
1518         save_exclude = mv64x60_pci_exclude_bridge;
1519         mv64x60_pci_exclude_bridge = FALSE;
1520
1521         /* Sanity check of bridge's Vendor ID */
1522         early_read_config_word(hose, 0, devfn, PCI_VENDOR_ID, &val);
1523
1524         if (val != PCI_VENDOR_ID_MARVELL)
1525                 return -1;
1526
1527         /* Figure out the type of Marvell bridge it is */
1528         early_read_config_word(hose, 0, devfn, PCI_DEVICE_ID, &val);
1529
1530         switch (val) {
1531         case PCI_DEVICE_ID_MARVELL_GT64260:
1532                 early_read_config_word(hose, 0, devfn,
1533                                        PCI_CLASS_REVISION, &val);
1534
1535                 switch (val & 0xff) {
1536                 case GT64260_REV_A:
1537                         bh->type = MV64x60_TYPE_GT64260A;
1538                         break;
1539                 case GT64260_REV_B:
1540                         bh->type = MV64x60_TYPE_GT64260B;
1541                         break;
1542                 }
1543                 break;
1544
1545         case PCI_DEVICE_ID_MARVELL_MV64360:
1546                 /* Marvell won't tell me how to distinguish a 64361 & 64362 */
1547                 bh->type = MV64x60_TYPE_MV64360;
1548                 break;
1549
1550         case PCI_DEVICE_ID_MARVELL_MV64460:
1551                 bh->type = MV64x60_TYPE_MV64460;
1552                 break;
1553
1554         default:
1555                 printk(KERN_CRIT "Unknown Marvell bridge type %04x\n", val);
1556                 return -1;
1557         }
1558
1559         mv64x60_pci_exclude_bridge = save_exclude;
1560         return 0;
1561 }
1562
1563 /*
1564  * mv64x60_setup_for_chip()
1565  *
1566  * Set 'bh' to use the proper set of routine for the bridge chip that we have.
1567  */
1568 static int __init
1569 mv64x60_setup_for_chip(mv64x60_handle_t *bh)
1570 {
1571         int     rc = 0;
1572
1573         /* Set up chip-specific info based on the chip/bridge type */
1574         switch(bh->type) {
1575                 case MV64x60_TYPE_GT64260A:
1576                         bh->ci = &gt64260a_ci;
1577                         break;
1578
1579                 case MV64x60_TYPE_GT64260B:
1580                         bh->ci = &gt64260b_ci;
1581                         break;
1582
1583                 case MV64x60_TYPE_MV64360:
1584                         bh->ci = &mv64360_ci;
1585                         break;
1586
1587 #if 0 /* Marvell won't tell me how to distinguish--MAG */
1588                 case MV64x60_TYPE_MV64361:
1589                 case MV64x60_TYPE_MV64362:
1590 #endif
1591                 case MV64x60_TYPE_MV64460:
1592                         bh->ci = &mv64460_ci;
1593                         break;
1594
1595                 case MV64x60_TYPE_INVALID:
1596                 default:
1597                         if (ppc_md.progress)
1598                                 ppc_md.progress("mv64x60: Unsupported bridge",
1599                                                                         0x0);
1600                         printk("mv64x60: Unsupported bridge\n");
1601                         rc = -1;
1602         }
1603
1604         return rc;
1605 }
1606
1607 /*
1608  *****************************************************************************
1609  *
1610  *      System Memory Window Related Routines
1611  *
1612  *****************************************************************************
1613  */
1614 /*
1615  * mv64x60_get_mem_windows()
1616  *
1617  * Get the values in the memory controller & return in the 'mem_windows' array.
1618  */
1619 static void __init
1620 mv64x60_get_mem_windows(mv64x60_handle_t *bh,
1621         u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
1622 {
1623         u32     i;
1624         u32     windows[] = { MV64x60_CPU2MEM_0_WIN, MV64x60_CPU2MEM_1_WIN,
1625                                 MV64x60_CPU2MEM_2_WIN, MV64x60_CPU2MEM_3_WIN };
1626
1627         for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
1628                 if (bh->ci->is_enabled_32bit(bh, i)) {
1629                         mv64x60_get_32bit_window(bh, windows[i],
1630                                 &mem_windows[i][0], &mem_windows[i][1]);
1631                 }
1632                 else {
1633                         mem_windows[i][0] = 0;
1634                         mem_windows[i][1] = 0;
1635                 }
1636         }
1637
1638         return;
1639 }
1640
1641 /*
1642  * mv64x60_calc_mem_size()
1643  *
1644  * Using the memory controller register values in 'mem_windows', determine
1645  * how much memory it is set up for.
1646  */
1647 static u32 __init
1648 mv64x60_calc_mem_size(mv64x60_handle_t *bh,
1649         u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
1650 {
1651         u32     i, total = 0;
1652
1653         for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
1654                 total += mem_windows[i][1];
1655         }
1656
1657         return total;
1658 }
1659
1660 /*
1661  *****************************************************************************
1662  *
1663  *      CPU->System MEM Config Routines
1664  *
1665  *****************************************************************************
1666  */
1667 /*
1668  * mv64x60_config_cpu2mem_windows()
1669  *
1670  * Configure CPU->Memory windows on the bridge.
1671  */
1672 static void __init
1673 mv64x60_config_cpu2mem_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si,
1674         u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
1675 {
1676         u32     i;
1677         u32     prot_windows[] = {
1678                         MV64x60_CPU_PROT_0_WIN, MV64x60_CPU_PROT_1_WIN,
1679                         MV64x60_CPU_PROT_2_WIN, MV64x60_CPU_PROT_3_WIN };
1680         u32     cpu_snoop_windows[] = {
1681                         MV64x60_CPU_SNOOP_0_WIN, MV64x60_CPU_SNOOP_1_WIN,
1682                         MV64x60_CPU_SNOOP_2_WIN, MV64x60_CPU_SNOOP_3_WIN };
1683
1684         /* Set CPU protection & snoop windows */
1685         for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
1686                 if (bh->ci->is_enabled_32bit(bh, i)) {
1687                         mv64x60_set_32bit_window(bh, prot_windows[i],
1688                                 mem_windows[i][0], mem_windows[i][1],
1689                                 si->cpu_prot_options[i]);
1690                         bh->ci->enable_window_32bit(bh, prot_windows[i]);
1691
1692                         if (bh->ci->window_tab_32bit[cpu_snoop_windows[i]].
1693                                                                 base_reg != 0) {
1694                                 mv64x60_set_32bit_window(bh,
1695                                         cpu_snoop_windows[i], mem_windows[i][0],
1696                                         mem_windows[i][1],
1697                                         si->cpu_snoop_options[i]);
1698                                 bh->ci->enable_window_32bit(bh,
1699                                         cpu_snoop_windows[i]);
1700                         }
1701
1702                 }
1703         }
1704
1705         return;
1706 }
1707
1708 /*
1709  *****************************************************************************
1710  *
1711  *      CPU->PCI Config Routines
1712  *
1713  *****************************************************************************
1714  */
1715
1716 /*
1717  * mv64x60_config_cpu2pci_windows()
1718  *
1719  * Configure the CPU->PCI windows on the bridge.
1720  */
1721 static void __init
1722 mv64x60_config_cpu2pci_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
1723 {
1724         if (ppc_md.progress)
1725                 ppc_md.progress("mv64x60_config_bridge: Enter", 0x0);
1726
1727         /*
1728          * Set up various parts of the bridge including CPU->PCI windows.
1729          * Depending on the board, there may be only one hose that needs to
1730          * be set up.
1731          */
1732         if (si->pci_0.enable_bus) {
1733                 u32     win_tab[] = { MV64x60_CPU2PCI0_IO_WIN,
1734                                 MV64x60_CPU2PCI0_MEM_0_WIN,
1735                                 MV64x60_CPU2PCI0_MEM_1_WIN,
1736                                 MV64x60_CPU2PCI0_MEM_2_WIN };
1737                 u32     remap_tab[] = { MV64x60_CPU2PCI0_IO_REMAP_WIN,
1738                                 MV64x60_CPU2PCI0_MEM_0_REMAP_WIN,
1739                                 MV64x60_CPU2PCI0_MEM_1_REMAP_WIN,
1740                                 MV64x60_CPU2PCI0_MEM_2_REMAP_WIN };
1741
1742                 mv64x60_set_cpu2pci_window(bh, &si->pci_0, win_tab, remap_tab);
1743         }
1744
1745         if (si->pci_1.enable_bus) {
1746                 u32     win_tab[] = { MV64x60_CPU2PCI1_IO_WIN,
1747                                 MV64x60_CPU2PCI1_MEM_0_WIN,
1748                                 MV64x60_CPU2PCI1_MEM_1_WIN,
1749                                 MV64x60_CPU2PCI1_MEM_2_WIN };
1750                 u32     remap_tab[] = { MV64x60_CPU2PCI1_IO_REMAP_WIN,
1751                                 MV64x60_CPU2PCI1_MEM_0_REMAP_WIN,
1752                                 MV64x60_CPU2PCI1_MEM_1_REMAP_WIN,
1753                                 MV64x60_CPU2PCI1_MEM_2_REMAP_WIN };
1754
1755                 mv64x60_set_cpu2pci_window(bh, &si->pci_1, win_tab, remap_tab);
1756         }
1757
1758         return;
1759 } /* mv64x60_config_bridge() */
1760
1761 /*
1762  * mv64x60_set_cpu2pci_window()
1763  *
1764  * Configure the CPU->PCI windows for one of the PCI buses.
1765  */
1766 static void __init
1767 mv64x60_set_cpu2pci_window(mv64x60_handle_t *bh, mv64x60_pci_info_t *pi,
1768                                                 u32 *win_tab, u32 *remap_tab)
1769 {
1770         int     i;
1771
1772         if (pi->pci_io.size > 0) {
1773                 mv64x60_set_32bit_window(bh, win_tab[0], pi->pci_io.cpu_base,
1774                                         pi->pci_io.size, pi->pci_io.swap);
1775                 mv64x60_set_32bit_window(bh, remap_tab[0],
1776                                         pi->pci_io.pci_base_lo, 0, 0);
1777                 bh->ci->enable_window_32bit(bh, win_tab[0]);
1778         }
1779         else { /* Actually, the window should already be disabled */
1780                 bh->ci->disable_window_32bit(bh, win_tab[0]);
1781         }
1782
1783         for (i=0; i<3; i++) {
1784                 if (pi->pci_mem[i].size > 0) {
1785                         mv64x60_set_32bit_window(bh, win_tab[i+1],
1786                                 pi->pci_mem[i].cpu_base, pi->pci_mem[i].size,
1787                                 pi->pci_mem[i].swap);
1788                         mv64x60_set_64bit_window(bh, remap_tab[i+1],
1789                                 pi->pci_mem[i].pci_base_hi,
1790                                 pi->pci_mem[i].pci_base_lo, 0, 0);
1791                         bh->ci->enable_window_32bit(bh, win_tab[i+1]);
1792                 }
1793                 else { /* Actually, the window should already be disabled */
1794                         bh->ci->disable_window_32bit(bh, win_tab[i+1]);
1795                 }
1796         }
1797
1798         return;
1799 }
1800
1801 /*
1802  *****************************************************************************
1803  *
1804  *      PCI->System MEM Config Routines
1805  *
1806  *****************************************************************************
1807  */
1808 /*
1809  * mv64x60_config_pci2mem_windows()
1810  *
1811  * Configure the PCI->Memory windows on the bridge.
1812  */
1813 static void __init
1814 mv64x60_config_pci2mem_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si,
1815         u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
1816 {
1817         u32     i;
1818         u32     pci_0_acc_windows[] = {
1819                         MV64x60_PCI02MEM_ACC_CNTL_0_WIN,
1820                         MV64x60_PCI02MEM_ACC_CNTL_1_WIN,
1821                         MV64x60_PCI02MEM_ACC_CNTL_2_WIN,
1822                         MV64x60_PCI02MEM_ACC_CNTL_3_WIN };
1823         u32     pci_1_acc_windows[] = {
1824                         MV64x60_PCI12MEM_ACC_CNTL_0_WIN,
1825                         MV64x60_PCI12MEM_ACC_CNTL_1_WIN,
1826                         MV64x60_PCI12MEM_ACC_CNTL_2_WIN,
1827                         MV64x60_PCI12MEM_ACC_CNTL_3_WIN };
1828         u32     pci_0_snoop_windows[] = {
1829                         MV64x60_PCI02MEM_SNOOP_0_WIN,
1830                         MV64x60_PCI02MEM_SNOOP_1_WIN,
1831                         MV64x60_PCI02MEM_SNOOP_2_WIN,
1832                         MV64x60_PCI02MEM_SNOOP_3_WIN };
1833         u32     pci_1_snoop_windows[] = {
1834                         MV64x60_PCI12MEM_SNOOP_0_WIN,
1835                         MV64x60_PCI12MEM_SNOOP_1_WIN,
1836                         MV64x60_PCI12MEM_SNOOP_2_WIN,
1837                         MV64x60_PCI12MEM_SNOOP_3_WIN };
1838         u32     pci_0_size[] = {
1839                         MV64x60_PCI0_MEM_0_SIZE, MV64x60_PCI0_MEM_1_SIZE,
1840                         MV64x60_PCI0_MEM_2_SIZE, MV64x60_PCI0_MEM_3_SIZE };
1841         u32     pci_1_size[] = {
1842                         MV64x60_PCI1_MEM_0_SIZE, MV64x60_PCI1_MEM_1_SIZE,
1843                         MV64x60_PCI1_MEM_2_SIZE, MV64x60_PCI1_MEM_3_SIZE };
1844
1845         /* Clear bit 0 of PCI addr decode control so PCI->CPU remap 1:1 */
1846         mv64x60_clr_bits(bh, MV64x60_PCI0_PCI_DECODE_CNTL, 0x00000001);
1847         mv64x60_clr_bits(bh, MV64x60_PCI1_PCI_DECODE_CNTL, 0x00000001);
1848
1849         /*
1850          * Set the access control, snoop, BAR size, and window base addresses.
1851          * PCI->MEM windows base addresses will match exactly what the
1852          * CPU->MEM windows are.
1853          */
1854         for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
1855                 if (bh->ci->is_enabled_32bit(bh, i)) {
1856                         if (si->pci_0.enable_bus) {
1857                                 mv64x60_set_64bit_window(bh,
1858                                         pci_0_acc_windows[i], 0,
1859                                         mem_windows[i][0], mem_windows[i][1],
1860                                         si->pci_0.acc_cntl_options[i]);
1861                                 bh->ci->enable_window_64bit(bh,
1862                                         pci_0_acc_windows[i]);
1863
1864                                 if (bh->ci->window_tab_64bit[
1865                                         pci_0_snoop_windows[i]].base_lo_reg
1866                                                                         != 0) {
1867                                         mv64x60_set_64bit_window(bh,
1868                                                 pci_0_snoop_windows[i], 0,
1869                                                 mem_windows[i][0],
1870                                                 mem_windows[i][1],
1871                                                 si->pci_0.snoop_options[i]);
1872                                         bh->ci->enable_window_64bit(bh,
1873                                                 pci_0_snoop_windows[i]);
1874                                 }
1875
1876                                 bh->ci->set_pci2mem_window(bh->hose_a, i,
1877                                         mem_windows[i][0]);
1878                                 mv64x60_write(bh, pci_0_size[i],
1879                                         mv64x60_mask(mem_windows[i][1] -1, 20));
1880
1881                                 /* Enable the window */
1882                                 mv64x60_clr_bits(bh, MV64x60_PCI0_BAR_ENABLE,
1883                                                                         1 << i);
1884                         }
1885                         if (si->pci_1.enable_bus) {
1886                                 mv64x60_set_64bit_window(bh,
1887                                         pci_1_acc_windows[i], 0,
1888                                         mem_windows[i][0], mem_windows[i][1],
1889                                         si->pci_1.acc_cntl_options[i]);
1890                                 bh->ci->enable_window_64bit(bh,
1891                                         pci_1_acc_windows[i]);
1892
1893                                 if (bh->ci->window_tab_64bit[
1894                                         pci_1_snoop_windows[i]].base_lo_reg
1895                                                                         != 0) {
1896                                         mv64x60_set_64bit_window(bh,
1897                                                 pci_1_snoop_windows[i], 0,
1898                                                 mem_windows[i][0],
1899                                                 mem_windows[i][1],
1900                                                 si->pci_1.snoop_options[i]);
1901                                         bh->ci->enable_window_64bit(bh,
1902                                                 pci_1_snoop_windows[i]);
1903                                 }
1904
1905                                 bh->ci->set_pci2mem_window(bh->hose_b, i,
1906                                         mem_windows[i][0]);
1907                                 mv64x60_write(bh, pci_1_size[i],
1908                                         mv64x60_mask(mem_windows[i][1] -1, 20));
1909
1910                                 /* Enable the window */
1911                                 mv64x60_clr_bits(bh, MV64x60_PCI1_BAR_ENABLE,
1912                                                                         1 << i);
1913                         }
1914                 }
1915         }
1916
1917         return;
1918 }
1919
1920 /*
1921  *****************************************************************************
1922  *
1923  *      Hose & Resource Alloc/Init Routines
1924  *
1925  *****************************************************************************
1926  */
1927 /*
1928  * mv64x60_alloc_hoses()
1929  *
1930  * Allocate the PCI hose structures for the bridge's PCI buses.
1931  */
1932 static void __init
1933 mv64x60_alloc_hoses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
1934 {
1935         /*
1936          * Alloc first hose struct even when its not to be configured b/c the
1937          * chip identification routines need to use it.
1938          */
1939         bh->hose_a = pcibios_alloc_controller();
1940         setup_indirect_pci(bh->hose_a,
1941                 bh->p_base + MV64x60_PCI0_CONFIG_ADDR,
1942                 bh->p_base + MV64x60_PCI0_CONFIG_DATA);
1943
1944         if (si->pci_1.enable_bus) {
1945                 bh->hose_b = pcibios_alloc_controller();
1946                 setup_indirect_pci(bh->hose_b,
1947                         bh->p_base + MV64x60_PCI1_CONFIG_ADDR,
1948                         bh->p_base + MV64x60_PCI1_CONFIG_DATA);
1949         }
1950
1951         return;
1952 }
1953
1954 /*
1955  * mv64x60_init_hoses()
1956  *
1957  * Initialize the PCI hose structures for the bridge's PCI hoses.
1958  */
1959 static void __init
1960 mv64x60_init_hoses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
1961 {
1962         if (si->pci_1.enable_bus) {
1963                 bh->io_base_b = (u32)ioremap(si->pci_1.pci_io.cpu_base,
1964                                                         si->pci_1.pci_io.size);
1965                 isa_io_base = bh->io_base_b;
1966         }
1967
1968         if (si->pci_0.enable_bus) {
1969                 bh->io_base_a = (u32)ioremap(si->pci_0.pci_io.cpu_base,
1970                                                         si->pci_0.pci_io.size);
1971                 isa_io_base = bh->io_base_a;
1972
1973                 mv64x60_init_resources(bh->hose_a, &si->pci_0, bh->io_base_a);
1974                 mv64x60_set_pci_params(bh->hose_a, &si->pci_0);
1975         }
1976
1977         /* Must do here so proper isa_io_base is used in calculations */
1978         if (si->pci_1.enable_bus) {
1979                 mv64x60_init_resources(bh->hose_b, &si->pci_1, bh->io_base_b);
1980                 mv64x60_set_pci_params(bh->hose_b, &si->pci_1);
1981         }
1982
1983         return;
1984 }
1985
1986 /*
1987  * mv64x60_init_resources()
1988  *
1989  * Calculate the offsets, etc. for the hose structures to reflect all of
1990  * the address remapping that happens as you go from CPU->PCI and PCI->MEM.
1991  */
1992 static void __init
1993 mv64x60_init_resources(struct pci_controller *hose, mv64x60_pci_info_t *pi,
1994                                 u32 io_base)
1995 {
1996         int             i;
1997         /* 2 hoses; 4 resources/hose; sting <= 64 bytes; not work if > 1 chip */
1998         static char     s[2][4][64];
1999
2000         if (pi->pci_io.size != 0) {
2001                 sprintf(s[hose->index][0], "PCI hose %d I/O Space",
2002                         hose->index);
2003                 pci_init_resource(&hose->io_resource, io_base - isa_io_base,
2004                         io_base - isa_io_base + pi->pci_io.size - 1,
2005                         IORESOURCE_IO, s[hose->index][0]);
2006                 hose->io_space.start = pi->pci_io.pci_base_lo;
2007                 hose->io_space.end = pi->pci_io.pci_base_lo + pi->pci_io.size-1;
2008                 hose->io_base_virt = (void *)isa_io_base;
2009         }
2010
2011         for (i=0; i<3; i++) {
2012                 if (pi->pci_mem[i].size != 0) {
2013                         sprintf(s[hose->index][i+1], "PCI hose %d MEM Space %d",
2014                                 hose->index, i);
2015                         pci_init_resource(&hose->mem_resources[i],
2016                                 pi->pci_mem[i].cpu_base,
2017                                 pi->pci_mem[i].cpu_base + pi->pci_mem[i].size-1,
2018                                 IORESOURCE_MEM, s[hose->index][i+1]);
2019                 }
2020         }
2021         
2022         hose->mem_space.end = pi->pci_mem[0].pci_base_lo +
2023                                                 pi->pci_mem[0].size - 1;
2024         hose->pci_mem_offset = pi->pci_mem[0].cpu_base -
2025                                                 pi->pci_mem[0].pci_base_lo;
2026
2027         return;
2028 } /* mv64x60_init_resources() */
2029
2030 /*
2031  * mv64x60_set_pci_params()
2032  *
2033  * Configure a hose's PCI config space parameters.
2034  */
2035 static void __init
2036 mv64x60_set_pci_params(struct pci_controller *hose, mv64x60_pci_info_t *pi)
2037 {
2038         u32     devfn;
2039         u16     u16_val;
2040         u8      save_exclude;
2041
2042         devfn = PCI_DEVFN(0,0);
2043
2044         save_exclude = mv64x60_pci_exclude_bridge;
2045         mv64x60_pci_exclude_bridge = FALSE;
2046
2047         /* Set class code to indicate host bridge */
2048         u16_val = PCI_CLASS_BRIDGE_HOST; /* 0x0600 (host bridge) */
2049         early_write_config_word(hose, 0, devfn, PCI_CLASS_DEVICE, u16_val);
2050
2051         /* Enable 64260 to be PCI master & respond to PCI MEM cycles */
2052         early_read_config_word(hose, 0, devfn, PCI_COMMAND, &u16_val);
2053         u16_val &= ~(PCI_COMMAND_IO | PCI_COMMAND_INVALIDATE |
2054                 PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK);
2055         u16_val |= pi->pci_cmd_bits | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
2056         early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val);
2057
2058         /* Set latency timer, cache line size, clear BIST */
2059         u16_val = (pi->latency_timer << 8) | (L1_CACHE_LINE_SIZE >> 2);
2060         early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val);
2061
2062         mv64x60_pci_exclude_bridge = save_exclude;
2063         return;
2064 }
2065
2066 /*
2067  *****************************************************************************
2068  *
2069  *      PCI Related Routine
2070  *
2071  *****************************************************************************
2072  */
2073 /*
2074  * mv64x60_enumerate_buses()
2075  *
2076  * If requested, enumerate the PCI buses and set the appropriate
2077  * info in the hose structures.
2078  */
2079 static void __init
2080 mv64x60_enumerate_buses(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
2081 {
2082         u32     val;
2083
2084         pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */
2085
2086         ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
2087         ppc_md.pci_swizzle = common_swizzle;
2088         ppc_md.pci_map_irq = si->map_irq;
2089
2090         /* Now that the bridge is set up, its safe to scan the PCI buses */
2091         if (si->pci_0.enable_bus) {
2092                 if (si->pci_0.enumerate_bus) {
2093                         /* Set bus number for PCI 0 to 0 */
2094                         val = mv64x60_read(bh, MV64x60_PCI0_P2P_CONFIG);
2095                         val &= 0xe0000000;
2096                         val |= 0x000000ff;
2097                         mv64x60_write(bh, MV64x60_PCI0_P2P_CONFIG, val);
2098                         /* Flush FIFO*/
2099                         (void)mv64x60_read(bh, MV64x60_PCI0_P2P_CONFIG);
2100
2101 #if 0
2102 XXXX Different if in PCI-X mode (look at mv64360_find_bridges()) XXXX
2103 #endif
2104
2105                         bh->hose_a->first_busno = 0;
2106                         bh->hose_a->last_busno  = 0xff;
2107
2108                         bh->hose_a->last_busno = pciauto_bus_scan(bh->hose_a,
2109                                                 bh->hose_a->first_busno);
2110                 }
2111                 else {
2112                         /* Assume bridge set up correctly by someone else */
2113                         val = mv64x60_read(bh, MV64x60_PCI0_P2P_CONFIG);
2114                         bh->hose_a->first_busno = (val & 0x00ff0000) >> 16;
2115                 }
2116         }
2117
2118         if (si->pci_1.enable_bus) {
2119                 if (si->pci_1.enumerate_bus) {
2120                         if (si->pci_0.enable_bus) {
2121                                 bh->hose_b->first_busno =
2122                                         bh->hose_a->last_busno + 1;
2123
2124                                 /* Set bus number for PCI 1 hose */
2125                                 val = mv64x60_read(bh, MV64x60_PCI1_P2P_CONFIG);
2126                                 val &= 0xe0000000;
2127                                 val |= (bh->hose_b->first_busno << 16) | 0xff;
2128                                 mv64x60_write(bh, MV64x60_PCI1_P2P_CONFIG, val);
2129                                 /* Flush FIFO */
2130                                 (void)mv64x60_read(bh, MV64x60_PCI1_P2P_CONFIG);
2131                         }
2132                         else {
2133                                 bh->hose_b->first_busno = 0;
2134                         }
2135
2136                         bh->hose_b->last_busno  = 0xff;
2137                         bh->hose_b->last_busno = pciauto_bus_scan(bh->hose_b,
2138                                                 bh->hose_b->first_busno);
2139                 }
2140                 else {
2141                         /* Assume bridge set up correctly by someone else */
2142                         val = mv64x60_read(bh, MV64x60_PCI1_P2P_CONFIG);
2143                         bh->hose_b->first_busno = (val & 0x00ff0000) >> 16;
2144                         bh->hose_b->last_busno = 0xff; /* No way to know */
2145                 }
2146         }
2147
2148         if (si->pci_0.enable_bus && !si->pci_0.enumerate_bus) {
2149                 if (si->pci_1.enable_bus) {
2150                         bh->hose_a->last_busno = bh->hose_b->first_busno - 1;
2151                 }
2152                 else {
2153                         bh->hose_a->last_busno = 0xff; /* No way to know */
2154                 }
2155         }
2156
2157         return;
2158 }
2159
2160 /*
2161  * mv64x60_exclude_pci_device()
2162  *
2163  * This routine is used to make the bridge not appear when the
2164  * PCI subsystem is accessing PCI devices (in PCI config space).
2165  */
2166 static int
2167 mv64x60_pci_exclude_device(u8 bus, u8 devfn)
2168 {
2169         struct pci_controller   *hose;
2170
2171         hose = pci_bus_to_hose(bus);
2172
2173         /* Skip slot 0 on both hoses */
2174         if ((mv64x60_pci_exclude_bridge == TRUE) &&
2175             (PCI_SLOT(devfn) == 0) &&
2176             (hose->first_busno == bus)) {
2177                 return PCIBIOS_DEVICE_NOT_FOUND;
2178         }
2179         else {
2180                 return PCIBIOS_SUCCESSFUL;
2181         }
2182 } /* mv64x60_pci_exclude_device() */
2183
2184 /*
2185  *****************************************************************************
2186  *
2187  *      OCP Fixup Routines
2188  *
2189  *****************************************************************************
2190  */
2191 /*
2192  * mv64x60_fixup_ocp()
2193  *
2194  * Adjust the 'paddr' field in the bridge's OCP entries to reflect where they
2195  * really are in the physical address space.
2196  */
2197 static void __init
2198 mv64x60_fixup_ocp(struct ocp_device *dev, void *arg)
2199 {
2200         mv64x60_handle_t        *bh = (mv64x60_handle_t *)arg;
2201
2202         if (dev->def->vendor == OCP_VENDOR_MARVELL) {
2203                 dev->def->paddr += bh->p_base;
2204         }
2205
2206         return;
2207 }
2208
2209 /*
2210  *****************************************************************************
2211  *
2212  *      GT64260-Specific Routines
2213  *
2214  *****************************************************************************
2215  */
2216 /*
2217  * gt64260_translate_size()
2218  *
2219  * On the GT64260, the size register is really the "top" address of the window.
2220  */
2221 static u32 __init
2222 gt64260_translate_size(u32 base, u32 size, u32 num_bits)
2223 {
2224         return base + mv64x60_mask(size - 1, num_bits);
2225 }
2226
2227 /*
2228  * gt64260_untranslate_size()
2229  *
2230  * Translate the top address of a window into a window size.
2231  */
2232 static u32 __init
2233 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits)
2234 {
2235         if (size >= base) {
2236                 size = size - base + (1 << (32 - num_bits));
2237         }
2238         else {
2239                 size = 0;
2240         }
2241
2242         return size;
2243 }
2244
2245 /*
2246  * gt64260_set_pci2mem_window()
2247  *
2248  * The PCI->MEM window registers are actually in PCI config space so need
2249  * to set them by setting the correct config space BARs.
2250  */
2251 static void __init
2252 gt64260_set_pci2mem_window(struct pci_controller *hose, u32 window, u32 base)
2253 {
2254         u32     reg_addrs[] = { 0x10, 0x14, 0x18, 0x1c };
2255
2256         DBG("set pci->mem window: %d, hose: %d, base: 0x%x\n", window,
2257                 hose->index, base);
2258
2259         early_write_config_dword(hose, hose->first_busno,
2260                         PCI_DEVFN(0, 0), reg_addrs[window],
2261                         mv64x60_mask(base, 20) | 0x8);
2262         return;
2263 }
2264
2265 /*
2266  * gt64260_is_enabled_32bit()
2267  *
2268  * On a GT64260, a window is enabled iff its top address is >= to its base
2269  * address.
2270  */
2271 static u32 __init
2272 gt64260_is_enabled_32bit(mv64x60_handle_t *bh, u32 window)
2273 {
2274         u32     rc = 0;
2275
2276         if ((gt64260_32bit_windows[window].base_reg != 0) &&
2277                 (gt64260_32bit_windows[window].size_reg != 0) &&
2278                 ((mv64x60_read(bh, gt64260_32bit_windows[window].size_reg) &
2279                         ((1 << gt64260_32bit_windows[window].size_bits) - 1)) >=
2280                  (mv64x60_read(bh, gt64260_32bit_windows[window].base_reg) &
2281                         ((1 << gt64260_32bit_windows[window].base_bits) - 1)))){
2282
2283                 rc = 1;
2284         }
2285
2286         if (rc) {
2287                 DBG("32bit window %d is enabled\n", window);
2288         }
2289         else {
2290                 DBG("32bit window %d is disabled\n", window);
2291         }
2292
2293         return rc;
2294 }
2295
2296 /*
2297  * gt64260_enable_window_32bit()
2298  *
2299  * On the GT64260, a window is enabled iff the top address is >= to the base
2300  * address of the window.  Since the window has already been configured by
2301  * the time this routine is called, we have nothing to do here.
2302  */
2303 static void __init
2304 gt64260_enable_window_32bit(mv64x60_handle_t *bh, u32 window)
2305 {
2306         DBG("enable 32bit window: %d\n", window);
2307         return;
2308 }
2309
2310 /*
2311  * gt64260_disable_window_32bit()
2312  *
2313  * On a GT64260, you disable a window by setting its top address to be less
2314  * than its base address.
2315  */
2316 static void __init
2317 gt64260_disable_window_32bit(mv64x60_handle_t *bh, u32 window)
2318 {
2319         DBG("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
2320                 window, gt64260_32bit_windows[window].base_reg,
2321                 gt64260_32bit_windows[window].size_reg);
2322
2323         if ((gt64260_32bit_windows[window].base_reg != 0) &&
2324                 (gt64260_32bit_windows[window].size_reg != 0)) {
2325
2326                 /* To disable, make bottom reg higher than top reg */
2327                 mv64x60_write(bh, gt64260_32bit_windows[window].base_reg,0xfff);
2328                 mv64x60_write(bh, gt64260_32bit_windows[window].size_reg, 0);
2329         }
2330
2331         return;
2332 }
2333
2334 /*
2335  * gt64260_enable_window_64bit()
2336  *
2337  * On the GT64260, a window is enabled iff the top address is >= to the base
2338  * address of the window.  Since the window has already been configured by
2339  * the time this routine is called, we have nothing to do here.
2340  */
2341 static void __init
2342 gt64260_enable_window_64bit(mv64x60_handle_t *bh, u32 window)
2343 {
2344         DBG("enable 64bit window: %d\n", window);
2345         return; /* Enabled when window configured (i.e., when top >= base) */
2346 }
2347
2348 /*
2349  * gt64260_disable_window_64bit()
2350  *
2351  * On a GT64260, you disable a window by setting its top address to be less
2352  * than its base address.
2353  */
2354 static void __init
2355 gt64260_disable_window_64bit(mv64x60_handle_t *bh, u32 window)
2356 {
2357         DBG("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
2358                 window, gt64260_64bit_windows[window].base_lo_reg,
2359                 gt64260_64bit_windows[window].size_reg);
2360
2361         if ((gt64260_64bit_windows[window].base_lo_reg != 0) &&
2362                 (gt64260_64bit_windows[window].size_reg != 0)) {
2363
2364                 /* To disable, make bottom reg higher than top reg */
2365                 mv64x60_write(bh, gt64260_64bit_windows[window].base_lo_reg,
2366                                                                         0xfff);
2367                 mv64x60_write(bh, gt64260_64bit_windows[window].base_hi_reg, 0);
2368                 mv64x60_write(bh, gt64260_64bit_windows[window].size_reg, 0);
2369         }
2370
2371         return;
2372 }
2373
2374 /*
2375  * gt64260_disable_all_windows()
2376  *
2377  * The GT64260 has several windows that aren't represented in the table of
2378  * windows at the top of this file.  This routine turns all of them off
2379  * except for the memory controller windows, of course.
2380  */
2381 static void __init
2382 gt64260_disable_all_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
2383 {
2384         u32     i;
2385
2386         /* Disable 32bit windows (don't disable cpu->mem windows) */
2387         for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) {
2388                 if (!(si->window_preserve_mask_32 & (1<<i)))
2389                         gt64260_disable_window_32bit(bh, i);
2390         }
2391
2392         /* Disable 64bit windows */
2393         for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++) {
2394                 if (!(si->window_preserve_mask_64 & (1<<i)))
2395                         gt64260_disable_window_64bit(bh, i);
2396         }
2397
2398         /* Turn off cpu protection windows not in gt64260_32bit_windows[] */
2399         mv64x60_write(bh, GT64260_CPU_PROT_BASE_4, 0xfff);
2400         mv64x60_write(bh, GT64260_CPU_PROT_SIZE_4, 0);
2401         mv64x60_write(bh, GT64260_CPU_PROT_BASE_5, 0xfff);
2402         mv64x60_write(bh, GT64260_CPU_PROT_SIZE_5, 0);
2403         mv64x60_write(bh, GT64260_CPU_PROT_BASE_6, 0xfff);
2404         mv64x60_write(bh, GT64260_CPU_PROT_SIZE_6, 0);
2405         mv64x60_write(bh, GT64260_CPU_PROT_BASE_7, 0xfff);
2406         mv64x60_write(bh, GT64260_CPU_PROT_SIZE_7, 0);
2407
2408         /* Turn off PCI->MEM access cntl wins not in gt64260_64bit_windows[] */
2409         mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0xfff);
2410         mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_HI, 0);
2411         mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_SIZE, 0);
2412         mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0xfff);
2413         mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_HI, 0);
2414         mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_SIZE, 0);
2415         mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_LO, 0xfff);
2416         mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_HI, 0);
2417         mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_SIZE, 0);
2418         mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_LO, 0xfff);
2419         mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_HI, 0);
2420         mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_SIZE, 0);
2421
2422         mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0xfff);
2423         mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_HI, 0);
2424         mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_SIZE, 0);
2425         mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0xfff);
2426         mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_HI, 0);
2427         mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_SIZE, 0);
2428         mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_LO, 0xfff);
2429         mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_HI, 0);
2430         mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_SIZE, 0);
2431         mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_LO, 0xfff);
2432         mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_HI, 0);
2433         mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_SIZE, 0);
2434
2435         /* Disable all PCI-><whatever> windows */
2436         mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x07ffffff);
2437         mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x07ffffff);
2438
2439         return;
2440 }
2441
2442 /*
2443  * gt64260a_chip_specific_init()
2444  *
2445  * Implement errata work arounds for the GT64260A.
2446  */
2447 static void
2448 gt64260a_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
2449 {
2450         struct ocp_device       *dev;
2451         mv64x60_ocp_mpsc_data_t *mpsc_dp;
2452         u8                      save_exclude;
2453         u32                     val;
2454
2455         /* R#18 */
2456         /* cpu read buffer to buffer 1 (reg 0x0448) */
2457         mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26));
2458
2459         /* No longer errata so turn on */
2460         /* Enable pci read/write combine, master write trigger,
2461         * disable slave sync barrier
2462         * readmultiple (reg 0x0c00 and 0x0c80)
2463         */
2464         if (si->pci_0.enable_bus) {
2465                 mv64x60_set_bits(bh, MV64x60_PCI0_CMD,
2466                         ((1<<4) | (1<<5) | (1<<9) | (1<<13)));
2467         }
2468
2469         if (si->pci_1.enable_bus) {
2470                 mv64x60_set_bits(bh, MV64x60_PCI1_CMD,
2471                         ((1<<4) | (1<<5) | (1<<9) | (1<<13)));
2472         }
2473
2474 #if 1   /* XXXX */
2475         /*
2476          * Dave Wilhardt found that bit 4 in the PCI Command registers must
2477          * be set if you are using cache coherency.
2478          *
2479          * Note: he also said that bit 4 must be on in all PCI devices but
2480          *       that has not been implemented yet.
2481          */
2482         save_exclude = mv64x60_pci_exclude_bridge;
2483         mv64x60_pci_exclude_bridge = FALSE;
2484
2485         early_read_config_dword(bh->hose_a,
2486                         bh->hose_a->first_busno,
2487                         PCI_DEVFN(0,0),
2488                         PCI_COMMAND,
2489                         &val);
2490         val |= PCI_COMMAND_INVALIDATE;
2491         early_write_config_dword(bh->hose_a,
2492                         bh->hose_a->first_busno,
2493                         PCI_DEVFN(0,0),
2494                         PCI_COMMAND,
2495                         val);
2496
2497         early_read_config_dword(bh->hose_b,
2498                         bh->hose_b->first_busno,
2499                         PCI_DEVFN(0,0),
2500                         PCI_COMMAND,
2501                         &val);
2502         val |= PCI_COMMAND_INVALIDATE;
2503         early_write_config_dword(bh->hose_b,
2504                         bh->hose_b->first_busno,
2505                         PCI_DEVFN(0,0),
2506                         PCI_COMMAND,
2507                         val);
2508
2509         mv64x60_pci_exclude_bridge = save_exclude;
2510 #endif
2511
2512         if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 0))
2513                                                                 != NULL) {
2514                 mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions;
2515                 mpsc_dp->mirror_regs = 1;
2516                 mpsc_dp->cache_mgmt = 1;
2517         }
2518
2519         if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 1))
2520                                                                 != NULL) {
2521                 mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions;
2522                 mpsc_dp->mirror_regs = 1;
2523                 mpsc_dp->cache_mgmt = 1;
2524         }
2525
2526         return;
2527 }
2528
2529 /*
2530  * gt64260b_chip_specific_init()
2531  *
2532  * Implement errata work arounds for the GT64260B.
2533  */
2534 static void
2535 gt64260b_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
2536 {
2537         struct ocp_device       *dev;
2538         mv64x60_ocp_mpsc_data_t *mpsc_dp;
2539
2540         /* R#18 */
2541         /* cpu read buffer to buffer 1 (reg 0x0448) */
2542         mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26));
2543
2544         /* No longer errata so turn on */
2545         /* Enable pci read/write combine, master write trigger,
2546         * disable slave sync barrier
2547         * readmultiple (reg 0x0c00 and 0x0c80)
2548         */
2549         if (si->pci_0.enable_bus) {
2550                 mv64x60_set_bits(bh, MV64x60_PCI0_CMD,
2551                         ((1<<4) | (1<<5) | (1<<9) | (1<<13)));
2552         }
2553
2554         if (si->pci_1.enable_bus) {
2555                 mv64x60_set_bits(bh, MV64x60_PCI1_CMD,
2556                         ((1<<4) | (1<<5) | (1<<9) | (1<<13)));
2557         }
2558
2559         mv64x60_set_bits(bh, GT64260_CPU_WB_PRIORITY_BUFFER_DEPTH, 0xf);
2560
2561         /*
2562          * The 64260B is not supposed to have the bug where the MPSC & ENET
2563          * can't access cache coherent regions.  However, testing has shown
2564          * that the MPSC, at least, still has this bug.
2565          */
2566         if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 0))
2567                                                                 != NULL) {
2568                 mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions;
2569                 mpsc_dp->cache_mgmt = 1;
2570         }
2571
2572         if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 1))
2573                                                                 != NULL) {
2574                 mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions;
2575                 mpsc_dp->cache_mgmt = 1;
2576         }
2577
2578         return;
2579 }
2580
2581 /*
2582  *****************************************************************************
2583  *
2584  *      MV64360-Specific Routines
2585  *
2586  *****************************************************************************
2587  */
2588 /*
2589  * mv64360_translate_size()
2590  *
2591  * On the MV64360, the size register is set similar to the size you get
2592  * from a pci config space BAR register.  That is, programmed from LSB to MSB
2593  * as a sequence of 1's followed by a sequence of 0's. IOW, "size -1" with the
2594  * assumption that the size is a power of 2.
2595  */
2596 static u32 __init
2597 mv64360_translate_size(u32 base_addr, u32 size, u32 num_bits)
2598 {
2599         return mv64x60_mask(size - 1, num_bits);
2600 }
2601
2602 /*
2603  * mv64360_untranslate_size()
2604  *
2605  * Translate the size register value of a window into a window size.
2606  */
2607 static u32 __init
2608 mv64360_untranslate_size(u32 base_addr, u32 size, u32 num_bits)
2609 {
2610         if (size > 0) {
2611                 size >>= (32 - num_bits);
2612                 size++;
2613                 size <<= (32 - num_bits);
2614         }
2615
2616         return size;
2617 }
2618
2619 /*
2620  * mv64360_set_pci2mem_window()
2621  *
2622  * The PCI->MEM window registers are actually in PCI config space so need
2623  * to set them by setting the correct config space BARs.
2624  */
2625 static void __init
2626 mv64360_set_pci2mem_window(struct pci_controller *hose, u32 window, u32 base)
2627 {
2628         struct {
2629                 u32     fcn;
2630                 u32     base_hi_bar;
2631                 u32     base_lo_bar;
2632         } reg_addrs[] = {{ 0, 0x14, 0x10 }, { 0, 0x1c, 0x18 },
2633                 { 1, 0x14, 0x10 }, { 1, 0x1c, 0x18 }};
2634
2635         DBG("set pci->mem window: %d, hose: %d, base: 0x%x\n", window,
2636                 hose->index, base);
2637
2638         early_write_config_dword(hose, hose->first_busno,
2639                         PCI_DEVFN(0, reg_addrs[window].fcn),
2640                         reg_addrs[window].base_hi_bar, 0);
2641         early_write_config_dword(hose, hose->first_busno,
2642                         PCI_DEVFN(0, reg_addrs[window].fcn),
2643                         reg_addrs[window].base_lo_bar,
2644                         mv64x60_mask(base, 20) | 0xc);
2645         return;
2646 }
2647
2648 /*
2649  * mv64360_is_enabled_32bit()
2650  *
2651  * On a MV64360, a window is enabled by either clearing a bit in the
2652  * CPU BAR Enable reg or setting a bit in the window's base reg.
2653  * Note that this doesn't work for windows on the PCI slave side but we don't
2654  * check those so its okay.
2655  */
2656 static u32 __init
2657 mv64360_is_enabled_32bit(mv64x60_handle_t *bh, u32 window)
2658 {
2659         u32     rc = 0;
2660
2661         if ((mv64360_32bit_windows[window].base_reg != 0) &&
2662                 (mv64360_32bit_windows[window].size_reg != 0)) {
2663
2664                 if (mv64360_32bit_windows[window].extra & 0x80000000) {
2665                         rc = (mv64x60_read(bh,
2666                                 mv64360_32bit_windows[window].base_reg) & 
2667                                 (1 << (mv64360_32bit_windows[window].extra &
2668                                                                 0xff))) != 0;
2669                 }
2670                 else {
2671                         rc = (mv64x60_read(bh, MV64360_CPU_BAR_ENABLE) & 
2672                                 (1 << mv64360_32bit_windows[window].extra)) ==0;
2673                 }
2674         }
2675
2676         if (rc) {
2677                 DBG("32bit window %d is enabled\n", window);
2678         }
2679         else {
2680                 DBG("32bit window %d is disabled\n", window);
2681         }
2682
2683         return rc;
2684 }
2685
2686 /*
2687  * mv64360_enable_window_32bit()
2688  *
2689  * On a MV64360, a window is enabled by either clearing a bit in the
2690  * CPU BAR Enable reg or setting a bit in the window's base reg.
2691  */
2692 static void __init
2693 mv64360_enable_window_32bit(mv64x60_handle_t *bh, u32 window)
2694 {
2695         DBG("enable 32bit window: %d\n", window);
2696
2697         if ((mv64360_32bit_windows[window].base_reg != 0) &&
2698                 (mv64360_32bit_windows[window].size_reg != 0)) {
2699
2700                 if (mv64360_32bit_windows[window].extra & 0x80000000) {
2701                         mv64x60_set_bits(bh,
2702                                 mv64360_32bit_windows[window].base_reg,
2703                                 (1 << (mv64360_32bit_windows[window].extra &
2704                                                                         0xff)));
2705                 }
2706                 else {
2707                         mv64x60_clr_bits(bh, MV64360_CPU_BAR_ENABLE,
2708                                 (1 << mv64360_32bit_windows[window].extra));
2709                 }
2710         }
2711
2712         return;
2713 }
2714
2715 /*
2716  * mv64360_disable_window_32bit()
2717  *
2718  * On a MV64360, a window is disabled by either setting a bit in the
2719  * CPU BAR Enable reg or clearing a bit in the window's base reg.
2720  */
2721 static void __init
2722 mv64360_disable_window_32bit(mv64x60_handle_t *bh, u32 window)
2723 {
2724         DBG("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
2725                 window, mv64360_32bit_windows[window].base_reg,
2726                 mv64360_32bit_windows[window].size_reg);
2727
2728         if ((mv64360_32bit_windows[window].base_reg != 0) &&
2729                 (mv64360_32bit_windows[window].size_reg != 0)) {
2730
2731                 if (mv64360_32bit_windows[window].extra & 0x80000000) {
2732                         mv64x60_clr_bits(bh,
2733                                 mv64360_32bit_windows[window].base_reg,
2734                                 (1 << (mv64360_32bit_windows[window].extra &
2735                                                                         0xff)));
2736                 }
2737                 else {
2738                         mv64x60_set_bits(bh, MV64360_CPU_BAR_ENABLE,
2739                                 (1 << mv64360_32bit_windows[window].extra));
2740                 }
2741         }
2742
2743         return;
2744 }
2745
2746 /*
2747  * mv64360_enable_window_64bit()
2748  *
2749  * On the MV64360, a 64-bit window is enabled by setting a bit in the window's 
2750  * base reg.
2751  */
2752 static void __init
2753 mv64360_enable_window_64bit(mv64x60_handle_t *bh, u32 window)
2754 {
2755         DBG("enable 64bit window: %d\n", window);
2756
2757         /* For 64360, 'extra' field holds bit that enables the window */
2758         if ((mv64360_64bit_windows[window].base_lo_reg!= 0) &&
2759                 (mv64360_64bit_windows[window].size_reg != 0)) {
2760
2761                 if (mv64360_64bit_windows[window].extra & 0x80000000) {
2762                         mv64x60_set_bits(bh,
2763                                 mv64360_64bit_windows[window].base_lo_reg,
2764                                 (1 << (mv64360_64bit_windows[window].extra &
2765                                                                         0xff)));
2766                 } /* Should be no 'else' ones */
2767         }
2768
2769         return;
2770 }
2771
2772 /*
2773  * mv64360_disable_window_64bit()
2774  *
2775  * On a MV64360, a 64-bit window is disabled by clearing a bit in the window's
2776  * base reg.
2777  */
2778 static void __init
2779 mv64360_disable_window_64bit(mv64x60_handle_t *bh, u32 window)
2780 {
2781         DBG("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
2782                 window, mv64360_64bit_windows[window].base_lo_reg,
2783                 mv64360_64bit_windows[window].size_reg);
2784
2785         if ((mv64360_64bit_windows[window].base_lo_reg != 0) &&
2786                 (mv64360_64bit_windows[window].size_reg != 0)) {
2787
2788                 if (mv64360_64bit_windows[window].extra & 0x80000000) {
2789                         mv64x60_clr_bits(bh,
2790                                 mv64360_64bit_windows[window].base_lo_reg,
2791                                 (1 << (mv64360_64bit_windows[window].extra &
2792                                                                         0xff)));
2793                 } /* Should be no 'else' ones */
2794         }
2795
2796         return;
2797 }
2798
2799 /*
2800  * mv64360_disable_all_windows()
2801  *
2802  * The MV64360 has a few windows that aren't represented in the table of
2803  * windows at the top of this file.  This routine turns all of them off
2804  * except for the memory controller windows, of course.
2805  */
2806 static void __init
2807 mv64360_disable_all_windows(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
2808 {
2809         u32     i;
2810
2811         /* Disable 32bit windows (don't disable cpu->mem windows) */
2812         for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) {
2813                 if (!(si->window_preserve_mask_32 & (1<<i)))
2814                         mv64360_disable_window_32bit(bh, i);
2815         }
2816
2817         /* Disable 64bit windows */
2818         for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++) {
2819                 if (!(si->window_preserve_mask_64 & (1<<i)))
2820                         mv64360_disable_window_64bit(bh, i);
2821         }
2822
2823         /* Turn off PCI->MEM access cntl wins not in mv64360_64bit_windows[] */
2824         mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0);
2825         mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0);
2826         mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0);
2827         mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0);
2828
2829         /* Disable all PCI-><whatever> windows */
2830         mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x0000f9ff);
2831         mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x0000f9ff);
2832
2833         return;
2834 }
2835
2836 /*
2837  * mv64360_chip_specific_init()
2838  *
2839  * No errata work arounds for the MV64360 implemented at this point.
2840  */
2841 static void
2842 mv64360_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
2843 {
2844         struct ocp_device       *dev;
2845         mv64x60_ocp_mpsc_data_t *mpsc_dp;
2846
2847         if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 0))
2848                                                                 != NULL) {
2849                 mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions;
2850                 mpsc_dp->brg_can_tune = 1;
2851         }
2852
2853         if ((dev = ocp_find_device(OCP_VENDOR_MARVELL, OCP_FUNC_MPSC, 1))
2854                                                                 != NULL) {
2855                 mpsc_dp = (mv64x60_ocp_mpsc_data_t *)dev->def->additions;
2856                 mpsc_dp->brg_can_tune = 1;
2857         }
2858
2859         return;
2860 }
2861
2862 /*
2863  * mv64460_chip_specific_init()
2864  *
2865  * No errata work arounds for the MV64460 implemented at this point.
2866  */
2867 static void
2868 mv64460_chip_specific_init(mv64x60_handle_t *bh, mv64x60_setup_info_t *si)
2869 {
2870         mv64360_chip_specific_init(bh, si); /* XXXX check errata */
2871         return;
2872 }