hal_ce.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /*
  2. * The interface function of controlling the CE register.
  3. *
  4. * Copyright (C) 2013 Allwinner.
  5. *
  6. * Mintow <duanmintao@allwinnertech.com>
  7. *
  8. * This file is licensed under the terms of the GNU General Public
  9. * License version 2. This program is licensed "as is" without any
  10. * warranty of any kind, whether express or implied.
  11. */
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <hal_mem.h>
  16. #include <hal_osal.h>
  17. #include <sunxi_hal_ce.h>
  18. #include <hal_log.h>
  19. #include "ce_common.h"
  20. #include "ce_reg.h"
  21. #include "platform_ce.h"
  22. #ifdef CONFIG_ARCH_SUN20IW2P1
  23. #include <hal_reset.h>
  24. static int sunxi_ce_clk_init(bool enable)
  25. {
  26. hal_clk_status_t ret;
  27. hal_reset_type_t reset_type = HAL_SUNXI_RESET;
  28. u32 reset_id;
  29. hal_clk_type_t clk_type = HAL_SUNXI_CCU;
  30. hal_clk_id_t clk_id;
  31. hal_clk_t clk;
  32. struct reset_control *reset;
  33. clk_id = SUNXI_CLK_CE;
  34. reset_id = SUNXI_RST_CE;
  35. if (enable)
  36. {
  37. reset = hal_reset_control_get(reset_type, reset_id);
  38. hal_reset_control_deassert(reset);
  39. hal_reset_control_put(reset);
  40. hal_clock_enable(hal_clock_get(clk_type, SUNXI_CLK_MBUS_CE));
  41. clk = hal_clock_get(clk_type, clk_id);
  42. ret = hal_clock_enable(clk);
  43. if (ret != HAL_CLK_STATUS_OK)
  44. CE_ERR("CE clock enable failed.\n");
  45. }
  46. else
  47. {
  48. clk = hal_clock_get(clk_type, clk_id);
  49. ret = hal_clock_disable(clk);
  50. if (ret != HAL_CLK_STATUS_OK)
  51. CE_ERR("CE clock disable failed.\n");
  52. hal_clock_disable(hal_clock_get(clk_type, SUNXI_CLK_MBUS_CE));
  53. hal_clock_put(clk);
  54. }
  55. return ret;
  56. }
  57. #endif
  58. void hal_ce_clock_init(void)
  59. {
  60. #ifdef CONFIG_ARCH_SUN20IW2P1
  61. sunxi_ce_clk_init(1);
  62. #else
  63. uint32_t reg_val;
  64. reg_val = readl(CCMU_CE_CLK_REG);
  65. /*set div n*/
  66. reg_val &= ~(CE_CLK_DIV_RATION_N_MASK << CE_CLK_DIV_RATION_N_BIT);
  67. reg_val |= CE_CLK_DIV_RATION_N << CE_CLK_DIV_RATION_N_BIT;
  68. /*set div m*/
  69. reg_val &= ~(CE_CLK_DIV_RATION_M_MASK << CE_CLK_DIV_RATION_M_BIT);
  70. reg_val |= CE_CLK_DIV_RATION_M << CE_CLK_DIV_RATION_M_BIT;
  71. writel(reg_val, CCMU_CE_CLK_REG);
  72. /*set CE src clock*/
  73. reg_val &= ~(CE_CLK_SRC_MASK << CE_CLK_SRC_SEL_BIT);
  74. /* PLL_PERI0(2X) */
  75. reg_val |= CE_CLK_SRC << CE_CLK_SRC_SEL_BIT;
  76. /*set src clock on*/
  77. reg_val |= CE_SCLK_ON << CE_SCLK_ONOFF_BIT;
  78. writel(reg_val, CCMU_CE_CLK_REG);
  79. /*open CE gating*/
  80. reg_val = readl(CCMU_CE_BGR_REG);
  81. reg_val |= CE_GATING_PASS << CE_GATING_BIT;
  82. writel(reg_val, CCMU_CE_BGR_REG);
  83. /*de-assert*/
  84. reg_val = readl(CCMU_CE_BGR_REG);
  85. reg_val |= CE_DEASSERT << CE_RST_BIT;
  86. writel(reg_val, CCMU_CE_BGR_REG);
  87. /*set mbus clock gating*/
  88. reg_val = readl(MBUS_MAT_CLK_GATING_REG);
  89. reg_val |= 1 << 2;
  90. writel(reg_val, MBUS_MAT_CLK_GATING_REG);
  91. #endif
  92. }
  93. uint32_t ce_readl(uint32_t offset)
  94. {
  95. #ifdef CONFIG_ARCH_SUN20IW2P1
  96. return readl(CE_NS_BASE_REG + offset);
  97. #else
  98. return readl(CE_S_BASE_REG + offset);
  99. #endif
  100. }
  101. static void ce_writel(uint32_t offset, uint32_t val)
  102. {
  103. #ifdef CONFIG_ARCH_SUN20IW2P1
  104. writel(val, CE_NS_BASE_REG + offset);
  105. #else
  106. writel(val, CE_S_BASE_REG + offset);
  107. #endif
  108. }
  109. uint32_t hal_ce_reg_rd(uint32_t offset)
  110. {
  111. return ce_readl(offset);
  112. }
  113. void hal_ce_reg_wr(uint32_t offset, uint32_t val)
  114. {
  115. ce_writel(offset, val);
  116. }
  117. void hal_ce_keyselect_set(int select, ce_task_desc_t *task)
  118. {
  119. task->sym_ctl |= select << CE_SYM_CTL_KEY_SELECT_SHIFT;
  120. }
  121. void hal_ce_keysize_set(int size, ce_task_desc_t *task)
  122. {
  123. volatile int type = CE_AES_KEY_SIZE_128;
  124. switch (size) {
  125. case AES_KEYSIZE_16:
  126. type = CE_AES_KEY_SIZE_128;
  127. break;
  128. case AES_KEYSIZE_24:
  129. type = CE_AES_KEY_SIZE_192;
  130. break;
  131. case AES_KEYSIZE_32:
  132. type = CE_AES_KEY_SIZE_256;
  133. break;
  134. default:
  135. break;
  136. }
  137. task->sym_ctl |= (type << CE_SYM_CTL_KEY_SIZE_SHIFT);
  138. }
  139. #ifdef CE_SUPPORT_CE_V3_1
  140. void hal_ce_rsa_width_set(int size, ce_task_desc_t *task)
  141. {
  142. int width_type = 0;
  143. switch (size) {
  144. case 512:
  145. width_type = CE_RSA_PUB_MODULUS_WIDTH_512;
  146. break;
  147. case 1024:
  148. width_type = CE_RSA_PUB_MODULUS_WIDTH_1024;
  149. break;
  150. case 2048:
  151. width_type = CE_RSA_PUB_MODULUS_WIDTH_2048;
  152. break;
  153. case 3072:
  154. width_type = CE_RSA_PUB_MODULUS_WIDTH_3072;
  155. break;
  156. case 4096:
  157. width_type = CE_RSA_PUB_MODULUS_WIDTH_4096;
  158. break;
  159. default:
  160. break;
  161. }
  162. task->asym_ctl |= width_type << CE_ASYM_CTL_RSA_PM_WIDTH_SHIFT;
  163. }
  164. #endif
  165. /* key: phsical address. */
  166. void hal_ce_key_set(char *key, int size, ce_task_desc_t *task)
  167. {
  168. int i = 0;
  169. int key_sel = CE_KEY_SELECT_INPUT;
  170. struct {
  171. int type;
  172. char desc[AES_MIN_KEY_SIZE];
  173. } keys[] = {
  174. {CE_KEY_SELECT_SSK, CE_KS_SSK},
  175. {CE_KEY_SELECT_HUK, CE_KS_HUK},
  176. {CE_KEY_SELECT_RSSK, CE_KS_RSSK},
  177. {CE_KEY_SELECT_INTERNAL_0, CE_KS_INTERNAL_0},
  178. {CE_KEY_SELECT_INTERNAL_1, CE_KS_INTERNAL_1},
  179. {CE_KEY_SELECT_INTERNAL_2, CE_KS_INTERNAL_2},
  180. {CE_KEY_SELECT_INTERNAL_3, CE_KS_INTERNAL_3},
  181. {CE_KEY_SELECT_INTERNAL_4, CE_KS_INTERNAL_4},
  182. {CE_KEY_SELECT_INTERNAL_5, CE_KS_INTERNAL_5},
  183. {CE_KEY_SELECT_INTERNAL_6, CE_KS_INTERNAL_6},
  184. {CE_KEY_SELECT_INTERNAL_7, CE_KS_INTERNAL_7},
  185. {CE_KEY_SELECT_INPUT, ""} };
  186. while (keys[i].type != CE_KEY_SELECT_INPUT) {
  187. if (strncasecmp(key, keys[i].desc, AES_MIN_KEY_SIZE) == 0) {
  188. key_sel = keys[i].type;
  189. memset(key, 0, size);
  190. break;
  191. }
  192. i++;
  193. }
  194. CE_DBG("The key size: %d\n", size);
  195. hal_ce_keyselect_set(key_sel, task);
  196. hal_ce_keysize_set(size, task);
  197. task->key_addr = (uint32_t)__va_to_pa((uint32_t)key);
  198. }
  199. void hal_ce_pending_clear(int flow)
  200. {
  201. int val = CE_CHAN_PENDING << flow;
  202. ce_writel(CE_REG_ISR, val);
  203. }
  204. int hal_ce_pending_get(void)
  205. {
  206. return ce_readl(CE_REG_ISR);
  207. }
  208. void hal_ce_irq_enable(int flow)
  209. {
  210. int val = ce_readl(CE_REG_ICR);
  211. val |= CE_CHAN_INT_ENABLE << flow;
  212. ce_writel(CE_REG_ICR, val);
  213. }
  214. void hal_ce_irq_disable(int flow)
  215. {
  216. int val = ce_readl(CE_REG_ICR);
  217. val &= ~(CE_CHAN_INT_ENABLE << flow);
  218. ce_writel(CE_REG_ICR, val);
  219. }
  220. void hal_ce_md_get(char *dst, char *src, int size)
  221. {
  222. memcpy(dst, src, size);
  223. }
  224. void hal_ce_iv_set(char *iv, int size, ce_task_desc_t *task)
  225. {
  226. task->iv_addr = (uint32_t)__va_to_pa((uint32_t)iv);
  227. }
  228. void hal_ce_iv_mode_set(int mode, ce_task_desc_t *task)
  229. {
  230. task->comm_ctl |= mode << CE_COMM_CTL_IV_MODE_SHIFT;
  231. }
  232. void hal_ce_cntsize_set(int size, ce_task_desc_t *task)
  233. {
  234. task->sym_ctl |= size << CE_SYM_CTL_CTR_SIZE_SHIFT;
  235. }
  236. void hal_ce_cnt_set(char *cnt, int size, ce_task_desc_t *task)
  237. {
  238. task->ctr_addr = (uint32_t)__va_to_pa((uint32_t)cnt);
  239. hal_ce_cntsize_set(CE_CTR_SIZE_128, task);
  240. }
  241. void hal_ce_cts_last(ce_task_desc_t *task)
  242. {
  243. task->sym_ctl |= CE_SYM_CTL_AES_CTS_LAST;
  244. }
  245. #ifndef CE_SUPPORT_CE_V3_1
  246. void hal_ce_xts_first(ce_task_desc_t *task)
  247. {
  248. task->sym_ctl |= CE_SYM_CTL_AES_XTS_FIRST;
  249. }
  250. void hal_ce_xts_last(ce_task_desc_t *task)
  251. {
  252. task->sym_ctl |= CE_SYM_CTL_AES_XTS_LAST;
  253. }
  254. #endif
  255. void hal_ce_method_set(int dir, int type, ce_task_desc_t *task)
  256. {
  257. if (dir != 0)
  258. task->comm_ctl |= 1 << CE_COMM_CTL_OP_DIR_SHIFT;
  259. task->comm_ctl |= type << CE_COMM_CTL_METHOD_SHIFT;
  260. }
  261. void hal_ce_aes_mode_set(int mode, ce_task_desc_t *task)
  262. {
  263. task->sym_ctl |= mode << CE_SYM_CTL_OP_MODE_SHIFT;
  264. }
  265. void hal_ce_task_enable(ce_task_desc_t *task)
  266. {
  267. task->comm_ctl |= CE_COMM_CTL_TASK_INT_MASK;
  268. }
  269. void hal_ce_cfb_bitwidth_set(int bitwidth, ce_task_desc_t *task)
  270. {
  271. int val = 0;
  272. switch (bitwidth) {
  273. case 1:
  274. val = CE_CFB_WIDTH_1;
  275. break;
  276. case 8:
  277. val = CE_CFB_WIDTH_8;
  278. break;
  279. case 64:
  280. val = CE_CFB_WIDTH_64;
  281. break;
  282. case 128:
  283. val = CE_CFB_WIDTH_128;
  284. break;
  285. default:
  286. break;
  287. }
  288. task->sym_ctl |= val << CE_SYM_CTL_CFB_WIDTH_SHIFT;
  289. }
  290. void hal_ce_set_task(uint32_t task_addr)
  291. {
  292. ce_writel(CE_REG_TSK, __va_to_pa((uint32_t)task_addr));
  293. }
  294. void hal_ce_ctrl_start(void)
  295. {
  296. uint32_t val = ce_readl(CE_REG_TLR);
  297. val = val | (0x1 << 0);
  298. ce_writel(CE_REG_TLR, val);
  299. }
  300. int hal_ce_flow_err(int flow)
  301. {
  302. return ce_readl(CE_REG_ERR) & CE_REG_ESR_CHAN_MASK(flow);
  303. }
  304. void hal_ce_data_len_set(int len, ce_task_desc_t *task)
  305. {
  306. #ifdef CE_SUPPORT_CE_V3_1
  307. task->data_len = (len >> 2);
  308. #else
  309. task->data_len = len;
  310. #endif
  311. }
  312. void hal_ce_wait_finish(uint32_t flow)
  313. {
  314. uint32_t int_en;
  315. int_en = ce_readl(CE_REG_ICR) & 0xf;
  316. int_en = int_en & (0x01 << flow);
  317. if (int_en != 0) {
  318. while ((ce_readl(CE_REG_ISR) & (0x01 << flow)) == 0) {
  319. ;
  320. }
  321. }
  322. }
  323. uint32_t hal_ce_get_erro(void)
  324. {
  325. return (ce_readl(CE_REG_ERR));
  326. }
  327. void hal_ce_reg_printf(void)
  328. {
  329. hal_log_err("The ce control register:\n");
  330. hal_log_err("[TSK] = 0x%08x\n", ce_readl(CE_REG_TSK));
  331. #ifdef CE_SUPPORT_CE_V3_1
  332. hal_log_err("[CTL] = 0x%08x\n", ce_readl(CE_REG_CTL));
  333. #endif
  334. hal_log_err("[ICR] = 0x%08x\n", ce_readl(CE_REG_ICR));
  335. hal_log_err("[ISR] = 0x%08x\n", ce_readl(CE_REG_ISR));
  336. hal_log_err("[TLR] = 0x%08x\n", ce_readl(CE_REG_TLR));
  337. hal_log_err("[TSR] = 0x%08x\n", ce_readl(CE_REG_TSR));
  338. hal_log_err("[ERR] = 0x%08x\n", ce_readl(CE_REG_ERR));
  339. hal_log_err("[CSA] = 0x%08x\n", ce_readl(CE_REG_CSA));
  340. hal_log_err("[CDA] = 0x%08x\n", ce_readl(CE_REG_CDA));
  341. hal_log_err("[VER] = 0x%08x\n", ce_readl(CE_REG_VER));
  342. }