ddr3_training_centralization.c 21 KB

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