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