denali_data_eye.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /*
  2. * cpu/ppc4xx/denali_data_eye.c
  3. * Extracted from board/amcc/sequoia/sdram.c by Larry Johnson <lrj@acm.org>.
  4. *
  5. * (C) Copyright 2006
  6. * Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com
  7. * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
  8. * Thierry Roman, AMCC/IBM, thierry_roman@fr.ibm.com
  9. * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com
  10. * Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com
  11. *
  12. * (C) Copyright 2006-2007
  13. * Stefan Roese, DENX Software Engineering, sr@denx.de.
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License as
  17. * published by the Free Software Foundation; either version 2 of
  18. * the License, or (at your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  28. * MA 02111-1307 USA
  29. */
  30. /* define DEBUG for debugging output (obviously ;-)) */
  31. #if 0
  32. #define DEBUG
  33. #endif
  34. #include <common.h>
  35. #include <asm/processor.h>
  36. #include <asm/io.h>
  37. #include <ppc4xx.h>
  38. #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
  39. /*-----------------------------------------------------------------------------+
  40. * denali_wait_for_dlllock.
  41. +----------------------------------------------------------------------------*/
  42. int denali_wait_for_dlllock(void)
  43. {
  44. u32 val;
  45. int wait;
  46. /* -----------------------------------------------------------+
  47. * Wait for the DCC master delay line to finish calibration
  48. * ----------------------------------------------------------*/
  49. for (wait = 0; wait != 0xffff; ++wait) {
  50. mfsdram(DDR0_17, val);
  51. if (DDR0_17_DLLLOCKREG_DECODE(val)) {
  52. /* dlllockreg bit on */
  53. return 0;
  54. }
  55. }
  56. debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
  57. debug("Waiting for dlllockreg bit to raise\n");
  58. return -1;
  59. }
  60. #if defined(CONFIG_DDR_DATA_EYE)
  61. #define DDR_DCR_BASE 0x10
  62. #define ddrcfga (DDR_DCR_BASE+0x0) /* DDR configuration address reg */
  63. #define ddrcfgd (DDR_DCR_BASE+0x1) /* DDR configuration data reg */
  64. /*-----------------------------------------------------------------------------+
  65. * wait_for_dram_init_complete.
  66. +----------------------------------------------------------------------------*/
  67. static int wait_for_dram_init_complete(void)
  68. {
  69. unsigned long val;
  70. int wait = 0;
  71. /* --------------------------------------------------------------+
  72. * Wait for 'DRAM initialization complete' bit in status register
  73. * -------------------------------------------------------------*/
  74. mtdcr(ddrcfga, DDR0_00);
  75. while (wait != 0xffff) {
  76. val = mfdcr(ddrcfgd);
  77. if ((val & DDR0_00_INT_STATUS_BIT6) == DDR0_00_INT_STATUS_BIT6)
  78. /* 'DRAM initialization complete' bit */
  79. return 0;
  80. else
  81. wait++;
  82. }
  83. debug("DRAM initialization complete bit in status register did not "
  84. "rise\n");
  85. return -1;
  86. }
  87. #define NUM_TRIES 64
  88. #define NUM_READS 10
  89. /*-----------------------------------------------------------------------------+
  90. * denali_core_search_data_eye.
  91. +----------------------------------------------------------------------------*/
  92. void denali_core_search_data_eye(void)
  93. {
  94. int k, j;
  95. u32 val;
  96. u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X;
  97. u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0;
  98. u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0;
  99. u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0;
  100. volatile u32 *ram_pointer;
  101. u32 test[NUM_TRIES] = {
  102. 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
  103. 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
  104. 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
  105. 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
  106. 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
  107. 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
  108. 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
  109. 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
  110. 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
  111. 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
  112. 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
  113. 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
  114. 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
  115. 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
  116. 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
  117. 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55
  118. };
  119. ram_pointer = (volatile u32 *)(CONFIG_SYS_SDRAM_BASE);
  120. for (wr_dqs_shift = 64; wr_dqs_shift < 96; wr_dqs_shift++) {
  121. /* for (wr_dqs_shift=1; wr_dqs_shift<96; wr_dqs_shift++) { */
  122. /* -----------------------------------------------------------+
  123. * De-assert 'start' parameter.
  124. * ----------------------------------------------------------*/
  125. mtdcr(ddrcfga, DDR0_02);
  126. val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
  127. DDR0_02_START_OFF;
  128. mtdcr(ddrcfgd, val);
  129. /* -----------------------------------------------------------+
  130. * Set 'wr_dqs_shift'
  131. * ----------------------------------------------------------*/
  132. mtdcr(ddrcfga, DDR0_09);
  133. val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) |
  134. DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
  135. mtdcr(ddrcfgd, val);
  136. /* -----------------------------------------------------------+
  137. * Set 'dqs_out_shift' = wr_dqs_shift + 32
  138. * ----------------------------------------------------------*/
  139. dqs_out_shift = wr_dqs_shift + 32;
  140. mtdcr(ddrcfga, DDR0_22);
  141. val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) |
  142. DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
  143. mtdcr(ddrcfgd, val);
  144. passing_cases = 0;
  145. for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64;
  146. dll_dqs_delay_X++) {
  147. /* for (dll_dqs_delay_X=1; dll_dqs_delay_X<128;
  148. dll_dqs_delay_X++) { */
  149. /* -----------------------------------------------------------+
  150. * Set 'dll_dqs_delay_X'.
  151. * ----------------------------------------------------------*/
  152. /* dll_dqs_delay_0 */
  153. mtdcr(ddrcfga, DDR0_17);
  154. val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
  155. | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
  156. mtdcr(ddrcfgd, val);
  157. /* dll_dqs_delay_1 to dll_dqs_delay_4 */
  158. mtdcr(ddrcfga, DDR0_18);
  159. val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
  160. | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
  161. | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
  162. | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
  163. | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
  164. mtdcr(ddrcfgd, val);
  165. /* dll_dqs_delay_5 to dll_dqs_delay_8 */
  166. mtdcr(ddrcfga, DDR0_19);
  167. val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
  168. | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
  169. | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
  170. | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
  171. | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
  172. mtdcr(ddrcfgd, val);
  173. /* clear any ECC errors */
  174. mtdcr(ddrcfga, DDR0_00);
  175. mtdcr(ddrcfgd,
  176. mfdcr(ddrcfgd) | DDR0_00_INT_ACK_ENCODE(0x3C));
  177. sync();
  178. eieio();
  179. /* -----------------------------------------------------------+
  180. * Assert 'start' parameter.
  181. * ----------------------------------------------------------*/
  182. mtdcr(ddrcfga, DDR0_02);
  183. val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
  184. DDR0_02_START_ON;
  185. mtdcr(ddrcfgd, val);
  186. sync();
  187. eieio();
  188. /* -----------------------------------------------------------+
  189. * Wait for the DCC master delay line to finish calibration
  190. * ----------------------------------------------------------*/
  191. if (denali_wait_for_dlllock() != 0) {
  192. printf("dll lock did not occur !!!\n");
  193. printf("denali_core_search_data_eye!!!\n");
  194. printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
  195. "%d\n", wr_dqs_shift, dll_dqs_delay_X);
  196. hang();
  197. }
  198. sync();
  199. eieio();
  200. if (wait_for_dram_init_complete() != 0) {
  201. printf("dram init complete did not occur!!!\n");
  202. printf("denali_core_search_data_eye!!!\n");
  203. printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
  204. "%d\n", wr_dqs_shift, dll_dqs_delay_X);
  205. hang();
  206. }
  207. udelay(100); /* wait 100us to ensure init is really completed !!! */
  208. /* write values */
  209. for (j = 0; j < NUM_TRIES; j++) {
  210. ram_pointer[j] = test[j];
  211. /* clear any cache at ram location */
  212. __asm__("dcbf 0,%0": :"r"(&ram_pointer[j]));
  213. }
  214. /* read values back */
  215. for (j = 0; j < NUM_TRIES; j++) {
  216. for (k = 0; k < NUM_READS; k++) {
  217. /* clear any cache at ram location */
  218. __asm__("dcbf 0,%0": :"r"(&ram_pointer
  219. [j]));
  220. if (ram_pointer[j] != test[j])
  221. break;
  222. }
  223. /* read error */
  224. if (k != NUM_READS)
  225. break;
  226. }
  227. /* See if the dll_dqs_delay_X value passed. */
  228. mtdcr(ddrcfga, DDR0_00);
  229. if (j < NUM_TRIES
  230. || (DDR0_00_INT_STATUS_DECODE(mfdcr(ddrcfgd)) &
  231. 0x3F)) {
  232. /* Failed */
  233. passing_cases = 0;
  234. /* break; */
  235. } else {
  236. /* Passed */
  237. if (passing_cases == 0)
  238. dll_dqs_delay_X_sw_val =
  239. dll_dqs_delay_X;
  240. passing_cases++;
  241. if (passing_cases >= max_passing_cases) {
  242. max_passing_cases = passing_cases;
  243. wr_dqs_shift_with_max_passing_cases =
  244. wr_dqs_shift;
  245. dll_dqs_delay_X_start_window =
  246. dll_dqs_delay_X_sw_val;
  247. dll_dqs_delay_X_end_window =
  248. dll_dqs_delay_X;
  249. }
  250. }
  251. /* -----------------------------------------------------------+
  252. * De-assert 'start' parameter.
  253. * ----------------------------------------------------------*/
  254. mtdcr(ddrcfga, DDR0_02);
  255. val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
  256. DDR0_02_START_OFF;
  257. mtdcr(ddrcfgd, val);
  258. } /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */
  259. } /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */
  260. /* -----------------------------------------------------------+
  261. * Largest passing window is now detected.
  262. * ----------------------------------------------------------*/
  263. /* Compute dll_dqs_delay_X value */
  264. dll_dqs_delay_X = (dll_dqs_delay_X_end_window +
  265. dll_dqs_delay_X_start_window) / 2;
  266. wr_dqs_shift = wr_dqs_shift_with_max_passing_cases;
  267. debug("DQS calibration - Window detected:\n");
  268. debug("max_passing_cases = %d\n", max_passing_cases);
  269. debug("wr_dqs_shift = %d\n", wr_dqs_shift);
  270. debug("dll_dqs_delay_X = %d\n", dll_dqs_delay_X);
  271. debug("dll_dqs_delay_X window = %d - %d\n",
  272. dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window);
  273. /* -----------------------------------------------------------+
  274. * De-assert 'start' parameter.
  275. * ----------------------------------------------------------*/
  276. mtdcr(ddrcfga, DDR0_02);
  277. val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
  278. mtdcr(ddrcfgd, val);
  279. /* -----------------------------------------------------------+
  280. * Set 'wr_dqs_shift'
  281. * ----------------------------------------------------------*/
  282. mtdcr(ddrcfga, DDR0_09);
  283. val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
  284. | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
  285. mtdcr(ddrcfgd, val);
  286. debug("DDR0_09=0x%08lx\n", val);
  287. /* -----------------------------------------------------------+
  288. * Set 'dqs_out_shift' = wr_dqs_shift + 32
  289. * ----------------------------------------------------------*/
  290. dqs_out_shift = wr_dqs_shift + 32;
  291. mtdcr(ddrcfga, DDR0_22);
  292. val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
  293. | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
  294. mtdcr(ddrcfgd, val);
  295. debug("DDR0_22=0x%08lx\n", val);
  296. /* -----------------------------------------------------------+
  297. * Set 'dll_dqs_delay_X'.
  298. * ----------------------------------------------------------*/
  299. /* dll_dqs_delay_0 */
  300. mtdcr(ddrcfga, DDR0_17);
  301. val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
  302. | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
  303. mtdcr(ddrcfgd, val);
  304. debug("DDR0_17=0x%08lx\n", val);
  305. /* dll_dqs_delay_1 to dll_dqs_delay_4 */
  306. mtdcr(ddrcfga, DDR0_18);
  307. val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
  308. | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
  309. | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
  310. | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
  311. | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
  312. mtdcr(ddrcfgd, val);
  313. debug("DDR0_18=0x%08lx\n", val);
  314. /* dll_dqs_delay_5 to dll_dqs_delay_8 */
  315. mtdcr(ddrcfga, DDR0_19);
  316. val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
  317. | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
  318. | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
  319. | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
  320. | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
  321. mtdcr(ddrcfgd, val);
  322. debug("DDR0_19=0x%08lx\n", val);
  323. /* -----------------------------------------------------------+
  324. * Assert 'start' parameter.
  325. * ----------------------------------------------------------*/
  326. mtdcr(ddrcfga, DDR0_02);
  327. val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
  328. mtdcr(ddrcfgd, val);
  329. sync();
  330. eieio();
  331. /* -----------------------------------------------------------+
  332. * Wait for the DCC master delay line to finish calibration
  333. * ----------------------------------------------------------*/
  334. if (denali_wait_for_dlllock() != 0) {
  335. printf("dll lock did not occur !!!\n");
  336. hang();
  337. }
  338. sync();
  339. eieio();
  340. if (wait_for_dram_init_complete() != 0) {
  341. printf("dram init complete did not occur !!!\n");
  342. hang();
  343. }
  344. udelay(100); /* wait 100us to ensure init is really completed !!! */
  345. }
  346. #endif /* defined(CONFIG_DDR_DATA_EYE) */
  347. #endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */