1/** 2 * Copyright (C) ST-Ericsson SA 2010 3 * Author: Shujuan Chen <shujuan.chen@stericsson.com> for ST-Ericsson. 4 * Author: Jonas Linde <jonas.linde@stericsson.com> for ST-Ericsson. 5 * Author: Niklas Hernaeus <niklas.hernaeus@stericsson.com> for ST-Ericsson. 6 * Author: Joakim Bech <joakim.xx.bech@stericsson.com> for ST-Ericsson. 7 * Author: Berne Hebark <berne.herbark@stericsson.com> for ST-Ericsson. 8 * License terms: GNU General Public License (GPL) version 2 9 */ 10 11#include <linux/errno.h> 12#include <linux/kernel.h> 13#include <linux/types.h> 14 15#include "cryp_p.h" 16#include "cryp.h" 17 18/** 19 * cryp_wait_until_done - wait until the device logic is not busy 20 */ 21void cryp_wait_until_done(struct cryp_device_data *device_data) 22{ 23 while (cryp_is_logic_busy(device_data)) 24 cpu_relax(); 25} 26 27/** 28 * cryp_check - This routine checks Peripheral and PCell Id 29 * @device_data: Pointer to the device data struct for base address. 30 */ 31int cryp_check(struct cryp_device_data *device_data) 32{ 33 int peripheralid2 = 0; 34 35 if (NULL == device_data) 36 return -EINVAL; 37 38 peripheralid2 = readl_relaxed(&device_data->base->periphId2); 39 40 if (peripheralid2 != CRYP_PERIPHERAL_ID2_DB8500) 41 return -EPERM; 42 43 /* Check Peripheral and Pcell Id Register for CRYP */ 44 if ((CRYP_PERIPHERAL_ID0 == 45 readl_relaxed(&device_data->base->periphId0)) 46 && (CRYP_PERIPHERAL_ID1 == 47 readl_relaxed(&device_data->base->periphId1)) 48 && (CRYP_PERIPHERAL_ID3 == 49 readl_relaxed(&device_data->base->periphId3)) 50 && (CRYP_PCELL_ID0 == 51 readl_relaxed(&device_data->base->pcellId0)) 52 && (CRYP_PCELL_ID1 == 53 readl_relaxed(&device_data->base->pcellId1)) 54 && (CRYP_PCELL_ID2 == 55 readl_relaxed(&device_data->base->pcellId2)) 56 && (CRYP_PCELL_ID3 == 57 readl_relaxed(&device_data->base->pcellId3))) { 58 return 0; 59 } 60 61 return -EPERM; 62} 63 64/** 65 * cryp_activity - This routine enables/disable the cryptography function. 66 * @device_data: Pointer to the device data struct for base address. 67 * @cryp_crypen: Enable/Disable functionality 68 */ 69void cryp_activity(struct cryp_device_data *device_data, 70 enum cryp_crypen cryp_crypen) 71{ 72 CRYP_PUT_BITS(&device_data->base->cr, 73 cryp_crypen, 74 CRYP_CR_CRYPEN_POS, 75 CRYP_CR_CRYPEN_MASK); 76} 77 78/** 79 * cryp_flush_inoutfifo - Resets both the input and the output FIFOs 80 * @device_data: Pointer to the device data struct for base address. 81 */ 82void cryp_flush_inoutfifo(struct cryp_device_data *device_data) 83{ 84 /* 85 * We always need to disble the hardware before trying to flush the 86 * FIFO. This is something that isn't written in the design 87 * specification, but we have been informed by the hardware designers 88 * that this must be done. 89 */ 90 cryp_activity(device_data, CRYP_CRYPEN_DISABLE); 91 cryp_wait_until_done(device_data); 92 93 CRYP_SET_BITS(&device_data->base->cr, CRYP_CR_FFLUSH_MASK); 94 /* 95 * CRYP_SR_INFIFO_READY_MASK is the expected value on the status 96 * register when starting a new calculation, which means Input FIFO is 97 * not full and input FIFO is empty. 98 */ 99 while (readl_relaxed(&device_data->base->sr) != 100 CRYP_SR_INFIFO_READY_MASK) 101 cpu_relax(); 102} 103 104/** 105 * cryp_set_configuration - This routine set the cr CRYP IP 106 * @device_data: Pointer to the device data struct for base address. 107 * @cryp_config: Pointer to the configuration parameter 108 * @control_register: The control register to be written later on. 109 */ 110int cryp_set_configuration(struct cryp_device_data *device_data, 111 struct cryp_config *cryp_config, 112 u32 *control_register) 113{ 114 u32 cr_for_kse; 115 116 if (NULL == device_data || NULL == cryp_config) 117 return -EINVAL; 118 119 *control_register |= (cryp_config->keysize << CRYP_CR_KEYSIZE_POS); 120 121 /* Prepare key for decryption in AES_ECB and AES_CBC mode. */ 122 if ((CRYP_ALGORITHM_DECRYPT == cryp_config->algodir) && 123 ((CRYP_ALGO_AES_ECB == cryp_config->algomode) || 124 (CRYP_ALGO_AES_CBC == cryp_config->algomode))) { 125 cr_for_kse = *control_register; 126 /* 127 * This seems a bit odd, but it is indeed needed to set this to 128 * encrypt even though it is a decryption that we are doing. It 129 * also mentioned in the design spec that you need to do this. 130 * After the keyprepartion for decrypting is done you should set 131 * algodir back to decryption, which is done outside this if 132 * statement. 133 * 134 * According to design specification we should set mode ECB 135 * during key preparation even though we might be running CBC 136 * when enter this function. 137 * 138 * Writing to KSE_ENABLED will drop CRYPEN when key preparation 139 * is done. Therefore we need to set CRYPEN again outside this 140 * if statement when running decryption. 141 */ 142 cr_for_kse |= ((CRYP_ALGORITHM_ENCRYPT << CRYP_CR_ALGODIR_POS) | 143 (CRYP_ALGO_AES_ECB << CRYP_CR_ALGOMODE_POS) | 144 (CRYP_CRYPEN_ENABLE << CRYP_CR_CRYPEN_POS) | 145 (KSE_ENABLED << CRYP_CR_KSE_POS)); 146 147 writel_relaxed(cr_for_kse, &device_data->base->cr); 148 cryp_wait_until_done(device_data); 149 } 150 151 *control_register |= 152 ((cryp_config->algomode << CRYP_CR_ALGOMODE_POS) | 153 (cryp_config->algodir << CRYP_CR_ALGODIR_POS)); 154 155 return 0; 156} 157 158/** 159 * cryp_configure_protection - set the protection bits in the CRYP logic. 160 * @device_data: Pointer to the device data struct for base address. 161 * @p_protect_config: Pointer to the protection mode and 162 * secure mode configuration 163 */ 164int cryp_configure_protection(struct cryp_device_data *device_data, 165 struct cryp_protection_config *p_protect_config) 166{ 167 if (NULL == p_protect_config) 168 return -EINVAL; 169 170 CRYP_WRITE_BIT(&device_data->base->cr, 171 (u32) p_protect_config->secure_access, 172 CRYP_CR_SECURE_MASK); 173 CRYP_PUT_BITS(&device_data->base->cr, 174 p_protect_config->privilege_access, 175 CRYP_CR_PRLG_POS, 176 CRYP_CR_PRLG_MASK); 177 178 return 0; 179} 180 181/** 182 * cryp_is_logic_busy - returns the busy status of the CRYP logic 183 * @device_data: Pointer to the device data struct for base address. 184 */ 185int cryp_is_logic_busy(struct cryp_device_data *device_data) 186{ 187 return CRYP_TEST_BITS(&device_data->base->sr, 188 CRYP_SR_BUSY_MASK); 189} 190 191/** 192 * cryp_configure_for_dma - configures the CRYP IP for DMA operation 193 * @device_data: Pointer to the device data struct for base address. 194 * @dma_req: Specifies the DMA request type value. 195 */ 196void cryp_configure_for_dma(struct cryp_device_data *device_data, 197 enum cryp_dma_req_type dma_req) 198{ 199 CRYP_SET_BITS(&device_data->base->dmacr, 200 (u32) dma_req); 201} 202 203/** 204 * cryp_configure_key_values - configures the key values for CRYP operations 205 * @device_data: Pointer to the device data struct for base address. 206 * @key_reg_index: Key value index register 207 * @key_value: The key value struct 208 */ 209int cryp_configure_key_values(struct cryp_device_data *device_data, 210 enum cryp_key_reg_index key_reg_index, 211 struct cryp_key_value key_value) 212{ 213 while (cryp_is_logic_busy(device_data)) 214 cpu_relax(); 215 216 switch (key_reg_index) { 217 case CRYP_KEY_REG_1: 218 writel_relaxed(key_value.key_value_left, 219 &device_data->base->key_1_l); 220 writel_relaxed(key_value.key_value_right, 221 &device_data->base->key_1_r); 222 break; 223 case CRYP_KEY_REG_2: 224 writel_relaxed(key_value.key_value_left, 225 &device_data->base->key_2_l); 226 writel_relaxed(key_value.key_value_right, 227 &device_data->base->key_2_r); 228 break; 229 case CRYP_KEY_REG_3: 230 writel_relaxed(key_value.key_value_left, 231 &device_data->base->key_3_l); 232 writel_relaxed(key_value.key_value_right, 233 &device_data->base->key_3_r); 234 break; 235 case CRYP_KEY_REG_4: 236 writel_relaxed(key_value.key_value_left, 237 &device_data->base->key_4_l); 238 writel_relaxed(key_value.key_value_right, 239 &device_data->base->key_4_r); 240 break; 241 default: 242 return -EINVAL; 243 } 244 245 return 0; 246} 247 248/** 249 * cryp_configure_init_vector - configures the initialization vector register 250 * @device_data: Pointer to the device data struct for base address. 251 * @init_vector_index: Specifies the index of the init vector. 252 * @init_vector_value: Specifies the value for the init vector. 253 */ 254int cryp_configure_init_vector(struct cryp_device_data *device_data, 255 enum cryp_init_vector_index 256 init_vector_index, 257 struct cryp_init_vector_value 258 init_vector_value) 259{ 260 while (cryp_is_logic_busy(device_data)) 261 cpu_relax(); 262 263 switch (init_vector_index) { 264 case CRYP_INIT_VECTOR_INDEX_0: 265 writel_relaxed(init_vector_value.init_value_left, 266 &device_data->base->init_vect_0_l); 267 writel_relaxed(init_vector_value.init_value_right, 268 &device_data->base->init_vect_0_r); 269 break; 270 case CRYP_INIT_VECTOR_INDEX_1: 271 writel_relaxed(init_vector_value.init_value_left, 272 &device_data->base->init_vect_1_l); 273 writel_relaxed(init_vector_value.init_value_right, 274 &device_data->base->init_vect_1_r); 275 break; 276 default: 277 return -EINVAL; 278 } 279 280 return 0; 281} 282 283/** 284 * cryp_save_device_context - Store hardware registers and 285 * other device context parameter 286 * @device_data: Pointer to the device data struct for base address. 287 * @ctx: Crypto device context 288 */ 289void cryp_save_device_context(struct cryp_device_data *device_data, 290 struct cryp_device_context *ctx, 291 int cryp_mode) 292{ 293 enum cryp_algo_mode algomode; 294 struct cryp_register __iomem *src_reg = device_data->base; 295 struct cryp_config *config = 296 (struct cryp_config *)device_data->current_ctx; 297 298 /* 299 * Always start by disable the hardware and wait for it to finish the 300 * ongoing calculations before trying to reprogram it. 301 */ 302 cryp_activity(device_data, CRYP_CRYPEN_DISABLE); 303 cryp_wait_until_done(device_data); 304 305 if (cryp_mode == CRYP_MODE_DMA) 306 cryp_configure_for_dma(device_data, CRYP_DMA_DISABLE_BOTH); 307 308 if (CRYP_TEST_BITS(&src_reg->sr, CRYP_SR_IFEM_MASK) == 0) 309 ctx->din = readl_relaxed(&src_reg->din); 310 311 ctx->cr = readl_relaxed(&src_reg->cr) & CRYP_CR_CONTEXT_SAVE_MASK; 312 313 switch (config->keysize) { 314 case CRYP_KEY_SIZE_256: 315 ctx->key_4_l = readl_relaxed(&src_reg->key_4_l); 316 ctx->key_4_r = readl_relaxed(&src_reg->key_4_r); 317 318 case CRYP_KEY_SIZE_192: 319 ctx->key_3_l = readl_relaxed(&src_reg->key_3_l); 320 ctx->key_3_r = readl_relaxed(&src_reg->key_3_r); 321 322 case CRYP_KEY_SIZE_128: 323 ctx->key_2_l = readl_relaxed(&src_reg->key_2_l); 324 ctx->key_2_r = readl_relaxed(&src_reg->key_2_r); 325 326 default: 327 ctx->key_1_l = readl_relaxed(&src_reg->key_1_l); 328 ctx->key_1_r = readl_relaxed(&src_reg->key_1_r); 329 } 330 331 /* Save IV for CBC mode for both AES and DES. */ 332 algomode = ((ctx->cr & CRYP_CR_ALGOMODE_MASK) >> CRYP_CR_ALGOMODE_POS); 333 if (algomode == CRYP_ALGO_TDES_CBC || 334 algomode == CRYP_ALGO_DES_CBC || 335 algomode == CRYP_ALGO_AES_CBC) { 336 ctx->init_vect_0_l = readl_relaxed(&src_reg->init_vect_0_l); 337 ctx->init_vect_0_r = readl_relaxed(&src_reg->init_vect_0_r); 338 ctx->init_vect_1_l = readl_relaxed(&src_reg->init_vect_1_l); 339 ctx->init_vect_1_r = readl_relaxed(&src_reg->init_vect_1_r); 340 } 341} 342 343/** 344 * cryp_restore_device_context - Restore hardware registers and 345 * other device context parameter 346 * @device_data: Pointer to the device data struct for base address. 347 * @ctx: Crypto device context 348 */ 349void cryp_restore_device_context(struct cryp_device_data *device_data, 350 struct cryp_device_context *ctx) 351{ 352 struct cryp_register __iomem *reg = device_data->base; 353 struct cryp_config *config = 354 (struct cryp_config *)device_data->current_ctx; 355 356 /* 357 * Fall through for all items in switch statement. DES is captured in 358 * the default. 359 */ 360 switch (config->keysize) { 361 case CRYP_KEY_SIZE_256: 362 writel_relaxed(ctx->key_4_l, ®->key_4_l); 363 writel_relaxed(ctx->key_4_r, ®->key_4_r); 364 365 case CRYP_KEY_SIZE_192: 366 writel_relaxed(ctx->key_3_l, ®->key_3_l); 367 writel_relaxed(ctx->key_3_r, ®->key_3_r); 368 369 case CRYP_KEY_SIZE_128: 370 writel_relaxed(ctx->key_2_l, ®->key_2_l); 371 writel_relaxed(ctx->key_2_r, ®->key_2_r); 372 373 default: 374 writel_relaxed(ctx->key_1_l, ®->key_1_l); 375 writel_relaxed(ctx->key_1_r, ®->key_1_r); 376 } 377 378 /* Restore IV for CBC mode for AES and DES. */ 379 if (config->algomode == CRYP_ALGO_TDES_CBC || 380 config->algomode == CRYP_ALGO_DES_CBC || 381 config->algomode == CRYP_ALGO_AES_CBC) { 382 writel_relaxed(ctx->init_vect_0_l, ®->init_vect_0_l); 383 writel_relaxed(ctx->init_vect_0_r, ®->init_vect_0_r); 384 writel_relaxed(ctx->init_vect_1_l, ®->init_vect_1_l); 385 writel_relaxed(ctx->init_vect_1_r, ®->init_vect_1_r); 386 } 387} 388