Merge branch 'master' of git://www.denx.de/git/u-boot-ixp
[oweals/u-boot.git] / cpu / bf537 / 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 .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;
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          * Now, Initialize the SDRAM,
123          * start with the SDRAM Refresh Rate Control Register
124          */
125         p0.l = lo(EBIU_SDRRC);
126         p0.h = hi(EBIU_SDRRC);
127         r0 = mem_SDRRC;
128         w[p0] = r0.l;
129         ssync;
130
131         /*
132          * SDRAM Memory Bank Control Register - bank specific parameters
133          */
134         p0.l = (EBIU_SDBCTL & 0xFFFF);
135         p0.h = (EBIU_SDBCTL >> 16);
136         r0 = mem_SDBCTL;
137         w[p0] = r0.l;
138         ssync;
139
140         /*
141          * SDRAM Global Control Register - global programmable parameters
142          * Disable self-refresh
143          */
144         P2.H = hi(EBIU_SDGCTL);
145         P2.L = lo(EBIU_SDGCTL);
146         R0 = [P2];
147         BITCLR (R0, 24);
148
149         /*
150          * Check if SDRAM is already powered up, if it is, enable self-refresh
151          */
152         p0.h = hi(EBIU_SDSTAT);
153         p0.l = lo(EBIU_SDSTAT);
154         r2.l = w[p0];
155         cc = bittst(r2,3);
156         if !cc jump skip;
157         NOP;
158         BITSET (R0, 23);
159 skip:
160         [P2] = R0;
161         SSYNC;
162
163         /* Write in the new value in the register */
164         R0.L = lo(mem_SDGCTL);
165         R0.H = hi(mem_SDGCTL);
166         [P2] = R0;
167         SSYNC;
168         nop;
169
170         (P5:0) = [SP++];
171         (R7:0) = [SP++];
172         RETS   = [SP++];
173         ASTAT  = [SP++];
174         RTS;