xor.c 11 KB

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