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