1 #include <common.h>
2 #include <asm/io.h>
3 
4 #include <post.h>
5 #include <watchdog.h>
6 
7 #if CONFIG_POST & CONFIG_SYS_POST_MEMORY
8 #define CLKIN 25000000
9 #define PATTERN1 0x5A5A5A5A
10 #define PATTERN2 0xAAAAAAAA
11 
12 #define CCLK_NUM	4
13 #define SCLK_NUM	3
14 
15 void post_out_buff(char *buff);
16 void post_init_pll(int mult, int div);
17 int post_init_sdram(int sclk);
18 void post_init_uart(int sclk);
19 
20 const int pll[CCLK_NUM][SCLK_NUM][2] = {
21 	{ {20, 4}, {20, 5}, {20, 10} },	/* CCLK = 500M */
22 	{ {16, 4}, {16, 5}, {16, 8} },	/* CCLK = 400M */
23 	{ {8, 2}, {8, 4}, {8, 5} },	/* CCLK = 200M */
24 	{ {4, 1}, {4, 2}, {4, 4} }	/* CCLK = 100M */
25 };
26 const char *const log[CCLK_NUM][SCLK_NUM] = {
27 	{"CCLK-500MHz SCLK-125MHz:    Writing...\0",
28 	 "CCLK-500MHz SCLK-100MHz:    Writing...\0",
29 	 "CCLK-500MHz SCLK- 50MHz:    Writing...\0",},
30 	{"CCLK-400MHz SCLK-100MHz:    Writing...\0",
31 	 "CCLK-400MHz SCLK- 80MHz:    Writing...\0",
32 	 "CCLK-400MHz SCLK- 50MHz:    Writing...\0",},
33 	{"CCLK-200MHz SCLK-100MHz:    Writing...\0",
34 	 "CCLK-200MHz SCLK- 50MHz:    Writing...\0",
35 	 "CCLK-200MHz SCLK- 40MHz:    Writing...\0",},
36 	{"CCLK-100MHz SCLK-100MHz:    Writing...\0",
37 	 "CCLK-100MHz SCLK- 50MHz:    Writing...\0",
38 	 "CCLK-100MHz SCLK- 25MHz:    Writing...\0",},
39 };
40 
memory_post_test(int flags)41 int memory_post_test(int flags)
42 {
43 	int addr;
44 	int m, n;
45 	int sclk, sclk_temp;
46 	int ret = 1;
47 
48 	sclk_temp = CLKIN / 1000000;
49 	sclk_temp = sclk_temp * CONFIG_VCO_MULT;
50 	for (sclk = 0; sclk_temp > 0; sclk++)
51 		sclk_temp -= CONFIG_SCLK_DIV;
52 	sclk = sclk * 1000000;
53 	post_init_uart(sclk);
54 	if (post_hotkeys_pressed() == 0)
55 		return 0;
56 
57 	for (m = 0; m < CCLK_NUM; m++) {
58 		for (n = 0; n < SCLK_NUM; n++) {
59 			/* Calculate the sclk */
60 			sclk_temp = CLKIN / 1000000;
61 			sclk_temp = sclk_temp * pll[m][n][0];
62 			for (sclk = 0; sclk_temp > 0; sclk++)
63 				sclk_temp -= pll[m][n][1];
64 			sclk = sclk * 1000000;
65 
66 			post_init_pll(pll[m][n][0], pll[m][n][1]);
67 			post_init_sdram(sclk);
68 			post_init_uart(sclk);
69 			post_out_buff("\n\r\0");
70 			post_out_buff(log[m][n]);
71 			for (addr = 0x0; addr < CONFIG_SYS_MAX_RAM_SIZE; addr += 4)
72 				*(unsigned long *)addr = PATTERN1;
73 			post_out_buff("Reading...\0");
74 			for (addr = 0x0; addr < CONFIG_SYS_MAX_RAM_SIZE; addr += 4) {
75 				if ((*(unsigned long *)addr) != PATTERN1) {
76 					post_out_buff("Error\n\r\0");
77 					ret = 0;
78 				}
79 			}
80 			post_out_buff("OK\n\r\0");
81 		}
82 	}
83 	if (ret)
84 		post_out_buff("memory POST passed\n\r\0");
85 	else
86 		post_out_buff("memory POST failed\n\r\0");
87 
88 	post_out_buff("\n\r\n\r\0");
89 	return 1;
90 }
91 
post_init_uart(int sclk)92 void post_init_uart(int sclk)
93 {
94 	int divisor;
95 
96 	for (divisor = 0; sclk > 0; divisor++)
97 		sclk -= 57600 * 16;
98 
99 	bfin_write_PORTF_FER(0x000F);
100 	bfin_write_PORTH_FER(0xFFFF);
101 
102 	bfin_write_UART_GCTL(0x00);
103 	bfin_write_UART_LCR(0x83);
104 	SSYNC();
105 	bfin_write_UART_DLL(divisor & 0xFF);
106 	SSYNC();
107 	bfin_write_UART_DLH((divisor >> 8) & 0xFF);
108 	SSYNC();
109 	bfin_write_UART_LCR(0x03);
110 	SSYNC();
111 	bfin_write_UART_GCTL(0x01);
112 	SSYNC();
113 }
114 
post_out_buff(char * buff)115 void post_out_buff(char *buff)
116 {
117 
118 	int i = 0;
119 	for (i = 0; i < 0x80000; i++)
120 		;
121 	i = 0;
122 	while ((buff[i] != '\0') && (i != 100)) {
123 		while (!(bfin_read_pUART_LSR() & 0x20)) ;
124 		bfin_write_UART_THR(buff[i]);
125 		SSYNC();
126 		i++;
127 	}
128 	for (i = 0; i < 0x80000; i++)
129 		;
130 }
131 
post_init_pll(int mult,int div)132 void post_init_pll(int mult, int div)
133 {
134 
135 	bfin_write_SIC_IWR(0x01);
136 	bfin_write_PLL_CTL((mult << 9));
137 	bfin_write_PLL_DIV(div);
138 	asm("CLI R2;");
139 	asm("IDLE;");
140 	asm("STI R2;");
141 	while (!(bfin_read_PLL_STAT() & 0x20)) ;
142 }
143 
post_init_sdram(int sclk)144 int post_init_sdram(int sclk)
145 {
146 	int SDRAM_tRP, SDRAM_tRP_num, SDRAM_tRAS, SDRAM_tRAS_num, SDRAM_tRCD,
147 	    SDRAM_tWR;
148 	int SDRAM_Tref, SDRAM_NRA, SDRAM_CL, SDRAM_SIZE, SDRAM_WIDTH,
149 	    mem_SDGCTL, mem_SDBCTL, mem_SDRRC;
150 
151 	if ((sclk > 119402985)) {
152 		SDRAM_tRP = TRP_2;
153 		SDRAM_tRP_num = 2;
154 		SDRAM_tRAS = TRAS_7;
155 		SDRAM_tRAS_num = 7;
156 		SDRAM_tRCD = TRCD_2;
157 		SDRAM_tWR = TWR_2;
158 	} else if ((sclk > 104477612) && (sclk <= 119402985)) {
159 		SDRAM_tRP = TRP_2;
160 		SDRAM_tRP_num = 2;
161 		SDRAM_tRAS = TRAS_6;
162 		SDRAM_tRAS_num = 6;
163 		SDRAM_tRCD = TRCD_2;
164 		SDRAM_tWR = TWR_2;
165 	} else if ((sclk > 89552239) && (sclk <= 104477612)) {
166 		SDRAM_tRP = TRP_2;
167 		SDRAM_tRP_num = 2;
168 		SDRAM_tRAS = TRAS_5;
169 		SDRAM_tRAS_num = 5;
170 		SDRAM_tRCD = TRCD_2;
171 		SDRAM_tWR = TWR_2;
172 	} else if ((sclk > 74626866) && (sclk <= 89552239)) {
173 		SDRAM_tRP = TRP_2;
174 		SDRAM_tRP_num = 2;
175 		SDRAM_tRAS = TRAS_4;
176 		SDRAM_tRAS_num = 4;
177 		SDRAM_tRCD = TRCD_2;
178 		SDRAM_tWR = TWR_2;
179 	} else if ((sclk > 66666667) && (sclk <= 74626866)) {
180 		SDRAM_tRP = TRP_2;
181 		SDRAM_tRP_num = 2;
182 		SDRAM_tRAS = TRAS_3;
183 		SDRAM_tRAS_num = 3;
184 		SDRAM_tRCD = TRCD_2;
185 		SDRAM_tWR = TWR_2;
186 	} else if ((sclk > 59701493) && (sclk <= 66666667)) {
187 		SDRAM_tRP = TRP_1;
188 		SDRAM_tRP_num = 1;
189 		SDRAM_tRAS = TRAS_4;
190 		SDRAM_tRAS_num = 4;
191 		SDRAM_tRCD = TRCD_1;
192 		SDRAM_tWR = TWR_2;
193 	} else if ((sclk > 44776119) && (sclk <= 59701493)) {
194 		SDRAM_tRP = TRP_1;
195 		SDRAM_tRP_num = 1;
196 		SDRAM_tRAS = TRAS_3;
197 		SDRAM_tRAS_num = 3;
198 		SDRAM_tRCD = TRCD_1;
199 		SDRAM_tWR = TWR_2;
200 	} else if ((sclk > 29850746) && (sclk <= 44776119)) {
201 		SDRAM_tRP = TRP_1;
202 		SDRAM_tRP_num = 1;
203 		SDRAM_tRAS = TRAS_2;
204 		SDRAM_tRAS_num = 2;
205 		SDRAM_tRCD = TRCD_1;
206 		SDRAM_tWR = TWR_2;
207 	} else if (sclk <= 29850746) {
208 		SDRAM_tRP = TRP_1;
209 		SDRAM_tRP_num = 1;
210 		SDRAM_tRAS = TRAS_1;
211 		SDRAM_tRAS_num = 1;
212 		SDRAM_tRCD = TRCD_1;
213 		SDRAM_tWR = TWR_2;
214 	} else {
215 		SDRAM_tRP = TRP_1;
216 		SDRAM_tRP_num = 1;
217 		SDRAM_tRAS = TRAS_1;
218 		SDRAM_tRAS_num = 1;
219 		SDRAM_tRCD = TRCD_1;
220 		SDRAM_tWR = TWR_2;
221 	}
222 	/*SDRAM INFORMATION: */
223 	SDRAM_Tref = 64;	/* Refresh period in milliseconds */
224 	SDRAM_NRA = 4096;	/* Number of row addresses in SDRAM */
225 	SDRAM_CL = CL_3;	/* 2 */
226 
227 	SDRAM_SIZE = EBSZ_64;
228 	SDRAM_WIDTH = EBCAW_10;
229 
230 	mem_SDBCTL = SDRAM_WIDTH | SDRAM_SIZE | EBE;
231 
232 	/* Equation from section 17 (p17-46) of BF533 HRM */
233 	mem_SDRRC =
234 	    (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) -
235 	    (SDRAM_tRAS_num + SDRAM_tRP_num);
236 
237 	/* Enable SCLK Out */
238 	mem_SDGCTL =
239 	    (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR
240 	     | PSS);
241 
242 	SSYNC();
243 
244 	bfin_write_EBIU_SDGCTL(bfin_write_EBIU_SDGCTL() | 0x1000000);
245 	/* Set the SDRAM Refresh Rate control register based on SSCLK value */
246 	bfin_write_EBIU_SDRRC(mem_SDRRC);
247 
248 	/* SDRAM Memory Bank Control Register */
249 	bfin_write_EBIU_SDBCTL(mem_SDBCTL);
250 
251 	/* SDRAM Memory Global Control Register */
252 	bfin_write_EBIU_SDGCTL(mem_SDGCTL);
253 	SSYNC();
254 	return mem_SDRRC;
255 }
256 
257 #endif				/* CONFIG_POST & CONFIG_SYS_POST_MEMORY */
258