post-memory.c 7.3 KB

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