ddr3_dqs.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374
  1. /*
  2. * Copyright (C) Marvell International Ltd. and its affiliates
  3. *
  4. * SPDX-License-Identifier: GPL-2.0
  5. */
  6. #include <common.h>
  7. #include <i2c.h>
  8. #include <spl.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/cpu.h>
  11. #include <asm/arch/soc.h>
  12. #include "ddr3_hw_training.h"
  13. /*
  14. * Debug
  15. */
  16. #define DEBUG_DQS_C(s, d, l) \
  17. DEBUG_DQS_S(s); DEBUG_DQS_D(d, l); DEBUG_DQS_S("\n")
  18. #define DEBUG_DQS_FULL_C(s, d, l) \
  19. DEBUG_DQS_FULL_S(s); DEBUG_DQS_FULL_D(d, l); DEBUG_DQS_FULL_S("\n")
  20. #define DEBUG_DQS_RESULTS_C(s, d, l) \
  21. DEBUG_DQS_RESULTS_S(s); DEBUG_DQS_RESULTS_D(d, l); DEBUG_DQS_RESULTS_S("\n")
  22. #define DEBUG_PER_DQ_C(s, d, l) \
  23. puts(s); printf("%x", d); puts("\n")
  24. #define DEBUG_DQS_RESULTS_S(s) \
  25. debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%s", s)
  26. #define DEBUG_DQS_RESULTS_D(d, l) \
  27. debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%x", d)
  28. #define DEBUG_PER_DQ_S(s) \
  29. debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%s", s)
  30. #define DEBUG_PER_DQ_D(d, l) \
  31. debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%x", d)
  32. #define DEBUG_PER_DQ_DD(d, l) \
  33. debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%d", d)
  34. #ifdef MV_DEBUG_DQS
  35. #define DEBUG_DQS_S(s) puts(s)
  36. #define DEBUG_DQS_D(d, l) printf("%x", d)
  37. #else
  38. #define DEBUG_DQS_S(s)
  39. #define DEBUG_DQS_D(d, l)
  40. #endif
  41. #ifdef MV_DEBUG_DQS_FULL
  42. #define DEBUG_DQS_FULL_S(s) puts(s)
  43. #define DEBUG_DQS_FULL_D(d, l) printf("%x", d)
  44. #else
  45. #define DEBUG_DQS_FULL_S(s)
  46. #define DEBUG_DQS_FULL_D(d, l)
  47. #endif
  48. /* State machine for centralization - find low & high limit */
  49. enum {
  50. PUP_ADLL_LIMITS_STATE_FAIL,
  51. PUP_ADLL_LIMITS_STATE_PASS,
  52. PUP_ADLL_LIMITS_STATE_FAIL_AFTER_PASS,
  53. };
  54. /* Hold centralization low results */
  55. static int centralization_low_limit[MAX_PUP_NUM] = { 0 };
  56. /* Hold centralization high results */
  57. static int centralization_high_limit[MAX_PUP_NUM] = { 0 };
  58. int ddr3_find_adll_limits(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, int is_tx);
  59. int ddr3_check_window_limits(u32 pup, int high_limit, int low_limit, int is_tx,
  60. int *size_valid);
  61. static int ddr3_center_calc(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc,
  62. int is_tx);
  63. int ddr3_special_pattern_i_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc,
  64. int is_tx, u32 special_pattern_pup);
  65. int ddr3_special_pattern_ii_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc,
  66. int is_tx, u32 special_pattern_pup);
  67. int ddr3_set_dqs_centralization_results(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc,
  68. int is_tx);
  69. #ifdef MV88F78X60
  70. extern u32 killer_pattern_32b[DQ_NUM][LEN_SPECIAL_PATTERN];
  71. extern u32 killer_pattern_64b[DQ_NUM][LEN_SPECIAL_PATTERN];
  72. extern int per_bit_data[MAX_PUP_NUM][DQ_NUM];
  73. #else
  74. extern u32 killer_pattern[DQ_NUM][LEN_16BIT_KILLER_PATTERN];
  75. extern u32 killer_pattern_32b[DQ_NUM][LEN_SPECIAL_PATTERN];
  76. #if defined(MV88F672X)
  77. extern int per_bit_data[MAX_PUP_NUM][DQ_NUM];
  78. #endif
  79. #endif
  80. extern u32 special_pattern[DQ_NUM][LEN_SPECIAL_PATTERN];
  81. static u32 *ddr3_dqs_choose_pattern(MV_DRAM_INFO *dram_info, u32 victim_dq)
  82. {
  83. u32 *pattern_ptr;
  84. /* Choose pattern */
  85. switch (dram_info->ddr_width) {
  86. #if defined(MV88F672X)
  87. case 16:
  88. pattern_ptr = (u32 *)&killer_pattern[victim_dq];
  89. break;
  90. #endif
  91. case 32:
  92. pattern_ptr = (u32 *)&killer_pattern_32b[victim_dq];
  93. break;
  94. #if defined(MV88F78X60)
  95. case 64:
  96. pattern_ptr = (u32 *)&killer_pattern_64b[victim_dq];
  97. break;
  98. #endif
  99. default:
  100. #if defined(MV88F78X60)
  101. pattern_ptr = (u32 *)&killer_pattern_32b[victim_dq];
  102. #else
  103. pattern_ptr = (u32 *)&killer_pattern[victim_dq];
  104. #endif
  105. break;
  106. }
  107. return pattern_ptr;
  108. }
  109. /*
  110. * Name: ddr3_dqs_centralization_rx
  111. * Desc: Execute the DQS centralization RX phase.
  112. * Args: dram_info
  113. * Notes:
  114. * Returns: MV_OK if success, other error code if fail.
  115. */
  116. int ddr3_dqs_centralization_rx(MV_DRAM_INFO *dram_info)
  117. {
  118. u32 cs, ecc, reg;
  119. int status;
  120. DEBUG_DQS_S("DDR3 - DQS Centralization RX - Starting procedure\n");
  121. /* Enable SW override */
  122. reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
  123. (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
  124. /* [0] = 1 - Enable SW override */
  125. /* 0x15B8 - Training SW 2 Register */
  126. reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
  127. DEBUG_DQS_S("DDR3 - DQS Centralization RX - SW Override Enabled\n");
  128. reg = (1 << REG_DRAM_TRAINING_AUTO_OFFS);
  129. reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
  130. /* Loop for each CS */
  131. for (cs = 0; cs < MAX_CS; cs++) {
  132. if (dram_info->cs_ena & (1 << cs)) {
  133. DEBUG_DQS_FULL_C("DDR3 - DQS Centralization RX - CS - ",
  134. (u32) cs, 1);
  135. for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) {
  136. /* ECC Support - Switch ECC Mux on ecc=1 */
  137. reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
  138. ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
  139. reg |= (dram_info->ecc_ena *
  140. ecc << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
  141. reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
  142. if (ecc)
  143. DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - ECC Mux Enabled\n");
  144. else
  145. DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - ECC Mux Disabled\n");
  146. DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - Find all limits\n");
  147. status = ddr3_find_adll_limits(dram_info, cs,
  148. ecc, 0);
  149. if (MV_OK != status)
  150. return status;
  151. DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - Start calculating center\n");
  152. status = ddr3_center_calc(dram_info, cs, ecc,
  153. 0);
  154. if (MV_OK != status)
  155. return status;
  156. }
  157. }
  158. }
  159. /* ECC Support - Disable ECC MUX */
  160. reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
  161. ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
  162. reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
  163. /* Disable SW override - Must be in a different stage */
  164. /* [0]=0 - Enable SW override */
  165. reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
  166. reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
  167. /* 0x15B8 - Training SW 2 Register */
  168. reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
  169. reg = reg_read(REG_DRAM_TRAINING_1_ADDR) |
  170. (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS);
  171. reg_write(REG_DRAM_TRAINING_1_ADDR, reg);
  172. return MV_OK;
  173. }
  174. /*
  175. * Name: ddr3_dqs_centralization_tx
  176. * Desc: Execute the DQS centralization TX phase.
  177. * Args: dram_info
  178. * Notes:
  179. * Returns: MV_OK if success, other error code if fail.
  180. */
  181. int ddr3_dqs_centralization_tx(MV_DRAM_INFO *dram_info)
  182. {
  183. u32 cs, ecc, reg;
  184. int status;
  185. DEBUG_DQS_S("DDR3 - DQS Centralization TX - Starting procedure\n");
  186. /* Enable SW override */
  187. reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
  188. (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
  189. /* [0] = 1 - Enable SW override */
  190. /* 0x15B8 - Training SW 2 Register */
  191. reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
  192. DEBUG_DQS_S("DDR3 - DQS Centralization TX - SW Override Enabled\n");
  193. reg = (1 << REG_DRAM_TRAINING_AUTO_OFFS);
  194. reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
  195. /* Loop for each CS */
  196. for (cs = 0; cs < MAX_CS; cs++) {
  197. if (dram_info->cs_ena & (1 << cs)) {
  198. DEBUG_DQS_FULL_C("DDR3 - DQS Centralization TX - CS - ",
  199. (u32) cs, 1);
  200. for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) {
  201. /* ECC Support - Switch ECC Mux on ecc=1 */
  202. reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
  203. ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
  204. reg |= (dram_info->ecc_ena *
  205. ecc << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
  206. reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
  207. if (ecc)
  208. DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - ECC Mux Enabled\n");
  209. else
  210. DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - ECC Mux Disabled\n");
  211. DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - Find all limits\n");
  212. status = ddr3_find_adll_limits(dram_info, cs,
  213. ecc, 1);
  214. if (MV_OK != status)
  215. return status;
  216. DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - Start calculating center\n");
  217. status = ddr3_center_calc(dram_info, cs, ecc,
  218. 1);
  219. if (MV_OK != status)
  220. return status;
  221. }
  222. }
  223. }
  224. /* ECC Support - Disable ECC MUX */
  225. reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
  226. ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
  227. reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
  228. /* Disable SW override - Must be in a different stage */
  229. /* [0]=0 - Enable SW override */
  230. reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
  231. reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
  232. /* 0x15B8 - Training SW 2 Register */
  233. reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
  234. reg = reg_read(REG_DRAM_TRAINING_1_ADDR) |
  235. (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS);
  236. reg_write(REG_DRAM_TRAINING_1_ADDR, reg);
  237. return MV_OK;
  238. }
  239. /*
  240. * Name: ddr3_find_adll_limits
  241. * Desc: Execute the Find ADLL limits phase.
  242. * Args: dram_info
  243. * cs
  244. * ecc_ena
  245. * is_tx Indicate whether Rx or Tx
  246. * Notes:
  247. * Returns: MV_OK if success, other error code if fail.
  248. */
  249. int ddr3_find_adll_limits(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, int is_tx)
  250. {
  251. u32 victim_dq, pup, tmp;
  252. u32 adll_addr;
  253. u32 max_pup; /* maximal pup index */
  254. u32 pup_mask = 0;
  255. u32 unlock_pup; /* bit array of un locked pups */
  256. u32 new_unlock_pup; /* bit array of compare failed pups */
  257. u32 curr_adll;
  258. u32 adll_start_val; /* adll start loop value - for rx or tx limit */
  259. u32 high_limit; /* holds found High Limit */
  260. u32 low_limit; /* holds found Low Limit */
  261. int win_valid;
  262. int update_win;
  263. u32 sdram_offset;
  264. u32 uj, cs_count, cs_tmp, ii;
  265. u32 *pattern_ptr;
  266. u32 dq;
  267. u32 adll_end_val; /* adll end of loop val - for rx or tx limit */
  268. u8 analog_pbs[DQ_NUM][MAX_PUP_NUM][DQ_NUM][2];
  269. u8 analog_pbs_sum[MAX_PUP_NUM][DQ_NUM][2];
  270. int pup_adll_limit_state[MAX_PUP_NUM]; /* hold state of each pup */
  271. adll_addr = ((is_tx == 1) ? PUP_DQS_WR : PUP_DQS_RD);
  272. adll_end_val = ((is_tx == 1) ? ADLL_MIN : ADLL_MAX);
  273. adll_start_val = ((is_tx == 1) ? ADLL_MAX : ADLL_MIN);
  274. max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups);
  275. DEBUG_DQS_FULL_S("DDR3 - DQS Find Limits - Starting Find ADLL Limits\n");
  276. /* init the array */
  277. for (pup = 0; pup < max_pup; pup++) {
  278. centralization_low_limit[pup] = ADLL_MIN;
  279. centralization_high_limit[pup] = ADLL_MAX;
  280. }
  281. /* Killer Pattern */
  282. cs_count = 0;
  283. for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) {
  284. if (dram_info->cs_ena & (1 << cs_tmp))
  285. cs_count++;
  286. }
  287. sdram_offset = cs_count * (SDRAM_CS_SIZE + 1);
  288. sdram_offset += ((is_tx == 1) ?
  289. SDRAM_DQS_TX_OFFS : SDRAM_DQS_RX_OFFS);
  290. /* Prepare pup masks */
  291. for (pup = 0; pup < max_pup; pup++)
  292. pup_mask |= (1 << pup);
  293. for (pup = 0; pup < max_pup; pup++) {
  294. for (dq = 0; dq < DQ_NUM; dq++) {
  295. analog_pbs_sum[pup][dq][0] = adll_start_val;
  296. analog_pbs_sum[pup][dq][1] = adll_end_val;
  297. }
  298. }
  299. /* Loop - use different pattern for each victim_dq */
  300. for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) {
  301. DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Victim DQ - ",
  302. (u32)victim_dq, 1);
  303. /*
  304. * The pups 3 bit arrays represent state machine. with
  305. * 3 stages for each pup.
  306. * 1. fail and didn't get pass in earlier compares.
  307. * 2. pass compare
  308. * 3. fail after pass - end state.
  309. * The window limits are the adll values where the adll
  310. * was in the pass stage.
  311. */
  312. /* Set all states to Fail (1st state) */
  313. for (pup = 0; pup < max_pup; pup++)
  314. pup_adll_limit_state[pup] = PUP_ADLL_LIMITS_STATE_FAIL;
  315. /* Set current valid pups */
  316. unlock_pup = pup_mask;
  317. /* Set ADLL to start value */
  318. curr_adll = adll_start_val;
  319. #if defined(MV88F78X60)
  320. for (pup = 0; pup < max_pup; pup++) {
  321. for (dq = 0; dq < DQ_NUM; dq++) {
  322. analog_pbs[victim_dq][pup][dq][0] =
  323. adll_start_val;
  324. analog_pbs[victim_dq][pup][dq][1] =
  325. adll_end_val;
  326. per_bit_data[pup][dq] = 0;
  327. }
  328. }
  329. #endif
  330. for (uj = 0; uj < ADLL_MAX; uj++) {
  331. DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Setting ADLL to ",
  332. curr_adll, 2);
  333. for (pup = 0; pup < max_pup; pup++) {
  334. if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
  335. tmp = ((is_tx == 1) ? curr_adll +
  336. dram_info->wl_val[cs]
  337. [pup * (1 - ecc) + ecc * ECC_PUP]
  338. [D] : curr_adll);
  339. ddr3_write_pup_reg(adll_addr, cs, pup +
  340. (ecc * ECC_PUP), 0, tmp);
  341. }
  342. }
  343. /* Choose pattern */
  344. pattern_ptr = ddr3_dqs_choose_pattern(dram_info,
  345. victim_dq);
  346. /* '1' - means pup failed, '0' - means pup pass */
  347. new_unlock_pup = 0;
  348. /* Read and compare results for Victim_DQ# */
  349. for (ii = 0; ii < 3; ii++) {
  350. u32 tmp = 0;
  351. if (MV_OK != ddr3_sdram_dqs_compare(dram_info,
  352. unlock_pup, &tmp,
  353. pattern_ptr,
  354. LEN_KILLER_PATTERN,
  355. sdram_offset +
  356. LEN_KILLER_PATTERN *
  357. 4 * victim_dq,
  358. is_tx, 0, NULL,
  359. 0))
  360. return MV_DDR3_TRAINING_ERR_DRAM_COMPARE;
  361. new_unlock_pup |= tmp;
  362. }
  363. pup = 0;
  364. DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - UnlockPup: ",
  365. unlock_pup, 2);
  366. DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - NewUnlockPup: ",
  367. new_unlock_pup, 2);
  368. /* Update pup state */
  369. for (pup = 0; pup < max_pup; pup++) {
  370. if (IS_PUP_ACTIVE(unlock_pup, pup) == 0) {
  371. DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Skipping pup ",
  372. pup, 1);
  373. continue;
  374. }
  375. /*
  376. * Still didn't find the window limit of the pup
  377. */
  378. if (IS_PUP_ACTIVE(new_unlock_pup, pup) == 1) {
  379. /* Current compare result == fail */
  380. if (pup_adll_limit_state[pup] ==
  381. PUP_ADLL_LIMITS_STATE_PASS) {
  382. /*
  383. * If now it failed but passed
  384. * earlier
  385. */
  386. DEBUG_DQS_S("DDR3 - DQS Find Limits - PASS to FAIL: CS - ");
  387. DEBUG_DQS_D(cs, 1);
  388. DEBUG_DQS_S(", DQ - ");
  389. DEBUG_DQS_D(victim_dq, 1);
  390. DEBUG_DQS_S(", Pup - ");
  391. DEBUG_DQS_D(pup, 1);
  392. DEBUG_DQS_S(", ADLL - ");
  393. DEBUG_DQS_D(curr_adll, 2);
  394. DEBUG_DQS_S("\n");
  395. #if defined(MV88F78X60)
  396. for (dq = 0; dq < DQ_NUM; dq++) {
  397. if ((analog_pbs[victim_dq][pup][dq][0] != adll_start_val)
  398. && (analog_pbs[victim_dq][pup]
  399. [dq][1] == adll_end_val))
  400. analog_pbs
  401. [victim_dq]
  402. [pup][dq]
  403. [1] =
  404. curr_adll;
  405. }
  406. #endif
  407. win_valid = 1;
  408. update_win = 0;
  409. /* Keep min / max limit value */
  410. if (is_tx == 0) {
  411. /* RX - found upper limit */
  412. if (centralization_high_limit[pup] >
  413. (curr_adll - 1)) {
  414. high_limit =
  415. curr_adll - 1;
  416. low_limit =
  417. centralization_low_limit[pup];
  418. update_win = 1;
  419. }
  420. } else {
  421. /* TX - found lower limit */
  422. if (centralization_low_limit[pup] < (curr_adll + 1)) {
  423. high_limit =
  424. centralization_high_limit
  425. [pup];
  426. low_limit =
  427. curr_adll + 1;
  428. update_win =
  429. 1;
  430. }
  431. }
  432. if (update_win == 1) {
  433. /*
  434. * Before updating
  435. * window limits we need
  436. * to check that the
  437. * limits are valid
  438. */
  439. if (MV_OK !=
  440. ddr3_check_window_limits
  441. (pup, high_limit,
  442. low_limit, is_tx,
  443. &win_valid))
  444. return MV_DDR3_TRAINING_ERR_WIN_LIMITS;
  445. if (win_valid == 1) {
  446. /*
  447. * Window limits
  448. * should be
  449. * updated
  450. */
  451. centralization_low_limit
  452. [pup] =
  453. low_limit;
  454. centralization_high_limit
  455. [pup] =
  456. high_limit;
  457. }
  458. }
  459. if (win_valid == 1) {
  460. /* Found end of window - lock the pup */
  461. pup_adll_limit_state[pup] =
  462. PUP_ADLL_LIMITS_STATE_FAIL_AFTER_PASS;
  463. unlock_pup &= ~(1 << pup);
  464. } else {
  465. /* Probably false pass - reset status */
  466. pup_adll_limit_state[pup] =
  467. PUP_ADLL_LIMITS_STATE_FAIL;
  468. #if defined(MV88F78X60)
  469. /* Clear logging array of win size (per Dq) */
  470. for (dq = 0;
  471. dq < DQ_NUM;
  472. dq++) {
  473. analog_pbs
  474. [victim_dq]
  475. [pup][dq]
  476. [0] =
  477. adll_start_val;
  478. analog_pbs
  479. [victim_dq]
  480. [pup][dq]
  481. [1] =
  482. adll_end_val;
  483. per_bit_data
  484. [pup][dq]
  485. = 0;
  486. }
  487. #endif
  488. }
  489. }
  490. } else {
  491. /* Current compare result == pass */
  492. if (pup_adll_limit_state[pup] ==
  493. PUP_ADLL_LIMITS_STATE_FAIL) {
  494. /* If now it passed but failed earlier */
  495. DEBUG_DQS_S("DDR3 - DQS Find Limits - FAIL to PASS: CS - ");
  496. DEBUG_DQS_D(cs, 1);
  497. DEBUG_DQS_S(", DQ - ");
  498. DEBUG_DQS_D(victim_dq, 1);
  499. DEBUG_DQS_S(", Pup - ");
  500. DEBUG_DQS_D(pup, 1);
  501. DEBUG_DQS_S(", ADLL - ");
  502. DEBUG_DQS_D(curr_adll, 2);
  503. DEBUG_DQS_S("\n");
  504. #if defined(MV88F78X60)
  505. for (dq = 0; dq < DQ_NUM;
  506. dq++) {
  507. if (analog_pbs[victim_dq][pup][dq][0] == adll_start_val)
  508. analog_pbs
  509. [victim_dq]
  510. [pup][dq]
  511. [0] =
  512. curr_adll;
  513. }
  514. #endif
  515. /* Found start of window */
  516. pup_adll_limit_state[pup] =
  517. PUP_ADLL_LIMITS_STATE_PASS;
  518. /* Keep min / max limit value */
  519. if (is_tx == 0) {
  520. /* RX - found low limit */
  521. if (centralization_low_limit[pup] <= curr_adll)
  522. centralization_low_limit
  523. [pup] =
  524. curr_adll;
  525. } else {
  526. /* TX - found high limit */
  527. if (centralization_high_limit[pup] >= curr_adll)
  528. centralization_high_limit
  529. [pup] =
  530. curr_adll;
  531. }
  532. }
  533. }
  534. }
  535. if (unlock_pup == 0) {
  536. /* Found limit to all pups */
  537. DEBUG_DQS_FULL_S("DDR3 - DQS Find Limits - found PUP limit\n");
  538. break;
  539. }
  540. /*
  541. * Increment / decrement (Move to right / left
  542. * one phase - ADLL) dqs RX / TX delay (for all un
  543. * lock pups
  544. */
  545. if (is_tx == 0)
  546. curr_adll++;
  547. else
  548. curr_adll--;
  549. }
  550. if (unlock_pup != 0) {
  551. /*
  552. * Found pups that didn't reach to the end of the
  553. * state machine
  554. */
  555. DEBUG_DQS_C("DDR3 - DQS Find Limits - Pups that didn't reached end of the state machine: ",
  556. unlock_pup, 1);
  557. for (pup = 0; pup < max_pup; pup++) {
  558. if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
  559. if (pup_adll_limit_state[pup] ==
  560. PUP_ADLL_LIMITS_STATE_FAIL) {
  561. /* ERROR - found fail for all window size */
  562. DEBUG_DQS_S("DDR3 - DQS Find Limits - Got FAIL for the complete range on pup - ");
  563. DEBUG_DQS_D(pup, 1);
  564. DEBUG_DQS_C(" victim DQ ",
  565. victim_dq, 1);
  566. /* For debug - set min limit to illegal limit */
  567. centralization_low_limit[pup]
  568. = ADLL_ERROR;
  569. /*
  570. * In case the pup is in mode
  571. * PASS - the limit is the min
  572. * / max adll, no need to
  573. * update because of the results
  574. * array default value
  575. */
  576. return MV_DDR3_TRAINING_ERR_PUP_RANGE;
  577. }
  578. }
  579. }
  580. }
  581. }
  582. DEBUG_DQS_S("DDR3 - DQS Find Limits - DQ values per victim results:\n");
  583. for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) {
  584. for (pup = 0; pup < max_pup; pup++) {
  585. DEBUG_DQS_S("Victim DQ-");
  586. DEBUG_DQS_D(victim_dq, 1);
  587. DEBUG_DQS_S(", PUP-");
  588. DEBUG_DQS_D(pup, 1);
  589. for (dq = 0; dq < DQ_NUM; dq++) {
  590. DEBUG_DQS_S(", DQ-");
  591. DEBUG_DQS_D(dq, 1);
  592. DEBUG_DQS_S(",S-");
  593. DEBUG_DQS_D(analog_pbs[victim_dq][pup][dq]
  594. [0], 2);
  595. DEBUG_DQS_S(",E-");
  596. DEBUG_DQS_D(analog_pbs[victim_dq][pup][dq]
  597. [1], 2);
  598. if (is_tx == 0) {
  599. if (analog_pbs[victim_dq][pup][dq][0]
  600. > analog_pbs_sum[pup][dq][0])
  601. analog_pbs_sum[pup][dq][0] =
  602. analog_pbs[victim_dq][pup]
  603. [dq][0];
  604. if (analog_pbs[victim_dq][pup][dq][1]
  605. < analog_pbs_sum[pup][dq][1])
  606. analog_pbs_sum[pup][dq][1] =
  607. analog_pbs[victim_dq][pup]
  608. [dq][1];
  609. } else {
  610. if (analog_pbs[victim_dq][pup][dq][0]
  611. < analog_pbs_sum[pup][dq][0])
  612. analog_pbs_sum[pup][dq][0] =
  613. analog_pbs[victim_dq][pup]
  614. [dq][0];
  615. if (analog_pbs[victim_dq][pup][dq][1]
  616. > analog_pbs_sum[pup][dq][1])
  617. analog_pbs_sum[pup][dq][1] =
  618. analog_pbs[victim_dq][pup]
  619. [dq][1];
  620. }
  621. }
  622. DEBUG_DQS_S("\n");
  623. }
  624. }
  625. if (ddr3_get_log_level() >= MV_LOG_LEVEL_3) {
  626. u32 dq;
  627. DEBUG_PER_DQ_S("\n########## LOG LEVEL 3(Windows margins per-DQ) ##########\n");
  628. if (is_tx) {
  629. DEBUG_PER_DQ_C("DDR3 - TX CS: ", cs, 1);
  630. } else {
  631. DEBUG_PER_DQ_C("DDR3 - RX CS: ", cs, 1);
  632. }
  633. if (ecc == 0) {
  634. DEBUG_PER_DQ_S("\n DATA RESULTS:\n");
  635. } else {
  636. DEBUG_PER_DQ_S("\n ECC RESULTS:\n");
  637. }
  638. /* Since all dq has the same value we take 0 as representive */
  639. dq = 0;
  640. for (pup = 0; pup < max_pup; pup++) {
  641. if (ecc == 0) {
  642. DEBUG_PER_DQ_S("\nBYTE:");
  643. DEBUG_PER_DQ_D(pup, 1);
  644. DEBUG_PER_DQ_S("\n");
  645. } else {
  646. DEBUG_PER_DQ_S("\nECC BYTE:\n");
  647. }
  648. DEBUG_PER_DQ_S(" DQ's LOW HIGH WIN-SIZE\n");
  649. DEBUG_PER_DQ_S("============================================\n");
  650. for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) {
  651. if (ecc == 0) {
  652. DEBUG_PER_DQ_S("DQ[");
  653. DEBUG_PER_DQ_DD((victim_dq +
  654. DQ_NUM * pup), 2);
  655. DEBUG_PER_DQ_S("]");
  656. } else {
  657. DEBUG_PER_DQ_S("CB[");
  658. DEBUG_PER_DQ_DD(victim_dq, 2);
  659. DEBUG_PER_DQ_S("]");
  660. }
  661. if (is_tx) {
  662. DEBUG_PER_DQ_S(" 0x");
  663. DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][1], 2); /* low value */
  664. DEBUG_PER_DQ_S(" 0x");
  665. DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0], 2); /* high value */
  666. DEBUG_PER_DQ_S(" 0x");
  667. DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0] - analog_pbs[victim_dq][pup][dq][1], 2); /* win-size */
  668. } else {
  669. DEBUG_PER_DQ_S(" 0x");
  670. DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0], 2); /* low value */
  671. DEBUG_PER_DQ_S(" 0x");
  672. DEBUG_PER_DQ_D((analog_pbs[victim_dq][pup][dq][1] - 1), 2); /* high value */
  673. DEBUG_PER_DQ_S(" 0x");
  674. DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][1] - analog_pbs[victim_dq][pup][dq][0], 2); /* win-size */
  675. }
  676. DEBUG_PER_DQ_S("\n");
  677. }
  678. }
  679. DEBUG_PER_DQ_S("\n");
  680. }
  681. if (is_tx) {
  682. DEBUG_DQS_S("DDR3 - DQS TX - Find Limits - DQ values Summary:\n");
  683. } else {
  684. DEBUG_DQS_S("DDR3 - DQS RX - Find Limits - DQ values Summary:\n");
  685. }
  686. for (pup = 0; pup < max_pup; pup++) {
  687. DEBUG_DQS_S("PUP-");
  688. DEBUG_DQS_D(pup, 1);
  689. for (dq = 0; dq < DQ_NUM; dq++) {
  690. DEBUG_DQS_S(", DQ-");
  691. DEBUG_DQS_D(dq, 1);
  692. DEBUG_DQS_S(",S-");
  693. DEBUG_DQS_D(analog_pbs_sum[pup][dq][0], 2);
  694. DEBUG_DQS_S(",E-");
  695. DEBUG_DQS_D(analog_pbs_sum[pup][dq][1], 2);
  696. }
  697. DEBUG_DQS_S("\n");
  698. }
  699. if (is_tx) {
  700. DEBUG_DQS_S("DDR3 - DQS TX - Find Limits - DQ values Summary:\n");
  701. } else {
  702. DEBUG_DQS_S("DDR3 - DQS RX - Find Limits - DQ values Summary:\n");
  703. }
  704. for (pup = 0; pup < max_pup; pup++) {
  705. if (max_pup == 1) {
  706. /* For ECC PUP */
  707. DEBUG_DQS_S("DDR3 - DQS8");
  708. } else {
  709. DEBUG_DQS_S("DDR3 - DQS");
  710. DEBUG_DQS_D(pup, 1);
  711. }
  712. for (dq = 0; dq < DQ_NUM; dq++) {
  713. DEBUG_DQS_S(", DQ-");
  714. DEBUG_DQS_D(dq, 1);
  715. DEBUG_DQS_S("::S-");
  716. DEBUG_DQS_D(analog_pbs_sum[pup][dq][0], 2);
  717. DEBUG_DQS_S(",E-");
  718. DEBUG_DQS_D(analog_pbs_sum[pup][dq][1], 2);
  719. }
  720. DEBUG_DQS_S("\n");
  721. }
  722. DEBUG_DQS_S("DDR3 - DQS Find Limits - Ended\n");
  723. return MV_OK;
  724. }
  725. /*
  726. * Name: ddr3_check_window_limits
  727. * Desc: Check window High & Low limits.
  728. * Args: pup pup index
  729. * high_limit window high limit
  730. * low_limit window low limit
  731. * is_tx Indicate whether Rx or Tx
  732. * size_valid Indicate whether window size is valid
  733. * Notes:
  734. * Returns: MV_OK if success, other error code if fail.
  735. */
  736. int ddr3_check_window_limits(u32 pup, int high_limit, int low_limit, int is_tx,
  737. int *size_valid)
  738. {
  739. DEBUG_DQS_FULL_S("DDR3 - DQS Check Win Limits - Starting\n");
  740. if (low_limit > high_limit) {
  741. DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup ");
  742. DEBUG_DQS_D(pup, 1);
  743. DEBUG_DQS_S(" Low Limit grater than High Limit\n");
  744. *size_valid = 0;
  745. return MV_OK;
  746. }
  747. /*
  748. * Check that window size is valid, if not it was probably false pass
  749. * before
  750. */
  751. if ((high_limit - low_limit) < MIN_WIN_SIZE) {
  752. /*
  753. * Since window size is too small probably there was false
  754. * pass
  755. */
  756. *size_valid = 0;
  757. DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup ");
  758. DEBUG_DQS_D(pup, 1);
  759. DEBUG_DQS_S(" Window size is smaller than MIN_WIN_SIZE\n");
  760. } else if ((high_limit - low_limit) > ADLL_MAX) {
  761. *size_valid = 0;
  762. DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup ");
  763. DEBUG_DQS_D(pup, 1);
  764. DEBUG_DQS_S
  765. (" Window size is bigger than max ADLL taps (31) Exiting.\n");
  766. return MV_FAIL;
  767. } else {
  768. *size_valid = 1;
  769. DEBUG_DQS_FULL_S("DDR3 - DQS Check Win Limits - Pup ");
  770. DEBUG_DQS_FULL_D(pup, 1);
  771. DEBUG_DQS_FULL_C(" window size is ", (high_limit - low_limit),
  772. 2);
  773. }
  774. return MV_OK;
  775. }
  776. /*
  777. * Name: ddr3_center_calc
  778. * Desc: Execute the calculate the center of windows phase.
  779. * Args: pDram Info
  780. * is_tx Indicate whether Rx or Tx
  781. * Notes:
  782. * Returns: MV_OK if success, other error code if fail.
  783. */
  784. static int ddr3_center_calc(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc,
  785. int is_tx)
  786. {
  787. /* bit array of pups that need specail search */
  788. u32 special_pattern_i_pup = 0;
  789. u32 special_pattern_ii_pup = 0;
  790. u32 pup;
  791. u32 max_pup;
  792. max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups);
  793. for (pup = 0; pup < max_pup; pup++) {
  794. if (is_tx == 0) {
  795. /* Check special pattern I */
  796. /*
  797. * Special pattern Low limit search - relevant only
  798. * for Rx, win size < threshold and low limit = 0
  799. */
  800. if (((centralization_high_limit[pup] -
  801. centralization_low_limit[pup]) < VALID_WIN_THRS)
  802. && (centralization_low_limit[pup] == MIN_DELAY))
  803. special_pattern_i_pup |= (1 << pup);
  804. /* Check special pattern II */
  805. /*
  806. * Special pattern High limit search - relevant only
  807. * for Rx, win size < threshold and high limit = 31
  808. */
  809. if (((centralization_high_limit[pup] -
  810. centralization_low_limit[pup]) < VALID_WIN_THRS)
  811. && (centralization_high_limit[pup] == MAX_DELAY))
  812. special_pattern_ii_pup |= (1 << pup);
  813. }
  814. }
  815. /* Run special pattern Low limit search - for relevant pup */
  816. if (special_pattern_i_pup != 0) {
  817. DEBUG_DQS_S("DDR3 - DQS Center Calc - Entering special pattern I for Low limit search\n");
  818. if (MV_OK !=
  819. ddr3_special_pattern_i_search(dram_info, cs, ecc, is_tx,
  820. special_pattern_i_pup))
  821. return MV_DDR3_TRAINING_ERR_DQS_LOW_LIMIT_SEARCH;
  822. }
  823. /* Run special pattern High limit search - for relevant pup */
  824. if (special_pattern_ii_pup != 0) {
  825. DEBUG_DQS_S("DDR3 - DQS Center Calc - Entering special pattern II for High limit search\n");
  826. if (MV_OK !=
  827. ddr3_special_pattern_ii_search(dram_info, cs, ecc, is_tx,
  828. special_pattern_ii_pup))
  829. return MV_DDR3_TRAINING_ERR_DQS_HIGH_LIMIT_SEARCH;
  830. }
  831. /* Set adll to center = (General_High_limit + General_Low_limit)/2 */
  832. return ddr3_set_dqs_centralization_results(dram_info, cs, ecc, is_tx);
  833. }
  834. /*
  835. * Name: ddr3_special_pattern_i_search
  836. * Desc: Execute special pattern low limit search.
  837. * Args:
  838. * special_pattern_pup The pups that need the special search
  839. * Notes:
  840. * Returns: MV_OK if success, other error code if fail.
  841. */
  842. int ddr3_special_pattern_i_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc,
  843. int is_tx, u32 special_pattern_pup)
  844. {
  845. u32 victim_dq; /* loop index - victim DQ */
  846. u32 adll_idx;
  847. u32 pup;
  848. u32 unlock_pup; /* bit array of the unlock pups */
  849. u32 first_fail; /* bit array - of pups that get first fail */
  850. u32 new_lockup_pup; /* bit array of compare failed pups */
  851. u32 pass_pup; /* bit array of compare pass pup */
  852. u32 sdram_offset;
  853. u32 max_pup;
  854. u32 comp_val;
  855. u32 special_res[MAX_PUP_NUM]; /* hold tmp results */
  856. DEBUG_DQS_S("DDR3 - DQS - Special Pattern I Search - Starting\n");
  857. max_pup = ecc + (1 - ecc) * dram_info->num_of_std_pups;
  858. /* Init the temporary results to max ADLL value */
  859. for (pup = 0; pup < max_pup; pup++)
  860. special_res[pup] = ADLL_MAX;
  861. /* Run special pattern for all DQ - use the same pattern */
  862. for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) {
  863. unlock_pup = special_pattern_pup;
  864. first_fail = 0;
  865. sdram_offset = cs * SDRAM_CS_SIZE + SDRAM_DQS_RX_OFFS +
  866. LEN_KILLER_PATTERN * 4 * victim_dq;
  867. for (pup = 0; pup < max_pup; pup++) {
  868. /* Set adll value per PUP. adll = high limit per pup */
  869. if (IS_PUP_ACTIVE(unlock_pup, pup)) {
  870. /* only for pups that need special search */
  871. ddr3_write_pup_reg(PUP_DQS_RD, cs,
  872. pup + (ecc * ECC_PUP), 0,
  873. centralization_high_limit
  874. [pup]);
  875. }
  876. }
  877. adll_idx = 0;
  878. do {
  879. /*
  880. * Perform read and compare simultaneously for all
  881. * un-locked MC use the special pattern mask
  882. */
  883. new_lockup_pup = 0;
  884. if (MV_OK !=
  885. ddr3_sdram_dqs_compare(dram_info, unlock_pup,
  886. &new_lockup_pup,
  887. special_pattern
  888. [victim_dq],
  889. LEN_SPECIAL_PATTERN,
  890. sdram_offset, 0,
  891. 0, NULL, 1))
  892. return MV_FAIL;
  893. DEBUG_DQS_S("DDR3 - DQS - Special I - ADLL value is: ");
  894. DEBUG_DQS_D(adll_idx, 2);
  895. DEBUG_DQS_S(", UnlockPup: ");
  896. DEBUG_DQS_D(unlock_pup, 2);
  897. DEBUG_DQS_S(", NewLockPup: ");
  898. DEBUG_DQS_D(new_lockup_pup, 2);
  899. DEBUG_DQS_S("\n");
  900. if (unlock_pup != new_lockup_pup)
  901. DEBUG_DQS_S("DDR3 - DQS - Special I - Some Pup passed!\n");
  902. /* Search for pups with passed compare & already fail */
  903. pass_pup = first_fail & ~new_lockup_pup & unlock_pup;
  904. first_fail |= new_lockup_pup;
  905. unlock_pup &= ~pass_pup;
  906. /* Get pass pups */
  907. if (pass_pup != 0) {
  908. for (pup = 0; pup < max_pup; pup++) {
  909. if (IS_PUP_ACTIVE(pass_pup, pup) ==
  910. 1) {
  911. /* If pup passed and has first fail = 1 */
  912. /* keep min value of ADLL max value - current adll */
  913. /* (centralization_high_limit[pup] + adll_idx) = current adll !!! */
  914. comp_val =
  915. (ADLL_MAX -
  916. (centralization_high_limit
  917. [pup] + adll_idx));
  918. DEBUG_DQS_C
  919. ("DDR3 - DQS - Special I - Pup - ",
  920. pup, 1);
  921. DEBUG_DQS_C
  922. (" comp_val = ",
  923. comp_val, 2);
  924. if (comp_val <
  925. special_res[pup]) {
  926. special_res[pup] =
  927. comp_val;
  928. centralization_low_limit
  929. [pup] =
  930. (-1) *
  931. comp_val;
  932. DEBUG_DQS_C
  933. ("DDR3 - DQS - Special I - Pup - ",
  934. pup, 1);
  935. DEBUG_DQS_C
  936. (" Changed Low limit to ",
  937. centralization_low_limit
  938. [pup], 2);
  939. }
  940. }
  941. }
  942. }
  943. /*
  944. * Did all PUP found missing window?
  945. * Check for each pup if adll (different for each pup)
  946. * reach maximum if reach max value - lock the pup
  947. * if not - increment (Move to right one phase - ADLL)
  948. * dqs RX delay
  949. */
  950. adll_idx++;
  951. for (pup = 0; pup < max_pup; pup++) {
  952. if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
  953. /* Check only unlocked pups */
  954. if ((centralization_high_limit[pup] +
  955. adll_idx) >= ADLL_MAX) {
  956. /* reach maximum - lock the pup */
  957. DEBUG_DQS_C("DDR3 - DQS - Special I - reach maximum - lock pup ",
  958. pup, 1);
  959. unlock_pup &= ~(1 << pup);
  960. } else {
  961. /* Didn't reach maximum - increment ADLL */
  962. ddr3_write_pup_reg(PUP_DQS_RD,
  963. cs,
  964. pup +
  965. (ecc *
  966. ECC_PUP), 0,
  967. (centralization_high_limit
  968. [pup] +
  969. adll_idx));
  970. }
  971. }
  972. }
  973. } while (unlock_pup != 0);
  974. }
  975. return MV_OK;
  976. }
  977. /*
  978. * Name: ddr3_special_pattern_ii_search
  979. * Desc: Execute special pattern high limit search.
  980. * Args:
  981. * special_pattern_pup The pups that need the special search
  982. * Notes:
  983. * Returns: MV_OK if success, other error code if fail.
  984. */
  985. int ddr3_special_pattern_ii_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc,
  986. int is_tx, u32 special_pattern_pup)
  987. {
  988. u32 victim_dq; /* loop index - victim DQ */
  989. u32 adll_idx;
  990. u32 pup;
  991. u32 unlock_pup; /* bit array of the unlock pups */
  992. u32 first_fail; /* bit array - of pups that get first fail */
  993. u32 new_lockup_pup; /* bit array of compare failed pups */
  994. u32 pass_pup; /* bit array of compare pass pup */
  995. u32 sdram_offset;
  996. u32 max_pup;
  997. u32 comp_val;
  998. u32 special_res[MAX_PUP_NUM]; /* hold tmp results */
  999. DEBUG_DQS_S("DDR3 - DQS - Special Pattern II Search - Starting\n");
  1000. max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups);
  1001. /* init the tmporary results to max ADLL value */
  1002. for (pup = 0; pup < max_pup; pup++)
  1003. special_res[pup] = ADLL_MAX;
  1004. sdram_offset = cs * SDRAM_CS_SIZE + SDRAM_DQS_RX_OFFS;
  1005. /* run special pattern for all DQ - use the same pattern */
  1006. for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) {
  1007. unlock_pup = special_pattern_pup;
  1008. first_fail = 0;
  1009. for (pup = 0; pup < max_pup; pup++) {
  1010. /* Set adll value per PUP. adll = 0 */
  1011. if (IS_PUP_ACTIVE(unlock_pup, pup)) {
  1012. /* Only for pups that need special search */
  1013. ddr3_write_pup_reg(PUP_DQS_RD, cs,
  1014. pup + (ecc * ECC_PUP), 0,
  1015. ADLL_MIN);
  1016. }
  1017. }
  1018. adll_idx = 0;
  1019. do {
  1020. /*
  1021. * Perform read and compare simultaneously for all
  1022. * un-locked MC use the special pattern mask
  1023. */
  1024. new_lockup_pup = 0;
  1025. if (MV_OK != ddr3_sdram_dqs_compare(
  1026. dram_info, unlock_pup, &new_lockup_pup,
  1027. special_pattern[victim_dq],
  1028. LEN_SPECIAL_PATTERN,
  1029. sdram_offset, 0, 0, NULL, 0))
  1030. return MV_FAIL;
  1031. DEBUG_DQS_S("DDR3 - DQS - Special II - ADLL value is ");
  1032. DEBUG_DQS_D(adll_idx, 2);
  1033. DEBUG_DQS_S("unlock_pup ");
  1034. DEBUG_DQS_D(unlock_pup, 1);
  1035. DEBUG_DQS_S("new_lockup_pup ");
  1036. DEBUG_DQS_D(new_lockup_pup, 1);
  1037. DEBUG_DQS_S("\n");
  1038. if (unlock_pup != new_lockup_pup) {
  1039. DEBUG_DQS_S("DDR3 - DQS - Special II - Some Pup passed!\n");
  1040. }
  1041. /* Search for pups with passed compare & already fail */
  1042. pass_pup = first_fail & ~new_lockup_pup & unlock_pup;
  1043. first_fail |= new_lockup_pup;
  1044. unlock_pup &= ~pass_pup;
  1045. /* Get pass pups */
  1046. if (pass_pup != 0) {
  1047. for (pup = 0; pup < max_pup; pup++) {
  1048. if (IS_PUP_ACTIVE(pass_pup, pup) ==
  1049. 1) {
  1050. /* If pup passed and has first fail = 1 */
  1051. /* keep min value of ADLL max value - current adll */
  1052. /* (adll_idx) = current adll !!! */
  1053. comp_val = adll_idx;
  1054. DEBUG_DQS_C("DDR3 - DQS - Special II - Pup - ",
  1055. pup, 1);
  1056. DEBUG_DQS_C(" comp_val = ",
  1057. comp_val, 1);
  1058. if (comp_val <
  1059. special_res[pup]) {
  1060. special_res[pup] =
  1061. comp_val;
  1062. centralization_high_limit
  1063. [pup] =
  1064. ADLL_MAX +
  1065. comp_val;
  1066. DEBUG_DQS_C
  1067. ("DDR3 - DQS - Special II - Pup - ",
  1068. pup, 1);
  1069. DEBUG_DQS_C
  1070. (" Changed High limit to ",
  1071. centralization_high_limit
  1072. [pup], 2);
  1073. }
  1074. }
  1075. }
  1076. }
  1077. /*
  1078. * Did all PUP found missing window?
  1079. * Check for each pup if adll (different for each pup)
  1080. * reach maximum if reach max value - lock the pup
  1081. * if not - increment (Move to right one phase - ADLL)
  1082. * dqs RX delay
  1083. */
  1084. adll_idx++;
  1085. for (pup = 0; pup < max_pup; pup++) {
  1086. if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
  1087. /* Check only unlocked pups */
  1088. if ((adll_idx) >= ADLL_MAX) {
  1089. /* Reach maximum - lock the pup */
  1090. DEBUG_DQS_C("DDR3 - DQS - Special II - reach maximum - lock pup ",
  1091. pup, 1);
  1092. unlock_pup &= ~(1 << pup);
  1093. } else {
  1094. /* Didn't reach maximum - increment ADLL */
  1095. ddr3_write_pup_reg(PUP_DQS_RD,
  1096. cs,
  1097. pup +
  1098. (ecc *
  1099. ECC_PUP), 0,
  1100. (adll_idx));
  1101. }
  1102. }
  1103. }
  1104. } while (unlock_pup != 0);
  1105. }
  1106. return MV_OK;
  1107. }
  1108. /*
  1109. * Name: ddr3_set_dqs_centralization_results
  1110. * Desc: Set to HW the DQS centralization phase results.
  1111. * Args:
  1112. * is_tx Indicates whether to set Tx or RX results
  1113. * Notes:
  1114. * Returns: MV_OK if success, other error code if fail.
  1115. */
  1116. int ddr3_set_dqs_centralization_results(MV_DRAM_INFO *dram_info, u32 cs,
  1117. u32 ecc, int is_tx)
  1118. {
  1119. u32 pup, pup_num;
  1120. int addl_val;
  1121. u32 max_pup;
  1122. max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups);
  1123. DEBUG_DQS_RESULTS_S("\n############ LOG LEVEL 2(Windows margins) ############\n");
  1124. if (is_tx) {
  1125. DEBUG_DQS_RESULTS_C("DDR3 - DQS TX - Set Dqs Centralization Results - CS: ",
  1126. cs, 1);
  1127. } else {
  1128. DEBUG_DQS_RESULTS_C("DDR3 - DQS RX - Set Dqs Centralization Results - CS: ",
  1129. cs, 1);
  1130. }
  1131. /* Set adll to center = (General_High_limit + General_Low_limit)/2 */
  1132. DEBUG_DQS_RESULTS_S("\nDQS LOW HIGH WIN-SIZE Set\n");
  1133. DEBUG_DQS_RESULTS_S("==============================================\n");
  1134. for (pup = 0; pup < max_pup; pup++) {
  1135. addl_val = (centralization_high_limit[pup] +
  1136. centralization_low_limit[pup]) / 2;
  1137. pup_num = pup * (1 - ecc) + ecc * ECC_PUP;
  1138. DEBUG_DQS_RESULTS_D(pup_num, 1);
  1139. DEBUG_DQS_RESULTS_S(" 0x");
  1140. DEBUG_DQS_RESULTS_D(centralization_low_limit[pup], 2);
  1141. DEBUG_DQS_RESULTS_S(" 0x");
  1142. DEBUG_DQS_RESULTS_D(centralization_high_limit[pup], 2);
  1143. DEBUG_DQS_RESULTS_S(" 0x");
  1144. DEBUG_DQS_RESULTS_D(centralization_high_limit[pup] -
  1145. centralization_low_limit[pup], 2);
  1146. DEBUG_DQS_RESULTS_S(" 0x");
  1147. DEBUG_DQS_RESULTS_D(addl_val, 2);
  1148. DEBUG_DQS_RESULTS_S("\n");
  1149. if (addl_val < ADLL_MIN) {
  1150. addl_val = ADLL_MIN;
  1151. DEBUG_DQS_RESULTS_S("DDR3 - DQS - Setting ADLL value for Pup to MIN (since it was lower than 0)\n");
  1152. }
  1153. if (addl_val > ADLL_MAX) {
  1154. addl_val = ADLL_MAX;
  1155. DEBUG_DQS_RESULTS_S("DDR3 - DQS - Setting ADLL value for Pup to MAX (since it was higher than 31)\n");
  1156. }
  1157. if (is_tx) {
  1158. ddr3_write_pup_reg(PUP_DQS_WR, cs, pup_num, 0,
  1159. addl_val +
  1160. dram_info->wl_val[cs][pup_num][D]);
  1161. } else {
  1162. ddr3_write_pup_reg(PUP_DQS_RD, cs, pup_num, 0,
  1163. addl_val);
  1164. }
  1165. }
  1166. return MV_OK;
  1167. }
  1168. /*
  1169. * Set training patterns
  1170. */
  1171. int ddr3_load_dqs_patterns(MV_DRAM_INFO *dram_info)
  1172. {
  1173. u32 cs, cs_count, cs_tmp, victim_dq;
  1174. u32 sdram_addr;
  1175. u32 *pattern_ptr;
  1176. /* Loop for each CS */
  1177. for (cs = 0; cs < MAX_CS; cs++) {
  1178. if (dram_info->cs_ena & (1 << cs)) {
  1179. cs_count = 0;
  1180. for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) {
  1181. if (dram_info->cs_ena & (1 << cs_tmp))
  1182. cs_count++;
  1183. }
  1184. /* Init killer pattern */
  1185. sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
  1186. SDRAM_DQS_RX_OFFS);
  1187. for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) {
  1188. pattern_ptr = ddr3_dqs_choose_pattern(dram_info,
  1189. victim_dq);
  1190. if (MV_OK != ddr3_sdram_dqs_compare(
  1191. dram_info, (u32)NULL, NULL,
  1192. pattern_ptr, LEN_KILLER_PATTERN,
  1193. sdram_addr + LEN_KILLER_PATTERN *
  1194. 4 * victim_dq, 1, 0, NULL,
  1195. 0))
  1196. return MV_DDR3_TRAINING_ERR_DQS_PATTERN;
  1197. }
  1198. /* Init special-killer pattern */
  1199. sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
  1200. SDRAM_DQS_RX_SPECIAL_OFFS);
  1201. for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) {
  1202. if (MV_OK != ddr3_sdram_dqs_compare(
  1203. dram_info, (u32)NULL, NULL,
  1204. special_pattern[victim_dq],
  1205. LEN_KILLER_PATTERN, sdram_addr +
  1206. LEN_KILLER_PATTERN * 4 * victim_dq,
  1207. 1, 0, NULL, 0))
  1208. return MV_DDR3_TRAINING_ERR_DQS_PATTERN;
  1209. }
  1210. }
  1211. }
  1212. return MV_OK;
  1213. }