- Fix bug for initial stack in data cache as pointed out by Thomas Schaefer (tschaefe...
[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 <405gp_enet.h>
27 #include <asm/processor.h>
28 #include <ppc4xx.h>
29
30
31 #define mtebc(reg, data)  mtdcr(ebccfga,reg);mtdcr(ebccfgd,data)
32
33 #ifdef CFG_INIT_DCACHE_CS
34 # if (CFG_INIT_DCACHE_CS == 0)
35 #  define PBxAP pb0ap
36 #  define PBxCR pb0cr
37 #  if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
38 #   define PBxAP_VAL CFG_EBC_PB0AP
39 #   define PBxCR_VAL CFG_EBC_PB0CR
40 #  endif
41 # endif
42 # if (CFG_INIT_DCACHE_CS == 1)
43 #  define PBxAP pb1ap
44 #  define PBxCR pb1cr
45 #  if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
46 #   define PBxAP_VAL CFG_EBC_PB1AP
47 #   define PBxCR_VAL CFG_EBC_PB1CR
48 #  endif
49 # endif
50 # if (CFG_INIT_DCACHE_CS == 2)
51 #  define PBxAP pb2ap
52 #  define PBxCR pb2cr
53 #  if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
54 #   define PBxAP_VAL CFG_EBC_PB2AP
55 #   define PBxCR_VAL CFG_EBC_PB2CR
56 #  endif
57 # endif
58 # if (CFG_INIT_DCACHE_CS == 3)
59 #  define PBxAP pb3ap
60 #  define PBxCR pb3cr
61 #  if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
62 #   define PBxAP_VAL CFG_EBC_PB3AP
63 #   define PBxCR_VAL CFG_EBC_PB3CR
64 #  endif
65 # endif
66 # if (CFG_INIT_DCACHE_CS == 4)
67 #  define PBxAP pb4ap
68 #  define PBxCR pb4cr
69 #  if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
70 #   define PBxAP_VAL CFG_EBC_PB4AP
71 #   define PBxCR_VAL CFG_EBC_PB4CR
72 #  endif
73 # endif
74 # if (CFG_INIT_DCACHE_CS == 5)
75 #  define PBxAP pb5ap
76 #  define PBxCR pb5cr
77 #  if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
78 #   define PBxAP_VAL CFG_EBC_PB5AP
79 #   define PBxCR_VAL CFG_EBC_PB5CR
80 #  endif
81 # endif
82 # if (CFG_INIT_DCACHE_CS == 6)
83 #  define PBxAP pb6ap
84 #  define PBxCR pb6cr
85 #  if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
86 #   define PBxAP_VAL CFG_EBC_PB6AP
87 #   define PBxCR_VAL CFG_EBC_PB6CR
88 #  endif
89 # endif
90 # if (CFG_INIT_DCACHE_CS == 7)
91 #  define PBxAP pb7ap
92 #  define PBxCR pb7cr
93 #  if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
94 #   define PBxAP_VAL CFG_EBC_PB7AP
95 #   define PBxCR_VAL CFG_EBC_PB7CR
96 #  endif
97 # endif
98 #endif /* CFG_INIT_DCACHE_CS */
99
100
101 /*
102  * Breath some life into the CPU...
103  *
104  * Set up the memory map,
105  * initialize a bunch of registers
106  */
107 void
108 cpu_init_f (void)
109 {
110 #if defined(CONFIG_405EP)
111         /*
112          * GPIO0 setup (select GPIO or alternate function)
113          */
114         out32(GPIO0_OSRH, CFG_GPIO0_OSRH);   /* output select */
115         out32(GPIO0_OSRL, CFG_GPIO0_OSRL);
116         out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
117         out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
118         out32(GPIO0_TSRH, CFG_GPIO0_TSRH);   /* three-state select */
119         out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
120         out32(GPIO0_TCR, CFG_GPIO0_TCR);     /* enable output driver for outputs */
121
122         /*
123          * Set EMAC noise filter bits
124          */
125         mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE);
126 #endif /* CONFIG_405EP */
127
128         /*
129          * External Bus Controller (EBC) Setup
130          */
131 #if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
132         /*
133          * Move the next instructions into icache, since these modify the flash
134          * we are running from!
135          */
136         asm volatile("  bl      0f"             ::: "lr");
137         asm volatile("0:        mflr    3"              ::: "r3");
138         asm volatile("  addi    4, 0, 14"       ::: "r4");
139         asm volatile("  mtctr   4"              ::: "ctr");
140         asm volatile("1:        icbt    0, 3");
141         asm volatile("  addi    3, 3, 32"       ::: "r3");
142         asm volatile("  bdnz    1b"             ::: "ctr", "cr0");
143         asm volatile("  addis   3, 0, 0x0"      ::: "r3");
144         asm volatile("  ori     3, 3, 0xA000"   ::: "r3");
145         asm volatile("  mtctr   3"              ::: "ctr");
146         asm volatile("2:        bdnz    2b"             ::: "ctr", "cr0");
147
148         mtebc(pb0ap, CFG_EBC_PB0AP);
149         mtebc(pb0cr, CFG_EBC_PB0CR);
150 #endif
151
152 #if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR) && !(CFG_INIT_DCACHE_CS == 1))
153         mtebc(pb1ap, CFG_EBC_PB1AP);
154         mtebc(pb1cr, CFG_EBC_PB1CR);
155 #endif
156
157 #if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR) && !(CFG_INIT_DCACHE_CS == 2))
158         mtebc(pb2ap, CFG_EBC_PB2AP);
159         mtebc(pb2cr, CFG_EBC_PB2CR);
160 #endif
161
162 #if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR) && !(CFG_INIT_DCACHE_CS == 3))
163         mtebc(pb3ap, CFG_EBC_PB3AP);
164         mtebc(pb3cr, CFG_EBC_PB3CR);
165 #endif
166
167 #if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR) && !(CFG_INIT_DCACHE_CS == 4))
168         mtebc(pb4ap, CFG_EBC_PB4AP);
169         mtebc(pb4cr, CFG_EBC_PB4CR);
170 #endif
171
172 #if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR) && !(CFG_INIT_DCACHE_CS == 5))
173         mtebc(pb5ap, CFG_EBC_PB5AP);
174         mtebc(pb5cr, CFG_EBC_PB5CR);
175 #endif
176
177 #if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR) && !(CFG_INIT_DCACHE_CS == 6))
178         mtebc(pb6ap, CFG_EBC_PB6AP);
179         mtebc(pb6cr, CFG_EBC_PB6CR);
180 #endif
181
182 #if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR) && !(CFG_INIT_DCACHE_CS == 7))
183         mtebc(pb7ap, CFG_EBC_PB7AP);
184         mtebc(pb7cr, CFG_EBC_PB7CR);
185 #endif
186
187 #if defined(CONFIG_WATCHDOG)
188         unsigned long val;
189
190         val = mfspr(tcr);
191         val |= 0xf0000000;      /* generate system reset after 2.684 seconds */
192         mtspr(tcr, val);
193
194         val = mfspr(tsr);
195         val |= 0x80000000;      /* enable watchdog timer */
196         mtspr(tsr, val);
197
198         reset_4xx_watchdog();
199 #endif /* CONFIG_WATCHDOG */
200 }
201
202 /*
203  * initialize higher level parts of CPU like time base and timers
204  */
205 int cpu_init_r (void)
206 {
207 #if defined(CONFIG_405GP)  || defined(CONFIG_405EP)
208         DECLARE_GLOBAL_DATA_PTR;
209
210         bd_t *bd = gd->bd;
211         unsigned long reg;
212 #if defined(CONFIG_405GP)
213         uint pvr = get_pvr();
214 #endif
215
216 #ifdef CFG_INIT_DCACHE_CS
217         /*
218          * Flush and invalidate dcache, then disable CS for temporary stack.
219          * Afterwards, this CS can be used for other purposes
220          */
221         dcache_disable();   /* flush and invalidate dcache */
222         mtebc(PBxAP, 0);
223         mtebc(PBxCR, 0);    /* disable CS for temporary stack */
224
225 #if (defined(PBxAP_VAL) && defined(PBxCR_VAL))
226         /*
227          * Write new value into CS register
228          */
229         mtebc(PBxAP, PBxAP_VAL);
230         mtebc(PBxCR, PBxCR_VAL);
231 #endif
232 #endif /* CFG_INIT_DCACHE_CS */
233
234         /*
235          * Write Ethernetaddress into on-chip register
236          */
237         reg = 0x00000000;
238         reg |= bd->bi_enetaddr[0];           /* set high address */
239         reg = reg << 8;
240         reg |= bd->bi_enetaddr[1];
241         out32 (EMAC_IAH, reg);
242
243         reg = 0x00000000;
244         reg |= bd->bi_enetaddr[2];           /* set low address  */
245         reg = reg << 8;
246         reg |= bd->bi_enetaddr[3];
247         reg = reg << 8;
248         reg |= bd->bi_enetaddr[4];
249         reg = reg << 8;
250         reg |= bd->bi_enetaddr[5];
251         out32 (EMAC_IAL, reg);
252
253 #if defined(CONFIG_405GP)
254         /*
255          * Set edge conditioning circuitry on PPC405GPr
256          * for compatibility to existing PPC405GP designs.
257          */
258         if ((pvr & 0xfffffff0) == (PVR_405GPR_RB & 0xfffffff0)) {
259                 mtdcr(ecr, 0x60606000);
260         }
261 #endif  /* defined(CONFIG_405GP) */
262 #endif  /* defined(CONFIG_405GP) || defined(CONFIG_405EP) */
263         return (0);
264 }