ddr3_training_centralization.c 21 KB

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