888417f864baba3cdb94b724aa6363cc33168ac6
[platform/kernel/u-boot.git] / cpu / mpc85xx / cpu_init.c
1 /*
2  * Copyright 2007 Freescale Semiconductor.
3  *
4  * (C) Copyright 2003 Motorola Inc.
5  * Modified by Xianghua Xiao, X.Xiao@motorola.com
6  *
7  * (C) Copyright 2000
8  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
9  *
10  * See file CREDITS for list of people who contributed to this
11  * project.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License as
15  * published by the Free Software Foundation; either version 2 of
16  * the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26  * MA 02111-1307 USA
27  */
28
29 #include <common.h>
30 #include <watchdog.h>
31 #include <asm/processor.h>
32 #include <ioports.h>
33 #include <asm/io.h>
34
35 DECLARE_GLOBAL_DATA_PTR;
36
37
38 #ifdef CONFIG_CPM2
39 static void config_8560_ioports (volatile immap_t * immr)
40 {
41         int portnum;
42
43         for (portnum = 0; portnum < 4; portnum++) {
44                 uint pmsk = 0,
45                      ppar = 0,
46                      psor = 0,
47                      pdir = 0,
48                      podr = 0,
49                      pdat = 0;
50                 iop_conf_t *iopc = (iop_conf_t *) & iop_conf_tab[portnum][0];
51                 iop_conf_t *eiopc = iopc + 32;
52                 uint msk = 1;
53
54                 /*
55                  * NOTE:
56                  * index 0 refers to pin 31,
57                  * index 31 refers to pin 0
58                  */
59                 while (iopc < eiopc) {
60                         if (iopc->conf) {
61                                 pmsk |= msk;
62                                 if (iopc->ppar)
63                                         ppar |= msk;
64                                 if (iopc->psor)
65                                         psor |= msk;
66                                 if (iopc->pdir)
67                                         pdir |= msk;
68                                 if (iopc->podr)
69                                         podr |= msk;
70                                 if (iopc->pdat)
71                                         pdat |= msk;
72                         }
73
74                         msk <<= 1;
75                         iopc++;
76                 }
77
78                 if (pmsk != 0) {
79                         volatile ioport_t *iop = ioport_addr (immr, portnum);
80                         uint tpmsk = ~pmsk;
81
82                         /*
83                          * the (somewhat confused) paragraph at the
84                          * bottom of page 35-5 warns that there might
85                          * be "unknown behaviour" when programming
86                          * PSORx and PDIRx, if PPARx = 1, so I
87                          * decided this meant I had to disable the
88                          * dedicated function first, and enable it
89                          * last.
90                          */
91                         iop->ppar &= tpmsk;
92                         iop->psor = (iop->psor & tpmsk) | psor;
93                         iop->podr = (iop->podr & tpmsk) | podr;
94                         iop->pdat = (iop->pdat & tpmsk) | pdat;
95                         iop->pdir = (iop->pdir & tpmsk) | pdir;
96                         iop->ppar |= ppar;
97                 }
98         }
99 }
100 #endif
101
102 /*
103  * Breathe some life into the CPU...
104  *
105  * Set up the memory map
106  * initialize a bunch of registers
107  */
108
109 void cpu_init_f (void)
110 {
111         volatile immap_t    *immap = (immap_t *)CFG_IMMR;
112         volatile ccsr_lbc_t *memctl = &immap->im_lbc;
113         extern void m8560_cpm_reset (void);
114
115         /* Pointer is writable since we allocated a register for it */
116         gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
117
118         /* Clear initial global data */
119         memset ((void *) gd, 0, sizeof (gd_t));
120
121
122 #ifdef CONFIG_CPM2
123         config_8560_ioports(immap);
124 #endif
125
126         /* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
127          * addresses - these have to be modified later when FLASH size
128          * has been determined
129          */
130 #if defined(CFG_OR0_REMAP)
131         memctl->or0 = CFG_OR0_REMAP;
132 #endif
133 #if defined(CFG_OR1_REMAP)
134         memctl->or1 = CFG_OR1_REMAP;
135 #endif
136
137         /* now restrict to preliminary range */
138         /* if cs1 is already set via debugger, leave cs0/cs1 alone */
139         if (! memctl->br1 & 1) {
140 #if defined(CFG_BR0_PRELIM) && defined(CFG_OR0_PRELIM)
141                 memctl->br0 = CFG_BR0_PRELIM;
142                 memctl->or0 = CFG_OR0_PRELIM;
143 #endif
144
145 #if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM)
146                 memctl->or1 = CFG_OR1_PRELIM;
147                 memctl->br1 = CFG_BR1_PRELIM;
148 #endif
149         }
150
151 #if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
152         memctl->or2 = CFG_OR2_PRELIM;
153         memctl->br2 = CFG_BR2_PRELIM;
154 #endif
155
156 #if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM)
157         memctl->or3 = CFG_OR3_PRELIM;
158         memctl->br3 = CFG_BR3_PRELIM;
159 #endif
160
161 #if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
162         memctl->or4 = CFG_OR4_PRELIM;
163         memctl->br4 = CFG_BR4_PRELIM;
164 #endif
165
166 #if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
167         memctl->or5 = CFG_OR5_PRELIM;
168         memctl->br5 = CFG_BR5_PRELIM;
169 #endif
170
171 #if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM)
172         memctl->or6 = CFG_OR6_PRELIM;
173         memctl->br6 = CFG_BR6_PRELIM;
174 #endif
175
176 #if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM)
177         memctl->or7 = CFG_OR7_PRELIM;
178         memctl->br7 = CFG_BR7_PRELIM;
179 #endif
180
181 #if defined(CONFIG_CPM2)
182         m8560_cpm_reset();
183 #endif
184 }
185
186
187 /*
188  * Initialize L2 as cache.
189  *
190  * The newer 8548, etc, parts have twice as much cache, but
191  * use the same bit-encoding as the older 8555, etc, parts.
192  *
193  */
194
195 int cpu_init_r(void)
196 {
197         volatile immap_t    *immap = (immap_t *)CFG_IMMR;
198         volatile ccsr_local_ecm_t *ecm = &immap->im_local_ecm;
199
200 #ifdef CONFIG_CLEAR_LAW0
201         /* clear alternate boot location LAW (used for sdram, or ddr bank) */
202         ecm->lawar0 = 0;
203 #endif
204
205 #if defined(CONFIG_L2_CACHE)
206         volatile ccsr_l2cache_t *l2cache = &immap->im_l2cache;
207         volatile uint cache_ctl;
208         uint svr, ver;
209         uint l2srbar;
210
211         svr = get_svr();
212         ver = SVR_VER(svr);
213
214         asm("msync;isync");
215         cache_ctl = l2cache->l2ctl;
216
217         switch (cache_ctl & 0x30000000) {
218         case 0x20000000:
219                 if (ver == SVR_8548 || ver == SVR_8548_E ||
220                     ver == SVR_8544) {
221                         printf ("L2 cache 512KB:");
222                         /* set L2E=1, L2I=1, & L2SRAM=0 */
223                         cache_ctl = 0xc0000000;
224                 } else {
225                         printf ("L2 cache 256KB:");
226                         /* set L2E=1, L2I=1, & L2BLKSZ=2 (256 Kbyte) */
227                         cache_ctl = 0xc8000000;
228                 }
229                 break;
230         case 0x10000000:
231                 printf ("L2 cache 256KB:");
232                 if (ver == SVR_8544 || ver == SVR_8544_E) {
233                         cache_ctl = 0xc0000000; /* set L2E=1, L2I=1, & L2SRAM=0 */
234                 }
235                 break;
236         case 0x30000000:
237         case 0x00000000:
238         default:
239                 printf ("L2 cache unknown size (0x%08x)\n", cache_ctl);
240                 return -1;
241         }
242
243         if (l2cache->l2ctl & 0x80000000) {
244                 printf(" already enabled.");
245                 l2srbar = l2cache->l2srbar0;
246 #ifdef CFG_INIT_L2_ADDR
247                 if (l2cache->l2ctl & 0x00010000 && l2srbar >= CFG_FLASH_BASE) {
248                         l2srbar = CFG_INIT_L2_ADDR;
249                         l2cache->l2srbar0 = l2srbar;
250                         printf("  Moving to 0x%08x", CFG_INIT_L2_ADDR);
251                 }
252 #endif /* CFG_INIT_L2_ADDR */
253                 puts("\n");
254         } else {
255                 asm("msync;isync");
256                 l2cache->l2ctl = cache_ctl; /* invalidate & enable */
257                 asm("msync;isync");
258                 printf(" enabled\n");
259         }
260 #else
261         printf("L2 cache: disabled\n");
262 #endif
263
264         return 0;
265 }