1/*
2 * File:         arch/blackfin/mach-bf537/head.S
3 * Based on:     arch/blackfin/mach-bf533/head.S
4 * Author:       Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
5 *
6 * Created:      1998
7 * Description:  Startup code for Blackfin BF537
8 *
9 * Modified:
10 *               Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs:         Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28 */
29
30#include <linux/linkage.h>
31#include <linux/init.h>
32#include <asm/blackfin.h>
33#if CONFIG_BFIN_KERNEL_CLOCK
34#include <asm/mach/mem_init.h>
35#endif
36
37.global __rambase
38.global __ramstart
39.global __ramend
40.extern ___bss_stop
41.extern ___bss_start
42.extern _bf53x_relocate_l1_mem
43
44#define INITIAL_STACK	0xFFB01000
45
46__INIT
47
48ENTRY(__start)
49	/* R0: argument of command line string, passed from uboot, save it */
50	R7 = R0;
51	/* Set the SYSCFG register:
52	 * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
53	 */
54	R0 = 0x36;
55	SYSCFG = R0;
56	R0 = 0;
57
58	/* Clear Out All the data and pointer Registers */
59	R1 = R0;
60	R2 = R0;
61	R3 = R0;
62	R4 = R0;
63	R5 = R0;
64	R6 = R0;
65
66	P0 = R0;
67	P1 = R0;
68	P2 = R0;
69	P3 = R0;
70	P4 = R0;
71	P5 = R0;
72
73	LC0 = r0;
74	LC1 = r0;
75	L0 = r0;
76	L1 = r0;
77	L2 = r0;
78	L3 = r0;
79
80	/* Clear Out All the DAG Registers */
81	B0 = r0;
82	B1 = r0;
83	B2 = r0;
84	B3 = r0;
85
86	I0 = r0;
87	I1 = r0;
88	I2 = r0;
89	I3 = r0;
90
91	M0 = r0;
92	M1 = r0;
93	M2 = r0;
94	M3 = r0;
95
96	/* Turn off the icache */
97	p0.l = (IMEM_CONTROL & 0xFFFF);
98	p0.h = (IMEM_CONTROL >> 16);
99	R1 = [p0];
100	R0 = ~ENICPLB;
101	R0 = R0 & R1;
102
103	/* Anomaly 05000125 */
104#ifdef ANOMALY_05000125
105	CLI R2;
106	SSYNC;
107#endif
108	[p0] = R0;
109	SSYNC;
110#ifdef ANOMALY_05000125
111	STI R2;
112#endif
113
114	/* Turn off the dcache */
115	p0.l = (DMEM_CONTROL & 0xFFFF);
116	p0.h = (DMEM_CONTROL >> 16);
117	R1 = [p0];
118	R0 = ~ENDCPLB;
119	R0 = R0 & R1;
120
121	/* Anomaly 05000125 */
122#ifdef ANOMALY_05000125
123	CLI R2;
124	SSYNC;
125#endif
126	[p0] = R0;
127	SSYNC;
128#ifdef ANOMALY_05000125
129	STI R2;
130#endif
131
132	/* Initialise General-Purpose I/O Modules on BF537 */
133	/* Rev 0.0 Anomaly 05000212 - PORTx_FER,
134	 * PORT_MUX Registers Do Not accept "writes" correctly:
135	 */
136	p0.h = hi(BFIN_PORT_MUX);
137	p0.l = lo(BFIN_PORT_MUX);
138#ifdef ANOMALY_05000212
139	R0.L = W[P0]; /* Read */
140	SSYNC;
141#endif
142	R0 = (PGDE_UART | PFTE_UART)(Z);
143#ifdef ANOMALY_05000212
144	W[P0] = R0.L; /* Write */
145	SSYNC;
146#endif
147	W[P0] = R0.L; /* Enable both UARTS */
148	SSYNC;
149
150	p0.h = hi(PORTF_FER);
151	p0.l = lo(PORTF_FER);
152#ifdef ANOMALY_05000212
153	R0.L = W[P0]; /* Read */
154	SSYNC;
155#endif
156	R0 = 0x000F(Z);
157#ifdef ANOMALY_05000212
158	W[P0] = R0.L; /* Write */
159	SSYNC;
160#endif
161	/* Enable peripheral function of PORTF for UART0 and UART1 */
162	W[P0] = R0.L;
163	SSYNC;
164
165#if !defined(CONFIG_BF534)
166	p0.h = hi(EMAC_SYSTAT);
167	p0.l = lo(EMAC_SYSTAT);
168	R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */
169	R0.l = 0xFFFF;
170	[P0] = R0;
171	SSYNC;
172#endif
173
174#ifdef CONFIG_BF537_PORT_H
175	p0.h = hi(PORTH_FER);
176	p0.l = lo(PORTH_FER);
177	R0.L = W[P0]; /* Read */
178	SSYNC;
179	R0 = 0x0000;
180	W[P0] = R0.L; /* Write */
181	SSYNC;
182	W[P0] = R0.L; /* Disable peripheral function of PORTH */
183	SSYNC;
184#endif
185
186	/* Initialise UART - when booting from u-boot, the UART is not disabled
187	 * so if we dont initalize here, our serial console gets hosed */
188	p0.h = hi(UART_LCR);
189	p0.l = lo(UART_LCR);
190	r0 = 0x0(Z);
191	w[p0] = r0.L;	/* To enable DLL writes */
192	ssync;
193
194	p0.h = hi(UART_DLL);
195	p0.l = lo(UART_DLL);
196	r0 = 0x0(Z);
197	w[p0] = r0.L;
198	ssync;
199
200	p0.h = hi(UART_DLH);
201	p0.l = lo(UART_DLH);
202	r0 = 0x00(Z);
203	w[p0] = r0.L;
204	ssync;
205
206	p0.h = hi(UART_GCTL);
207	p0.l = lo(UART_GCTL);
208	r0 = 0x0(Z);
209	w[p0] = r0.L;	/* To enable UART clock */
210	ssync;
211
212	/* Initialize stack pointer */
213	sp.l = lo(INITIAL_STACK);
214	sp.h = hi(INITIAL_STACK);
215	fp = sp;
216	usp = sp;
217
218	/* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
219	call _bf53x_relocate_l1_mem;
220#if CONFIG_BFIN_KERNEL_CLOCK
221	call _start_dma_code;
222#endif
223
224	/* Code for initializing Async memory banks */
225
226	p2.h = hi(EBIU_AMBCTL1);
227	p2.l = lo(EBIU_AMBCTL1);
228	r0.h = hi(AMBCTL1VAL);
229	r0.l = lo(AMBCTL1VAL);
230	[p2] = r0;
231	ssync;
232
233	p2.h = hi(EBIU_AMBCTL0);
234	p2.l = lo(EBIU_AMBCTL0);
235	r0.h = hi(AMBCTL0VAL);
236	r0.l = lo(AMBCTL0VAL);
237	[p2] = r0;
238	ssync;
239
240	p2.h = hi(EBIU_AMGCTL);
241	p2.l = lo(EBIU_AMGCTL);
242	r0 = AMGCTLVAL;
243	w[p2] = r0;
244	ssync;
245
246	/* This section keeps the processor in supervisor mode
247	 * during kernel boot.  Switches to user mode at end of boot.
248	 * See page 3-9 of Hardware Reference manual for documentation.
249	 */
250
251	/* EVT15 = _real_start */
252
253	p0.l = lo(EVT15);
254	p0.h = hi(EVT15);
255	p1.l = _real_start;
256	p1.h = _real_start;
257	[p0] = p1;
258	csync;
259
260	p0.l = lo(IMASK);
261	p0.h = hi(IMASK);
262	p1.l = IMASK_IVG15;
263	p1.h = 0x0;
264	[p0] = p1;
265	csync;
266
267	raise 15;
268	p0.l = .LWAIT_HERE;
269	p0.h = .LWAIT_HERE;
270	reti = p0;
271#if defined(ANOMALY_05000281)
272	nop; nop; nop;
273#endif
274	rti;
275
276.LWAIT_HERE:
277	jump .LWAIT_HERE;
278ENDPROC(__start)
279
280ENTRY(_real_start)
281	[ -- sp ] = reti;
282	p0.l = lo(WDOG_CTL);
283	p0.h = hi(WDOG_CTL);
284	r0 = 0xAD6(z);
285	w[p0] = r0;	/* watchdog off for now */
286	ssync;
287
288	/* Code update for BSS size == 0
289	 * Zero out the bss region.
290	 */
291
292	p1.l = ___bss_start;
293	p1.h = ___bss_start;
294	p2.l = ___bss_stop;
295	p2.h = ___bss_stop;
296	r0 = 0;
297	p2 -= p1;
298	lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2;
299.L_clear_bss:
300	B[p1++] = r0;
301
302	/* In case there is a NULL pointer reference
303	 * Zero out region before stext
304	 */
305
306	p1.l = 0x0;
307	p1.h = 0x0;
308	r0.l = __stext;
309	r0.h = __stext;
310	r0 = r0 >> 1;
311	p2 = r0;
312	r0 = 0;
313	lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2;
314.L_clear_zero:
315	W[p1++] = r0;
316
317	/* pass the uboot arguments to the global value command line */
318	R0 = R7;
319	call _cmdline_init;
320
321	p1.l = __rambase;
322	p1.h = __rambase;
323	r0.l = __sdata;
324	r0.h = __sdata;
325	[p1] = r0;
326
327	p1.l = __ramstart;
328	p1.h = __ramstart;
329	p3.l = ___bss_stop;
330	p3.h = ___bss_stop;
331
332	r1 = p3;
333	[p1] = r1;
334
335	/*
336	 * load the current thread pointer and stack
337	 */
338	r1.l = _init_thread_union;
339	r1.h = _init_thread_union;
340
341	r2.l = 0x2000;
342	r2.h = 0x0000;
343	r1 = r1 + r2;
344	sp = r1;
345	usp = sp;
346	fp = sp;
347	jump.l _start_kernel;
348ENDPROC(_real_start)
349
350__FINIT
351
352.section .l1.text
353#if CONFIG_BFIN_KERNEL_CLOCK
354ENTRY(_start_dma_code)
355
356	/* Enable PHY CLK buffer output */
357	p0.h = hi(VR_CTL);
358	p0.l = lo(VR_CTL);
359	r0.l = w[p0];
360	bitset(r0, 14);
361	w[p0] = r0.l;
362	ssync;
363
364	p0.h = hi(SIC_IWR);
365	p0.l = lo(SIC_IWR);
366	r0.l = 0x1;
367	r0.h = 0x0;
368	[p0] = r0;
369	SSYNC;
370
371	/*
372	 *  Set PLL_CTL
373	 *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
374	 *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
375	 *   - [7]     = output delay (add 200ps of delay to mem signals)
376	 *   - [6]     = input delay (add 200ps of input delay to mem signals)
377	 *   - [5]     = PDWN      : 1=All Clocks off
378	 *   - [3]     = STOPCK    : 1=Core Clock off
379	 *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
380	 *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
381	 *   all other bits set to zero
382	 */
383
384	p0.h = hi(PLL_LOCKCNT);
385	p0.l = lo(PLL_LOCKCNT);
386	r0 = 0x300(Z);
387	w[p0] = r0.l;
388	ssync;
389
390	P2.H = hi(EBIU_SDGCTL);
391	P2.L = lo(EBIU_SDGCTL);
392	R0 = [P2];
393	BITSET (R0, 24);
394	[P2] = R0;
395	SSYNC;
396
397	r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
398	r0 = r0 << 9;                    /* Shift it over,                  */
399	r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
400	r0 = r1 | r0;
401	r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
402	r1 = r1 << 8;                    /* Shift it over                   */
403	r0 = r1 | r0;                    /* add them all together           */
404
405	p0.h = hi(PLL_CTL);
406	p0.l = lo(PLL_CTL);              /* Load the address                */
407	cli r2;                          /* Disable interrupts              */
408	ssync;
409	w[p0] = r0.l;                    /* Set the value                   */
410	idle;                            /* Wait for the PLL to stablize    */
411	sti r2;                          /* Enable interrupts               */
412
413.Lcheck_again:
414	p0.h = hi(PLL_STAT);
415	p0.l = lo(PLL_STAT);
416	R0 = W[P0](Z);
417	CC = BITTST(R0,5);
418	if ! CC jump .Lcheck_again;
419
420	/* Configure SCLK & CCLK Dividers */
421	r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
422	p0.h = hi(PLL_DIV);
423	p0.l = lo(PLL_DIV);
424	w[p0] = r0.l;
425	ssync;
426
427	p0.l = lo(EBIU_SDRRC);
428	p0.h = hi(EBIU_SDRRC);
429	r0 = mem_SDRRC;
430	w[p0] = r0.l;
431	ssync;
432
433	p0.l = (EBIU_SDBCTL & 0xFFFF);
434	p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
435	r0 = mem_SDBCTL;
436	w[p0] = r0.l;
437	ssync;
438
439	P2.H = hi(EBIU_SDGCTL);
440	P2.L = lo(EBIU_SDGCTL);
441	R0 = [P2];
442	BITCLR (R0, 24);
443	p0.h = hi(EBIU_SDSTAT);
444	p0.l = lo(EBIU_SDSTAT);
445	r2.l = w[p0];
446	cc = bittst(r2,3);
447	if !cc jump .Lskip;
448	NOP;
449	BITSET (R0, 23);
450.Lskip:
451	[P2] = R0;
452	SSYNC;
453
454	R0.L = lo(mem_SDGCTL);
455	R0.H = hi(mem_SDGCTL);
456	R1 = [p2];
457	R1 = R1 | R0;
458	[P2] = R1;
459	SSYNC;
460
461	p0.h = hi(SIC_IWR);
462	p0.l = lo(SIC_IWR);
463	r0.l = lo(IWR_ENABLE_ALL);
464	r0.h = hi(IWR_ENABLE_ALL);
465	[p0] = r0;
466	SSYNC;
467
468	RTS;
469ENDPROC(_start_dma_code)
470#endif /* CONFIG_BFIN_KERNEL_CLOCK */
471
472ENTRY(_bfin_reset)
473	/* No more interrupts to be handled*/
474	CLI R6;
475	SSYNC;
476
477#if defined(CONFIG_MTD_M25P80)
478	/*
479	 * The following code fix the SPI flash reboot issue,
480	 * /CS signal of the chip which is using PF10 return to GPIO mode
481	 */
482	p0.h = hi(PORTF_FER);
483	p0.l = lo(PORTF_FER);
484	r0.l = 0x0000;
485	w[p0] = r0.l;
486	SSYNC;
487
488	/* /CS return to high */
489	p0.h = hi(PORTFIO);
490	p0.l = lo(PORTFIO);
491	r0.l = 0xFFFF;
492	w[p0] = r0.l;
493	SSYNC;
494
495	/* Delay some time, This is necessary */
496	r1.h = 0;
497	r1.l = 0x400;
498	p1   = r1;
499	lsetup (.L_delay_lab1, .L_delay_lab1_end) lc1 = p1;
500.L_delay_lab1:
501	r0.h = 0;
502	r0.l = 0x8000;
503	p0   = r0;
504	lsetup (.L_delay_lab0, .L_delay_lab0_end) lc0 = p0;
505.L_delay_lab0:
506	nop;
507.L_delay_lab0_end:
508	nop;
509.L_delay_lab1_end:
510	nop;
511#endif
512
513	/* Clear the IMASK register */
514	p0.h = hi(IMASK);
515	p0.l = lo(IMASK);
516	r0 = 0x0;
517	[p0] = r0;
518
519	/* Clear the ILAT register */
520	p0.h = hi(ILAT);
521	p0.l = lo(ILAT);
522	r0 = [p0];
523	[p0] = r0;
524	SSYNC;
525
526	/* make sure SYSCR is set to use BMODE */
527	P0.h = hi(SYSCR);
528	P0.l = lo(SYSCR);
529	R0.l = 0x0;
530	W[P0] = R0.l;
531	SSYNC;
532
533	/* issue a system soft reset */
534	P1.h = hi(SWRST);
535	P1.l = lo(SWRST);
536	R1.l = 0x0007;
537	W[P1] = R1;
538	SSYNC;
539
540	/* clear system soft reset */
541	R0.l = 0x0000;
542	W[P0] = R0;
543	SSYNC;
544
545	/* issue core reset */
546	raise 1;
547
548	RTS;
549ENDPROC(_bfin_reset)
550
551.data
552
553/*
554 * Set up the usable of RAM stuff. Size of RAM is determined then
555 * an initial stack set up at the end.
556 */
557
558.align 4
559__rambase:
560.long   0
561__ramstart:
562.long   0
563__ramend:
564.long   0
565