Merge with /home/tur/git/u-boot#motionpro
[platform/kernel/u-boot.git] / board / mpc7448hpc2 / tsi108_init.c
1 /*****************************************************************************
2  * (C) Copyright 2003;  Tundra Semiconductor Corp.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307 USA
18  *****************************************************************************/
19
20 /*----------------------------------------------------------------------------
21  * FILENAME: tsi108_init.c
22  *
23  * Originator: Alex Bounine
24  *
25  * DESCRIPTION:
26  * Initialization code for the Tundra Tsi108 bridge chip
27  *---------------------------------------------------------------------------*/
28
29 #include <common.h>
30 #include <74xx_7xx.h>
31 #include <config.h>
32 #include <version.h>
33 #include <asm/processor.h>
34 #include <tsi108.h>
35
36 extern void mpicInit (int verbose);
37
38 /*
39  * Configuration Options
40  */
41
42 typedef struct {
43         ulong upper;
44         ulong lower;
45 } PB2OCN_LUT_ENTRY;
46
47 PB2OCN_LUT_ENTRY pb2ocn_lut1[32] = {
48         /* 0 - 7 */
49         {0x00000000, 0x00000201}, /* PBA=0xE000_0000 -> PCI/X (Byte-Swap) */
50         {0x00000000, 0x00000201}, /* PBA=0xE100_0000 -> PCI/X (Byte-Swap) */
51         {0x00000000, 0x00000201}, /* PBA=0xE200_0000 -> PCI/X (Byte-Swap) */
52         {0x00000000, 0x00000201}, /* PBA=0xE300_0000 -> PCI/X (Byte-Swap) */
53         {0x00000000, 0x00000201}, /* PBA=0xE400_0000 -> PCI/X (Byte-Swap) */
54         {0x00000000, 0x00000201}, /* PBA=0xE500_0000 -> PCI/X (Byte-Swap) */
55         {0x00000000, 0x00000201}, /* PBA=0xE600_0000 -> PCI/X (Byte-Swap) */
56         {0x00000000, 0x00000201}, /* PBA=0xE700_0000 -> PCI/X (Byte-Swap) */
57
58         /* 8 - 15 */
59         {0x00000000, 0x00000201}, /* PBA=0xE800_0000 -> PCI/X (Byte-Swap) */
60         {0x00000000, 0x00000201}, /* PBA=0xE900_0000 -> PCI/X (Byte-Swap) */
61         {0x00000000, 0x00000201}, /* PBA=0xEA00_0000 -> PCI/X (Byte-Swap) */
62         {0x00000000, 0x00000201}, /* PBA=0xEB00_0000 -> PCI/X (Byte-Swap) */
63         {0x00000000, 0x00000201}, /* PBA=0xEC00_0000 -> PCI/X (Byte-Swap) */
64         {0x00000000, 0x00000201}, /* PBA=0xED00_0000 -> PCI/X (Byte-Swap) */
65         {0x00000000, 0x00000201}, /* PBA=0xEE00_0000 -> PCI/X (Byte-Swap) */
66         {0x00000000, 0x00000201}, /* PBA=0xEF00_0000 -> PCI/X (Byte-Swap) */
67
68         /* 16 - 23 */
69         {0x00000000, 0x00000201}, /* PBA=0xF000_0000 -> PCI/X (Byte-Swap) */
70         {0x00000000, 0x00000201}, /* PBA=0xF100_0000 -> PCI/X (Byte-Swap) */
71         {0x00000000, 0x00000201}, /* PBA=0xF200_0000 -> PCI/X (Byte-Swap) */
72         {0x00000000, 0x00000201}, /* PBA=0xF300_0000 -> PCI/X (Byte-Swap) */
73         {0x00000000, 0x00000201}, /* PBA=0xF400_0000 -> PCI/X (Byte-Swap) */
74         {0x00000000, 0x00000201}, /* PBA=0xF500_0000 -> PCI/X (Byte-Swap) */
75         {0x00000000, 0x00000201}, /* PBA=0xF600_0000 -> PCI/X (Byte-Swap) */
76         {0x00000000, 0x00000201}, /* PBA=0xF700_0000 -> PCI/X (Byte-Swap) */
77         /* 24 - 31 */
78         {0x00000000, 0x00000201}, /* PBA=0xF800_0000 -> PCI/X (Byte-Swap) */
79         {0x00000000, 0x00000201}, /* PBA=0xF900_0000 -> PCI/X (Byte-Swap) */
80         {0x00000000, 0x00000201}, /* PBA=0xFA00_0000 -> PCI/X  PCI I/O (Byte-Swap) */
81         {0x00000000, 0x00000201}, /* PBA=0xFB00_0000 -> PCI/X  PCI Config (Byte-Swap) */
82
83         {0x00000000, 0x02000240}, /* PBA=0xFC00_0000 -> HLP */
84         {0x00000000, 0x01000240}, /* PBA=0xFD00_0000 -> HLP */
85         {0x00000000, 0x03000240}, /* PBA=0xFE00_0000 -> HLP */
86         {0x00000000, 0x00000240}  /* PBA=0xFF00_0000 -> HLP : (Translation Enabled + Byte-Swap)*/
87 };
88
89 #ifdef CFG_CLK_SPREAD
90 typedef struct {
91         ulong ctrl0;
92         ulong ctrl1;
93 } PLL_CTRL_SET;
94
95 /*
96  * Clock Generator SPLL0 initialization values
97  * PLL0 configuration table for various PB_CLKO freq.
98  * Uses pre-calculated values for Fs = 30 kHz, D = 0.5%
99  * Fout depends on required PB_CLKO. Based on Fref = 33 MHz
100  */
101
102 static PLL_CTRL_SET pll0_config[8] = {
103         {0x00000000, 0x00000000},       /* 0: bypass */
104         {0x00000000, 0x00000000},       /* 1: reserved */
105         {0x00430044, 0x00000043},       /* 2: CG_PB_CLKO = 183 MHz */
106         {0x005c0044, 0x00000039},       /* 3: CG_PB_CLKO = 100 MHz */
107         {0x005c0044, 0x00000039},       /* 4: CG_PB_CLKO = 133 MHz */
108         {0x004a0044, 0x00000040},       /* 5: CG_PB_CLKO = 167 MHz */
109         {0x005c0044, 0x00000039},       /* 6: CG_PB_CLKO = 200 MHz */
110         {0x004f0044, 0x0000003e}        /* 7: CG_PB_CLKO = 233 MHz */
111 };
112 #endif  /* CFG_CLK_SPREAD */
113
114 /*
115  * Prosessor Bus Clock (in MHz) defined by CG_PB_SELECT
116  * (based on recommended Tsi108 reference clock 33MHz)
117  */
118 static int pb_clk_sel[8] = { 0, 0, 183, 100, 133, 167, 200, 233 };
119
120 /*
121  * get_board_bus_clk ()
122  *
123  * returns the bus clock in Hz.
124  */
125 unsigned long get_board_bus_clk (void)
126 {
127         ulong i;
128
129         /* Detect PB clock freq. */
130         i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
131         i = (i >> 16) & 0x07;   /* Get PB PLL multiplier */
132
133         return pb_clk_sel[i] * 1000000;
134 }
135
136 /*
137  * board_early_init_f ()
138  *
139  * board-specific initialization executed from flash
140  */
141
142 int board_early_init_f (void)
143 {
144         DECLARE_GLOBAL_DATA_PTR;
145         ulong i;
146
147         gd->mem_clk = 0;
148         i = in32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET +
149                         CG_PWRUP_STATUS);
150         i = (i >> 20) & 0x07;   /* Get GD PLL multiplier */
151         switch (i) {
152         case 0: /* external clock */
153                 printf ("Using external clock\n");
154                 break;
155         case 1: /* system clock */
156                 gd->mem_clk = gd->bus_clk;
157                 break;
158         case 4: /* 133 MHz */
159         case 5: /* 166 MHz */
160         case 6: /* 200 MHz */
161                 gd->mem_clk = pb_clk_sel[i] * 1000000;
162                 break;
163         default:
164                 printf ("Invalid DDR2 clock setting\n");
165                 return -1;
166         }
167         printf ("BUS: %d MHz\n", get_board_bus_clk() / 1000000);
168         printf ("MEM: %d MHz\n", gd->mem_clk / 1000000);
169         return 0;
170 }
171
172 /*
173  * board_early_init_r() - Tsi108 initialization function executed right after
174  * relocation. Contains code that cannot be executed from flash.
175  */
176
177 int board_early_init_r (void)
178 {
179         ulong temp, i;
180         ulong reg_val;
181         volatile ulong *reg_ptr;
182
183         reg_ptr =
184                 (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + 0x900);
185
186         for (i = 0; i < 32; i++) {
187                 *reg_ptr++ = 0x00000201;        /* SWAP ENABLED */
188                 *reg_ptr++ = 0x00;
189         }
190
191         __asm__ __volatile__ ("eieio");
192         __asm__ __volatile__ ("sync");
193
194         /* Setup PB_OCN_BAR2: size 256B + ENable @ 0x0_80000000 */
195
196         out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2,
197                 0x80000001);
198         __asm__ __volatile__ ("sync");
199
200         /* Make sure that OCN_BAR2 decoder is set (to allow following immediate
201          * read from SDRAM)
202          */
203
204         temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2);
205         __asm__ __volatile__ ("sync");
206
207         /*
208          * Remap PB_OCN_BAR1 to accomodate PCI-bus aperture and EPROM into the
209          * processor bus address space. Immediately after reset LUT and address
210          * translation are disabled for this BAR. Now we have to initialize LUT
211          * and switch from the BOOT mode to the normal operation mode.
212          *
213          * The aperture defined by PB_OCN_BAR1 startes at address 0xE0000000
214          * and covers 512MB of address space. To allow larger aperture we also
215          * have to relocate register window of Tsi108
216          *
217          * Initialize LUT (32-entries) prior switching PB_OCN_BAR1 from BOOT
218          * mode.
219          *
220          * initialize pointer to LUT associated with PB_OCN_BAR1
221          */
222         reg_ptr =
223                 (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + 0x800);
224
225         for (i = 0; i < 32; i++) {
226                 *reg_ptr++ = pb2ocn_lut1[i].lower;
227                 *reg_ptr++ = pb2ocn_lut1[i].upper;
228         }
229
230         __asm__ __volatile__ ("sync");
231
232         /* Base addresses for CS0, CS1, CS2, CS3 */
233
234         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_ADDR,
235                 0x00000000);
236         __asm__ __volatile__ ("sync");
237
238         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_ADDR,
239                 0x00100000);
240         __asm__ __volatile__ ("sync");
241
242         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_ADDR,
243                 0x00200000);
244         __asm__ __volatile__ ("sync");
245
246         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_ADDR,
247                 0x00300000);
248         __asm__ __volatile__ ("sync");
249
250         /* Masks for HLP banks */
251
252         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_MASK,
253                 0xFFF00000);
254         __asm__ __volatile__ ("sync");
255
256         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_MASK,
257                 0xFFF00000);
258         __asm__ __volatile__ ("sync");
259
260         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_MASK,
261                 0xFFF00000);
262         __asm__ __volatile__ ("sync");
263
264         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_MASK,
265                 0xFFF00000);
266         __asm__ __volatile__ ("sync");
267
268         /* Set CTRL0 values for banks */
269
270         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL0,
271                 0x7FFC44C2);
272         __asm__ __volatile__ ("sync");
273
274         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL0,
275                 0x7FFC44C0);
276         __asm__ __volatile__ ("sync");
277
278         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL0,
279                 0x7FFC44C0);
280         __asm__ __volatile__ ("sync");
281
282         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_CTRL0,
283                 0x7FFC44C2);
284         __asm__ __volatile__ ("sync");
285
286         /* Set banks to latched mode, enabled, and other default settings */
287
288         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL1,
289                 0x7C0F2000);
290         __asm__ __volatile__ ("sync");
291
292         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL1,
293                 0x7C0F2000);
294         __asm__ __volatile__ ("sync");
295
296         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL1,
297                 0x7C0F2000);
298         __asm__ __volatile__ ("sync");
299
300         out32 (CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_CTRL1,
301                 0x7C0F2000);
302         __asm__ __volatile__ ("sync");
303
304         /*
305          * Set new value for PB_OCN_BAR1: switch from BOOT to LUT mode.
306          * value for PB_OCN_BAR1: (BA-0xE000_0000 + size 512MB + ENable)
307          */
308         out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1,
309                 0xE0000011);
310         __asm__ __volatile__ ("sync");
311
312         /* Make sure that OCN_BAR2 decoder is set (to allow following
313          * immediate read from SDRAM)
314          */
315
316         temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1);
317         __asm__ __volatile__ ("sync");
318
319         /*
320          * SRI: At this point we have enabled the HLP banks. That means we can
321          * now read from the NVRAM and initialize the environment variables.
322          * We will over-ride the env_init called in board_init_f
323          * This is really a work-around because, the HLP bank 1
324          * where NVRAM resides is not visible during board_init_f
325          * (lib_ppc/board.c)
326          * Alternatively, we could use the I2C EEPROM at start-up to configure
327          * and enable all HLP banks and not just HLP 0 as is being done for
328          * Taiga Rev. 2.
329          */
330
331         env_init ();
332
333 #ifndef DISABLE_PBM
334
335         /*
336          * For IBM processors we have to set Address-Only commands generated
337          * by PBM that are different from ones set after reset.
338          */
339
340         temp = get_cpu_type ();
341
342         if ((CPU_750FX == temp) || (CPU_750GX == temp))
343                 out32 (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_MCMD,
344                         0x00009955);
345 #endif  /* DISABLE_PBM */
346
347 #ifdef CONFIG_PCI
348         /*
349          * Initialize PCI/X block
350          */
351
352         /* Map PCI/X Configuration Space (16MB @ 0x0_FE000000) */
353         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
354                 PCI_PFAB_BAR0_UPPER, 0);
355         __asm__ __volatile__ ("sync");
356
357         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_BAR0,
358                 0xFB000001);
359         __asm__ __volatile__ ("sync");
360
361         /* Set Bus Number for the attached PCI/X bus (we will use 0 for NB) */
362
363         temp =  in32(CFG_TSI108_CSR_BASE +
364                 TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT);
365
366         temp &= ~0xFF00;        /* Clear the BUS_NUM field */
367
368         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT,
369                 temp);
370
371         /* Map PCI/X IO Space (64KB @ 0x0_FD000000) takes one 16MB LUT entry */
372
373         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO_UPPER,
374                 0);
375         __asm__ __volatile__ ("sync");
376
377         /* This register is on the PCI side to interpret the address it receives
378          * and maps it as a IO address.
379          */
380
381         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO,
382                 0xFA000001);
383         __asm__ __volatile__ ("sync");
384
385         /*
386          * Map PCI/X Memory Space
387          *
388          * Transactions directed from OCM to PCI Memory Space are directed
389          * from PB to PCI
390          * unchanged (as defined by PB_OCN_BAR1,2 and LUT settings).
391          * If address remapping is required the corresponding PCI_PFAB_MEM32
392          * and PCI_PFAB_PFMx register groups have to be configured.
393          *
394          * Map the path from the PCI/X bus into the system memory
395          *
396          * The memory mapped window assotiated with PCI P2O_BAR2 provides
397          * access to the system memory without address remapping.
398          * All system memory is opened for accesses initiated by PCI/X bus
399          * masters.
400          *
401          * Initialize LUT associated with PCI P2O_BAR2
402          *
403          * set pointer to LUT associated with PCI P2O_BAR2
404          */
405
406         reg_ptr =
407                 (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + 0x500);
408
409 #ifdef DISABLE_PBM
410
411         /* In case when PBM is disabled (no HW supported cache snoopng on PB)
412          * P2O_BAR2 is directly mapped into the system memory without address
413          * translation.
414          */
415
416         reg_val = 0x00000004;   /* SDRAM port + NO Addr_Translation */
417
418         for (i = 0; i < 32; i++) {
419                 *reg_ptr++ = reg_val;   /* P2O_BAR2_LUTx */
420                 *reg_ptr++ = 0;         /* P2O_BAR2_LUT_UPPERx */
421         }
422
423         /* value for PCI BAR2 (size = 512MB, Enabled, No Addr. Translation) */
424         reg_val = 0x00007500;
425 #else
426
427         reg_val = 0x00000002;   /* Destination port = PBM */
428
429         for (i = 0; i < 32; i++) {
430                 *reg_ptr++ = reg_val;   /* P2O_BAR2_LUTx */
431 /* P2O_BAR2_LUT_UPPERx : Set data swapping mode for PBM (byte swapping) */
432                 *reg_ptr++ = 0x40000000;
433 /* offset = 16MB, address translation is enabled to allow byte swapping */
434                 reg_val += 0x01000000;
435         }
436
437 /* value for PCI BAR2 (size = 512MB, Enabled, Address Translation Enabled) */
438         reg_val = 0x00007100;
439 #endif
440
441         __asm__ __volatile__ ("eieio");
442         __asm__ __volatile__ ("sync");
443
444         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_PAGE_SIZES,
445                 reg_val);
446         __asm__ __volatile__ ("sync");
447
448         /* Set 64-bit PCI bus address for system memory
449          * ( 0 is the best choice for easy mapping)
450          */
451
452         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2,
453                 0x00000000);
454         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2_UPPER,
455                 0x00000000);
456         __asm__ __volatile__ ("sync");
457
458 #ifndef DISABLE_PBM
459         /*
460          *  The memory mapped window assotiated with PCI P2O_BAR3 provides
461          *  access to the system memory using SDRAM OCN port and address
462          *  translation. This is alternative way to access SDRAM from PCI
463          *  required for Tsi108 emulation testing.
464          *  All system memory is opened for accesses initiated by
465          *  PCI/X bus masters.
466          *
467          *  Initialize LUT associated with PCI P2O_BAR3
468          *
469          *  set pointer to LUT associated with PCI P2O_BAR3
470          */
471         reg_ptr =
472                 (ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + 0x600);
473
474         reg_val = 0x00000004;   /* Destination port = SDC */
475
476         for (i = 0; i < 32; i++) {
477                 *reg_ptr++ = reg_val;   /* P2O_BAR3_LUTx */
478
479 /* P2O_BAR3_LUT_UPPERx : Set data swapping mode for PBM (byte swapping) */
480                 *reg_ptr++ = 0;
481
482 /* offset = 16MB, address translation is enabled to allow byte swapping */
483                 reg_val += 0x01000000;
484         }
485
486         __asm__ __volatile__ ("eieio");
487         __asm__ __volatile__ ("sync");
488
489         /* Configure PCI P2O_BAR3 (size = 512MB, Enabled) */
490
491         reg_val =
492                 in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
493                  PCI_P2O_PAGE_SIZES);
494         reg_val &= ~0x00FF;
495         reg_val |= 0x0071;
496         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_PAGE_SIZES,
497                 reg_val);
498         __asm__ __volatile__ ("sync");
499
500         /* Set 64-bit base PCI bus address for window (0x20000000) */
501
502         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3_UPPER,
503                 0x00000000);
504         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3,
505                 0x20000000);
506         __asm__ __volatile__ ("sync");
507
508 #endif  /* !DISABLE_PBM */
509
510 #ifdef ENABLE_PCI_CSR_BAR
511         /* open if required access to Tsi108 CSRs from the PCI/X bus */
512         /* enable BAR0 on the PCI/X bus */
513         reg_val = in32(CFG_TSI108_CSR_BASE +
514                 TSI108_PCI_REG_OFFSET + PCI_MISC_CSR);
515         reg_val |= 0x02;
516         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_MISC_CSR,
517                 reg_val);
518         __asm__ __volatile__ ("sync");
519
520         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0_UPPER,
521                 0x00000000);
522         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0,
523                 CFG_TSI108_CSR_BASE);
524         __asm__ __volatile__ ("sync");
525
526 #endif
527
528         /*
529          * Finally enable PCI/X Bus Master and Memory Space access
530          */
531
532         reg_val = in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR);
533         reg_val |= 0x06;
534         out32 (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR, reg_val);
535         __asm__ __volatile__ ("sync");
536
537 #endif  /* CONFIG_PCI */
538
539         /*
540          * Initialize MPIC outputs (interrupt pins):
541          * Interrupt routing on the Grendel Emul. Board:
542          * PB_INT[0] -> INT (CPU0)
543          * PB_INT[1] -> INT (CPU1)
544          * PB_INT[2] -> MCP (CPU0)
545          * PB_INT[3] -> MCP (CPU1)
546          * Set interrupt controller outputs as Level_Sensitive/Active_Low
547          */
548         out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(0), 0x02);
549         out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(1), 0x02);
550         out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(2), 0x02);
551         out32 (CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(3), 0x02);
552         __asm__ __volatile__ ("sync");
553
554         /*
555          * Ensure that Machine Check exception is enabled
556          * We need it to support PCI Bus probing (configuration reads)
557          */
558
559         reg_val = mfmsr ();
560         mtmsr(reg_val | MSR_ME);
561
562         return 0;
563 }
564
565 /*
566  * Needed to print out L2 cache info
567  * used in the misc_init_r function
568  */
569
570 unsigned long get_l2cr (void)
571 {
572         unsigned long l2controlreg;
573         asm volatile ("mfspr %0, 1017":"=r" (l2controlreg):);
574         return l2controlreg;
575 }
576
577 /*
578  * misc_init_r()
579  *
580  * various things to do after relocation
581  *
582  */
583
584 int misc_init_r (void)
585 {
586         DECLARE_GLOBAL_DATA_PTR;
587 #ifdef CFG_CLK_SPREAD   /* Initialize Spread-Spectrum Clock generation */
588         ulong i;
589
590         /* Ensure that Spread-Spectrum is disabled */
591         out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, 0);
592         out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, 0);
593
594         /* Initialize PLL1: CG_PCI_CLK , internal OCN_CLK
595          * Uses pre-calculated value for Fout = 800 MHz, Fs = 30 kHz, D = 0.5%
596          */
597
598         out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0,
599                 0x002e0044);    /* D = 0.25% */
600         out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL1,
601                 0x00000039);    /* BWADJ */
602
603         /* Initialize PLL0: CG_PB_CLKO  */
604         /* Detect PB clock freq. */
605         i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
606         i = (i >> 16) & 0x07;   /* Get PB PLL multiplier */
607
608         out32 (CFG_TSI108_CSR_BASE +
609                 TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, pll0_config[i].ctrl0);
610         out32 (CFG_TSI108_CSR_BASE +
611                 TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL1, pll0_config[i].ctrl1);
612
613         /* Wait and set SSEN for both PLL0 and 1 */
614         udelay (1000);
615         out32 (CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0,
616                 0x802e0044);    /* D=0.25% */
617         out32 (CFG_TSI108_CSR_BASE +
618                 TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0,
619                 0x80000000 | pll0_config[i].ctrl0);
620 #endif  /* CFG_CLK_SPREAD */
621
622 #ifdef CFG_L2
623         l2cache_enable ();
624 #endif
625         printf ("BUS:   %d MHz\n", gd->bus_clk / 1000000);
626         printf ("MEM:   %d MHz\n", gd->mem_clk / 1000000);
627
628         /*
629          * All the information needed to print the cache details is avaiblable
630          * at this point i.e. above call to l2cache_enable is the very last
631          * thing done with regards to enabling diabling the cache.
632          * So this seems like a good place to print all this information
633          */
634
635         printf ("CACHE: ");
636         switch (get_cpu_type()) {
637         case CPU_7447A:
638                 printf ("L1 Instruction cache - 32KB 8-way");
639                 (get_hid0 () & (1 << 15)) ? printf (" ENABLED\n") :
640                         printf (" DISABLED\n");
641                 printf ("L1 Data cache - 32KB 8-way");
642                 (get_hid0 () & (1 << 14)) ? printf (" ENABLED\n") :
643                         printf (" DISABLED\n");
644                 printf ("Unified L2 cache - 512KB 8-way");
645                 (get_l2cr () & (1 << 31)) ? printf (" ENABLED\n") :
646                         printf (" DISABLED\n");
647                 printf ("\n");
648                 break;
649
650         case CPU_7448:
651                 printf ("L1 Instruction cache - 32KB 8-way");
652                 (get_hid0 () & (1 << 15)) ? printf (" ENABLED\n") :
653                         printf (" DISABLED\n");
654                 printf ("L1 Data cache - 32KB 8-way");
655                 (get_hid0 () & (1 << 14)) ? printf (" ENABLED\n") :
656                         printf (" DISABLED\n");
657                 printf ("Unified L2 cache - 1MB 8-way");
658                 (get_l2cr () & (1 << 31)) ? printf (" ENABLED\n") :
659                         printf (" DISABLED\n");
660                 break;
661         default:
662                 break;
663         }
664         return 0;
665 }