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