xor.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * Copyright (C) Marvell International Ltd. and its affiliates
  3. *
  4. * SPDX-License-Identifier: GPL-2.0
  5. */
  6. #include <common.h>
  7. #include <i2c.h>
  8. #include <spl.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/cpu.h>
  11. #include <asm/arch/soc.h>
  12. #include "ddr3_init.h"
  13. #include "xor_regs.h"
  14. /* defines */
  15. #ifdef MV_DEBUG
  16. #define DB(x) x
  17. #else
  18. #define DB(x)
  19. #endif
  20. static u32 ui_xor_regs_ctrl_backup;
  21. static u32 ui_xor_regs_base_backup[MAX_CS];
  22. static u32 ui_xor_regs_mask_backup[MAX_CS];
  23. void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta)
  24. {
  25. u32 reg, ui, base, cs_count;
  26. ui_xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0));
  27. for (ui = 0; ui < MAX_CS; ui++)
  28. ui_xor_regs_base_backup[ui] =
  29. reg_read(XOR_BASE_ADDR_REG(0, ui));
  30. for (ui = 0; ui < MAX_CS; ui++)
  31. ui_xor_regs_mask_backup[ui] =
  32. reg_read(XOR_SIZE_MASK_REG(0, ui));
  33. reg = 0;
  34. for (ui = 0; ui < (num_of_cs); ui++) {
  35. /* Enable Window x for each CS */
  36. reg |= (0x1 << (ui));
  37. /* Enable Window x for each CS */
  38. reg |= (0x3 << ((ui * 2) + 16));
  39. }
  40. reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
  41. cs_count = 0;
  42. for (ui = 0; ui < num_of_cs; ui++) {
  43. if (cs_ena & (1 << ui)) {
  44. /*
  45. * window x - Base - 0x00000000,
  46. * Attribute 0x0e - DRAM
  47. */
  48. base = cs_size * ui + base_delta;
  49. switch (ui) {
  50. case 0:
  51. base |= 0xe00;
  52. break;
  53. case 1:
  54. base |= 0xd00;
  55. break;
  56. case 2:
  57. base |= 0xb00;
  58. break;
  59. case 3:
  60. base |= 0x700;
  61. break;
  62. }
  63. reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);
  64. /* window x - Size */
  65. reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x7fff0000);
  66. cs_count++;
  67. }
  68. }
  69. mv_xor_hal_init(1);
  70. return;
  71. }
  72. void mv_sys_xor_finish(void)
  73. {
  74. u32 ui;
  75. reg_write(XOR_WINDOW_CTRL_REG(0, 0), ui_xor_regs_ctrl_backup);
  76. for (ui = 0; ui < MAX_CS; ui++)
  77. reg_write(XOR_BASE_ADDR_REG(0, ui),
  78. ui_xor_regs_base_backup[ui]);
  79. for (ui = 0; ui < MAX_CS; ui++)
  80. reg_write(XOR_SIZE_MASK_REG(0, ui),
  81. ui_xor_regs_mask_backup[ui]);
  82. reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
  83. }
  84. /*
  85. * mv_xor_hal_init - Initialize XOR engine
  86. *
  87. * DESCRIPTION:
  88. * This function initialize XOR unit.
  89. * INPUT:
  90. * None.
  91. *
  92. * OUTPUT:
  93. * None.
  94. *
  95. * RETURN:
  96. * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  97. */
  98. void mv_xor_hal_init(u32 xor_chan_num)
  99. {
  100. u32 i;
  101. /* Abort any XOR activity & set default configuration */
  102. for (i = 0; i < xor_chan_num; i++) {
  103. mv_xor_command_set(i, MV_STOP);
  104. mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) |
  105. (4 << XEXCR_DST_BURST_LIMIT_OFFS) |
  106. (4 << XEXCR_SRC_BURST_LIMIT_OFFS));
  107. }
  108. }
  109. /*
  110. * mv_xor_ctrl_set - Set XOR channel control registers
  111. *
  112. * DESCRIPTION:
  113. *
  114. * INPUT:
  115. *
  116. * OUTPUT:
  117. * None.
  118. *
  119. * RETURN:
  120. * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  121. * NOTE:
  122. * This function does not modify the Operation_mode field of control register.
  123. */
  124. int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
  125. {
  126. u32 old_value;
  127. /* update the XOR Engine [0..1] Configuration Registers (XEx_c_r) */
  128. old_value = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) &
  129. XEXCR_OPERATION_MODE_MASK;
  130. xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK;
  131. xor_ctrl |= old_value;
  132. reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl);
  133. return MV_OK;
  134. }
  135. int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size,
  136. u32 init_val_high, u32 init_val_low)
  137. {
  138. u32 temp;
  139. /* Parameter checking */
  140. if (chan >= MV_XOR_MAX_CHAN)
  141. return MV_BAD_PARAM;
  142. if (MV_ACTIVE == mv_xor_state_get(chan))
  143. return MV_BUSY;
  144. if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
  145. (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE))
  146. return MV_BAD_PARAM;
  147. /* set the operation mode to Memory Init */
  148. temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
  149. temp &= ~XEXCR_OPERATION_MODE_MASK;
  150. temp |= XEXCR_OPERATION_MODE_MEM_INIT;
  151. reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);
  152. /*
  153. * update the start_ptr field in XOR Engine [0..1] Destination Pointer
  154. * Register
  155. */
  156. reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr);
  157. /*
  158. * update the Block_size field in the XOR Engine[0..1] Block Size
  159. * Registers
  160. */
  161. reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  162. block_size);
  163. /*
  164. * update the field Init_val_l in the XOR Engine Initial Value Register
  165. * Low (XEIVRL)
  166. */
  167. reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low);
  168. /*
  169. * update the field Init_val_h in the XOR Engine Initial Value Register
  170. * High (XEIVRH)
  171. */
  172. reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high);
  173. /* start transfer */
  174. reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  175. XEXACTR_XESTART_MASK);
  176. return MV_OK;
  177. }
  178. /*
  179. * mv_xor_state_get - Get XOR channel state.
  180. *
  181. * DESCRIPTION:
  182. * XOR channel activity state can be active, idle, paused.
  183. * This function retrunes the channel activity state.
  184. *
  185. * INPUT:
  186. * chan - the channel number
  187. *
  188. * OUTPUT:
  189. * None.
  190. *
  191. * RETURN:
  192. * XOR_CHANNEL_IDLE - If the engine is idle.
  193. * XOR_CHANNEL_ACTIVE - If the engine is busy.
  194. * XOR_CHANNEL_PAUSED - If the engine is paused.
  195. * MV_UNDEFINED_STATE - If the engine state is undefind or there is no
  196. * such engine
  197. */
  198. enum mv_state mv_xor_state_get(u32 chan)
  199. {
  200. u32 state;
  201. /* Parameter checking */
  202. if (chan >= MV_XOR_MAX_CHAN) {
  203. DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
  204. return MV_UNDEFINED_STATE;
  205. }
  206. /* read the current state */
  207. state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
  208. state &= XEXACTR_XESTATUS_MASK;
  209. /* return the state */
  210. switch (state) {
  211. case XEXACTR_XESTATUS_IDLE:
  212. return MV_IDLE;
  213. case XEXACTR_XESTATUS_ACTIVE:
  214. return MV_ACTIVE;
  215. case XEXACTR_XESTATUS_PAUSED:
  216. return MV_PAUSED;
  217. }
  218. return MV_UNDEFINED_STATE;
  219. }
  220. /*
  221. * mv_xor_command_set - Set command of XOR channel
  222. *
  223. * DESCRIPTION:
  224. * XOR channel can be started, idle, paused and restarted.
  225. * Paused can be set only if channel is active.
  226. * Start can be set only if channel is idle or paused.
  227. * Restart can be set only if channel is paused.
  228. * Stop can be set only if channel is active.
  229. *
  230. * INPUT:
  231. * chan - The channel number
  232. * command - The command type (start, stop, restart, pause)
  233. *
  234. * OUTPUT:
  235. * None.
  236. *
  237. * RETURN:
  238. * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on
  239. * undefind XOR engine mode
  240. */
  241. int mv_xor_command_set(u32 chan, enum mv_command command)
  242. {
  243. enum mv_state state;
  244. /* Parameter checking */
  245. if (chan >= MV_XOR_MAX_CHAN) {
  246. DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
  247. return MV_BAD_PARAM;
  248. }
  249. /* get the current state */
  250. state = mv_xor_state_get(chan);
  251. if ((command == MV_START) && (state == MV_IDLE)) {
  252. /* command is start and current state is idle */
  253. reg_bit_set(XOR_ACTIVATION_REG
  254. (XOR_UNIT(chan), XOR_CHAN(chan)),
  255. XEXACTR_XESTART_MASK);
  256. return MV_OK;
  257. } else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
  258. /* command is stop and current state is active */
  259. reg_bit_set(XOR_ACTIVATION_REG
  260. (XOR_UNIT(chan), XOR_CHAN(chan)),
  261. XEXACTR_XESTOP_MASK);
  262. return MV_OK;
  263. } else if (((enum mv_state)command == MV_PAUSED) &&
  264. (state == MV_ACTIVE)) {
  265. /* command is paused and current state is active */
  266. reg_bit_set(XOR_ACTIVATION_REG
  267. (XOR_UNIT(chan), XOR_CHAN(chan)),
  268. XEXACTR_XEPAUSE_MASK);
  269. return MV_OK;
  270. } else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
  271. /* command is restart and current state is paused */
  272. reg_bit_set(XOR_ACTIVATION_REG
  273. (XOR_UNIT(chan), XOR_CHAN(chan)),
  274. XEXACTR_XERESTART_MASK);
  275. return MV_OK;
  276. } else if ((command == MV_STOP) && (state == MV_IDLE)) {
  277. /* command is stop and current state is active */
  278. return MV_OK;
  279. }
  280. /* illegal command */
  281. DB(printf("%s: ERR. Illegal command\n", __func__));
  282. return MV_BAD_PARAM;
  283. }
  284. void ddr3_new_tip_ecc_scrub(void)
  285. {
  286. u32 cs_c, max_cs;
  287. u32 cs_ena = 0;
  288. printf("DDR3 Training Sequence - Start scrubbing\n");
  289. max_cs = hws_ddr3_tip_max_cs_get();
  290. for (cs_c = 0; cs_c < max_cs; cs_c++)
  291. cs_ena |= 1 << cs_c;
  292. mv_sys_xor_init(max_cs, cs_ena, 0x80000000, 0);
  293. mv_xor_mem_init(0, 0x00000000, 0x80000000, 0xdeadbeef, 0xdeadbeef);
  294. /* wait for previous transfer completion */
  295. while (mv_xor_state_get(0) != MV_IDLE)
  296. ;
  297. mv_xor_mem_init(0, 0x80000000, 0x40000000, 0xdeadbeef, 0xdeadbeef);
  298. /* wait for previous transfer completion */
  299. while (mv_xor_state_get(0) != MV_IDLE)
  300. ;
  301. /* Return XOR State */
  302. mv_sys_xor_finish();
  303. printf("DDR3 Training Sequence - End scrubbing\n");
  304. }