]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/bf537-stamp/post-memory.c
Blackfin: tighten up post memory coding style
[karo-tx-uboot.git] / board / bf537-stamp / post-memory.c
1 #include <common.h>
2 #include <asm/io.h>
3
4 #ifdef CONFIG_POST
5
6 #include <post.h>
7 #include <watchdog.h>
8
9 #if CONFIG_POST & CONFIG_SYS_POST_MEMORY
10 #define CLKIN 25000000
11 #define PATTERN1 0x5A5A5A5A
12 #define PATTERN2 0xAAAAAAAA
13
14 #define CCLK_NUM        4
15 #define SCLK_NUM        3
16
17 void post_out_buff(char *buff);
18 int post_key_pressed(void);
19 void post_init_pll(int mult, int div);
20 int post_init_sdram(int sclk);
21 void post_init_uart(int sclk);
22
23 const int pll[CCLK_NUM][SCLK_NUM][2] = {
24         { {20, 4}, {20, 5}, {20, 10} }, /* CCLK = 500M */
25         { {16, 4}, {16, 5}, {16, 8} },  /* CCLK = 400M */
26         { {8, 2}, {8, 4}, {8, 5} },     /* CCLK = 200M */
27         { {4, 1}, {4, 2}, {4, 4} }      /* CCLK = 100M */
28 };
29 const char *const log[CCLK_NUM][SCLK_NUM] = {
30         {"CCLK-500MHz SCLK-125MHz:    Writing...\0",
31          "CCLK-500MHz SCLK-100MHz:    Writing...\0",
32          "CCLK-500MHz SCLK- 50MHz:    Writing...\0",},
33         {"CCLK-400MHz SCLK-100MHz:    Writing...\0",
34          "CCLK-400MHz SCLK- 80MHz:    Writing...\0",
35          "CCLK-400MHz SCLK- 50MHz:    Writing...\0",},
36         {"CCLK-200MHz SCLK-100MHz:    Writing...\0",
37          "CCLK-200MHz SCLK- 50MHz:    Writing...\0",
38          "CCLK-200MHz SCLK- 40MHz:    Writing...\0",},
39         {"CCLK-100MHz SCLK-100MHz:    Writing...\0",
40          "CCLK-100MHz SCLK- 50MHz:    Writing...\0",
41          "CCLK-100MHz SCLK- 25MHz:    Writing...\0",},
42 };
43
44 int memory_post_test(int flags)
45 {
46         int addr;
47         int m, n;
48         int sclk, sclk_temp;
49         int ret = 1;
50
51         sclk_temp = CLKIN / 1000000;
52         sclk_temp = sclk_temp * CONFIG_VCO_MULT;
53         for (sclk = 0; sclk_temp > 0; sclk++)
54                 sclk_temp -= CONFIG_SCLK_DIV;
55         sclk = sclk * 1000000;
56         post_init_uart(sclk);
57         if (post_key_pressed() == 0)
58                 return 0;
59
60         for (m = 0; m < CCLK_NUM; m++) {
61                 for (n = 0; n < SCLK_NUM; n++) {
62                         /* Calculate the sclk */
63                         sclk_temp = CLKIN / 1000000;
64                         sclk_temp = sclk_temp * pll[m][n][0];
65                         for (sclk = 0; sclk_temp > 0; sclk++)
66                                 sclk_temp -= pll[m][n][1];
67                         sclk = sclk * 1000000;
68
69                         post_init_pll(pll[m][n][0], pll[m][n][1]);
70                         post_init_sdram(sclk);
71                         post_init_uart(sclk);
72                         post_out_buff("\n\r\0");
73                         post_out_buff(log[m][n]);
74                         for (addr = 0x0; addr < CONFIG_SYS_MAX_RAM_SIZE; addr += 4)
75                                 *(unsigned long *)addr = PATTERN1;
76                         post_out_buff("Reading...\0");
77                         for (addr = 0x0; addr < CONFIG_SYS_MAX_RAM_SIZE; addr += 4) {
78                                 if ((*(unsigned long *)addr) != PATTERN1) {
79                                         post_out_buff("Error\n\r\0");
80                                         ret = 0;
81                                 }
82                         }
83                         post_out_buff("OK\n\r\0");
84                 }
85         }
86         if (ret)
87                 post_out_buff("memory POST passed\n\r\0");
88         else
89                 post_out_buff("memory POST failed\n\r\0");
90
91         post_out_buff("\n\r\n\r\0");
92         return 1;
93 }
94
95 void post_init_uart(int sclk)
96 {
97         int divisor;
98
99         for (divisor = 0; sclk > 0; divisor++)
100                 sclk -= 57600 * 16;
101
102         *pPORTF_FER = 0x000F;
103         *pPORTH_FER = 0xFFFF;
104
105         *pUART_GCTL = 0x00;
106         *pUART_LCR = 0x83;
107         SSYNC();
108         *pUART_DLL = (divisor & 0xFF);
109         SSYNC();
110         *pUART_DLH = ((divisor >> 8) & 0xFF);
111         SSYNC();
112         *pUART_LCR = 0x03;
113         SSYNC();
114         *pUART_GCTL = 0x01;
115         SSYNC();
116 }
117
118 void post_out_buff(char *buff)
119 {
120
121         int i = 0;
122         for (i = 0; i < 0x80000; i++)
123                 ;
124         i = 0;
125         while ((buff[i] != '\0') && (i != 100)) {
126                 while (!(*pUART_LSR & 0x20)) ;
127                 *pUART_THR = buff[i];
128                 SSYNC();
129                 i++;
130         }
131         for (i = 0; i < 0x80000; i++)
132                 ;
133 }
134
135 /* Using sw10-PF5 as the hotkey */
136 #define KEY_LOOP 0x80000
137 #define KEY_DELAY 0x80
138 int post_key_pressed(void)
139 {
140         int i, n;
141         unsigned short value;
142
143         *pPORTF_FER &= ~PF5;
144         *pPORTFIO_DIR &= ~PF5;
145         *pPORTFIO_INEN |= PF5;
146         SSYNC();
147
148         post_out_buff("########Press SW10 to enter Memory POST########: 3\0");
149         for (i = 0; i < KEY_LOOP; i++) {
150                 value = *pPORTFIO & PF5;
151                 if (*pUART0_RBR == 0x0D) {
152                         value = 0;
153                         goto key_pressed;
154                 }
155                 if (value != 0)
156                         goto key_pressed;
157                 for (n = 0; n < KEY_DELAY; n++)
158                         asm("nop");
159         }
160         post_out_buff("\b2\0");
161
162         for (i = 0; i < KEY_LOOP; i++) {
163                 value = *pPORTFIO & PF5;
164                 if (*pUART0_RBR == 0x0D) {
165                         value = 0;
166                         goto key_pressed;
167                 }
168                 if (value != 0)
169                         goto key_pressed;
170                 for (n = 0; n < KEY_DELAY; n++)
171                         asm("nop");
172         }
173         post_out_buff("\b1\0");
174
175         for (i = 0; i < KEY_LOOP; i++) {
176                 value = *pPORTFIO & PF5;
177                 if (*pUART0_RBR == 0x0D) {
178                         value = 0;
179                         goto key_pressed;
180                 }
181                 if (value != 0)
182                         goto key_pressed;
183                 for (n = 0; n < KEY_DELAY; n++)
184                         asm("nop");
185         }
186       key_pressed:
187         post_out_buff("\b0");
188         post_out_buff("\n\r\0");
189         if (value == 0)
190                 return 0;
191         post_out_buff("Hotkey has been pressed, Enter POST . . . . . .\n\r\0");
192         return 1;
193 }
194
195 void post_init_pll(int mult, int div)
196 {
197
198         *pSIC_IWR = 0x01;
199         *pPLL_CTL = (mult << 9);
200         *pPLL_DIV = div;
201         asm("CLI R2;");
202         asm("IDLE;");
203         asm("STI R2;");
204         while (!(*pPLL_STAT & 0x20)) ;
205 }
206
207 int post_init_sdram(int sclk)
208 {
209         int SDRAM_tRP, SDRAM_tRP_num, SDRAM_tRAS, SDRAM_tRAS_num, SDRAM_tRCD,
210             SDRAM_tWR;
211         int SDRAM_Tref, SDRAM_NRA, SDRAM_CL, SDRAM_SIZE, SDRAM_WIDTH,
212             mem_SDGCTL, mem_SDBCTL, mem_SDRRC;
213
214         if ((sclk > 119402985)) {
215                 SDRAM_tRP = TRP_2;
216                 SDRAM_tRP_num = 2;
217                 SDRAM_tRAS = TRAS_7;
218                 SDRAM_tRAS_num = 7;
219                 SDRAM_tRCD = TRCD_2;
220                 SDRAM_tWR = TWR_2;
221         } else if ((sclk > 104477612) && (sclk <= 119402985)) {
222                 SDRAM_tRP = TRP_2;
223                 SDRAM_tRP_num = 2;
224                 SDRAM_tRAS = TRAS_6;
225                 SDRAM_tRAS_num = 6;
226                 SDRAM_tRCD = TRCD_2;
227                 SDRAM_tWR = TWR_2;
228         } else if ((sclk > 89552239) && (sclk <= 104477612)) {
229                 SDRAM_tRP = TRP_2;
230                 SDRAM_tRP_num = 2;
231                 SDRAM_tRAS = TRAS_5;
232                 SDRAM_tRAS_num = 5;
233                 SDRAM_tRCD = TRCD_2;
234                 SDRAM_tWR = TWR_2;
235         } else if ((sclk > 74626866) && (sclk <= 89552239)) {
236                 SDRAM_tRP = TRP_2;
237                 SDRAM_tRP_num = 2;
238                 SDRAM_tRAS = TRAS_4;
239                 SDRAM_tRAS_num = 4;
240                 SDRAM_tRCD = TRCD_2;
241                 SDRAM_tWR = TWR_2;
242         } else if ((sclk > 66666667) && (sclk <= 74626866)) {
243                 SDRAM_tRP = TRP_2;
244                 SDRAM_tRP_num = 2;
245                 SDRAM_tRAS = TRAS_3;
246                 SDRAM_tRAS_num = 3;
247                 SDRAM_tRCD = TRCD_2;
248                 SDRAM_tWR = TWR_2;
249         } else if ((sclk > 59701493) && (sclk <= 66666667)) {
250                 SDRAM_tRP = TRP_1;
251                 SDRAM_tRP_num = 1;
252                 SDRAM_tRAS = TRAS_4;
253                 SDRAM_tRAS_num = 4;
254                 SDRAM_tRCD = TRCD_1;
255                 SDRAM_tWR = TWR_2;
256         } else if ((sclk > 44776119) && (sclk <= 59701493)) {
257                 SDRAM_tRP = TRP_1;
258                 SDRAM_tRP_num = 1;
259                 SDRAM_tRAS = TRAS_3;
260                 SDRAM_tRAS_num = 3;
261                 SDRAM_tRCD = TRCD_1;
262                 SDRAM_tWR = TWR_2;
263         } else if ((sclk > 29850746) && (sclk <= 44776119)) {
264                 SDRAM_tRP = TRP_1;
265                 SDRAM_tRP_num = 1;
266                 SDRAM_tRAS = TRAS_2;
267                 SDRAM_tRAS_num = 2;
268                 SDRAM_tRCD = TRCD_1;
269                 SDRAM_tWR = TWR_2;
270         } else if (sclk <= 29850746) {
271                 SDRAM_tRP = TRP_1;
272                 SDRAM_tRP_num = 1;
273                 SDRAM_tRAS = TRAS_1;
274                 SDRAM_tRAS_num = 1;
275                 SDRAM_tRCD = TRCD_1;
276                 SDRAM_tWR = TWR_2;
277         } else {
278                 SDRAM_tRP = TRP_1;
279                 SDRAM_tRP_num = 1;
280                 SDRAM_tRAS = TRAS_1;
281                 SDRAM_tRAS_num = 1;
282                 SDRAM_tRCD = TRCD_1;
283                 SDRAM_tWR = TWR_2;
284         }
285         /*SDRAM INFORMATION: */
286         SDRAM_Tref = 64;        /* Refresh period in milliseconds */
287         SDRAM_NRA = 4096;       /* Number of row addresses in SDRAM */
288         SDRAM_CL = CL_3;        /* 2 */
289
290         SDRAM_SIZE = EBSZ_64;
291         SDRAM_WIDTH = EBCAW_10;
292
293         mem_SDBCTL = SDRAM_WIDTH | SDRAM_SIZE | EBE;
294
295         /* Equation from section 17 (p17-46) of BF533 HRM */
296         mem_SDRRC =
297             (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) -
298             (SDRAM_tRAS_num + SDRAM_tRP_num);
299
300         /* Enable SCLK Out */
301         mem_SDGCTL =
302             (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR
303              | PSS);
304
305         SSYNC();
306
307         *pEBIU_SDGCTL |= 0x1000000;
308         /* Set the SDRAM Refresh Rate control register based on SSCLK value */
309         *pEBIU_SDRRC = mem_SDRRC;
310
311         /* SDRAM Memory Bank Control Register */
312         *pEBIU_SDBCTL = mem_SDBCTL;
313
314         /* SDRAM Memory Global Control Register */
315         *pEBIU_SDGCTL = mem_SDGCTL;
316         SSYNC();
317         return mem_SDRRC;
318 }
319
320 #endif                          /* CONFIG_POST & CONFIG_SYS_POST_MEMORY */
321 #endif                          /* CONFIG_POST */