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