post-memory.c 7.2 KB

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