Merge branch '080208_dupint' of git://linux-arm.org/u-boot-armdev
[platform/kernel/u-boot.git] / cpu / bf561 / init_sdram.S
1 #define ASSEMBLY
2
3 #include <linux/config.h>
4 #include <config.h>
5 #include <asm/blackfin.h>
6 #include <asm/mem_init.h>
7 #include <asm/mach-common/bits/bootrom.h>
8 #include <asm/mach-common/bits/ebiu.h>
9 #include <asm/mach-common/bits/pll.h>
10 #include <asm/mach-common/bits/uart.h>
11 .global init_sdram;
12
13 #if (CONFIG_CCLK_DIV == 1)
14 #define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
15 #endif
16 #if (CONFIG_CCLK_DIV == 2)
17 #define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
18 #endif
19 #if (CONFIG_CCLK_DIV == 4)
20 #define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
21 #endif
22 #if (CONFIG_CCLK_DIV == 8)
23 #define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
24 #endif
25 #ifndef CONFIG_CCLK_ACT_DIV
26 #define CONFIG_CCLK_ACT_DIV   CONFIG_CCLK_DIV_not_defined_properly
27 #endif
28
29 init_sdram:
30         [--SP] = ASTAT;
31         [--SP] = RETS;
32         [--SP] = (R7:0);
33         [--SP] = (P5:0);
34
35         /*
36          * PLL_LOCKCNT - how many SCLK Cycles to delay while PLL becomes stable
37          */
38         p0.h = hi(PLL_LOCKCNT);
39         p0.l = lo(PLL_LOCKCNT);
40         r0 = 0x300(Z);
41         w[p0] = r0.l;
42         ssync;
43
44         /*
45          * Put SDRAM in self-refresh, incase anything is running
46          */
47         P2.H = hi(EBIU_SDGCTL);
48         P2.L = lo(EBIU_SDGCTL);
49         R0 = [P2];
50         BITSET (R0, 24);
51         [P2] = R0;
52         SSYNC;
53
54         /*
55          *  Set PLL_CTL with the value that we calculate in R0
56          *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
57          *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
58          *   - [7]     = output delay (add 200ps of delay to mem signals)
59          *   - [6]     = input delay (add 200ps of input delay to mem signals)
60          *   - [5]     = PDWN      : 1=All Clocks off
61          *   - [3]     = STOPCK    : 1=Core Clock off
62          *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
63          *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
64          *   all other bits set to zero
65          */
66
67         r0 = CONFIG_VCO_MULT & 63;      /* Load the VCO multiplier */
68         r0 = r0 << 9;                   /* Shift it over, */
69         r1 = CONFIG_CLKIN_HALF;         /* Do we need to divide CLKIN by 2? */
70         r0 = r1 | r0;
71         r1 = CONFIG_PLL_BYPASS;         /* Bypass the PLL? */
72         r1 = r1 << 8;                   /* Shift it over */
73         r0 = r1 | r0;                   /* add them all together */
74
75         p0.h = hi(PLL_CTL);
76         p0.l = lo(PLL_CTL);             /* Load the address */
77         cli r2;                         /* Disable interrupts */
78         ssync;
79         w[p0] = r0.l;                   /* Set the value */
80         idle;                           /* Wait for the PLL to stablize */
81         sti r2;                         /* Enable interrupts */
82
83 check_again:
84         p0.h = hi(PLL_STAT);
85         p0.l = lo(PLL_STAT);
86         R0 = W[P0](Z);
87         CC = BITTST(R0,5);
88         if ! CC jump check_again;
89
90         /* Configure SCLK & CCLK Dividers */
91         r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
92         p0.h = hi(PLL_DIV);
93         p0.l = lo(PLL_DIV);
94         w[p0] = r0.l;
95         ssync;
96
97         /*
98          * We now are running at speed, time to set the Async mem bank wait states
99          * This will speed up execution, since we are normally running from FLASH.
100          */
101
102         p2.h = (EBIU_AMBCTL1 >> 16);
103         p2.l = (EBIU_AMBCTL1 & 0xFFFF);
104         r0.h = (AMBCTL1VAL >> 16);
105         r0.l = (AMBCTL1VAL & 0xFFFF);
106         [p2] = r0;
107         ssync;
108
109         p2.h = (EBIU_AMBCTL0 >> 16);
110         p2.l = (EBIU_AMBCTL0 & 0xFFFF);
111         r0.h = (AMBCTL0VAL >> 16);
112         r0.l = (AMBCTL0VAL & 0xFFFF);
113         [p2] = r0;
114         ssync;
115
116         p2.h = (EBIU_AMGCTL >> 16);
117         p2.l = (EBIU_AMGCTL & 0xffff);
118         r0 = AMGCTLVAL;
119         w[p2] = r0;
120         ssync;
121
122         /*
123          * Now, Initialize the SDRAM,
124          * start with the SDRAM Refresh Rate Control Register
125          */
126         p0.l = lo(EBIU_SDRRC);
127         p0.h = hi(EBIU_SDRRC);
128         r0 = mem_SDRRC;
129         w[p0] = r0.l;
130         ssync;
131
132         /*
133          * SDRAM Memory Bank Control Register - bank specific parameters
134          */
135         p0.l = (EBIU_SDBCTL & 0xFFFF);
136         p0.h = (EBIU_SDBCTL >> 16);
137         r0 = mem_SDBCTL;
138         w[p0] = r0.l;
139         ssync;
140
141         /*
142          * SDRAM Global Control Register - global programmable parameters
143          * Disable self-refresh
144          */
145         P2.H = hi(EBIU_SDGCTL);
146         P2.L = lo(EBIU_SDGCTL);
147         R0 = [P2];
148         BITCLR (R0, 24);
149
150         /*
151          * Check if SDRAM is already powered up, if it is, enable self-refresh
152          */
153         p0.h = hi(EBIU_SDSTAT);
154         p0.l = lo(EBIU_SDSTAT);
155         r2.l = w[p0];
156         cc = bittst(r2,3);
157         if !cc jump skip;
158         NOP;
159         BITSET (R0, 23);
160 skip:
161         [P2] = R0;
162         SSYNC;
163
164         /* Write in the new value in the register */
165         R0.L = lo(mem_SDGCTL);
166         R0.H = hi(mem_SDGCTL);
167         [P2] = R0;
168         SSYNC;
169         nop;
170
171         (P5:0) = [SP++];
172         (R7:0) = [SP++];
173         RETS   = [SP++];
174         ASTAT  = [SP++];
175         RTS;