ddr3_dqs.c 38 KB

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