aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-bf548/head.S
diff options
context:
space:
mode:
authorRoy Huang <roy.huang@analog.com>2007-07-12 10:41:45 -0400
committerBryan Wu <bryan.wu@analog.com>2007-07-12 10:41:45 -0400
commit24a07a124198153540f8f43d9e91d16227aba66e (patch)
tree917b2011e67e224515830833b1151e276b6c6137 /arch/blackfin/mach-bf548/head.S
parent088eec1192a0ae60fc218796027e622008af36c0 (diff)
Blackfin arch: initial supporting for BF548-EZKIT
The ADSP-BF54x was specifically designed to meet the needs of convergent multimedia applications where system performance and cost are essential ingredients. The integration of multimedia, human interface, and connectivity peripherals combined with increased system bandwidth and on-chip memory provides customers a platform to design the most demanding applications. Since now, ADSP-BF54x will be supported in the Linux kernel and bunch of related drivers such as USB OTG, ATAPI, NAND flash controller, LCD framebuffer, sound, touch screen will be submitted later. Please enjoy the show. Signed-off-by: Roy Huang <roy.huang@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/mach-bf548/head.S')
-rw-r--r--arch/blackfin/mach-bf548/head.S507
1 files changed, 507 insertions, 0 deletions
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
new file mode 100644
index 000000000000..0e1a25447391
--- /dev/null
+++ b/arch/blackfin/mach-bf548/head.S
@@ -0,0 +1,507 @@
1/*
2 * File: arch/blackfin/mach-bf548/head.S
3 * Based on: arch/blackfin/mach-bf537/head.S
4 * Author: Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
5 *
6 * Created: 1998
7 * Description: Startup code for Blackfin BF548
8 *
9 * Modified:
10 * Copyright 2004-2007 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 <asm/blackfin.h>
32#if CONFIG_BFIN_KERNEL_CLOCK
33#include <asm/mach/mem_init.h>
34#endif
35
36.global __rambase
37.global __ramstart
38.global __ramend
39.extern ___bss_stop
40.extern ___bss_start
41.extern _bf53x_relocate_l1_mem
42
43#define INITIAL_STACK 0xFFB01000
44
45.text
46
47ENTRY(__start)
48ENTRY(__stext)
49 /* R0: argument of command line string, passed from uboot, save it */
50 R7 = R0;
51 /* Set the SYSCFG register */
52 R0 = 0x36;
53 SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
54 R0 = 0;
55
56 /* Clear Out All the data and pointer Registers*/
57 R1 = R0;
58 R2 = R0;
59 R3 = R0;
60 R4 = R0;
61 R5 = R0;
62 R6 = R0;
63
64 P0 = R0;
65 P1 = R0;
66 P2 = R0;
67 P3 = R0;
68 P4 = R0;
69 P5 = R0;
70
71 LC0 = r0;
72 LC1 = r0;
73 L0 = r0;
74 L1 = r0;
75 L2 = r0;
76 L3 = r0;
77
78 /* Clear Out All the DAG Registers*/
79 B0 = r0;
80 B1 = r0;
81 B2 = r0;
82 B3 = r0;
83
84 I0 = r0;
85 I1 = r0;
86 I2 = r0;
87 I3 = r0;
88
89 M0 = r0;
90 M1 = r0;
91 M2 = r0;
92 M3 = r0;
93
94 /* Turn off the icache */
95 p0.l = (IMEM_CONTROL & 0xFFFF);
96 p0.h = (IMEM_CONTROL >> 16);
97 R1 = [p0];
98 R0 = ~ENICPLB;
99 R0 = R0 & R1;
100 [p0] = R0;
101 SSYNC;
102
103 /* Turn off the dcache */
104 p0.l = (DMEM_CONTROL & 0xFFFF);
105 p0.h = (DMEM_CONTROL >> 16);
106 R1 = [p0];
107 R0 = ~ENDCPLB;
108 R0 = R0 & R1;
109 [p0] = R0;
110 SSYNC;
111
112 /* Initialize stack pointer */
113 SP.L = LO(INITIAL_STACK);
114 SP.H = HI(INITIAL_STACK);
115 FP = SP;
116 USP = SP;
117
118 /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
119 call _bf53x_relocate_l1_mem;
120#if CONFIG_BFIN_KERNEL_CLOCK
121 call _start_dma_code;
122#endif
123 /* Code for initializing Async memory banks */
124
125 p2.h = hi(EBIU_AMBCTL1);
126 p2.l = lo(EBIU_AMBCTL1);
127 r0.h = hi(AMBCTL1VAL);
128 r0.l = lo(AMBCTL1VAL);
129 [p2] = r0;
130 ssync;
131
132 p2.h = hi(EBIU_AMBCTL0);
133 p2.l = lo(EBIU_AMBCTL0);
134 r0.h = hi(AMBCTL0VAL);
135 r0.l = lo(AMBCTL0VAL);
136 [p2] = r0;
137 ssync;
138
139 p2.h = hi(EBIU_AMGCTL);
140 p2.l = lo(EBIU_AMGCTL);
141 r0 = AMGCTLVAL;
142 w[p2] = r0;
143 ssync;
144
145 /* This section keeps the processor in supervisor mode
146 * during kernel boot. Switches to user mode at end of boot.
147 * See page 3-9 of Hardware Reference manual for documentation.
148 */
149
150 /* EVT15 = _real_start */
151
152 p0.l = lo(EVT15);
153 p0.h = hi(EVT15);
154 p1.l = _real_start;
155 p1.h = _real_start;
156 [p0] = p1;
157 csync;
158
159 p0.l = lo(IMASK);
160 p0.h = hi(IMASK);
161 p1.l = IMASK_IVG15;
162 p1.h = 0x0;
163 [p0] = p1;
164 csync;
165
166 raise 15;
167 p0.l = .LWAIT_HERE;
168 p0.h = .LWAIT_HERE;
169 reti = p0;
170#if defined (ANOMALY_05000281)
171 nop;
172 nop;
173 nop;
174#endif
175 rti;
176
177.LWAIT_HERE:
178 jump .LWAIT_HERE;
179
180ENTRY(_real_start)
181 [ -- sp ] = reti;
182 p0.l = lo(WDOG_CTL);
183 p0.h = hi(WDOG_CTL);
184 r0 = 0xAD6(z);
185 w[p0] = r0; /* watchdog off for now */
186 ssync;
187
188 /* Code update for BSS size == 0
189 * Zero out the bss region.
190 */
191
192 p1.l = ___bss_start;
193 p1.h = ___bss_start;
194 p2.l = ___bss_stop;
195 p2.h = ___bss_stop;
196 r0 = 0;
197 p2 -= p1;
198 lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
199.L_clear_bss:
200 B[p1++] = r0;
201
202 /* In case there is a NULL pointer reference
203 * Zero out region before stext
204 */
205
206 p1.l = 0x0;
207 p1.h = 0x0;
208 r0.l = __stext;
209 r0.h = __stext;
210 r0 = r0 >> 1;
211 p2 = r0;
212 r0 = 0;
213 lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
214.L_clear_zero:
215 W[p1++] = r0;
216
217 /* pass the uboot arguments to the global value command line */
218 R0 = R7;
219 call _cmdline_init;
220
221 p1.l = __rambase;
222 p1.h = __rambase;
223 r0.l = __sdata;
224 r0.h = __sdata;
225 [p1] = r0;
226
227 p1.l = __ramstart;
228 p1.h = __ramstart;
229 p3.l = ___bss_stop;
230 p3.h = ___bss_stop;
231
232 r1 = p3;
233 [p1] = r1;
234
235
236 /*
237 * load the current thread pointer and stack
238 */
239 r1.l = _init_thread_union;
240 r1.h = _init_thread_union;
241
242 r2.l = 0x2000;
243 r2.h = 0x0000;
244 r1 = r1 + r2;
245 sp = r1;
246 usp = sp;
247 fp = sp;
248 call _start_kernel;
249.L_exit:
250 jump.s .L_exit;
251
252.section .l1.text
253#if CONFIG_BFIN_KERNEL_CLOCK
254ENTRY(_start_dma_code)
255
256 /* Enable PHY CLK buffer output */
257 p0.h = hi(VR_CTL);
258 p0.l = lo(VR_CTL);
259 r0.l = w[p0];
260 bitset(r0, 14);
261 w[p0] = r0.l;
262 ssync;
263
264 p0.h = hi(SIC_IWR);
265 p0.l = lo(SIC_IWR);
266 r0.l = 0x1;
267 r0.h = 0x0;
268 [p0] = r0;
269 SSYNC;
270
271 /*
272 * Set PLL_CTL
273 * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
274 * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
275 * - [7] = output delay (add 200ps of delay to mem signals)
276 * - [6] = input delay (add 200ps of input delay to mem signals)
277 * - [5] = PDWN : 1=All Clocks off
278 * - [3] = STOPCK : 1=Core Clock off
279 * - [1] = PLL_OFF : 1=Disable Power to PLL
280 * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
281 * all other bits set to zero
282 */
283
284 p0.h = hi(PLL_LOCKCNT);
285 p0.l = lo(PLL_LOCKCNT);
286 r0 = 0x300(Z);
287 w[p0] = r0.l;
288 ssync;
289
290 P2.H = hi(EBIU_SDGCTL);
291 P2.L = lo(EBIU_SDGCTL);
292 R0 = [P2];
293 BITSET (R0, 24);
294 [P2] = R0;
295 SSYNC;
296
297 r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
298 r0 = r0 << 9; /* Shift it over, */
299 r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
300 r0 = r1 | r0;
301 r1 = PLL_BYPASS; /* Bypass the PLL? */
302 r1 = r1 << 8; /* Shift it over */
303 r0 = r1 | r0; /* add them all together */
304
305 p0.h = hi(PLL_CTL);
306 p0.l = lo(PLL_CTL); /* Load the address */
307 cli r2; /* Disable interrupts */
308 ssync;
309 w[p0] = r0.l; /* Set the value */
310 idle; /* Wait for the PLL to stablize */
311 sti r2; /* Enable interrupts */
312
313.Lcheck_again:
314 p0.h = hi(PLL_STAT);
315 p0.l = lo(PLL_STAT);
316 R0 = W[P0](Z);
317 CC = BITTST(R0,5);
318 if ! CC jump .Lcheck_again;
319
320 /* Configure SCLK & CCLK Dividers */
321 r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
322 p0.h = hi(PLL_DIV);
323 p0.l = lo(PLL_DIV);
324 w[p0] = r0.l;
325 ssync;
326
327 p0.l = lo(EBIU_SDRRC);
328 p0.h = hi(EBIU_SDRRC);
329 r0 = mem_SDRRC;
330 w[p0] = r0.l;
331 ssync;
332
333 p0.l = (EBIU_SDBCTL & 0xFFFF);
334 p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
335 r0 = mem_SDBCTL;
336 w[p0] = r0.l;
337 ssync;
338
339 P2.H = hi(EBIU_SDGCTL);
340 P2.L = lo(EBIU_SDGCTL);
341 R0 = [P2];
342 BITCLR (R0, 24);
343 p0.h = hi(EBIU_SDSTAT);
344 p0.l = lo(EBIU_SDSTAT);
345 r2.l = w[p0];
346 cc = bittst(r2,3);
347 if !cc jump .Lskip;
348 NOP;
349 BITSET (R0, 23);
350.Lskip:
351 [P2] = R0;
352 SSYNC;
353
354 R0.L = lo(mem_SDGCTL);
355 R0.H = hi(mem_SDGCTL);
356 R1 = [p2];
357 R1 = R1 | R0;
358 [P2] = R1;
359 SSYNC;
360
361 p0.h = hi(SIC_IWR);
362 p0.l = lo(SIC_IWR);
363 r0.l = lo(IWR_ENABLE_ALL);
364 r0.h = hi(IWR_ENABLE_ALL);
365 [p0] = r0;
366 SSYNC;
367
368 RTS;
369#endif /* CONFIG_BFIN_KERNEL_CLOCK */
370
371ENTRY(_bfin_reset)
372 /* No more interrupts to be handled*/
373 CLI R6;
374 SSYNC;
375
376#if defined(CONFIG_MTD_M25P80)
377/*
378 * The following code fix the SPI flash reboot issue,
379 * /CS signal of the chip which is using PF10 return to GPIO mode
380 */
381 p0.h = hi(PORTF_FER);
382 p0.l = lo(PORTF_FER);
383 r0.l = 0x0000;
384 w[p0] = r0.l;
385 SSYNC;
386
387/* /CS return to high */
388 p0.h = hi(PORTFIO);
389 p0.l = lo(PORTFIO);
390 r0.l = 0xFFFF;
391 w[p0] = r0.l;
392 SSYNC;
393
394/* Delay some time, This is necessary */
395 r1.h = 0;
396 r1.l = 0x400;
397 p1 = r1;
398 lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
399_delay_lab1:
400 r0.h = 0;
401 r0.l = 0x8000;
402 p0 = r0;
403 lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
404_delay_lab0:
405 nop;
406_delay_lab0_end:
407 nop;
408_delay_lab1_end:
409 nop;
410#endif
411
412 /* Clear the bits 13-15 in SWRST if they werent cleared */
413 p0.h = hi(SWRST);
414 p0.l = lo(SWRST);
415 csync;
416 r0.l = w[p0];
417
418 /* Clear the IMASK register */
419 p0.h = hi(IMASK);
420 p0.l = lo(IMASK);
421 r0 = 0x0;
422 [p0] = r0;
423
424 /* Clear the ILAT register */
425 p0.h = hi(ILAT);
426 p0.l = lo(ILAT);
427 r0 = [p0];
428 [p0] = r0;
429 SSYNC;
430
431 /* Disable the WDOG TIMER */
432 p0.h = hi(WDOG_CTL);
433 p0.l = lo(WDOG_CTL);
434 r0.l = 0xAD6;
435 w[p0] = r0.l;
436 SSYNC;
437
438 /* Clear the sticky bit incase it is already set */
439 p0.h = hi(WDOG_CTL);
440 p0.l = lo(WDOG_CTL);
441 r0.l = 0x8AD6;
442 w[p0] = r0.l;
443 SSYNC;
444
445 /* Program the count value */
446 R0.l = 0x100;
447 R0.h = 0x0;
448 P0.h = hi(WDOG_CNT);
449 P0.l = lo(WDOG_CNT);
450 [P0] = R0;
451 SSYNC;
452
453 /* Program WDOG_STAT if necessary */
454 P0.h = hi(WDOG_CTL);
455 P0.l = lo(WDOG_CTL);
456 R0 = W[P0](Z);
457 CC = BITTST(R0,1);
458 if !CC JUMP .LWRITESTAT;
459 CC = BITTST(R0,2);
460 if !CC JUMP .LWRITESTAT;
461 JUMP .LSKIP_WRITE;
462
463.LWRITESTAT:
464 /* When watch dog timer is enabled,
465 * a write to STAT will load the contents of CNT to STAT
466 */
467 R0 = 0x0000(z);
468 P0.h = hi(WDOG_STAT);
469 P0.l = lo(WDOG_STAT)
470 [P0] = R0;
471 SSYNC;
472
473.LSKIP_WRITE:
474 /* Enable the reset event */
475 P0.h = hi(WDOG_CTL);
476 P0.l = lo(WDOG_CTL);
477 R0 = W[P0](Z);
478 BITCLR(R0,1);
479 BITCLR(R0,2);
480 W[P0] = R0.L;
481 SSYNC;
482 NOP;
483
484 /* Enable the wdog counter */
485 R0 = W[P0](Z);
486 BITCLR(R0,4);
487 W[P0] = R0.L;
488 SSYNC;
489
490 IDLE;
491
492 RTS;
493
494.data
495
496/*
497 * Set up the usable of RAM stuff. Size of RAM is determined then
498 * an initial stack set up at the end.
499 */
500
501.align 4
502__rambase:
503.long 0
504__ramstart:
505.long 0
506__ramend:
507.long 0