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