]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/mpc8540ads/mpc8540ads.c
c97e8ba15e15bf7f3080a1c8e9ddd11c2095c3ec
[karo-tx-uboot.git] / board / mpc8540ads / mpc8540ads.c
1  /*
2  * Copyright 2004 Freescale Semiconductor.
3  * (C) Copyright 2002,2003, Motorola Inc.
4  * Xianghua Xiao, (X.Xiao@motorola.com)
5  *
6  * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27
28 #include <common.h>
29 #include <pci.h>
30 #include <asm/processor.h>
31 #include <asm/immap_85xx.h>
32 #include <spd.h>
33
34 #if defined(CONFIG_DDR_ECC)
35 extern void ddr_enable_ecc(unsigned int dram_size);
36 #endif
37
38 extern long int spd_sdram(void);
39
40 void local_bus_init(void);
41 void sdram_init(void);
42 long int fixed_sdram(void);
43
44
45 int board_early_init_f (void)
46 {
47 #if defined(CONFIG_PCI)
48     volatile immap_t *immr = (immap_t *)CFG_IMMR;
49     volatile ccsr_pcix_t *pci = &immr->im_pcix;
50
51     pci->peer &= 0xffffffdf; /* disable master abort */
52 #endif
53
54     return 0;
55 }
56
57 int checkboard (void)
58 {
59         puts("Board: ADS\n");
60
61 #ifdef CONFIG_PCI
62         printf("    PCI1: 32 bit, %d MHz (compiled)\n",
63                CONFIG_SYS_CLK_FREQ / 1000000);
64 #else
65         printf("    PCI1: disabled\n");
66 #endif
67
68         /*
69          * Initialize local bus.
70          */
71         local_bus_init();
72
73         return 0;
74 }
75
76
77 long int
78 initdram(int board_type)
79 {
80         long dram_size = 0;
81         extern long spd_sdram (void);
82         volatile immap_t *immap = (immap_t *)CFG_IMMR;
83
84         puts("Initializing\n");
85
86 #if defined(CONFIG_DDR_DLL)
87         {
88             volatile ccsr_gur_t *gur= &immap->im_gur;
89             uint temp_ddrdll = 0;
90
91             /*
92              * Work around to stabilize DDR DLL
93              */
94             temp_ddrdll = gur->ddrdllcr;
95             gur->ddrdllcr = ((temp_ddrdll & 0xff) << 16) | 0x80000000;
96             asm("sync;isync;msync");
97         }
98 #endif
99
100 #if defined(CONFIG_SPD_EEPROM)
101         dram_size = spd_sdram ();
102 #else
103         dram_size = fixed_sdram ();
104 #endif
105
106 #if defined(CONFIG_DDR_ECC)
107         /*
108          * Initialize and enable DDR ECC.
109          */
110         ddr_enable_ecc(dram_size);
111 #endif
112
113         /*
114          * Initialize SDRAM.
115          */
116         sdram_init();
117
118         puts("    DDR: ");
119         return dram_size;
120 }
121
122
123 /*
124  * Initialize Local Bus
125  */
126
127 void
128 local_bus_init(void)
129 {
130         volatile immap_t *immap = (immap_t *)CFG_IMMR;
131         volatile ccsr_gur_t *gur = &immap->im_gur;
132         volatile ccsr_lbc_t *lbc = &immap->im_lbc;
133
134         uint clkdiv;
135         uint lbc_hz;
136         sys_info_t sysinfo;
137
138         /*
139          * Errata LBC11.
140          * Fix Local Bus clock glitch when DLL is enabled.
141          *
142          * If localbus freq is < 66Mhz, DLL bypass mode must be used.
143          * If localbus freq is > 133Mhz, DLL can be safely enabled.
144          * Between 66 and 133, the DLL is enabled with an override workaround.
145          */
146
147         get_sys_info(&sysinfo);
148         clkdiv = lbc->lcrr & 0x0f;
149         lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv;
150
151         if (lbc_hz < 66) {
152                 lbc->lcrr = CFG_LBC_LCRR | 0x80000000;  /* DLL Bypass */
153
154         } else if (lbc_hz >= 133) {
155                 lbc->lcrr = CFG_LBC_LCRR & (~0x80000000); /* DLL Enabled */
156
157         } else {
158                 /*
159                  * On REV1 boards, need to change CLKDIV before enable DLL.
160                  * Default CLKDIV is 8, change it to 4 temporarily.
161                  */
162                 uint pvr = get_pvr();
163                 uint temp_lbcdll = 0;
164
165                 if (pvr == PVR_85xx_REV1) {
166                         /* FIXME: Justify the high bit here. */
167                         lbc->lcrr = 0x10000004;
168                 }
169
170                 lbc->lcrr = CFG_LBC_LCRR & (~0x80000000); /* DLL Enabled */
171                 udelay(200);
172
173                 /*
174                  * Sample LBC DLL ctrl reg, upshift it to set the
175                  * override bits.
176                  */
177                 temp_lbcdll = gur->lbcdllcr;
178                 gur->lbcdllcr = (((temp_lbcdll & 0xff) << 16) | 0x80000000);
179                 asm("sync;isync;msync");
180         }
181 }
182
183
184 /*
185  * Initialize SDRAM memory on the Local Bus.
186  */
187
188 void
189 sdram_init(void)
190 {
191         volatile immap_t *immap = (immap_t *)CFG_IMMR;
192         volatile ccsr_lbc_t *lbc= &immap->im_lbc;
193         uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE;
194
195         puts("    SDRAM: ");
196         print_size (CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
197
198         /*
199          * Setup SDRAM Base and Option Registers
200          */
201         lbc->or2 = CFG_OR2_PRELIM;
202         lbc->br2 = CFG_BR2_PRELIM;
203         lbc->lbcr = CFG_LBC_LBCR;
204         asm("msync");
205
206         lbc->lsrt = CFG_LBC_LSRT;
207         lbc->mrtpr = CFG_LBC_MRTPR;
208         asm("sync");
209
210         /*
211          * Configure the SDRAM controller.
212          */
213         lbc->lsdmr = CFG_LBC_LSDMR_1;
214         asm("sync");
215         *sdram_addr = 0xff;
216         ppcDcbf((unsigned long) sdram_addr);
217         udelay(100);
218
219         lbc->lsdmr = CFG_LBC_LSDMR_2;
220         asm("sync");
221         *sdram_addr = 0xff;
222         ppcDcbf((unsigned long) sdram_addr);
223         udelay(100);
224
225         lbc->lsdmr = CFG_LBC_LSDMR_3;
226         asm("sync");
227         *sdram_addr = 0xff;
228         ppcDcbf((unsigned long) sdram_addr);
229         udelay(100);
230
231         lbc->lsdmr = CFG_LBC_LSDMR_4;
232         asm("sync");
233         *sdram_addr = 0xff;
234         ppcDcbf((unsigned long) sdram_addr);
235         udelay(100);
236
237         lbc->lsdmr = CFG_LBC_LSDMR_5;
238         asm("sync");
239         *sdram_addr = 0xff;
240         ppcDcbf((unsigned long) sdram_addr);
241         udelay(100);
242 }
243
244
245 #if defined(CFG_DRAM_TEST)
246 int testdram (void)
247 {
248         uint *pstart = (uint *) CFG_MEMTEST_START;
249         uint *pend = (uint *) CFG_MEMTEST_END;
250         uint *p;
251
252         printf("SDRAM test phase 1:\n");
253         for (p = pstart; p < pend; p++)
254                 *p = 0xaaaaaaaa;
255
256         for (p = pstart; p < pend; p++) {
257                 if (*p != 0xaaaaaaaa) {
258                         printf ("SDRAM test fails at: %08x\n", (uint) p);
259                         return 1;
260                 }
261         }
262
263         printf("SDRAM test phase 2:\n");
264         for (p = pstart; p < pend; p++)
265                 *p = 0x55555555;
266
267         for (p = pstart; p < pend; p++) {
268                 if (*p != 0x55555555) {
269                         printf ("SDRAM test fails at: %08x\n", (uint) p);
270                         return 1;
271                 }
272         }
273
274         printf("SDRAM test passed.\n");
275         return 0;
276 }
277 #endif
278
279
280 #if !defined(CONFIG_SPD_EEPROM)
281 /*************************************************************************
282  *  fixed sdram init -- doesn't use serial presence detect.
283  ************************************************************************/
284 long int fixed_sdram (void)
285 {
286   #ifndef CFG_RAMBOOT
287         volatile immap_t *immap = (immap_t *)CFG_IMMR;
288         volatile ccsr_ddr_t *ddr= &immap->im_ddr;
289
290         ddr->cs0_bnds = CFG_DDR_CS0_BNDS;
291         ddr->cs0_config = CFG_DDR_CS0_CONFIG;
292         ddr->timing_cfg_1 = CFG_DDR_TIMING_1;
293         ddr->timing_cfg_2 = CFG_DDR_TIMING_2;
294         ddr->sdram_mode = CFG_DDR_MODE;
295         ddr->sdram_interval = CFG_DDR_INTERVAL;
296     #if defined (CONFIG_DDR_ECC)
297         ddr->err_disable = 0x0000000D;
298         ddr->err_sbe = 0x00ff0000;
299     #endif
300         asm("sync;isync;msync");
301         udelay(500);
302     #if defined (CONFIG_DDR_ECC)
303         /* Enable ECC checking */
304         ddr->sdram_cfg = (CFG_DDR_CONTROL | 0x20000000);
305     #else
306         ddr->sdram_cfg = CFG_DDR_CONTROL;
307     #endif
308         asm("sync; isync; msync");
309         udelay(500);
310   #endif
311         return CFG_SDRAM_SIZE * 1024 * 1024;
312 }
313 #endif  /* !defined(CONFIG_SPD_EEPROM) */
314
315
316 #if defined(CONFIG_PCI)
317 /*
318  * Initialize PCI Devices, report devices found.
319  */
320
321 #ifndef CONFIG_PCI_PNP
322 static struct pci_config_table pci_mpc85xxads_config_table[] = {
323     { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
324       PCI_IDSEL_NUMBER, PCI_ANY_ID,
325       pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
326                                    PCI_ENET0_MEMADDR,
327                                    PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
328       } },
329     { }
330 };
331 #endif
332
333
334 static struct pci_controller hose = {
335 #ifndef CONFIG_PCI_PNP
336         config_table: pci_mpc85xxads_config_table,
337 #endif
338 };
339
340 #endif  /* CONFIG_PCI */
341
342
343 void
344 pci_init_board(void)
345 {
346 #ifdef CONFIG_PCI
347         extern void pci_mpc85xx_init(struct pci_controller *hose);
348
349         pci_mpc85xx_init(&hose);
350 #endif /* CONFIG_PCI */
351 }