xor.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  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 "xor.h"
  13. #include "xor_regs.h"
  14. static u32 xor_regs_ctrl_backup;
  15. static u32 xor_regs_base_backup[MAX_CS];
  16. static u32 xor_regs_mask_backup[MAX_CS];
  17. static void mv_xor_hal_init(u32 chan_num);
  18. static int mv_xor_cmd_set(u32 chan, int command);
  19. static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl);
  20. void mv_sys_xor_init(MV_DRAM_INFO *dram_info)
  21. {
  22. u32 reg, ui, base, cs_count;
  23. xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0));
  24. for (ui = 0; ui < MAX_CS; ui++)
  25. xor_regs_base_backup[ui] = reg_read(XOR_BASE_ADDR_REG(0, ui));
  26. for (ui = 0; ui < MAX_CS; ui++)
  27. xor_regs_mask_backup[ui] = reg_read(XOR_SIZE_MASK_REG(0, ui));
  28. reg = 0;
  29. for (ui = 0; ui < (dram_info->num_cs + 1); ui++) {
  30. /* Enable Window x for each CS */
  31. reg |= (0x1 << (ui));
  32. /* Enable Window x for each CS */
  33. reg |= (0x3 << ((ui * 2) + 16));
  34. }
  35. reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
  36. /* Last window - Base - 0x40000000, Attribute 0x1E - SRAM */
  37. base = (SRAM_BASE & 0xFFFF0000) | 0x1E00;
  38. reg_write(XOR_BASE_ADDR_REG(0, dram_info->num_cs), base);
  39. /* Last window - Size - 64 MB */
  40. reg_write(XOR_SIZE_MASK_REG(0, dram_info->num_cs), 0x03FF0000);
  41. cs_count = 0;
  42. for (ui = 0; ui < MAX_CS; ui++) {
  43. if (dram_info->cs_ena & (1 << ui)) {
  44. /*
  45. * Window x - Base - 0x00000000, Attribute 0x0E - DRAM
  46. */
  47. base = 0;
  48. switch (ui) {
  49. case 0:
  50. base |= 0xE00;
  51. break;
  52. case 1:
  53. base |= 0xD00;
  54. break;
  55. case 2:
  56. base |= 0xB00;
  57. break;
  58. case 3:
  59. base |= 0x700;
  60. break;
  61. }
  62. reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);
  63. /* Window x - Size - 256 MB */
  64. reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x0FFF0000);
  65. cs_count++;
  66. }
  67. }
  68. mv_xor_hal_init(1);
  69. return;
  70. }
  71. void mv_sys_xor_finish(void)
  72. {
  73. u32 ui;
  74. reg_write(XOR_WINDOW_CTRL_REG(0, 0), xor_regs_ctrl_backup);
  75. for (ui = 0; ui < MAX_CS; ui++)
  76. reg_write(XOR_BASE_ADDR_REG(0, ui), xor_regs_base_backup[ui]);
  77. for (ui = 0; ui < MAX_CS; ui++)
  78. reg_write(XOR_SIZE_MASK_REG(0, ui), xor_regs_mask_backup[ui]);
  79. reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
  80. }
  81. /*
  82. * mv_xor_hal_init - Initialize XOR engine
  83. *
  84. * DESCRIPTION:
  85. * This function initialize XOR unit.
  86. * INPUT:
  87. * None.
  88. *
  89. * OUTPUT:
  90. * None.
  91. *
  92. * RETURN:
  93. * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  94. */
  95. static void mv_xor_hal_init(u32 chan_num)
  96. {
  97. u32 i;
  98. /* Abort any XOR activity & set default configuration */
  99. for (i = 0; i < chan_num; i++) {
  100. mv_xor_cmd_set(i, MV_STOP);
  101. mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) |
  102. (4 << XEXCR_DST_BURST_LIMIT_OFFS) |
  103. (4 << XEXCR_SRC_BURST_LIMIT_OFFS));
  104. }
  105. }
  106. /*
  107. * mv_xor_ctrl_set - Set XOR channel control registers
  108. *
  109. * DESCRIPTION:
  110. *
  111. * INPUT:
  112. *
  113. * OUTPUT:
  114. * None.
  115. *
  116. * RETURN:
  117. * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  118. * NOTE:
  119. * This function does not modify the OperationMode field of control register.
  120. *
  121. */
  122. static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
  123. {
  124. u32 val;
  125. /* Update the XOR Engine [0..1] Configuration Registers (XExCR) */
  126. val = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)))
  127. & XEXCR_OPERATION_MODE_MASK;
  128. xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK;
  129. xor_ctrl |= val;
  130. reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl);
  131. return MV_OK;
  132. }
  133. int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size, u32 init_val_high,
  134. u32 init_val_low)
  135. {
  136. u32 tmp;
  137. /* Parameter checking */
  138. if (chan >= MV_XOR_MAX_CHAN)
  139. return MV_BAD_PARAM;
  140. if (MV_ACTIVE == mv_xor_state_get(chan))
  141. return MV_BUSY;
  142. if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
  143. (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE))
  144. return MV_BAD_PARAM;
  145. /* Set the operation mode to Memory Init */
  146. tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
  147. tmp &= ~XEXCR_OPERATION_MODE_MASK;
  148. tmp |= XEXCR_OPERATION_MODE_MEM_INIT;
  149. reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp);
  150. /*
  151. * Update the start_ptr field in XOR Engine [0..1] Destination Pointer
  152. * Register (XExDPR0)
  153. */
  154. reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr);
  155. /*
  156. * Update the BlockSize field in the XOR Engine[0..1] Block Size
  157. * Registers (XExBSR)
  158. */
  159. reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  160. block_size);
  161. /*
  162. * Update the field InitValL in the XOR Engine Initial Value Register
  163. * Low (XEIVRL)
  164. */
  165. reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low);
  166. /*
  167. * Update the field InitValH in the XOR Engine Initial Value Register
  168. * High (XEIVRH)
  169. */
  170. reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high);
  171. /* Start transfer */
  172. reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  173. XEXACTR_XESTART_MASK);
  174. return MV_OK;
  175. }
  176. /*
  177. * mv_xor_transfer - Transfer data from source to destination on one of
  178. * three modes (XOR,CRC32,DMA)
  179. *
  180. * DESCRIPTION:
  181. * This function initiates XOR channel, according to function parameters,
  182. * in order to perform XOR or CRC32 or DMA transaction.
  183. * To gain maximum performance the user is asked to keep the following
  184. * restrictions:
  185. * 1) Selected engine is available (not busy).
  186. * 1) This module does not take into consideration CPU MMU issues.
  187. * In order for the XOR engine to access the appropreate source
  188. * and destination, address parameters must be given in system
  189. * physical mode.
  190. * 2) This API does not take care of cache coherency issues. The source,
  191. * destination and in case of chain the descriptor list are assumed
  192. * to be cache coherent.
  193. * 4) Parameters validity. For example, does size parameter exceeds
  194. * maximum byte count of descriptor mode (16M or 64K).
  195. *
  196. * INPUT:
  197. * chan - XOR channel number. See MV_XOR_CHANNEL enumerator.
  198. * xor_type - One of three: XOR, CRC32 and DMA operations.
  199. * xor_chain_ptr - address of chain pointer
  200. *
  201. * OUTPUT:
  202. * None.
  203. *
  204. * RETURS:
  205. * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  206. *
  207. */
  208. int mv_xor_transfer(u32 chan, int xor_type, u32 xor_chain_ptr)
  209. {
  210. u32 tmp;
  211. /* Parameter checking */
  212. if (chan >= MV_XOR_MAX_CHAN) {
  213. debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
  214. return MV_BAD_PARAM;
  215. }
  216. if (MV_ACTIVE == mv_xor_state_get(chan)) {
  217. debug("%s: ERR. Channel is already active\n", __func__);
  218. return MV_BUSY;
  219. }
  220. if (0x0 == xor_chain_ptr) {
  221. debug("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__);
  222. return MV_BAD_PARAM;
  223. }
  224. /* Read configuration register and mask the operation mode field */
  225. tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
  226. tmp &= ~XEXCR_OPERATION_MODE_MASK;
  227. switch (xor_type) {
  228. case MV_XOR:
  229. if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK)) {
  230. debug("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n",
  231. __func__);
  232. return MV_BAD_PARAM;
  233. }
  234. /* Set the operation mode to XOR */
  235. tmp |= XEXCR_OPERATION_MODE_XOR;
  236. break;
  237. case MV_DMA:
  238. if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK)) {
  239. debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
  240. __func__);
  241. return MV_BAD_PARAM;
  242. }
  243. /* Set the operation mode to DMA */
  244. tmp |= XEXCR_OPERATION_MODE_DMA;
  245. break;
  246. case MV_CRC32:
  247. if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK)) {
  248. debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
  249. __func__);
  250. return MV_BAD_PARAM;
  251. }
  252. /* Set the operation mode to CRC32 */
  253. tmp |= XEXCR_OPERATION_MODE_CRC;
  254. break;
  255. default:
  256. return MV_BAD_PARAM;
  257. }
  258. /* Write the operation mode to the register */
  259. reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp);
  260. /*
  261. * Update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor
  262. * Pointer Register (XExNDPR)
  263. */
  264. reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  265. xor_chain_ptr);
  266. /* Start transfer */
  267. reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  268. XEXACTR_XESTART_MASK);
  269. return MV_OK;
  270. }
  271. /*
  272. * mv_xor_state_get - Get XOR channel state.
  273. *
  274. * DESCRIPTION:
  275. * XOR channel activity state can be active, idle, paused.
  276. * This function retrunes the channel activity state.
  277. *
  278. * INPUT:
  279. * chan - the channel number
  280. *
  281. * OUTPUT:
  282. * None.
  283. *
  284. * RETURN:
  285. * XOR_CHANNEL_IDLE - If the engine is idle.
  286. * XOR_CHANNEL_ACTIVE - If the engine is busy.
  287. * XOR_CHANNEL_PAUSED - If the engine is paused.
  288. * MV_UNDEFINED_STATE - If the engine state is undefind or there is no
  289. * such engine
  290. *
  291. */
  292. int mv_xor_state_get(u32 chan)
  293. {
  294. u32 state;
  295. /* Parameter checking */
  296. if (chan >= MV_XOR_MAX_CHAN) {
  297. debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
  298. return MV_UNDEFINED_STATE;
  299. }
  300. /* Read the current state */
  301. state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
  302. state &= XEXACTR_XESTATUS_MASK;
  303. /* Return the state */
  304. switch (state) {
  305. case XEXACTR_XESTATUS_IDLE:
  306. return MV_IDLE;
  307. case XEXACTR_XESTATUS_ACTIVE:
  308. return MV_ACTIVE;
  309. case XEXACTR_XESTATUS_PAUSED:
  310. return MV_PAUSED;
  311. }
  312. return MV_UNDEFINED_STATE;
  313. }
  314. /*
  315. * mv_xor_cmd_set - Set command of XOR channel
  316. *
  317. * DESCRIPTION:
  318. * XOR channel can be started, idle, paused and restarted.
  319. * Paused can be set only if channel is active.
  320. * Start can be set only if channel is idle or paused.
  321. * Restart can be set only if channel is paused.
  322. * Stop can be set only if channel is active.
  323. *
  324. * INPUT:
  325. * chan - The channel number
  326. * command - The command type (start, stop, restart, pause)
  327. *
  328. * OUTPUT:
  329. * None.
  330. *
  331. * RETURN:
  332. * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on
  333. * undefind XOR engine mode
  334. *
  335. */
  336. static int mv_xor_cmd_set(u32 chan, int command)
  337. {
  338. int state;
  339. /* Parameter checking */
  340. if (chan >= MV_XOR_MAX_CHAN) {
  341. debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
  342. return MV_BAD_PARAM;
  343. }
  344. /* Get the current state */
  345. state = mv_xor_state_get(chan);
  346. /* Command is start and current state is idle */
  347. if ((command == MV_START) && (state == MV_IDLE)) {
  348. reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  349. XEXACTR_XESTART_MASK);
  350. return MV_OK;
  351. }
  352. /* Command is stop and current state is active */
  353. else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
  354. reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  355. XEXACTR_XESTOP_MASK);
  356. return MV_OK;
  357. }
  358. /* Command is paused and current state is active */
  359. else if ((command == MV_PAUSED) && (state == MV_ACTIVE)) {
  360. reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  361. XEXACTR_XEPAUSE_MASK);
  362. return MV_OK;
  363. }
  364. /* Command is restart and current state is paused */
  365. else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
  366. reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
  367. XEXACTR_XERESTART_MASK);
  368. return MV_OK;
  369. }
  370. /* Command is stop and current state is active */
  371. else if ((command == MV_STOP) && (state == MV_IDLE))
  372. return MV_OK;
  373. /* Illegal command */
  374. debug("%s: ERR. Illegal command\n", __func__);
  375. return MV_BAD_PARAM;
  376. }