blob: 1aae9e30f96b95fa36a073383a2150826b51463f [file] [log] [blame]
Aubrey.Li3f0606a2007-03-09 13:38:44 +08001#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 (CONFIG_CCLK_DIV == 1)
10#define CONFIG_CCLK_ACT_DIV CCLK_DIV1
11#endif
12#if (CONFIG_CCLK_DIV == 2)
13#define CONFIG_CCLK_ACT_DIV CCLK_DIV2
14#endif
15#if (CONFIG_CCLK_DIV == 4)
16#define CONFIG_CCLK_ACT_DIV CCLK_DIV4
17#endif
18#if (CONFIG_CCLK_DIV == 8)
19#define CONFIG_CCLK_ACT_DIV CCLK_DIV8
20#endif
21#ifndef CONFIG_CCLK_ACT_DIV
22#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly
23#endif
24
25init_sdram:
26 [--SP] = ASTAT;
27 [--SP] = RETS;
28 [--SP] = (R7:0);
29 [--SP] = (P5:0);
30
Aubrey Li8db13d62007-03-10 23:49:29 +080031#if (BFIN_BOOT_MODE == BF533_SPI_BOOT)
Aubrey.Li3f0606a2007-03-09 13:38:44 +080032 p0.h = hi(SPI_BAUD);
33 p0.l = lo(SPI_BAUD);
34 r0.l = CONFIG_SPI_BAUD;
35 w[p0] = r0.l;
Aubrey Li8db13d62007-03-10 23:49:29 +080036 SSYNC;
Aubrey.Li3f0606a2007-03-09 13:38:44 +080037#endif
38
39 /*
Aubrey Li8db13d62007-03-10 23:49:29 +080040 * PLL_LOCKCNT - how many SCLK Cycles to delay while PLL becomes stable
41 */
Aubrey.Li3f0606a2007-03-09 13:38:44 +080042 p0.h = hi(PLL_LOCKCNT);
43 p0.l = lo(PLL_LOCKCNT);
44 r0 = 0x300(Z);
45 w[p0] = r0.l;
46 ssync;
47
48 /*
Aubrey Li8db13d62007-03-10 23:49:29 +080049 * Put SDRAM in self-refresh, incase anything is running
50 */
51 P2.H = hi(EBIU_SDGCTL);
52 P2.L = lo(EBIU_SDGCTL);
53 R0 = [P2];
54 BITSET (R0, 24);
55 [P2] = R0;
56 SSYNC;
Aubrey.Li3f0606a2007-03-09 13:38:44 +080057
Aubrey Li8db13d62007-03-10 23:49:29 +080058 /*
59 * Set PLL_CTL with the value that we calculate in R0
60 * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
61 * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
62 * - [7] = output delay (add 200ps of delay to mem signals)
63 * - [6] = input delay (add 200ps of input delay to mem signals)
64 * - [5] = PDWN : 1=All Clocks off
65 * - [3] = STOPCK : 1=Core Clock off
66 * - [1] = PLL_OFF : 1=Disable Power to PLL
67 * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
68 * all other bits set to zero
69 */
Aubrey.Li3f0606a2007-03-09 13:38:44 +080070
Aubrey Li8db13d62007-03-10 23:49:29 +080071 r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
72 r0 = r0 << 9; /* Shift it over, */
73 r1 = CONFIG_CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
74 r0 = r1 | r0;
75 r1 = CONFIG_PLL_BYPASS; /* Bypass the PLL? */
76 r1 = r1 << 8; /* Shift it over */
77 r0 = r1 | r0; /* add them all together */
Aubrey.Li3f0606a2007-03-09 13:38:44 +080078
Aubrey Li8db13d62007-03-10 23:49:29 +080079 p0.h = hi(PLL_CTL);
80 p0.l = lo(PLL_CTL); /* Load the address */
81 cli r2; /* Disable interrupts */
Aubrey.Li3f0606a2007-03-09 13:38:44 +080082 ssync;
Aubrey Li8db13d62007-03-10 23:49:29 +080083 w[p0] = r0.l; /* Set the value */
84 idle; /* Wait for the PLL to stablize */
85 sti r2; /* Enable interrupts */
Aubrey.Li3f0606a2007-03-09 13:38:44 +080086
87check_again:
88 p0.h = hi(PLL_STAT);
89 p0.l = lo(PLL_STAT);
90 R0 = W[P0](Z);
91 CC = BITTST(R0,5);
92 if ! CC jump check_again;
93
94 /* Configure SCLK & CCLK Dividers */
Aubrey Li8db13d62007-03-10 23:49:29 +080095 r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
96 p0.h = hi(PLL_DIV);
97 p0.l = lo(PLL_DIV);
98 w[p0] = r0.l;
99 ssync;
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800100
101 /*
Aubrey Li8db13d62007-03-10 23:49:29 +0800102 * We now are running at speed, time to set the Async mem bank wait states
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800103 * This will speed up execution, since we are normally running from FLASH.
104 */
105
Aubrey Li8db13d62007-03-10 23:49:29 +0800106 p2.h = (EBIU_AMBCTL1 >> 16);
107 p2.l = (EBIU_AMBCTL1 & 0xFFFF);
108 r0.h = (AMBCTL1VAL >> 16);
109 r0.l = (AMBCTL1VAL & 0xFFFF);
110 [p2] = r0;
111 ssync;
112
113 p2.h = (EBIU_AMBCTL0 >> 16);
114 p2.l = (EBIU_AMBCTL0 & 0xFFFF);
115 r0.h = (AMBCTL0VAL >> 16);
116 r0.l = (AMBCTL0VAL & 0xFFFF);
117 [p2] = r0;
118 ssync;
119
120 p2.h = (EBIU_AMGCTL >> 16);
121 p2.l = (EBIU_AMGCTL & 0xffff);
122 r0 = AMGCTLVAL;
123 w[p2] = r0;
124 ssync;
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800125
126 /*
127 * Now, Initialize the SDRAM,
128 * start with the SDRAM Refresh Rate Control Register
Aubrey Li8db13d62007-03-10 23:49:29 +0800129 */
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800130 p0.l = lo(EBIU_SDRRC);
Aubrey Li8db13d62007-03-10 23:49:29 +0800131 p0.h = hi(EBIU_SDRRC);
132 r0 = mem_SDRRC;
133 w[p0] = r0.l;
134 ssync;
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800135
136 /*
137 * SDRAM Memory Bank Control Register - bank specific parameters
138 */
139 p0.l = (EBIU_SDBCTL & 0xFFFF);
140 p0.h = (EBIU_SDBCTL >> 16);
141 r0 = mem_SDBCTL;
142 w[p0] = r0.l;
143 ssync;
144
145 /*
146 * SDRAM Global Control Register - global programmable parameters
147 * Disable self-refresh
148 */
149 P2.H = hi(EBIU_SDGCTL);
Aubrey Li8db13d62007-03-10 23:49:29 +0800150 P2.L = lo(EBIU_SDGCTL);
151 R0 = [P2];
152 BITCLR (R0, 24);
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800153
154 /*
Aubrey Li8db13d62007-03-10 23:49:29 +0800155 * Check if SDRAM is already powered up, if it is, enable self-refresh
156 */
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800157 p0.h = hi(EBIU_SDSTAT);
158 p0.l = lo(EBIU_SDSTAT);
159 r2.l = w[p0];
160 cc = bittst(r2,3);
161 if !cc jump skip;
Aubrey Li8db13d62007-03-10 23:49:29 +0800162 NOP;
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800163 BITSET (R0, 23);
164skip:
165 [P2] = R0;
Aubrey Li8db13d62007-03-10 23:49:29 +0800166 SSYNC;
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800167
168 /* Write in the new value in the register */
Aubrey Li8db13d62007-03-10 23:49:29 +0800169 R0.L = lo(mem_SDGCTL);
170 R0.H = hi(mem_SDGCTL);
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800171 [P2] = R0;
Aubrey Li8db13d62007-03-10 23:49:29 +0800172 SSYNC;
Aubrey.Li3f0606a2007-03-09 13:38:44 +0800173 nop;
174
175 (P5:0) = [SP++];
176 (R7:0) = [SP++];
177 RETS = [SP++];
178 ASTAT = [SP++];
179 RTS;