| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- /*
- * The interface function of controlling the CE register.
- *
- * Copyright (C) 2013 Allwinner.
- *
- * Mintow <duanmintao@allwinnertech.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <hal_mem.h>
- #include <hal_osal.h>
- #include <sunxi_hal_ce.h>
- #include <hal_log.h>
- #include "ce_common.h"
- #include "ce_reg.h"
- #include "platform_ce.h"
- #ifdef CONFIG_ARCH_SUN20IW2P1
- #include <hal_reset.h>
- static int sunxi_ce_clk_init(bool enable)
- {
- hal_clk_status_t ret;
- hal_reset_type_t reset_type = HAL_SUNXI_RESET;
- u32 reset_id;
- hal_clk_type_t clk_type = HAL_SUNXI_CCU;
- hal_clk_id_t clk_id;
- hal_clk_t clk;
- struct reset_control *reset;
- clk_id = SUNXI_CLK_CE;
- reset_id = SUNXI_RST_CE;
- if (enable)
- {
- reset = hal_reset_control_get(reset_type, reset_id);
- hal_reset_control_deassert(reset);
- hal_reset_control_put(reset);
- hal_clock_enable(hal_clock_get(clk_type, SUNXI_CLK_MBUS_CE));
- clk = hal_clock_get(clk_type, clk_id);
- ret = hal_clock_enable(clk);
- if (ret != HAL_CLK_STATUS_OK)
- CE_ERR("CE clock enable failed.\n");
- }
- else
- {
- clk = hal_clock_get(clk_type, clk_id);
- ret = hal_clock_disable(clk);
- if (ret != HAL_CLK_STATUS_OK)
- CE_ERR("CE clock disable failed.\n");
- hal_clock_disable(hal_clock_get(clk_type, SUNXI_CLK_MBUS_CE));
- hal_clock_put(clk);
- }
- return ret;
- }
- #endif
- void hal_ce_clock_init(void)
- {
- #ifdef CONFIG_ARCH_SUN20IW2P1
- sunxi_ce_clk_init(1);
- #else
- uint32_t reg_val;
- reg_val = readl(CCMU_CE_CLK_REG);
- /*set div n*/
- reg_val &= ~(CE_CLK_DIV_RATION_N_MASK << CE_CLK_DIV_RATION_N_BIT);
- reg_val |= CE_CLK_DIV_RATION_N << CE_CLK_DIV_RATION_N_BIT;
- /*set div m*/
- reg_val &= ~(CE_CLK_DIV_RATION_M_MASK << CE_CLK_DIV_RATION_M_BIT);
- reg_val |= CE_CLK_DIV_RATION_M << CE_CLK_DIV_RATION_M_BIT;
- writel(reg_val, CCMU_CE_CLK_REG);
- /*set CE src clock*/
- reg_val &= ~(CE_CLK_SRC_MASK << CE_CLK_SRC_SEL_BIT);
- /* PLL_PERI0(2X) */
- reg_val |= CE_CLK_SRC << CE_CLK_SRC_SEL_BIT;
- /*set src clock on*/
- reg_val |= CE_SCLK_ON << CE_SCLK_ONOFF_BIT;
- writel(reg_val, CCMU_CE_CLK_REG);
- /*open CE gating*/
- reg_val = readl(CCMU_CE_BGR_REG);
- reg_val |= CE_GATING_PASS << CE_GATING_BIT;
- writel(reg_val, CCMU_CE_BGR_REG);
- /*de-assert*/
- reg_val = readl(CCMU_CE_BGR_REG);
- reg_val |= CE_DEASSERT << CE_RST_BIT;
- writel(reg_val, CCMU_CE_BGR_REG);
- /*set mbus clock gating*/
- reg_val = readl(MBUS_MAT_CLK_GATING_REG);
- reg_val |= 1 << 2;
- writel(reg_val, MBUS_MAT_CLK_GATING_REG);
- #endif
- }
- uint32_t ce_readl(uint32_t offset)
- {
- #ifdef CONFIG_ARCH_SUN20IW2P1
- return readl(CE_NS_BASE_REG + offset);
- #else
- return readl(CE_S_BASE_REG + offset);
- #endif
- }
- static void ce_writel(uint32_t offset, uint32_t val)
- {
- #ifdef CONFIG_ARCH_SUN20IW2P1
- writel(val, CE_NS_BASE_REG + offset);
- #else
- writel(val, CE_S_BASE_REG + offset);
- #endif
- }
- uint32_t hal_ce_reg_rd(uint32_t offset)
- {
- return ce_readl(offset);
- }
- void hal_ce_reg_wr(uint32_t offset, uint32_t val)
- {
- ce_writel(offset, val);
- }
- void hal_ce_keyselect_set(int select, ce_task_desc_t *task)
- {
- task->sym_ctl |= select << CE_SYM_CTL_KEY_SELECT_SHIFT;
- }
- void hal_ce_keysize_set(int size, ce_task_desc_t *task)
- {
- volatile int type = CE_AES_KEY_SIZE_128;
- switch (size) {
- case AES_KEYSIZE_16:
- type = CE_AES_KEY_SIZE_128;
- break;
- case AES_KEYSIZE_24:
- type = CE_AES_KEY_SIZE_192;
- break;
- case AES_KEYSIZE_32:
- type = CE_AES_KEY_SIZE_256;
- break;
- default:
- break;
- }
- task->sym_ctl |= (type << CE_SYM_CTL_KEY_SIZE_SHIFT);
- }
- #ifdef CE_SUPPORT_CE_V3_1
- void hal_ce_rsa_width_set(int size, ce_task_desc_t *task)
- {
- int width_type = 0;
- switch (size) {
- case 512:
- width_type = CE_RSA_PUB_MODULUS_WIDTH_512;
- break;
- case 1024:
- width_type = CE_RSA_PUB_MODULUS_WIDTH_1024;
- break;
- case 2048:
- width_type = CE_RSA_PUB_MODULUS_WIDTH_2048;
- break;
- case 3072:
- width_type = CE_RSA_PUB_MODULUS_WIDTH_3072;
- break;
- case 4096:
- width_type = CE_RSA_PUB_MODULUS_WIDTH_4096;
- break;
- default:
- break;
- }
- task->asym_ctl |= width_type << CE_ASYM_CTL_RSA_PM_WIDTH_SHIFT;
- }
- #endif
- /* key: phsical address. */
- void hal_ce_key_set(char *key, int size, ce_task_desc_t *task)
- {
- int i = 0;
- int key_sel = CE_KEY_SELECT_INPUT;
- struct {
- int type;
- char desc[AES_MIN_KEY_SIZE];
- } keys[] = {
- {CE_KEY_SELECT_SSK, CE_KS_SSK},
- {CE_KEY_SELECT_HUK, CE_KS_HUK},
- {CE_KEY_SELECT_RSSK, CE_KS_RSSK},
- {CE_KEY_SELECT_INTERNAL_0, CE_KS_INTERNAL_0},
- {CE_KEY_SELECT_INTERNAL_1, CE_KS_INTERNAL_1},
- {CE_KEY_SELECT_INTERNAL_2, CE_KS_INTERNAL_2},
- {CE_KEY_SELECT_INTERNAL_3, CE_KS_INTERNAL_3},
- {CE_KEY_SELECT_INTERNAL_4, CE_KS_INTERNAL_4},
- {CE_KEY_SELECT_INTERNAL_5, CE_KS_INTERNAL_5},
- {CE_KEY_SELECT_INTERNAL_6, CE_KS_INTERNAL_6},
- {CE_KEY_SELECT_INTERNAL_7, CE_KS_INTERNAL_7},
- {CE_KEY_SELECT_INPUT, ""} };
- while (keys[i].type != CE_KEY_SELECT_INPUT) {
- if (strncasecmp(key, keys[i].desc, AES_MIN_KEY_SIZE) == 0) {
- key_sel = keys[i].type;
- memset(key, 0, size);
- break;
- }
- i++;
- }
- CE_DBG("The key size: %d\n", size);
- hal_ce_keyselect_set(key_sel, task);
- hal_ce_keysize_set(size, task);
- task->key_addr = (uint32_t)__va_to_pa((uint32_t)key);
- }
- void hal_ce_pending_clear(int flow)
- {
- int val = CE_CHAN_PENDING << flow;
- ce_writel(CE_REG_ISR, val);
- }
- int hal_ce_pending_get(void)
- {
- return ce_readl(CE_REG_ISR);
- }
- void hal_ce_irq_enable(int flow)
- {
- int val = ce_readl(CE_REG_ICR);
- val |= CE_CHAN_INT_ENABLE << flow;
- ce_writel(CE_REG_ICR, val);
- }
- void hal_ce_irq_disable(int flow)
- {
- int val = ce_readl(CE_REG_ICR);
- val &= ~(CE_CHAN_INT_ENABLE << flow);
- ce_writel(CE_REG_ICR, val);
- }
- void hal_ce_md_get(char *dst, char *src, int size)
- {
- memcpy(dst, src, size);
- }
- void hal_ce_iv_set(char *iv, int size, ce_task_desc_t *task)
- {
- task->iv_addr = (uint32_t)__va_to_pa((uint32_t)iv);
- }
- void hal_ce_iv_mode_set(int mode, ce_task_desc_t *task)
- {
- task->comm_ctl |= mode << CE_COMM_CTL_IV_MODE_SHIFT;
- }
- void hal_ce_cntsize_set(int size, ce_task_desc_t *task)
- {
- task->sym_ctl |= size << CE_SYM_CTL_CTR_SIZE_SHIFT;
- }
- void hal_ce_cnt_set(char *cnt, int size, ce_task_desc_t *task)
- {
- task->ctr_addr = (uint32_t)__va_to_pa((uint32_t)cnt);
- hal_ce_cntsize_set(CE_CTR_SIZE_128, task);
- }
- void hal_ce_cts_last(ce_task_desc_t *task)
- {
- task->sym_ctl |= CE_SYM_CTL_AES_CTS_LAST;
- }
- #ifndef CE_SUPPORT_CE_V3_1
- void hal_ce_xts_first(ce_task_desc_t *task)
- {
- task->sym_ctl |= CE_SYM_CTL_AES_XTS_FIRST;
- }
- void hal_ce_xts_last(ce_task_desc_t *task)
- {
- task->sym_ctl |= CE_SYM_CTL_AES_XTS_LAST;
- }
- #endif
- void hal_ce_method_set(int dir, int type, ce_task_desc_t *task)
- {
- if (dir != 0)
- task->comm_ctl |= 1 << CE_COMM_CTL_OP_DIR_SHIFT;
- task->comm_ctl |= type << CE_COMM_CTL_METHOD_SHIFT;
- }
- void hal_ce_aes_mode_set(int mode, ce_task_desc_t *task)
- {
- task->sym_ctl |= mode << CE_SYM_CTL_OP_MODE_SHIFT;
- }
- void hal_ce_task_enable(ce_task_desc_t *task)
- {
- task->comm_ctl |= CE_COMM_CTL_TASK_INT_MASK;
- }
- void hal_ce_cfb_bitwidth_set(int bitwidth, ce_task_desc_t *task)
- {
- int val = 0;
- switch (bitwidth) {
- case 1:
- val = CE_CFB_WIDTH_1;
- break;
- case 8:
- val = CE_CFB_WIDTH_8;
- break;
- case 64:
- val = CE_CFB_WIDTH_64;
- break;
- case 128:
- val = CE_CFB_WIDTH_128;
- break;
- default:
- break;
- }
- task->sym_ctl |= val << CE_SYM_CTL_CFB_WIDTH_SHIFT;
- }
- void hal_ce_set_task(uint32_t task_addr)
- {
- ce_writel(CE_REG_TSK, __va_to_pa((uint32_t)task_addr));
- }
- void hal_ce_ctrl_start(void)
- {
- uint32_t val = ce_readl(CE_REG_TLR);
- val = val | (0x1 << 0);
- ce_writel(CE_REG_TLR, val);
- }
- int hal_ce_flow_err(int flow)
- {
- return ce_readl(CE_REG_ERR) & CE_REG_ESR_CHAN_MASK(flow);
- }
- void hal_ce_data_len_set(int len, ce_task_desc_t *task)
- {
- #ifdef CE_SUPPORT_CE_V3_1
- task->data_len = (len >> 2);
- #else
- task->data_len = len;
- #endif
- }
- void hal_ce_wait_finish(uint32_t flow)
- {
- uint32_t int_en;
- int_en = ce_readl(CE_REG_ICR) & 0xf;
- int_en = int_en & (0x01 << flow);
- if (int_en != 0) {
- while ((ce_readl(CE_REG_ISR) & (0x01 << flow)) == 0) {
- ;
- }
- }
- }
- uint32_t hal_ce_get_erro(void)
- {
- return (ce_readl(CE_REG_ERR));
- }
- void hal_ce_reg_printf(void)
- {
- hal_log_err("The ce control register:\n");
- hal_log_err("[TSK] = 0x%08x\n", ce_readl(CE_REG_TSK));
- #ifdef CE_SUPPORT_CE_V3_1
- hal_log_err("[CTL] = 0x%08x\n", ce_readl(CE_REG_CTL));
- #endif
- hal_log_err("[ICR] = 0x%08x\n", ce_readl(CE_REG_ICR));
- hal_log_err("[ISR] = 0x%08x\n", ce_readl(CE_REG_ISR));
- hal_log_err("[TLR] = 0x%08x\n", ce_readl(CE_REG_TLR));
- hal_log_err("[TSR] = 0x%08x\n", ce_readl(CE_REG_TSR));
- hal_log_err("[ERR] = 0x%08x\n", ce_readl(CE_REG_ERR));
- hal_log_err("[CSA] = 0x%08x\n", ce_readl(CE_REG_CSA));
- hal_log_err("[CDA] = 0x%08x\n", ce_readl(CE_REG_CDA));
- hal_log_err("[VER] = 0x%08x\n", ce_readl(CE_REG_VER));
- }
|