Merge branch 'master' of rsync://rsync.denx.de/git/u-boot
[platform/kernel/u-boot.git] / cpu / ppc4xx / cpu_init.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <watchdog.h>
26 #include <ppc4xx_enet.h>
27 #include <asm/processor.h>
28 #include <ppc4xx.h>
29
30 #if defined(CONFIG_405GP)  || defined(CONFIG_405EP)
31 DECLARE_GLOBAL_DATA_PTR;
32 #endif
33
34
35 #define mtebc(reg, data)  mtdcr(ebccfga,reg);mtdcr(ebccfgd,data)
36
37 #ifdef CFG_INIT_DCACHE_CS
38 # if (CFG_INIT_DCACHE_CS == 0)
39 #  define PBxAP pb0ap
40 #  define PBxCR pb0cr
41 #  if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
42 #   define PBxAP_VAL CFG_EBC_PB0AP
43 #   define PBxCR_VAL CFG_EBC_PB0CR
44 #  endif
45 # endif
46 # if (CFG_INIT_DCACHE_CS == 1)
47 #  define PBxAP pb1ap
48 #  define PBxCR pb1cr
49 #  if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
50 #   define PBxAP_VAL CFG_EBC_PB1AP
51 #   define PBxCR_VAL CFG_EBC_PB1CR
52 #  endif
53 # endif
54 # if (CFG_INIT_DCACHE_CS == 2)
55 #  define PBxAP pb2ap
56 #  define PBxCR pb2cr
57 #  if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
58 #   define PBxAP_VAL CFG_EBC_PB2AP
59 #   define PBxCR_VAL CFG_EBC_PB2CR
60 #  endif
61 # endif
62 # if (CFG_INIT_DCACHE_CS == 3)
63 #  define PBxAP pb3ap
64 #  define PBxCR pb3cr
65 #  if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
66 #   define PBxAP_VAL CFG_EBC_PB3AP
67 #   define PBxCR_VAL CFG_EBC_PB3CR
68 #  endif
69 # endif
70 # if (CFG_INIT_DCACHE_CS == 4)
71 #  define PBxAP pb4ap
72 #  define PBxCR pb4cr
73 #  if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
74 #   define PBxAP_VAL CFG_EBC_PB4AP
75 #   define PBxCR_VAL CFG_EBC_PB4CR
76 #  endif
77 # endif
78 # if (CFG_INIT_DCACHE_CS == 5)
79 #  define PBxAP pb5ap
80 #  define PBxCR pb5cr
81 #  if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
82 #   define PBxAP_VAL CFG_EBC_PB5AP
83 #   define PBxCR_VAL CFG_EBC_PB5CR
84 #  endif
85 # endif
86 # if (CFG_INIT_DCACHE_CS == 6)
87 #  define PBxAP pb6ap
88 #  define PBxCR pb6cr
89 #  if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
90 #   define PBxAP_VAL CFG_EBC_PB6AP
91 #   define PBxCR_VAL CFG_EBC_PB6CR
92 #  endif
93 # endif
94 # if (CFG_INIT_DCACHE_CS == 7)
95 #  define PBxAP pb7ap
96 #  define PBxCR pb7cr
97 #  if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
98 #   define PBxAP_VAL CFG_EBC_PB7AP
99 #   define PBxCR_VAL CFG_EBC_PB7CR
100 #  endif
101 # endif
102 #endif /* CFG_INIT_DCACHE_CS */
103
104
105 /*
106  * Breath some life into the CPU...
107  *
108  * Set up the memory map,
109  * initialize a bunch of registers
110  */
111 void
112 cpu_init_f (void)
113 {
114 #if defined(CONFIG_405EP)
115         /*
116          * GPIO0 setup (select GPIO or alternate function)
117          */
118         out32(GPIO0_OSRH, CFG_GPIO0_OSRH);   /* output select */
119         out32(GPIO0_OSRL, CFG_GPIO0_OSRL);
120         out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
121         out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
122         out32(GPIO0_TSRH, CFG_GPIO0_TSRH);   /* three-state select */
123         out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
124         out32(GPIO0_TCR, CFG_GPIO0_TCR);     /* enable output driver for outputs */
125
126         /*
127          * Set EMAC noise filter bits
128          */
129         mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE);
130 #endif /* CONFIG_405EP */
131
132         /*
133          * External Bus Controller (EBC) Setup
134          */
135 #if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
136         /*
137          * Move the next instructions into icache, since these modify the flash
138          * we are running from!
139          */
140         asm volatile("  bl      0f"             ::: "lr");
141         asm volatile("0:        mflr    3"              ::: "r3");
142         asm volatile("  addi    4, 0, 14"       ::: "r4");
143         asm volatile("  mtctr   4"              ::: "ctr");
144         asm volatile("1:        icbt    0, 3");
145         asm volatile("  addi    3, 3, 32"       ::: "r3");
146         asm volatile("  bdnz    1b"             ::: "ctr", "cr0");
147         asm volatile("  addis   3, 0, 0x0"      ::: "r3");
148         asm volatile("  ori     3, 3, 0xA000"   ::: "r3");
149         asm volatile("  mtctr   3"              ::: "ctr");
150         asm volatile("2:        bdnz    2b"             ::: "ctr", "cr0");
151
152         mtebc(pb0ap, CFG_EBC_PB0AP);
153         mtebc(pb0cr, CFG_EBC_PB0CR);
154 #endif
155
156 #if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR) && !(CFG_INIT_DCACHE_CS == 1))
157         mtebc(pb1ap, CFG_EBC_PB1AP);
158         mtebc(pb1cr, CFG_EBC_PB1CR);
159 #endif
160
161 #if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR) && !(CFG_INIT_DCACHE_CS == 2))
162         mtebc(pb2ap, CFG_EBC_PB2AP);
163         mtebc(pb2cr, CFG_EBC_PB2CR);
164 #endif
165
166 #if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR) && !(CFG_INIT_DCACHE_CS == 3))
167         mtebc(pb3ap, CFG_EBC_PB3AP);
168         mtebc(pb3cr, CFG_EBC_PB3CR);
169 #endif
170
171 #if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR) && !(CFG_INIT_DCACHE_CS == 4))
172         mtebc(pb4ap, CFG_EBC_PB4AP);
173         mtebc(pb4cr, CFG_EBC_PB4CR);
174 #endif
175
176 #if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR) && !(CFG_INIT_DCACHE_CS == 5))
177         mtebc(pb5ap, CFG_EBC_PB5AP);
178         mtebc(pb5cr, CFG_EBC_PB5CR);
179 #endif
180
181 #if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR) && !(CFG_INIT_DCACHE_CS == 6))
182         mtebc(pb6ap, CFG_EBC_PB6AP);
183         mtebc(pb6cr, CFG_EBC_PB6CR);
184 #endif
185
186 #if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR) && !(CFG_INIT_DCACHE_CS == 7))
187         mtebc(pb7ap, CFG_EBC_PB7AP);
188         mtebc(pb7cr, CFG_EBC_PB7CR);
189 #endif
190
191 #if defined(CONFIG_WATCHDOG)
192         unsigned long val;
193
194         val = mfspr(tcr);
195 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
196         val |= 0xb8000000;      /* generate system reset after 1.34 seconds */
197 #else
198         val |= 0xf0000000;      /* generate system reset after 2.684 seconds */
199 #endif
200         mtspr(tcr, val);
201
202         val = mfspr(tsr);
203         val |= 0x80000000;      /* enable watchdog timer */
204         mtspr(tsr, val);
205
206         reset_4xx_watchdog();
207 #endif /* CONFIG_WATCHDOG */
208 }
209
210 /*
211  * initialize higher level parts of CPU like time base and timers
212  */
213 int cpu_init_r (void)
214 {
215 #if defined(CONFIG_405GP)  || defined(CONFIG_405EP)
216         bd_t *bd = gd->bd;
217         unsigned long reg;
218 #if defined(CONFIG_405GP)
219         uint pvr = get_pvr();
220 #endif
221
222 #ifdef CFG_INIT_DCACHE_CS
223         /*
224          * Flush and invalidate dcache, then disable CS for temporary stack.
225          * Afterwards, this CS can be used for other purposes
226          */
227         dcache_disable();   /* flush and invalidate dcache */
228         mtebc(PBxAP, 0);
229         mtebc(PBxCR, 0);    /* disable CS for temporary stack */
230
231 #if (defined(PBxAP_VAL) && defined(PBxCR_VAL))
232         /*
233          * Write new value into CS register
234          */
235         mtebc(PBxAP, PBxAP_VAL);
236         mtebc(PBxCR, PBxCR_VAL);
237 #endif
238 #endif /* CFG_INIT_DCACHE_CS */
239
240         /*
241          * Write Ethernetaddress into on-chip register
242          */
243         reg = 0x00000000;
244         reg |= bd->bi_enetaddr[0];           /* set high address */
245         reg = reg << 8;
246         reg |= bd->bi_enetaddr[1];
247         out32 (EMAC_IAH, reg);
248
249         reg = 0x00000000;
250         reg |= bd->bi_enetaddr[2];           /* set low address  */
251         reg = reg << 8;
252         reg |= bd->bi_enetaddr[3];
253         reg = reg << 8;
254         reg |= bd->bi_enetaddr[4];
255         reg = reg << 8;
256         reg |= bd->bi_enetaddr[5];
257         out32 (EMAC_IAL, reg);
258
259 #if defined(CONFIG_405GP)
260         /*
261          * Set edge conditioning circuitry on PPC405GPr
262          * for compatibility to existing PPC405GP designs.
263          */
264         if ((pvr & 0xfffffff0) == (PVR_405GPR_RB & 0xfffffff0)) {
265                 mtdcr(ecr, 0x60606000);
266         }
267 #endif  /* defined(CONFIG_405GP) */
268 #endif  /* defined(CONFIG_405GP) || defined(CONFIG_405EP) */
269         return (0);
270 }