ddr3_training_centralization.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  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 <spl.h>
  8. #include <asm/io.h>
  9. #include <asm/arch/cpu.h>
  10. #include <asm/arch/soc.h>
  11. #include "ddr3_init.h"
  12. #define VALIDATE_WIN_LENGTH(e1, e2, maxsize) \
  13. (((e2) + 1 > (e1) + (u8)MIN_WINDOW_SIZE) && \
  14. ((e2) + 1 < (e1) + (u8)maxsize))
  15. #define IS_WINDOW_OUT_BOUNDARY(e1, e2, maxsize) \
  16. (((e1) == 0 && (e2) != 0) || \
  17. ((e1) != (maxsize - 1) && (e2) == (maxsize - 1)))
  18. #define CENTRAL_TX 0
  19. #define CENTRAL_RX 1
  20. #define NUM_OF_CENTRAL_TYPES 2
  21. u32 start_pattern = PATTERN_KILLER_DQ0, end_pattern = PATTERN_KILLER_DQ7;
  22. u32 start_if = 0, end_if = (MAX_INTERFACE_NUM - 1);
  23. u8 bus_end_window[NUM_OF_CENTRAL_TYPES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
  24. u8 bus_start_window[NUM_OF_CENTRAL_TYPES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
  25. u8 centralization_state[MAX_INTERFACE_NUM][MAX_BUS_NUM];
  26. static u8 ddr3_tip_special_rx_run_once_flag;
  27. static int ddr3_tip_centralization(u32 dev_num, u32 mode);
  28. /*
  29. * Centralization RX Flow
  30. */
  31. int ddr3_tip_centralization_rx(u32 dev_num)
  32. {
  33. CHECK_STATUS(ddr3_tip_special_rx(dev_num));
  34. CHECK_STATUS(ddr3_tip_centralization(dev_num, CENTRAL_RX));
  35. return MV_OK;
  36. }
  37. /*
  38. * Centralization TX Flow
  39. */
  40. int ddr3_tip_centralization_tx(u32 dev_num)
  41. {
  42. CHECK_STATUS(ddr3_tip_centralization(dev_num, CENTRAL_TX));
  43. return MV_OK;
  44. }
  45. /*
  46. * Centralization Flow
  47. */
  48. static int ddr3_tip_centralization(u32 dev_num, u32 mode)
  49. {
  50. enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
  51. u32 if_id, pattern_id, bit_id;
  52. u8 bus_id;
  53. u8 cur_start_win[BUS_WIDTH_IN_BITS];
  54. u8 centralization_result[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
  55. u8 cur_end_win[BUS_WIDTH_IN_BITS];
  56. u8 current_window[BUS_WIDTH_IN_BITS];
  57. u8 opt_window, waste_window, start_window_skew, end_window_skew;
  58. u8 final_pup_window[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
  59. struct hws_topology_map *tm = ddr3_get_topology_map();
  60. enum hws_training_result result_type = RESULT_PER_BIT;
  61. enum hws_dir direction;
  62. u32 *result[HWS_SEARCH_DIR_LIMIT];
  63. u32 reg_phy_off, reg;
  64. u8 max_win_size;
  65. int lock_success = 1;
  66. u8 cur_end_win_min, cur_start_win_max;
  67. u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
  68. int is_if_fail = 0;
  69. enum hws_result *flow_result = ddr3_tip_get_result_ptr(training_stage);
  70. u32 pup_win_length = 0;
  71. enum hws_search_dir search_dir_id;
  72. u8 cons_tap = (mode == CENTRAL_TX) ? (64) : (0);
  73. for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
  74. VALIDATE_ACTIVE(tm->if_act_mask, if_id);
  75. /* save current cs enable reg val */
  76. CHECK_STATUS(ddr3_tip_if_read
  77. (dev_num, ACCESS_TYPE_UNICAST, if_id,
  78. CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
  79. /* enable single cs */
  80. CHECK_STATUS(ddr3_tip_if_write
  81. (dev_num, ACCESS_TYPE_UNICAST, if_id,
  82. CS_ENABLE_REG, (1 << 3), (1 << 3)));
  83. }
  84. if (mode == CENTRAL_TX) {
  85. max_win_size = MAX_WINDOW_SIZE_TX;
  86. reg_phy_off = WRITE_CENTRALIZATION_PHY_REG + (effective_cs * 4);
  87. direction = OPER_WRITE;
  88. } else {
  89. max_win_size = MAX_WINDOW_SIZE_RX;
  90. reg_phy_off = READ_CENTRALIZATION_PHY_REG + (effective_cs * 4);
  91. direction = OPER_READ;
  92. }
  93. /* DB initialization */
  94. for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
  95. VALIDATE_ACTIVE(tm->if_act_mask, if_id);
  96. for (bus_id = 0;
  97. bus_id < tm->num_of_bus_per_interface; bus_id++) {
  98. VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
  99. centralization_state[if_id][bus_id] = 0;
  100. bus_end_window[mode][if_id][bus_id] =
  101. (max_win_size - 1) + cons_tap;
  102. bus_start_window[mode][if_id][bus_id] = 0;
  103. centralization_result[if_id][bus_id] = 0;
  104. }
  105. }
  106. /* start flow */
  107. for (pattern_id = start_pattern; pattern_id <= end_pattern;
  108. pattern_id++) {
  109. ddr3_tip_ip_training_wrapper(dev_num, ACCESS_TYPE_MULTICAST,
  110. PARAM_NOT_CARE,
  111. ACCESS_TYPE_MULTICAST,
  112. PARAM_NOT_CARE, result_type,
  113. HWS_CONTROL_ELEMENT_ADLL,
  114. PARAM_NOT_CARE, direction,
  115. tm->
  116. if_act_mask, 0x0,
  117. max_win_size - 1,
  118. max_win_size - 1,
  119. pattern_id, EDGE_FPF, CS_SINGLE,
  120. PARAM_NOT_CARE, training_result);
  121. for (if_id = start_if; if_id <= end_if; if_id++) {
  122. VALIDATE_ACTIVE(tm->if_act_mask, if_id);
  123. for (bus_id = 0;
  124. bus_id <= tm->num_of_bus_per_interface - 1;
  125. bus_id++) {
  126. VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
  127. for (search_dir_id = HWS_LOW2HIGH;
  128. search_dir_id <= HWS_HIGH2LOW;
  129. search_dir_id++) {
  130. CHECK_STATUS
  131. (ddr3_tip_read_training_result
  132. (dev_num, if_id,
  133. ACCESS_TYPE_UNICAST, bus_id,
  134. ALL_BITS_PER_PUP,
  135. search_dir_id,
  136. direction, result_type,
  137. TRAINING_LOAD_OPERATION_UNLOAD,
  138. CS_SINGLE,
  139. &result[search_dir_id],
  140. 1, 0, 0));
  141. DEBUG_CENTRALIZATION_ENGINE
  142. (DEBUG_LEVEL_INFO,
  143. ("%s pat %d IF %d pup %d Regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
  144. ((mode ==
  145. CENTRAL_TX) ? "TX" : "RX"),
  146. pattern_id, if_id, bus_id,
  147. result[search_dir_id][0],
  148. result[search_dir_id][1],
  149. result[search_dir_id][2],
  150. result[search_dir_id][3],
  151. result[search_dir_id][4],
  152. result[search_dir_id][5],
  153. result[search_dir_id][6],
  154. result[search_dir_id][7]));
  155. }
  156. for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
  157. bit_id++) {
  158. /* check if this code is valid for 2 edge, probably not :( */
  159. cur_start_win[bit_id] =
  160. GET_TAP_RESULT(result
  161. [HWS_LOW2HIGH]
  162. [bit_id],
  163. EDGE_1);
  164. cur_end_win[bit_id] =
  165. GET_TAP_RESULT(result
  166. [HWS_HIGH2LOW]
  167. [bit_id],
  168. EDGE_1);
  169. /* window length */
  170. current_window[bit_id] =
  171. cur_end_win[bit_id] -
  172. cur_start_win[bit_id] + 1;
  173. DEBUG_CENTRALIZATION_ENGINE
  174. (DEBUG_LEVEL_TRACE,
  175. ("cs %x patern %d IF %d pup %d cur_start_win %d cur_end_win %d current_window %d\n",
  176. effective_cs, pattern_id,
  177. if_id, bus_id,
  178. cur_start_win[bit_id],
  179. cur_end_win[bit_id],
  180. current_window[bit_id]));
  181. }
  182. if ((ddr3_tip_is_pup_lock
  183. (result[HWS_LOW2HIGH], result_type)) &&
  184. (ddr3_tip_is_pup_lock
  185. (result[HWS_HIGH2LOW], result_type))) {
  186. /* read result success */
  187. DEBUG_CENTRALIZATION_ENGINE
  188. (DEBUG_LEVEL_INFO,
  189. ("Pup locked, pat %d IF %d pup %d\n",
  190. pattern_id, if_id, bus_id));
  191. } else {
  192. /* read result failure */
  193. DEBUG_CENTRALIZATION_ENGINE
  194. (DEBUG_LEVEL_INFO,
  195. ("fail Lock, pat %d IF %d pup %d\n",
  196. pattern_id, if_id, bus_id));
  197. if (centralization_state[if_id][bus_id]
  198. == 1) {
  199. /* continue with next pup */
  200. DEBUG_CENTRALIZATION_ENGINE
  201. (DEBUG_LEVEL_TRACE,
  202. ("continue to next pup %d %d\n",
  203. if_id, bus_id));
  204. continue;
  205. }
  206. for (bit_id = 0;
  207. bit_id < BUS_WIDTH_IN_BITS;
  208. bit_id++) {
  209. /*
  210. * the next check is relevant
  211. * only when using search
  212. * machine 2 edges
  213. */
  214. if (cur_start_win[bit_id] > 0 &&
  215. cur_end_win[bit_id] == 0) {
  216. cur_end_win
  217. [bit_id] =
  218. max_win_size - 1;
  219. DEBUG_CENTRALIZATION_ENGINE
  220. (DEBUG_LEVEL_TRACE,
  221. ("fail, IF %d pup %d bit %d fail #1\n",
  222. if_id, bus_id,
  223. bit_id));
  224. /* the next bit */
  225. continue;
  226. } else {
  227. centralization_state
  228. [if_id][bus_id] = 1;
  229. DEBUG_CENTRALIZATION_ENGINE
  230. (DEBUG_LEVEL_TRACE,
  231. ("fail, IF %d pup %d bit %d fail #2\n",
  232. if_id, bus_id,
  233. bit_id));
  234. }
  235. }
  236. if (centralization_state[if_id][bus_id]
  237. == 1) {
  238. /* going to next pup */
  239. continue;
  240. }
  241. } /*bit */
  242. opt_window =
  243. ddr3_tip_get_buf_min(current_window);
  244. /* final pup window length */
  245. final_pup_window[if_id][bus_id] =
  246. ddr3_tip_get_buf_min(cur_end_win) -
  247. ddr3_tip_get_buf_max(cur_start_win) +
  248. 1;
  249. waste_window =
  250. opt_window -
  251. final_pup_window[if_id][bus_id];
  252. start_window_skew =
  253. ddr3_tip_get_buf_max(cur_start_win) -
  254. ddr3_tip_get_buf_min(
  255. cur_start_win);
  256. end_window_skew =
  257. ddr3_tip_get_buf_max(
  258. cur_end_win) -
  259. ddr3_tip_get_buf_min(
  260. cur_end_win);
  261. /* min/max updated with pattern change */
  262. cur_end_win_min =
  263. ddr3_tip_get_buf_min(
  264. cur_end_win);
  265. cur_start_win_max =
  266. ddr3_tip_get_buf_max(
  267. cur_start_win);
  268. bus_end_window[mode][if_id][bus_id] =
  269. GET_MIN(bus_end_window[mode][if_id]
  270. [bus_id],
  271. cur_end_win_min);
  272. bus_start_window[mode][if_id][bus_id] =
  273. GET_MAX(bus_start_window[mode][if_id]
  274. [bus_id],
  275. cur_start_win_max);
  276. DEBUG_CENTRALIZATION_ENGINE(
  277. DEBUG_LEVEL_INFO,
  278. ("pat %d IF %d pup %d opt_win %d final_win %d waste_win %d st_win_skew %d end_win_skew %d cur_st_win_max %d cur_end_win_min %d bus_st_win %d bus_end_win %d\n",
  279. pattern_id, if_id, bus_id, opt_window,
  280. final_pup_window[if_id][bus_id],
  281. waste_window, start_window_skew,
  282. end_window_skew,
  283. cur_start_win_max,
  284. cur_end_win_min,
  285. bus_start_window[mode][if_id][bus_id],
  286. bus_end_window[mode][if_id][bus_id]));
  287. /* check if window is valid */
  288. if (ddr3_tip_centr_skip_min_win_check == 0) {
  289. if ((VALIDATE_WIN_LENGTH
  290. (bus_start_window[mode][if_id]
  291. [bus_id],
  292. bus_end_window[mode][if_id]
  293. [bus_id],
  294. max_win_size) == 1) ||
  295. (IS_WINDOW_OUT_BOUNDARY
  296. (bus_start_window[mode][if_id]
  297. [bus_id],
  298. bus_end_window[mode][if_id]
  299. [bus_id],
  300. max_win_size) == 1)) {
  301. DEBUG_CENTRALIZATION_ENGINE
  302. (DEBUG_LEVEL_INFO,
  303. ("win valid, pat %d IF %d pup %d\n",
  304. pattern_id, if_id,
  305. bus_id));
  306. /* window is valid */
  307. } else {
  308. DEBUG_CENTRALIZATION_ENGINE
  309. (DEBUG_LEVEL_INFO,
  310. ("fail win, pat %d IF %d pup %d bus_st_win %d bus_end_win %d\n",
  311. pattern_id, if_id, bus_id,
  312. bus_start_window[mode]
  313. [if_id][bus_id],
  314. bus_end_window[mode]
  315. [if_id][bus_id]));
  316. centralization_state[if_id]
  317. [bus_id] = 1;
  318. if (debug_mode == 0)
  319. return MV_FAIL;
  320. }
  321. } /* ddr3_tip_centr_skip_min_win_check */
  322. } /* pup */
  323. } /* interface */
  324. } /* pattern */
  325. for (if_id = start_if; if_id <= end_if; if_id++) {
  326. if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
  327. continue;
  328. is_if_fail = 0;
  329. flow_result[if_id] = TEST_SUCCESS;
  330. for (bus_id = 0;
  331. bus_id <= (tm->num_of_bus_per_interface - 1); bus_id++) {
  332. VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
  333. /* continue only if lock */
  334. if (centralization_state[if_id][bus_id] != 1) {
  335. if (ddr3_tip_centr_skip_min_win_check == 0) {
  336. if ((bus_end_window
  337. [mode][if_id][bus_id] ==
  338. (max_win_size - 1)) &&
  339. ((bus_end_window
  340. [mode][if_id][bus_id] -
  341. bus_start_window[mode][if_id]
  342. [bus_id]) < MIN_WINDOW_SIZE) &&
  343. ((bus_end_window[mode][if_id]
  344. [bus_id] - bus_start_window
  345. [mode][if_id][bus_id]) > 2)) {
  346. /* prevent false lock */
  347. /* TBD change to enum */
  348. centralization_state
  349. [if_id][bus_id] = 2;
  350. }
  351. if ((bus_end_window[mode][if_id][bus_id]
  352. == 0) &&
  353. ((bus_end_window[mode][if_id]
  354. [bus_id] -
  355. bus_start_window[mode][if_id]
  356. [bus_id]) < MIN_WINDOW_SIZE) &&
  357. ((bus_end_window[mode][if_id]
  358. [bus_id] -
  359. bus_start_window[mode][if_id]
  360. [bus_id]) > 2))
  361. /*prevent false lock */
  362. centralization_state[if_id]
  363. [bus_id] = 3;
  364. }
  365. if ((bus_end_window[mode][if_id][bus_id] >
  366. (max_win_size - 1)) && direction ==
  367. OPER_WRITE) {
  368. DEBUG_CENTRALIZATION_ENGINE
  369. (DEBUG_LEVEL_INFO,
  370. ("Tx special pattern\n"));
  371. cons_tap = 64;
  372. }
  373. }
  374. /* check states */
  375. if (centralization_state[if_id][bus_id] == 3) {
  376. DEBUG_CENTRALIZATION_ENGINE(
  377. DEBUG_LEVEL_INFO,
  378. ("SSW - TBD IF %d pup %d\n",
  379. if_id, bus_id));
  380. lock_success = 1;
  381. } else if (centralization_state[if_id][bus_id] == 2) {
  382. DEBUG_CENTRALIZATION_ENGINE(
  383. DEBUG_LEVEL_INFO,
  384. ("SEW - TBD IF %d pup %d\n",
  385. if_id, bus_id));
  386. lock_success = 1;
  387. } else if (centralization_state[if_id][bus_id] == 0) {
  388. lock_success = 1;
  389. } else {
  390. DEBUG_CENTRALIZATION_ENGINE(
  391. DEBUG_LEVEL_ERROR,
  392. ("fail, IF %d pup %d\n",
  393. if_id, bus_id));
  394. lock_success = 0;
  395. }
  396. if (lock_success == 1) {
  397. centralization_result[if_id][bus_id] =
  398. (bus_end_window[mode][if_id][bus_id] +
  399. bus_start_window[mode][if_id][bus_id])
  400. / 2 - cons_tap;
  401. DEBUG_CENTRALIZATION_ENGINE(
  402. DEBUG_LEVEL_TRACE,
  403. (" bus_id %d Res= %d\n", bus_id,
  404. centralization_result[if_id][bus_id]));
  405. /* copy results to registers */
  406. pup_win_length =
  407. bus_end_window[mode][if_id][bus_id] -
  408. bus_start_window[mode][if_id][bus_id] +
  409. 1;
  410. ddr3_tip_bus_read(dev_num, if_id,
  411. ACCESS_TYPE_UNICAST, bus_id,
  412. DDR_PHY_DATA,
  413. RESULT_DB_PHY_REG_ADDR +
  414. effective_cs, &reg);
  415. reg = (reg & (~0x1f <<
  416. ((mode == CENTRAL_TX) ?
  417. (RESULT_DB_PHY_REG_TX_OFFSET) :
  418. (RESULT_DB_PHY_REG_RX_OFFSET))))
  419. | pup_win_length <<
  420. ((mode == CENTRAL_TX) ?
  421. (RESULT_DB_PHY_REG_TX_OFFSET) :
  422. (RESULT_DB_PHY_REG_RX_OFFSET));
  423. CHECK_STATUS(ddr3_tip_bus_write
  424. (dev_num, ACCESS_TYPE_UNICAST,
  425. if_id, ACCESS_TYPE_UNICAST,
  426. bus_id, DDR_PHY_DATA,
  427. RESULT_DB_PHY_REG_ADDR +
  428. effective_cs, reg));
  429. /* offset per CS is calculated earlier */
  430. CHECK_STATUS(
  431. ddr3_tip_bus_write(dev_num,
  432. ACCESS_TYPE_UNICAST,
  433. if_id,
  434. ACCESS_TYPE_UNICAST,
  435. bus_id,
  436. DDR_PHY_DATA,
  437. reg_phy_off,
  438. centralization_result
  439. [if_id]
  440. [bus_id]));
  441. } else {
  442. is_if_fail = 1;
  443. }
  444. }
  445. if (is_if_fail == 1)
  446. flow_result[if_id] = TEST_FAILED;
  447. }
  448. for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
  449. /* restore cs enable value */
  450. VALIDATE_ACTIVE(tm->if_act_mask, if_id);
  451. CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_UNICAST,
  452. if_id, CS_ENABLE_REG,
  453. cs_enable_reg_val[if_id],
  454. MASK_ALL_BITS));
  455. }
  456. return is_if_fail;
  457. }
  458. /*
  459. * Centralization Flow
  460. */
  461. int ddr3_tip_special_rx(u32 dev_num)
  462. {
  463. enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
  464. u32 if_id, pup_id, pattern_id, bit_id;
  465. u8 cur_start_win[BUS_WIDTH_IN_BITS];
  466. u8 cur_end_win[BUS_WIDTH_IN_BITS];
  467. enum hws_training_result result_type = RESULT_PER_BIT;
  468. enum hws_dir direction;
  469. enum hws_search_dir search_dir_id;
  470. u32 *result[HWS_SEARCH_DIR_LIMIT];
  471. u32 max_win_size;
  472. u8 cur_end_win_min, cur_start_win_max;
  473. u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
  474. u32 temp = 0;
  475. int pad_num = 0;
  476. struct hws_topology_map *tm = ddr3_get_topology_map();
  477. if (ddr3_tip_special_rx_run_once_flag != 0)
  478. return MV_OK;
  479. ddr3_tip_special_rx_run_once_flag = 1;
  480. for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
  481. VALIDATE_ACTIVE(tm->if_act_mask, if_id);
  482. /* save current cs enable reg val */
  483. CHECK_STATUS(ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST,
  484. if_id, CS_ENABLE_REG,
  485. cs_enable_reg_val,
  486. MASK_ALL_BITS));
  487. /* enable single cs */
  488. CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_UNICAST,
  489. if_id, CS_ENABLE_REG,
  490. (1 << 3), (1 << 3)));
  491. }
  492. max_win_size = MAX_WINDOW_SIZE_RX;
  493. direction = OPER_READ;
  494. pattern_id = PATTERN_VREF;
  495. /* start flow */
  496. ddr3_tip_ip_training_wrapper(dev_num, ACCESS_TYPE_MULTICAST,
  497. PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
  498. PARAM_NOT_CARE, result_type,
  499. HWS_CONTROL_ELEMENT_ADLL,
  500. PARAM_NOT_CARE, direction,
  501. tm->if_act_mask, 0x0,
  502. max_win_size - 1, max_win_size - 1,
  503. pattern_id, EDGE_FPF, CS_SINGLE,
  504. PARAM_NOT_CARE, training_result);
  505. for (if_id = start_if; if_id <= end_if; if_id++) {
  506. VALIDATE_ACTIVE(tm->if_act_mask, if_id);
  507. for (pup_id = 0;
  508. pup_id <= tm->num_of_bus_per_interface; pup_id++) {
  509. VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
  510. for (search_dir_id = HWS_LOW2HIGH;
  511. search_dir_id <= HWS_HIGH2LOW;
  512. search_dir_id++) {
  513. CHECK_STATUS(ddr3_tip_read_training_result
  514. (dev_num, if_id,
  515. ACCESS_TYPE_UNICAST, pup_id,
  516. ALL_BITS_PER_PUP, search_dir_id,
  517. direction, result_type,
  518. TRAINING_LOAD_OPERATION_UNLOAD,
  519. CS_SINGLE, &result[search_dir_id],
  520. 1, 0, 0));
  521. DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_INFO,
  522. ("Special: pat %d IF %d pup %d Regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
  523. pattern_id, if_id,
  524. pup_id,
  525. result
  526. [search_dir_id][0],
  527. result
  528. [search_dir_id][1],
  529. result
  530. [search_dir_id][2],
  531. result
  532. [search_dir_id][3],
  533. result
  534. [search_dir_id][4],
  535. result
  536. [search_dir_id][5],
  537. result
  538. [search_dir_id][6],
  539. result
  540. [search_dir_id]
  541. [7]));
  542. }
  543. for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS; bit_id++) {
  544. /*
  545. * check if this code is valid for 2 edge,
  546. * probably not :(
  547. */
  548. cur_start_win[bit_id] =
  549. GET_TAP_RESULT(result[HWS_LOW2HIGH]
  550. [bit_id], EDGE_1);
  551. cur_end_win[bit_id] =
  552. GET_TAP_RESULT(result[HWS_HIGH2LOW]
  553. [bit_id], EDGE_1);
  554. }
  555. if (!((ddr3_tip_is_pup_lock
  556. (result[HWS_LOW2HIGH], result_type)) &&
  557. (ddr3_tip_is_pup_lock
  558. (result[HWS_HIGH2LOW], result_type)))) {
  559. DEBUG_CENTRALIZATION_ENGINE(
  560. DEBUG_LEVEL_ERROR,
  561. ("Special: Pup lock fail, pat %d IF %d pup %d\n",
  562. pattern_id, if_id, pup_id));
  563. return MV_FAIL;
  564. }
  565. cur_end_win_min =
  566. ddr3_tip_get_buf_min(cur_end_win);
  567. cur_start_win_max =
  568. ddr3_tip_get_buf_max(cur_start_win);
  569. if (cur_start_win_max <= 1) { /* Align left */
  570. for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
  571. bit_id++) {
  572. pad_num =
  573. dq_map_table[bit_id +
  574. pup_id *
  575. BUS_WIDTH_IN_BITS +
  576. if_id *
  577. BUS_WIDTH_IN_BITS *
  578. tm->
  579. num_of_bus_per_interface];
  580. CHECK_STATUS(ddr3_tip_bus_read
  581. (dev_num, if_id,
  582. ACCESS_TYPE_UNICAST,
  583. pup_id, DDR_PHY_DATA,
  584. PBS_RX_PHY_REG + pad_num,
  585. &temp));
  586. temp = (temp + 0xa > 31) ?
  587. (31) : (temp + 0xa);
  588. CHECK_STATUS(ddr3_tip_bus_write
  589. (dev_num,
  590. ACCESS_TYPE_UNICAST,
  591. if_id,
  592. ACCESS_TYPE_UNICAST,
  593. pup_id, DDR_PHY_DATA,
  594. PBS_RX_PHY_REG + pad_num,
  595. temp));
  596. }
  597. DEBUG_CENTRALIZATION_ENGINE(
  598. DEBUG_LEVEL_INFO,
  599. ("Special: PBS:: I/F# %d , Bus# %d fix align to the Left\n",
  600. if_id, pup_id));
  601. }
  602. if (cur_end_win_min > 30) { /* Align right */
  603. CHECK_STATUS(ddr3_tip_bus_read
  604. (dev_num, if_id,
  605. ACCESS_TYPE_UNICAST, pup_id,
  606. DDR_PHY_DATA, PBS_RX_PHY_REG + 4,
  607. &temp));
  608. temp += 0xa;
  609. CHECK_STATUS(ddr3_tip_bus_write
  610. (dev_num, ACCESS_TYPE_UNICAST,
  611. if_id, ACCESS_TYPE_UNICAST,
  612. pup_id, DDR_PHY_DATA,
  613. PBS_RX_PHY_REG + 4, temp));
  614. CHECK_STATUS(ddr3_tip_bus_read
  615. (dev_num, if_id,
  616. ACCESS_TYPE_UNICAST, pup_id,
  617. DDR_PHY_DATA, PBS_RX_PHY_REG + 5,
  618. &temp));
  619. temp += 0xa;
  620. CHECK_STATUS(ddr3_tip_bus_write
  621. (dev_num, ACCESS_TYPE_UNICAST,
  622. if_id, ACCESS_TYPE_UNICAST,
  623. pup_id, DDR_PHY_DATA,
  624. PBS_RX_PHY_REG + 5, temp));
  625. DEBUG_CENTRALIZATION_ENGINE(
  626. DEBUG_LEVEL_INFO,
  627. ("Special: PBS:: I/F# %d , Bus# %d fix align to the right\n",
  628. if_id, pup_id));
  629. }
  630. vref_window_size[if_id][pup_id] =
  631. cur_end_win_min -
  632. cur_start_win_max + 1;
  633. DEBUG_CENTRALIZATION_ENGINE(
  634. DEBUG_LEVEL_INFO,
  635. ("Special: Winsize I/F# %d , Bus# %d is %d\n",
  636. if_id, pup_id, vref_window_size
  637. [if_id][pup_id]));
  638. } /* pup */
  639. } /* end of interface */
  640. return MV_OK;
  641. }
  642. /*
  643. * Print Centralization Result
  644. */
  645. int ddr3_tip_print_centralization_result(u32 dev_num)
  646. {
  647. u32 if_id = 0, bus_id = 0;
  648. struct hws_topology_map *tm = ddr3_get_topology_map();
  649. dev_num = dev_num;
  650. printf("Centralization Results\n");
  651. printf("I/F0 Result[0 - success 1-fail 2 - state_2 3 - state_3] ...\n");
  652. for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
  653. VALIDATE_ACTIVE(tm->if_act_mask, if_id);
  654. for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
  655. bus_id++) {
  656. VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
  657. printf("%d ,\n", centralization_state[if_id][bus_id]);
  658. }
  659. }
  660. return MV_OK;
  661. }