Add support for the older CryptoCell 710 and 630P hardware revisions.

Signed-off-by: Gilad Ben-Yossef <gi...@benyossef.com>
---
 drivers/staging/ccree/Kconfig            |   7 +-
 drivers/staging/ccree/cc_crypto_ctx.h    |  16 ---
 drivers/staging/ccree/cc_hw_queue_defs.h |   2 +-
 drivers/staging/ccree/cc_regs.h          |   7 +-
 drivers/staging/ccree/dx_crys_kernel.h   |   1 +
 drivers/staging/ccree/dx_host.h          |   3 +
 drivers/staging/ccree/dx_reg_common.h    |   2 -
 drivers/staging/ccree/ssi_aead.c         |  36 +++--
 drivers/staging/ccree/ssi_cipher.c       |  27 +++-
 drivers/staging/ccree/ssi_config.h       |   2 +-
 drivers/staging/ccree/ssi_driver.c       | 115 ++++++++++-----
 drivers/staging/ccree/ssi_driver.h       |  25 +++-
 drivers/staging/ccree/ssi_fips_ll.c      |  59 ++++----
 drivers/staging/ccree/ssi_hash.c         | 234 +++++++++++++++++--------------
 drivers/staging/ccree/ssi_hash.h         |  10 +-
 drivers/staging/ccree/ssi_request_mgr.c  |  19 ++-
 drivers/staging/ccree/ssi_sram_mgr.c     |  15 +-
 17 files changed, 349 insertions(+), 231 deletions(-)

diff --git a/drivers/staging/ccree/Kconfig b/drivers/staging/ccree/Kconfig
index 4be87f5..f1e75e8 100644
--- a/drivers/staging/ccree/Kconfig
+++ b/drivers/staging/ccree/Kconfig
@@ -19,9 +19,10 @@ config CRYPTO_DEV_CCREE
        select CRYPTO_XTS
        help
          Say 'Y' to enable a driver for the Arm TrustZone CryptoCell 
-         C7xx. Currently only the CryptoCell 712 REE is supported.
-         Choose this if you wish to use hardware acceleration of
-         cryptographic operations on the system REE.
+         C7xx. Currently the REE interface of the CryptoCell 712,
+         710 and 630p are supported. Choose this if you wish to use
+         hardware acceleration of cryptographic operations on the
+         system REE.
          If unsure say Y.
 
 config CCREE_FIPS_SUPPORT
diff --git a/drivers/staging/ccree/cc_crypto_ctx.h 
b/drivers/staging/ccree/cc_crypto_ctx.h
index 591f6fd..1542aa7 100644
--- a/drivers/staging/ccree/cc_crypto_ctx.h
+++ b/drivers/staging/ccree/cc_crypto_ctx.h
@@ -19,17 +19,6 @@
 
 #include <linux/types.h>
 
-/* context size */
-#ifndef CC_CTX_SIZE_LOG2
-#if (CC_SUPPORT_SHA > 256)
-#define CC_CTX_SIZE_LOG2 8
-#else
-#define CC_CTX_SIZE_LOG2 7
-#endif
-#endif
-#define CC_CTX_SIZE BIT(CC_CTX_SIZE_LOG2)
-#define CC_DRV_CTX_SIZE_WORDS (CC_CTX_SIZE >> 2)
-
 #define CC_DRV_DES_IV_SIZE 8
 #define CC_DRV_DES_BLOCK_SIZE 8
 
@@ -72,13 +61,8 @@
 #define CC_SHA384_BLOCK_SIZE 128
 #define CC_SHA512_BLOCK_SIZE 128
 
-#if (CC_SUPPORT_SHA > 256)
 #define CC_DIGEST_SIZE_MAX CC_SHA512_DIGEST_SIZE
 #define CC_HASH_BLOCK_SIZE_MAX CC_SHA512_BLOCK_SIZE /*1024b*/
-#else /* Only up to SHA256 */
-#define CC_DIGEST_SIZE_MAX CC_SHA256_DIGEST_SIZE
-#define CC_HASH_BLOCK_SIZE_MAX CC_SHA256_BLOCK_SIZE /*512b*/
-#endif
 
 #define CC_HMAC_BLOCK_SIZE_MAX CC_HASH_BLOCK_SIZE_MAX
 
diff --git a/drivers/staging/ccree/cc_hw_queue_defs.h 
b/drivers/staging/ccree/cc_hw_queue_defs.h
index aaa56c8..c730c3c 100644
--- a/drivers/staging/ccree/cc_hw_queue_defs.h
+++ b/drivers/staging/ccree/cc_hw_queue_defs.h
@@ -220,7 +220,7 @@ static inline void hw_desc_init(struct cc_hw_desc *pdesc)
  *
  * @pdesc: pointer HW descriptor struct
  */
-static inline void set_queue_last_ind(struct cc_hw_desc *pdesc)
+static inline void set_queue_last_ind_bit(struct cc_hw_desc *pdesc)
 {
        pdesc->word[3] |= FIELD_PREP(WORD3_QUEUE_LAST_IND, 1);
 }
diff --git a/drivers/staging/ccree/cc_regs.h b/drivers/staging/ccree/cc_regs.h
index 4a893a6..62ace81 100644
--- a/drivers/staging/ccree/cc_regs.h
+++ b/drivers/staging/ccree/cc_regs.h
@@ -25,12 +25,9 @@
 
 #include <linux/bitfield.h>
 
-#define AXIM_MON_BASE_OFFSET CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_COMP)
-#define AXIM_MON_COMP_VALUE GENMASK(DX_AXIM_MON_COMP_VALUE_BIT_SIZE + \
-               DX_AXIM_MON_COMP_VALUE_BIT_SHIFT, \
-               DX_AXIM_MON_COMP_VALUE_BIT_SHIFT)
+#define AXIM_MON_BASE_712_OFFSET CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_COMP)
+#define AXIM_MON_BASE_630_OFFSET CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_COMP8)
 
-#define AXIM_MON_BASE_OFFSET CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_COMP)
 #define AXIM_MON_COMP_VALUE GENMASK(DX_AXIM_MON_COMP_VALUE_BIT_SIZE + \
                DX_AXIM_MON_COMP_VALUE_BIT_SHIFT, \
                DX_AXIM_MON_COMP_VALUE_BIT_SHIFT)
diff --git a/drivers/staging/ccree/dx_crys_kernel.h 
b/drivers/staging/ccree/dx_crys_kernel.h
index 2196030..0d1d01e 100644
--- a/drivers/staging/ccree/dx_crys_kernel.h
+++ b/drivers/staging/ccree/dx_crys_kernel.h
@@ -131,6 +131,7 @@
 #define DX_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SHIFT       0x0UL
 #define DX_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SIZE        0x8UL
 #define DX_AXIM_MON_COMP_REG_OFFSET    0xB80UL
+#define DX_AXIM_MON_COMP8_REG_OFFSET   0xBA0UL
 #define DX_AXIM_MON_COMP_VALUE_BIT_SHIFT       0x0UL
 #define DX_AXIM_MON_COMP_VALUE_BIT_SIZE        0x10UL
 #define DX_AXIM_MON_ERR_REG_OFFSET     0xBC4UL
diff --git a/drivers/staging/ccree/dx_host.h b/drivers/staging/ccree/dx_host.h
index 863c267..b4bdb42 100644
--- a/drivers/staging/ccree/dx_host.h
+++ b/drivers/staging/ccree/dx_host.h
@@ -31,6 +31,9 @@
 #define DX_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SIZE     0x1UL
 #define DX_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT    0x17UL
 #define DX_HOST_IRR_AXIM_COMP_INT_BIT_SIZE     0x1UL
+#define DX_HOST_SEP_SRAM_THRESHOLD_REG_OFFSET   0xA10UL
+#define DX_HOST_SEP_SRAM_THRESHOLD_VALUE_BIT_SHIFT      0x0UL
+#define DX_HOST_SEP_SRAM_THRESHOLD_VALUE_BIT_SIZE       0xCUL
 #define DX_HOST_IMR_REG_OFFSET 0xA04UL
 #define DX_HOST_IMR_NOT_USED_MASK_BIT_SHIFT    0x1UL
 #define DX_HOST_IMR_NOT_USED_MASK_BIT_SIZE     0x1UL
diff --git a/drivers/staging/ccree/dx_reg_common.h 
b/drivers/staging/ccree/dx_reg_common.h
index d5132ff..f7cec05 100644
--- a/drivers/staging/ccree/dx_reg_common.h
+++ b/drivers/staging/ccree/dx_reg_common.h
@@ -21,6 +21,4 @@
 
 #define CC_HW_VERSION 0xef840015UL
 
-#define DX_DEV_SHA_MAX 512
-
 #endif /*__DX_REG_COMMON_H__*/
diff --git a/drivers/staging/ccree/ssi_aead.c b/drivers/staging/ccree/ssi_aead.c
index c70e450..e228a9b 100644
--- a/drivers/staging/ccree/ssi_aead.c
+++ b/drivers/staging/ccree/ssi_aead.c
@@ -321,7 +321,7 @@ static int hmac_setkey(struct cc_hw_desc *desc, struct 
ssi_aead_ctx *ctx)
                /* Load the hash current length*/
                hw_desc_init(&desc[idx]);
                set_cipher_mode(&desc[idx], hash_mode);
-               set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
+               set_din_const(&desc[idx], 0, ctx->drvdata->hash_len_sz);
                set_flow_mode(&desc[idx], S_DIN_to_HASH);
                set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
                idx++;
@@ -456,7 +456,8 @@ ssi_get_plain_hmac_key(struct crypto_aead *tfm, const u8 
*key, unsigned int keyl
                        /* Load the hash current length*/
                        hw_desc_init(&desc[idx]);
                        set_cipher_mode(&desc[idx], hashmode);
-                       set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
+                       set_din_const(&desc[idx], 0,
+                                     ctx->drvdata->hash_len_sz);
                        set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
                        set_flow_mode(&desc[idx], S_DIN_to_HASH);
                        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
@@ -879,7 +880,7 @@ static inline void ssi_aead_process_digest_result_desc(
                set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
                set_dout_dlli(&desc[idx], req_ctx->icv_dma_addr, ctx->authsize,
                              NS_BIT, 1);
-               set_queue_last_ind(&desc[idx]);
+               set_queue_last_ind(ctx->drvdata, &desc[idx]);
                if (ctx->auth_mode == DRV_HASH_XCBC_MAC) {
                        set_aes_not_hash_mode(&desc[idx]);
                        set_cipher_mode(&desc[idx], DRV_CIPHER_XCBC_MAC);
@@ -895,7 +896,7 @@ static inline void ssi_aead_process_digest_result_desc(
                set_flow_mode(&desc[idx], S_HASH_to_DOUT);
                set_dout_dlli(&desc[idx], req_ctx->mac_buf_dma_addr,
                              ctx->authsize, NS_BIT, 1);
-               set_queue_last_ind(&desc[idx]);
+               set_queue_last_ind(ctx->drvdata, &desc[idx]);
                set_cipher_config0(&desc[idx],
                                   HASH_DIGEST_RESULT_LITTLE_ENDIAN);
                set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED);
@@ -1012,7 +1013,7 @@ static inline void ssi_aead_hmac_setup_digest_desc(
        set_din_sram(&desc[idx],
                     ssi_ahash_get_initial_digest_len_sram_addr(ctx->drvdata,
                                                                hash_mode),
-                                                               HASH_LEN_SIZE);
+                    ctx->drvdata->hash_len_sz);
        set_flow_mode(&desc[idx], S_DIN_to_HASH);
        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
        idx++;
@@ -1113,7 +1114,7 @@ static inline void ssi_aead_process_digest_scheme_desc(
        hw_desc_init(&desc[idx]);
        set_cipher_mode(&desc[idx], hash_mode);
        set_dout_sram(&desc[idx], aead_handle->sram_workspace_addr,
-                     HASH_LEN_SIZE);
+                     ctx->drvdata->hash_len_sz);
        set_flow_mode(&desc[idx], S_HASH_to_DOUT);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE1);
        set_cipher_do(&desc[idx], DO_PAD);
@@ -1145,7 +1146,7 @@ static inline void ssi_aead_process_digest_scheme_desc(
        set_din_sram(&desc[idx],
                     ssi_ahash_get_initial_digest_len_sram_addr(ctx->drvdata,
                                                                hash_mode),
-                    HASH_LEN_SIZE);
+                    ctx->drvdata->hash_len_sz);
        set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
        set_flow_mode(&desc[idx], S_DIN_to_HASH);
        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
@@ -1534,7 +1535,7 @@ static inline int ssi_aead_ccm(
        set_din_type(&desc[idx], DMA_DLLI, req_ctx->mac_buf_dma_addr,
                     ctx->authsize, NS_BIT);
        set_dout_dlli(&desc[idx], mac_result, ctx->authsize, NS_BIT, 1);
-       set_queue_last_ind(&desc[idx]);
+       set_queue_last_ind(ctx->drvdata, &desc[idx]);
        set_flow_mode(&desc[idx], DIN_AES_DOUT);
        idx++;
 
@@ -1791,7 +1792,7 @@ static inline void ssi_aead_process_gcm_result_desc(
        set_din_type(&desc[idx], DMA_DLLI, req_ctx->mac_buf_dma_addr,
                     AES_BLOCK_SIZE, NS_BIT);
        set_dout_dlli(&desc[idx], mac_result, ctx->authsize, NS_BIT, 1);
-       set_queue_last_ind(&desc[idx]);
+       set_queue_last_ind(ctx->drvdata, &desc[idx]);
        set_flow_mode(&desc[idx], DIN_AES_DOUT);
        idx++;
 
@@ -2423,6 +2424,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CBC,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_SHA1,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "authenc(hmac(sha1),cbc(des3_ede))",
@@ -2442,6 +2444,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CBC,
                .flow_mode = S_DIN_to_DES,
                .auth_mode = DRV_HASH_SHA1,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "authenc(hmac(sha256),cbc(aes))",
@@ -2461,6 +2464,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CBC,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_SHA256,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "authenc(hmac(sha256),cbc(des3_ede))",
@@ -2480,6 +2484,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CBC,
                .flow_mode = S_DIN_to_DES,
                .auth_mode = DRV_HASH_SHA256,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "authenc(xcbc(aes),cbc(aes))",
@@ -2499,6 +2504,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CBC,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_XCBC_MAC,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "authenc(hmac(sha1),rfc3686(ctr(aes)))",
@@ -2518,6 +2524,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CTR,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_SHA1,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "authenc(hmac(sha256),rfc3686(ctr(aes)))",
@@ -2537,6 +2544,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CTR,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_SHA256,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "authenc(xcbc(aes),rfc3686(ctr(aes)))",
@@ -2556,6 +2564,8 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CTR,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_XCBC_MAC,
+               .min_hw_rev = CC_HW_REV_630,
+
        },
 #if SSI_CC_HAS_AES_CCM
        {
@@ -2576,6 +2586,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CCM,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_NULL,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "rfc4309(ccm(aes))",
@@ -2595,6 +2606,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_CCM,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_NULL,
+               .min_hw_rev = CC_HW_REV_630,
        },
 #endif /*SSI_CC_HAS_AES_CCM*/
 #if SSI_CC_HAS_AES_GCM
@@ -2616,6 +2628,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_GCTR,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_NULL,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "rfc4106(gcm(aes))",
@@ -2635,6 +2648,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_GCTR,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_NULL,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "rfc4543(gcm(aes))",
@@ -2654,6 +2668,7 @@ static struct ssi_alg_template aead_algs[] = {
                .cipher_mode = DRV_CIPHER_GCTR,
                .flow_mode = S_DIN_to_AES,
                .auth_mode = DRV_HASH_NULL,
+               .min_hw_rev = CC_HW_REV_630,
        },
 #endif /*SSI_CC_HAS_AES_GCM*/
 };
@@ -2738,6 +2753,9 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata)
 
        /* Linux crypto */
        for (alg = 0; alg < ARRAY_SIZE(aead_algs); alg++) {
+               if (aead_algs[alg].min_hw_rev > drvdata->hw_rev)
+                       continue;
+
                t_alg = ssi_aead_create_alg(&aead_algs[alg]);
                if (IS_ERR(t_alg)) {
                        rc = PTR_ERR(t_alg);
diff --git a/drivers/staging/ccree/ssi_cipher.c 
b/drivers/staging/ccree/ssi_cipher.c
index 34450a5..349ccb9 100644
--- a/drivers/staging/ccree/ssi_cipher.c
+++ b/drivers/staging/ccree/ssi_cipher.c
@@ -663,7 +663,7 @@ ssi_blkcipher_create_data_desc(
                set_dout_dlli(&desc[*seq_size], sg_dma_address(dst),
                              nbytes, NS_BIT, (!areq ? 0 : 1));
                if (areq != NULL) {
-                       set_queue_last_ind(&desc[*seq_size]);
+                       set_queue_last_ind(ctx_p->drvdata, &desc[*seq_size]);
                }
                set_flow_mode(&desc[*seq_size], flow_mode);
                (*seq_size)++;
@@ -712,7 +712,7 @@ ssi_blkcipher_create_data_desc(
                                      (!areq ? 0 : 1));
                }
                if (areq != NULL) {
-                       set_queue_last_ind(&desc[*seq_size]);
+                       set_queue_last_ind(ctx_p->drvdata, &desc[*seq_size]);
                }
                set_flow_mode(&desc[*seq_size], flow_mode);
                (*seq_size)++;
@@ -951,6 +951,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_XTS,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "xts(aes)",
@@ -967,6 +968,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_XTS,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_712,
        },
        {
                .name = "xts(aes)",
@@ -983,6 +985,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_XTS,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_712,
        },
 #endif /*SSI_CC_HAS_AES_XTS*/
 #if SSI_CC_HAS_AES_ESSIV
@@ -1001,6 +1004,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_ESSIV,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_712,
        },
        {
                .name = "essiv(aes)",
@@ -1017,6 +1021,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_ESSIV,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_712,
        },
        {
                .name = "essiv(aes)",
@@ -1033,6 +1038,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_ESSIV,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_712,
        },
 #endif /*SSI_CC_HAS_AES_ESSIV*/
 #if SSI_CC_HAS_AES_BITLOCKER
@@ -1051,6 +1057,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_BITLOCKER,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_712,
        },
        {
                .name = "bitlocker(aes)",
@@ -1067,6 +1074,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_BITLOCKER,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_712,
        },
        {
                .name = "bitlocker(aes)",
@@ -1083,6 +1091,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_BITLOCKER,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_712,
        },
 #endif /*SSI_CC_HAS_AES_BITLOCKER*/
        {
@@ -1100,6 +1109,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_ECB,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "cbc(aes)",
@@ -1116,6 +1126,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                },
                .cipher_mode = DRV_CIPHER_CBC,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "ofb(aes)",
@@ -1132,6 +1143,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_OFB,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_630,
        },
 #if SSI_CC_HAS_AES_CTS
        {
@@ -1149,6 +1161,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_CBC_CTS,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_630,
        },
 #endif
        {
@@ -1166,6 +1179,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_CTR,
                .flow_mode = S_DIN_to_AES,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "cbc(des3_ede)",
@@ -1182,6 +1196,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_CBC,
                .flow_mode = S_DIN_to_DES,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "ecb(des3_ede)",
@@ -1198,6 +1213,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_ECB,
                .flow_mode = S_DIN_to_DES,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "cbc(des)",
@@ -1214,6 +1230,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_CBC,
                .flow_mode = S_DIN_to_DES,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "ecb(des)",
@@ -1230,6 +1247,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_CIPHER_ECB,
                .flow_mode = S_DIN_to_DES,
+               .min_hw_rev = CC_HW_REV_630,
        },
 #if SSI_CC_HAS_MULTI2
        {
@@ -1247,6 +1265,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_MULTI2_CBC,
                .flow_mode = S_DIN_to_MULTI2,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "ofb(multi2)",
@@ -1263,6 +1282,7 @@ static struct ssi_alg_template blkcipher_algs[] = {
                        },
                .cipher_mode = DRV_MULTI2_OFB,
                .flow_mode = S_DIN_to_MULTI2,
+               .min_hw_rev = CC_HW_REV_630,
        },
 #endif /*SSI_CC_HAS_MULTI2*/
 };
@@ -1347,6 +1367,9 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata)
        /* Linux crypto */
        SSI_LOG_DEBUG("Number of algorithms = %zu\n", 
ARRAY_SIZE(blkcipher_algs));
        for (alg = 0; alg < ARRAY_SIZE(blkcipher_algs); alg++) {
+               if (blkcipher_algs[alg].min_hw_rev > drvdata->hw_rev)
+                       continue;
+
                SSI_LOG_DEBUG("creating %s\n", blkcipher_algs[alg].driver_name);
                t_alg = ssi_ablkcipher_create_alg(&blkcipher_algs[alg]);
                if (IS_ERR(t_alg)) {
diff --git a/drivers/staging/ccree/ssi_config.h 
b/drivers/staging/ccree/ssi_config.h
index b7c0576..2484a06 100644
--- a/drivers/staging/ccree/ssi_config.h
+++ b/drivers/staging/ccree/ssi_config.h
@@ -23,7 +23,7 @@
 
 #include <linux/version.h>
 
-#define DISABLE_COHERENT_DMA_OPS
+//#define DISABLE_COHERENT_DMA_OPS
 //#define FLUSH_CACHE_ALL
 //#define COMPLETION_DELAY
 //#define DX_DUMP_DESCS
diff --git a/drivers/staging/ccree/ssi_driver.c 
b/drivers/staging/ccree/ssi_driver.c
index b9d0dd27..131bfc4 100644
--- a/drivers/staging/ccree/ssi_driver.c
+++ b/drivers/staging/ccree/ssi_driver.c
@@ -71,6 +71,33 @@
 #include "ssi_pm.h"
 #include "ssi_fips_local.h"
 
+struct cc_hw_data {
+       char *name;
+       enum cc_hw_rev rev;
+       u32 sig;
+};
+
+/* Hardware revisions defs. */
+
+static const struct cc_hw_data cc712_hw = {
+       .name = "712", .rev = CC_HW_REV_712, .sig =  0xDCC71200U
+};
+
+static const struct cc_hw_data cc710_hw = {
+       .name = "710", .rev = CC_HW_REV_710, .sig =  0xDCC63200U
+};
+
+static const struct cc_hw_data cc630p_hw = {
+       .name = "630P", .rev = CC_HW_REV_630, .sig = 0xDCC63000U
+};
+
+static const struct of_device_id arm_ccree_dev_of_match[] = {
+       { .compatible = "arm,cryptocell-712-ree", .data = &cc712_hw },
+       { .compatible = "arm,cryptocell-710-ree", .data = &cc710_hw },
+       { .compatible = "arm,cryptocell-630p-ree", .data = &cc630p_hw },
+       {}
+};
+MODULE_DEVICE_TABLE(of, arm_ccree_dev_of_match);
 
 #ifdef DX_DUMP_BYTES
 void dump_byte_array(const char *name, const u8 *the_array, unsigned long size)
@@ -185,8 +212,12 @@ int init_cc_regs(struct ssi_drvdata *drvdata, bool 
is_probe)
        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ICR), val);
 
        /* Unmask relevant interrupt cause */
-       val = (~(SSI_COMP_IRQ_MASK | SSI_AXI_ERR_IRQ_MASK | SSI_GPR0_IRQ_MASK));
-       CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR), val);
+       val = (SSI_COMP_IRQ_MASK | SSI_AXI_ERR_IRQ_MASK);
+
+       if (drvdata->hw_rev >= CC_HW_REV_712)
+               val |= SSI_GPR0_IRQ_MASK;
+
+       CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR), ~val);
 
 #ifdef DX_HOST_IRQ_TIMER_INIT_VAL_REG_OFFSET
 #ifdef DX_IRQ_DELAY
@@ -215,11 +246,15 @@ int init_cc_regs(struct ssi_drvdata *drvdata, bool 
is_probe)
 
 static int init_cc_resources(struct platform_device *plat_dev)
 {
-       struct resource *req_mem_cc_regs = NULL;
+       struct resource *cc_regs_res = NULL;
        void __iomem *cc_base = NULL;
        bool irq_registered = false;
        struct ssi_drvdata *new_drvdata = kzalloc(sizeof(struct ssi_drvdata), 
GFP_KERNEL);
        u32 signature_val;
+       struct device *dev = &plat_dev->dev;
+       struct device_node *np = dev->of_node;
+       const struct cc_hw_data *hw_rev;
+       const struct of_device_id *dev_id;
        int rc = 0;
 
        if (unlikely(new_drvdata == NULL)) {
@@ -228,6 +263,21 @@ static int init_cc_resources(struct platform_device 
*plat_dev)
                goto init_cc_res_err;
        }
 
+       dev_id = of_match_node(arm_ccree_dev_of_match, np);
+       if (!dev_id)
+               return -ENODEV;
+       hw_rev = (struct cc_hw_data *)dev_id->data;
+       new_drvdata->hw_rev_name = hw_rev->name;
+       new_drvdata->hw_rev = hw_rev->rev;
+
+       if (hw_rev->rev >= CC_HW_REV_712) {
+               new_drvdata->hash_len_sz = HASH_LEN_SIZE_712;
+               new_drvdata->axim_mon_offset = AXIM_MON_BASE_712_OFFSET;
+       } else {
+               new_drvdata->hash_len_sz = HASH_LEN_SIZE_630;
+               new_drvdata->axim_mon_offset = AXIM_MON_BASE_630_OFFSET;
+       }
+
        /*Initialize inflight counter used in dx_ablkcipher_secure_complete 
used for count of BYSPASS blocks operations*/
        new_drvdata->inflight_counter = 0;
 
@@ -245,8 +295,10 @@ static int init_cc_resources(struct platform_device 
*plat_dev)
                (unsigned long long)new_drvdata->res_mem->start,
                (unsigned long long)new_drvdata->res_mem->end);
        /* Map registers space */
-       req_mem_cc_regs = request_mem_region(new_drvdata->res_mem->start, 
resource_size(new_drvdata->res_mem), "arm_cc7x_regs");
-       if (unlikely(req_mem_cc_regs == NULL)) {
+       cc_regs_res = request_mem_region(new_drvdata->res_mem->start,
+                                        resource_size(new_drvdata->res_mem),
+                                        "arm_ccree_regs");
+       if (unlikely(!cc_regs_res)) {
                SSI_LOG_ERR("Couldn't allocate registers memory region at "
                             "0x%08X\n", (unsigned 
int)new_drvdata->res_mem->start);
                rc = -EBUSY;
@@ -271,7 +323,7 @@ static int init_cc_resources(struct platform_device 
*plat_dev)
                goto init_cc_res_err;
        }
        rc = request_irq(new_drvdata->res_irq->start, cc_isr,
-                        IRQF_SHARED, "arm_cc7x", new_drvdata);
+                        IRQF_SHARED, "arm_ccree", new_drvdata);
        if (unlikely(rc != 0)) {
                SSI_LOG_ERR("Could not register to interrupt %llu\n",
                        (unsigned long long)new_drvdata->res_irq->start);
@@ -297,17 +349,19 @@ static int init_cc_resources(struct platform_device 
*plat_dev)
 
        /* Verify correct mapping */
        signature_val = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, 
HOST_SIGNATURE));
-       if (signature_val != DX_DEV_SIGNATURE) {
-               SSI_LOG_ERR("Invalid CC signature: SIGNATURE=0x%08X != 
expected=0x%08X\n",
-                       signature_val, (u32)DX_DEV_SIGNATURE);
+       if (signature_val != hw_rev->sig) {
+               SSI_LOG_ERR("Signature mismatch: expected 0x%08X got 0x%08X\n",
+                           signature_val, hw_rev->sig);
                rc = -EINVAL;
                goto init_cc_res_err;
        }
        SSI_LOG_DEBUG("CC SIGNATURE=0x%08X\n", signature_val);
 
        /* Display HW versions */
-       SSI_LOG(KERN_INFO, "ARM CryptoCell %s Driver: HW version 0x%08X, Driver 
version %s\n", SSI_DEV_NAME_STR,
-               CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_VERSION)), 
DRV_MODULE_VERSION);
+       SSI_LOG(KERN_INFO, "ARM CryptoCell %s (HW ver 0x%08X, SW version %s)\n",
+               hw_rev->name,
+               CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_VERSION)),
+               DRV_MODULE_VERSION);
 
        rc = init_cc_regs(new_drvdata, true);
        if (unlikely(rc != 0)) {
@@ -406,7 +460,7 @@ static int init_cc_resources(struct platform_device 
*plat_dev)
                ssi_sysfs_fini();
 #endif
 
-               if (req_mem_cc_regs != NULL) {
+               if (cc_regs_res) {
                        if (irq_registered) {
                                free_irq(new_drvdata->res_irq->start, 
new_drvdata);
                                new_drvdata->res_irq = NULL;
@@ -470,7 +524,7 @@ static void cleanup_cc_resources(struct platform_device 
*plat_dev)
        dev_set_drvdata(&plat_dev->dev, NULL);
 }
 
-static int cc7x_probe(struct platform_device *plat_dev)
+static int ccree_probe(struct platform_device *plat_dev)
 {
        int rc;
 #if defined(CONFIG_ARM) && defined(CC_DEBUG)
@@ -492,54 +546,43 @@ static int cc7x_probe(struct platform_device *plat_dev)
        if (rc != 0)
                return rc;
 
-       SSI_LOG(KERN_INFO, "ARM cc7x_ree device initialized\n");
+       SSI_LOG(KERN_INFO, "ARM CryptoCell REE device initialized\n");
 
        return 0;
 }
 
-static int cc7x_remove(struct platform_device *plat_dev)
+static int ccree_remove(struct platform_device *plat_dev)
 {
-       SSI_LOG_DEBUG("Releasing cc7x resources...\n");
+       SSI_LOG_DEBUG("Releasing resources...\n");
 
        cleanup_cc_resources(plat_dev);
 
-       SSI_LOG(KERN_INFO, "ARM cc7x_ree device terminated\n");
+       SSI_LOG(KERN_INFO, "ARM CryptoCell REE device unloaded\n");
 
        return 0;
 }
 #if defined (CONFIG_PM_RUNTIME) || defined (CONFIG_PM_SLEEP)
-static struct dev_pm_ops arm_cc7x_driver_pm = {
+static const struct dev_pm_ops arm_ccree_driver_pm = {
        SET_RUNTIME_PM_OPS(ssi_power_mgr_runtime_suspend, 
ssi_power_mgr_runtime_resume, NULL)
 };
 #endif
 
 #if defined (CONFIG_PM_RUNTIME) || defined (CONFIG_PM_SLEEP)
-#define        DX_DRIVER_RUNTIME_PM    (&arm_cc7x_driver_pm)
+#define        DX_DRIVER_RUNTIME_PM    (&arm_ccree_driver_pm)
 #else
 #define        DX_DRIVER_RUNTIME_PM    NULL
 #endif
 
-
-#ifdef CONFIG_OF
-static const struct of_device_id arm_cc7x_dev_of_match[] = {
-       {.compatible = "arm,cryptocell-712-ree"},
-       {}
-};
-MODULE_DEVICE_TABLE(of, arm_cc7x_dev_of_match);
-#endif
-
-static struct platform_driver cc7x_driver = {
+static struct platform_driver ccree_driver = {
        .driver = {
-                  .name = "cc7xree",
-#ifdef CONFIG_OF
-                  .of_match_table = arm_cc7x_dev_of_match,
-#endif
+                  .name = "ccree",
+                  .of_match_table = arm_ccree_dev_of_match,
                   .pm = DX_DRIVER_RUNTIME_PM,
        },
-       .probe = cc7x_probe,
-       .remove = cc7x_remove,
+       .probe = ccree_probe,
+       .remove = ccree_remove,
 };
-module_platform_driver(cc7x_driver);
+module_platform_driver(ccree_driver);
 
 /* Module description */
 MODULE_DESCRIPTION("ARM TrustZone CryptoCell REE Driver");
diff --git a/drivers/staging/ccree/ssi_driver.h 
b/drivers/staging/ccree/ssi_driver.h
index 78a327a..3c27fd8 100644
--- a/drivers/staging/ccree/ssi_driver.h
+++ b/drivers/staging/ccree/ssi_driver.h
@@ -43,7 +43,6 @@
 #include "cc_regs.h"
 #include "dx_reg_common.h"
 #include "cc_hal.h"
-#define CC_SUPPORT_SHA DX_DEV_SHA_MAX
 #include "cc_crypto_ctx.h"
 #include "ssi_sysfs.h"
 #include "hash_defs.h"
@@ -51,9 +50,14 @@
 #include "cc_hw_queue_defs.h"
 #include "ssi_sram_mgr.h"
 
-#define DRV_MODULE_VERSION "3.0"
+#define DRV_MODULE_VERSION "4.0"
+
+enum cc_hw_rev {
+       CC_HW_REV_630 = 630,
+       CC_HW_REV_710 = 710,
+       CC_HW_REV_712 = 712
+};
 
-#define SSI_DEV_NAME_STR "cc715ree"
 #define SSI_CC_HAS_AES_CCM 1
 #define SSI_CC_HAS_AES_GCM 1
 #define SSI_CC_HAS_AES_XTS 1
@@ -90,7 +94,7 @@
 
 /* Logging macros */
 #define SSI_LOG(level, format, ...) \
-       printk(level "cc715ree::%s: " format , __func__, ##__VA_ARGS__)
+       printk(level "ccree::%s: " format, __func__, ##__VA_ARGS__)
 #define SSI_LOG_ERR(format, ...) SSI_LOG(KERN_ERR, format, ##__VA_ARGS__)
 #define SSI_LOG_WARNING(format, ...) SSI_LOG(KERN_WARNING, format, 
##__VA_ARGS__)
 #define SSI_LOG_NOTICE(format, ...) SSI_LOG(KERN_NOTICE, format, ##__VA_ARGS__)
@@ -148,7 +152,10 @@ struct ssi_drvdata {
        void *ivgen_handle;
        void *sram_mgr_handle;
        u32 inflight_counter;
-
+       char *hw_rev_name;
+       enum cc_hw_rev hw_rev;
+       u32 hash_len_sz;
+       u32 axim_mon_offset;
 };
 
 struct ssi_crypto_alg {
@@ -176,6 +183,7 @@ struct ssi_alg_template {
        int cipher_mode;
        int flow_mode; /* Note: currently, refers to the cipher mode only. */
        int auth_mode;
+       u32 min_hw_rev;
        struct ssi_drvdata *drvdata;
 };
 
@@ -194,5 +202,12 @@ void dump_byte_array(const char *name, const u8 
*the_array, unsigned long size);
 int init_cc_regs(struct ssi_drvdata *drvdata, bool is_probe);
 void fini_cc_regs(struct ssi_drvdata *drvdata);
 
+static inline void set_queue_last_ind(struct ssi_drvdata *drvdata,
+                                     struct cc_hw_desc *pdesc)
+{
+       if (drvdata->hw_rev >= CC_HW_REV_712)
+               set_queue_last_ind_bit(pdesc);
+}
+
 #endif /*__SSI_DRIVER_H__*/
 
diff --git a/drivers/staging/ccree/ssi_fips_ll.c 
b/drivers/staging/ccree/ssi_fips_ll.c
index 6c79e7d..811d6e9 100644
--- a/drivers/staging/ccree/ssi_fips_ll.c
+++ b/drivers/staging/ccree/ssi_fips_ll.c
@@ -35,13 +35,11 @@ static const u32 sha1_init[] = {
 static const u32 sha256_init[] = {
        SHA256_H7, SHA256_H6, SHA256_H5, SHA256_H4,
        SHA256_H3, SHA256_H2, SHA256_H1, SHA256_H0 };
-#if (CC_SUPPORT_SHA > 256)
 static const u32 digest_len_sha512_init[] = {
        0x00000080, 0x00000000, 0x00000000, 0x00000000 };
 static const u64 sha512_init[] = {
        SHA512_H7, SHA512_H6, SHA512_H5, SHA512_H4,
        SHA512_H3, SHA512_H2, SHA512_H1, SHA512_H0 };
-#endif
 
 
 #define NIST_CIPHER_AES_MAX_VECTOR_SIZE      32
@@ -102,7 +100,7 @@ struct fips_hmac_ctx {
        u8 initial_digest[CC_DIGEST_SIZE_MAX];
        u8 key[CC_HMAC_BLOCK_SIZE_MAX];
        u8 k0[CC_HMAC_BLOCK_SIZE_MAX];
-       u8 digest_bytes_len[HASH_LEN_SIZE];
+       u8 digest_bytes_len[HASH_MAX_LEN_SIZE];
        u8 tmp_digest[CC_DIGEST_SIZE_MAX];
        u8 din[NIST_HMAC_MSG_SIZE];
        u8 mac_res[CC_DIGEST_SIZE_MAX];
@@ -213,10 +211,8 @@ static const FipsCipherData FipsCipherDataTable[] = {
        { 1, RFC3962_AES_128_KEY,  CC_AES_128_BIT_KEY_SIZE, 
RFC3962_AES_CBC_CTS_IV, DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_CBC_CTS, 
RFC3962_AES_128_CBC_CTS_CIPHER, RFC3962_AES_PLAIN_DATA, RFC3962_AES_VECTOR_SIZE 
},
        { 1, NIST_AES_256_XTS_KEY, CC_AES_256_BIT_KEY_SIZE,   
NIST_AES_256_XTS_IV,  DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_XTS,     
NIST_AES_256_XTS_PLAIN, NIST_AES_256_XTS_CIPHER, NIST_AES_256_XTS_VECTOR_SIZE },
        { 1, NIST_AES_256_XTS_KEY, CC_AES_256_BIT_KEY_SIZE,   
NIST_AES_256_XTS_IV,  DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_XTS,     
NIST_AES_256_XTS_CIPHER, NIST_AES_256_XTS_PLAIN, NIST_AES_256_XTS_VECTOR_SIZE },
-#if (CC_SUPPORT_SHA > 256)
        { 1, NIST_AES_512_XTS_KEY, 2*CC_AES_256_BIT_KEY_SIZE, 
NIST_AES_512_XTS_IV,  DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_XTS,     
NIST_AES_512_XTS_PLAIN, NIST_AES_512_XTS_CIPHER, NIST_AES_512_XTS_VECTOR_SIZE },
        { 1, NIST_AES_512_XTS_KEY, 2*CC_AES_256_BIT_KEY_SIZE, 
NIST_AES_512_XTS_IV,  DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_XTS,     
NIST_AES_512_XTS_CIPHER, NIST_AES_512_XTS_PLAIN, NIST_AES_512_XTS_VECTOR_SIZE },
-#endif
        /* DES */
        { 0, NIST_TDES_ECB3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_ECB_IV, 
DRV_CRYPTO_DIRECTION_ENCRYPT, DRV_CIPHER_ECB, NIST_TDES_ECB3_PLAIN_DATA, 
NIST_TDES_ECB3_CIPHER, NIST_TDES_VECTOR_SIZE },
        { 0, NIST_TDES_ECB3_KEY, CC_DRV_DES_TRIPLE_KEY_SIZE, NIST_TDES_ECB_IV, 
DRV_CRYPTO_DIRECTION_DECRYPT, DRV_CIPHER_ECB, NIST_TDES_ECB3_CIPHER, 
NIST_TDES_ECB3_PLAIN_DATA, NIST_TDES_VECTOR_SIZE },
@@ -235,18 +231,16 @@ static const FipsCmacData FipsCmacDataTable[] = {
 static const FipsHashData FipsHashDataTable[] = {
        { DRV_HASH_SHA1,   NIST_SHA_1_MSG,   NIST_SHA_MSG_SIZE, NIST_SHA_1_MD },
        { DRV_HASH_SHA256, NIST_SHA_256_MSG, NIST_SHA_MSG_SIZE, NIST_SHA_256_MD 
},
-#if (CC_SUPPORT_SHA > 256)
-//        { DRV_HASH_SHA512, NIST_SHA_512_MSG, NIST_SHA_MSG_SIZE, 
NIST_SHA_512_MD },
-#endif
+       { DRV_HASH_SHA512, NIST_SHA_512_MSG, NIST_SHA_MSG_SIZE,
+               NIST_SHA_512_MD },
 };
 #define FIPS_HASH_NUM_OF_TESTS        (sizeof(FipsHashDataTable) / 
sizeof(FipsHashData))
 
 static const FipsHmacData FipsHmacDataTable[] = {
        { DRV_HASH_SHA1,   NIST_HMAC_SHA1_KEY,   NIST_HMAC_SHA1_KEY_SIZE,   
NIST_HMAC_SHA1_MSG,   NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA1_MD },
        { DRV_HASH_SHA256, NIST_HMAC_SHA256_KEY, NIST_HMAC_SHA256_KEY_SIZE, 
NIST_HMAC_SHA256_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA256_MD },
-#if (CC_SUPPORT_SHA > 256)
-//        { DRV_HASH_SHA512, NIST_HMAC_SHA512_KEY, NIST_HMAC_SHA512_KEY_SIZE, 
NIST_HMAC_SHA512_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA512_MD },
-#endif
+       { DRV_HASH_SHA512, NIST_HMAC_SHA512_KEY, NIST_HMAC_SHA512_KEY_SIZE,
+               NIST_HMAC_SHA512_MSG, NIST_HMAC_MSG_SIZE, NIST_HMAC_SHA512_MD },
 };
 #define FIPS_HMAC_NUM_OF_TESTS        (sizeof(FipsHmacDataTable) / 
sizeof(FipsHmacData))
 
@@ -434,6 +428,11 @@ ssi_cipher_fips_power_up_tests(struct ssi_drvdata 
*drvdata, void *cpu_addr_buffe
                int rc = 0;
                size_t iv_size = cipherData->isAes ? NIST_AES_IV_SIZE : 
NIST_TDES_IV_SIZE ;
 
+               /* AES 512 was introduced in 712 */
+               if ((cipherDara->keySize > CC_AES_256_BIT_KEY_SIZE) &&
+                   (drvdata->hw_rev < CC_HW_REV_712))
+                       continue;
+
                memset(cpu_addr_buffer, 0, sizeof(struct fips_cipher_ctx));
 
                /* copy into the allocated buffer */
@@ -612,10 +611,8 @@ FIPS_HashToFipsError(enum drv_hash_mode hash_mode)
                return CC_REE_FIPS_ERROR_SHA1_PUT;
        case DRV_HASH_SHA256:
                return CC_REE_FIPS_ERROR_SHA256_PUT;
-#if (CC_SUPPORT_SHA > 256)
        case DRV_HASH_SHA512:
                return CC_REE_FIPS_ERROR_SHA512_PUT;
-#endif
        default:
                return CC_REE_FIPS_ERROR_GENERAL;
        }
@@ -654,7 +651,7 @@ ssi_hash_fips_run_test(struct ssi_drvdata *drvdata,
        /* Load the hash current length */
        hw_desc_init(&desc[idx]);
        set_cipher_mode(&desc[idx], hw_mode);
-       set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
+       set_din_const(&desc[idx], 0, drvdata->hash_len_sz);
        set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
        set_flow_mode(&desc[idx], S_DIN_to_HASH);
        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
@@ -726,14 +723,15 @@ ssi_hash_fips_power_up_tests(struct ssi_drvdata *drvdata, 
void *cpu_addr_buffer,
                        inter_digestsize = CC_SHA256_DIGEST_SIZE;
                        memcpy(virt_ctx->initial_digest, (void*)sha256_init, 
CC_SHA256_DIGEST_SIZE);
                        break;
-#if (CC_SUPPORT_SHA > 256)
                case DRV_HASH_SHA512:
+                       /* SHA 512 was introduced in CC 712 */
+                       if (drvdata->hw_rev < CC_HW_REV_712)
+                               continue;
                        hw_mode = DRV_HASH_HW_SHA512;
                        digest_size = CC_SHA512_DIGEST_SIZE;
                        inter_digestsize = CC_SHA512_DIGEST_SIZE;
                        memcpy(virt_ctx->initial_digest, (void*)sha512_init, 
CC_SHA512_DIGEST_SIZE);
                        break;
-#endif
                default:
                        error = FIPS_HashToFipsError(hash_data->hash_mode);
                        break;
@@ -788,10 +786,8 @@ FIPS_HmacToFipsError(enum drv_hash_mode hash_mode)
                return CC_REE_FIPS_ERROR_HMAC_SHA1_PUT;
        case DRV_HASH_SHA256:
                return CC_REE_FIPS_ERROR_HMAC_SHA256_PUT;
-#if (CC_SUPPORT_SHA > 256)
        case DRV_HASH_SHA512:
                return CC_REE_FIPS_ERROR_HMAC_SHA512_PUT;
-#endif
        default:
                return CC_REE_FIPS_ERROR_GENERAL;
        }
@@ -871,7 +867,7 @@ ssi_hmac_fips_run_test(struct ssi_drvdata *drvdata,
                /* Load the hash current length*/
                hw_desc_init(&desc[idx]);
                set_cipher_mode(&desc[idx], hw_mode);
-               set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
+               set_din_const(&desc[idx], 0, drvdata->hash_len_sz);
                set_flow_mode(&desc[idx], S_DIN_to_HASH);
                set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
                idx++;
@@ -923,7 +919,7 @@ ssi_hmac_fips_run_test(struct ssi_drvdata *drvdata,
        /* HW last hash block padding (aka. "DO_PAD") */
        hw_desc_init(&desc[idx]);
        set_cipher_mode(&desc[idx], hw_mode);
-       set_dout_dlli(&desc[idx], k0_dma_addr, HASH_LEN_SIZE, NS_BIT, 0);
+       set_dout_dlli(&desc[idx], k0_dma_addr, drvdata->hash_len_sz, NS_BIT, 0);
        set_flow_mode(&desc[idx], S_HASH_to_DOUT);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE1);
        set_cipher_do(&desc[idx], DO_PAD);
@@ -963,7 +959,7 @@ ssi_hmac_fips_run_test(struct ssi_drvdata *drvdata,
        hw_desc_init(&desc[idx]);
        set_cipher_mode(&desc[idx], hw_mode);
        set_din_type(&desc[idx], DMA_DLLI, digest_bytes_len_dma_addr,
-                    HASH_LEN_SIZE, NS_BIT);
+                    drvdata->hash_len_sz, NS_BIT);
        set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
        set_flow_mode(&desc[idx], S_DIN_to_HASH);
        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
@@ -1039,27 +1035,32 @@ ssi_hmac_fips_power_up_tests(struct ssi_drvdata 
*drvdata, void *cpu_addr_buffer,
                        digest_size = CC_SHA1_DIGEST_SIZE;
                        block_size = CC_SHA1_BLOCK_SIZE;
                        inter_digestsize = CC_SHA1_DIGEST_SIZE;
-                       memcpy(virt_ctx->initial_digest, (void*)sha1_init, 
CC_SHA1_DIGEST_SIZE);
-                       memcpy(virt_ctx->digest_bytes_len, digest_len_init, 
HASH_LEN_SIZE);
+                       memcpy(virt_ctx->initial_digest, (void *)sha1_init,
+                              CC_SHA1_DIGEST_SIZE);
+                       memcpy(virt_ctx->digest_bytes_len, digest_len_init,
+                              drvdata->hash_len_sz);
                        break;
                case DRV_HASH_SHA256:
                        hw_mode = DRV_HASH_HW_SHA256;
                        digest_size = CC_SHA256_DIGEST_SIZE;
                        block_size = CC_SHA256_BLOCK_SIZE;
                        inter_digestsize = CC_SHA256_DIGEST_SIZE;
-                       memcpy(virt_ctx->initial_digest, (void*)sha256_init, 
CC_SHA256_DIGEST_SIZE);
-                       memcpy(virt_ctx->digest_bytes_len, digest_len_init, 
HASH_LEN_SIZE);
+                       memcpy(virt_ctx->initial_digest, (void *)sha256_init,
+                              CC_SHA256_DIGEST_SIZE);
+                       memcpy(virt_ctx->digest_bytes_len, digest_len_init,
+                              drvdata->hash_len_sz);
                        break;
-#if (CC_SUPPORT_SHA > 256)
                case DRV_HASH_SHA512:
                        hw_mode = DRV_HASH_HW_SHA512;
                        digest_size = CC_SHA512_DIGEST_SIZE;
                        block_size = CC_SHA512_BLOCK_SIZE;
                        inter_digestsize = CC_SHA512_DIGEST_SIZE;
-                       memcpy(virt_ctx->initial_digest, (void*)sha512_init, 
CC_SHA512_DIGEST_SIZE);
-                       memcpy(virt_ctx->digest_bytes_len, 
digest_len_sha512_init, HASH_LEN_SIZE);
+                       memcpy(virt_ctx->initial_digest, (void *)sha512_init,
+                              CC_SHA512_DIGEST_SIZE);
+                       memcpy(virt_ctx->digest_bytes_len,
+                              digest_len_sha512_init,
+                              drvdata->hash_len_sz);
                        break;
-#endif
                default:
                        error = FIPS_HmacToFipsError(hmac_data->hash_mode);
                        break;
diff --git a/drivers/staging/ccree/ssi_hash.c b/drivers/staging/ccree/ssi_hash.c
index f52e1af..623486d 100644
--- a/drivers/staging/ccree/ssi_hash.c
+++ b/drivers/staging/ccree/ssi_hash.c
@@ -54,7 +54,6 @@ static const u32 sha224_init[] = {
 static const u32 sha256_init[] = {
        SHA256_H7, SHA256_H6, SHA256_H5, SHA256_H4,
        SHA256_H3, SHA256_H2, SHA256_H1, SHA256_H0 };
-#if (DX_DEV_SHA_MAX > 256)
 static const u32 digest_len_sha512_init[] = {
        0x00000080, 0x00000000, 0x00000000, 0x00000000 };
 static const u64 sha384_init[] = {
@@ -63,7 +62,6 @@ static const u64 sha384_init[] = {
 static const u64 sha512_init[] = {
        SHA512_H7, SHA512_H6, SHA512_H5, SHA512_H4,
        SHA512_H3, SHA512_H2, SHA512_H1, SHA512_H0 };
-#endif
 
 static void ssi_hash_create_xcbc_setup(
        struct ahash_request *areq,
@@ -181,7 +179,8 @@ static int ssi_hash_map_request(struct device *dev,
 
        SSI_LOG_DEBUG("Allocated digest-buffer in context 
ctx->digest_buff=@%p\n", state->digest_buff);
        if (ctx->hw_mode != DRV_CIPHER_XCBC_MAC) {
-               state->digest_bytes_len = kzalloc(HASH_LEN_SIZE, 
GFP_KERNEL|GFP_DMA);
+               state->digest_bytes_len = kzalloc(HASH_MAX_LEN_SIZE,
+                                                 GFP_KERNEL | GFP_DMA);
                if (!state->digest_bytes_len) {
                        SSI_LOG_ERR("Allocating digest-bytes-len in context 
failed\n");
                        goto fail1;
@@ -214,15 +213,15 @@ static int ssi_hash_map_request(struct device *dev,
                        memset(state->digest_buff, 0, ctx->inter_digestsize);
                } else { /*sha*/
                        memcpy(state->digest_buff, ctx->digest_buff, 
ctx->inter_digestsize);
-#if (DX_DEV_SHA_MAX > 256)
                        if (unlikely((ctx->hash_mode == DRV_HASH_SHA512) || 
(ctx->hash_mode == DRV_HASH_SHA384))) {
-                               memcpy(state->digest_bytes_len, 
digest_len_sha512_init, HASH_LEN_SIZE);
+                               memcpy(state->digest_bytes_len,
+                                      digest_len_sha512_init,
+                                      ctx->drvdata->hash_len_sz);
                        } else {
-                               memcpy(state->digest_bytes_len, 
digest_len_init, HASH_LEN_SIZE);
+                               memcpy(state->digest_bytes_len,
+                                      digest_len_init,
+                                      ctx->drvdata->hash_len_sz);
                        }
-#else
-                       memcpy(state->digest_bytes_len, digest_len_init, 
HASH_LEN_SIZE);
-#endif
                }
                dma_sync_single_for_device(dev, state->digest_buff_dma_addr, 
ctx->inter_digestsize, DMA_BIDIRECTIONAL);
 
@@ -248,21 +247,26 @@ static int ssi_hash_map_request(struct device *dev,
        }
 
        if (ctx->hw_mode != DRV_CIPHER_XCBC_MAC) {
-               state->digest_bytes_len_dma_addr = dma_map_single(dev, (void 
*)state->digest_bytes_len, HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
+               state->digest_bytes_len_dma_addr =
+                       dma_map_single(dev, (void *)state->digest_bytes_len,
+                                      HASH_MAX_LEN_SIZE, DMA_BIDIRECTIONAL);
                if (dma_mapping_error(dev, state->digest_bytes_len_dma_addr)) {
                        SSI_LOG_ERR("Mapping digest len %u B at va=%pK for DMA 
failed\n",
-                       HASH_LEN_SIZE, state->digest_bytes_len);
+                       HASH_MAX_LEN_SIZE, state->digest_bytes_len);
                        goto fail4;
                }
                SSI_LOG_DEBUG("Mapped digest len %u B at va=%pK to 
dma=0x%llX\n",
-                       HASH_LEN_SIZE, state->digest_bytes_len,
+                       HASH_MAX_LEN_SIZE, state->digest_bytes_len,
                        (unsigned long long)state->digest_bytes_len_dma_addr);
        } else {
                state->digest_bytes_len_dma_addr = 0;
        }
 
        if (is_hmac && ctx->hash_mode != DRV_HASH_NULL) {
-               state->opad_digest_dma_addr = dma_map_single(dev, (void 
*)state->opad_digest_buff, ctx->inter_digestsize, DMA_BIDIRECTIONAL);
+               state->opad_digest_dma_addr =
+                       dma_map_single(dev, (void *)state->opad_digest_buff,
+                                      ctx->inter_digestsize,
+                                      DMA_BIDIRECTIONAL);
                if (dma_mapping_error(dev, state->opad_digest_dma_addr)) {
                        SSI_LOG_ERR("Mapping opad digest %d B at va=%pK for DMA 
failed\n",
                        ctx->inter_digestsize, state->opad_digest_buff);
@@ -283,7 +287,8 @@ static int ssi_hash_map_request(struct device *dev,
 
 fail5:
        if (state->digest_bytes_len_dma_addr != 0) {
-               dma_unmap_single(dev, state->digest_bytes_len_dma_addr, 
HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
+               dma_unmap_single(dev, state->digest_bytes_len_dma_addr,
+                                HASH_MAX_LEN_SIZE, DMA_BIDIRECTIONAL);
                state->digest_bytes_len_dma_addr = 0;
        }
 fail4:
@@ -329,7 +334,7 @@ static void ssi_hash_unmap_request(struct device *dev,
        }
        if (state->digest_bytes_len_dma_addr != 0) {
                dma_unmap_single(dev, state->digest_bytes_len_dma_addr,
-                                HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
+                                HASH_MAX_LEN_SIZE, DMA_BIDIRECTIONAL);
                SSI_LOG_DEBUG("Unmapped digest-bytes-len buffer: 
digest_bytes_len_dma_addr=0x%llX\n",
                        (unsigned long long)state->digest_bytes_len_dma_addr);
                state->digest_bytes_len_dma_addr = 0;
@@ -476,10 +481,11 @@ static int ssi_hash_digest(struct ahash_req_ctx *state,
 
        if (is_hmac) {
                set_din_type(&desc[idx], DMA_DLLI,
-                            state->digest_bytes_len_dma_addr, HASH_LEN_SIZE,
+                            state->digest_bytes_len_dma_addr,
+                            ctx->drvdata->hash_len_sz,
                             NS_BIT);
        } else {
-               set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
+               set_din_const(&desc[idx], 0, ctx->drvdata->hash_len_sz);
                if (likely(nbytes != 0)) {
                        set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
                } else {
@@ -497,7 +503,7 @@ static int ssi_hash_digest(struct ahash_req_ctx *state,
                hw_desc_init(&desc[idx]);
                set_cipher_mode(&desc[idx], ctx->hw_mode);
                set_dout_dlli(&desc[idx], state->digest_buff_dma_addr,
-                             HASH_LEN_SIZE, NS_BIT, 0);
+                             ctx->drvdata->hash_len_sz, NS_BIT, 0);
                set_flow_mode(&desc[idx], S_HASH_to_DOUT);
                set_setup_mode(&desc[idx], SETUP_WRITE_STATE1);
                set_cipher_do(&desc[idx], DO_PAD);
@@ -527,7 +533,7 @@ static int ssi_hash_digest(struct ahash_req_ctx *state,
                set_cipher_mode(&desc[idx], ctx->hw_mode);
                set_din_sram(&desc[idx],
                             ssi_ahash_get_initial_digest_len_sram_addr(
-ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE);
+ctx->drvdata, ctx->hash_mode), ctx->drvdata->hash_len_sz);
                set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
                set_flow_mode(&desc[idx], S_DIN_to_HASH);
                set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
@@ -554,7 +560,7 @@ ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE);
        set_dout_dlli(&desc[idx], state->digest_result_dma_addr, digestsize,
                      NS_BIT, (async_req ? 1 : 0));
        if (async_req) {
-               set_queue_last_ind(&desc[idx]);
+               set_queue_last_ind(ctx->drvdata, &desc[idx]);
        }
        set_flow_mode(&desc[idx], S_HASH_to_DOUT);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
@@ -635,7 +641,7 @@ static int ssi_hash_update(struct ahash_req_ctx *state,
        hw_desc_init(&desc[idx]);
        set_cipher_mode(&desc[idx], ctx->hw_mode);
        set_din_type(&desc[idx], DMA_DLLI, state->digest_bytes_len_dma_addr,
-                    HASH_LEN_SIZE, NS_BIT);
+                    ctx->drvdata->hash_len_sz, NS_BIT);
        set_flow_mode(&desc[idx], S_DIN_to_HASH);
        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
        idx++;
@@ -655,9 +661,9 @@ static int ssi_hash_update(struct ahash_req_ctx *state,
        hw_desc_init(&desc[idx]);
        set_cipher_mode(&desc[idx], ctx->hw_mode);
        set_dout_dlli(&desc[idx], state->digest_bytes_len_dma_addr,
-                     HASH_LEN_SIZE, NS_BIT, (async_req ? 1 : 0));
+                     ctx->drvdata->hash_len_sz, NS_BIT, (async_req ? 1 : 0));
        if (async_req) {
-               set_queue_last_ind(&desc[idx]);
+               set_queue_last_ind(ctx->drvdata, &desc[idx]);
        }
        set_flow_mode(&desc[idx], S_HASH_to_DOUT);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE1);
@@ -729,7 +735,7 @@ static int ssi_hash_finup(struct ahash_req_ctx *state,
        set_cipher_mode(&desc[idx], ctx->hw_mode);
        set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
        set_din_type(&desc[idx], DMA_DLLI, state->digest_bytes_len_dma_addr,
-                    HASH_LEN_SIZE, NS_BIT);
+                    ctx->drvdata->hash_len_sz, NS_BIT);
        set_flow_mode(&desc[idx], S_DIN_to_HASH);
        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
        idx++;
@@ -761,7 +767,7 @@ static int ssi_hash_finup(struct ahash_req_ctx *state,
                set_cipher_mode(&desc[idx], ctx->hw_mode);
                set_din_sram(&desc[idx],
                             ssi_ahash_get_initial_digest_len_sram_addr(
-ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE);
+ctx->drvdata, ctx->hash_mode), ctx->drvdata->hash_len_sz);
                set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
                set_flow_mode(&desc[idx], S_DIN_to_HASH);
                set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
@@ -787,7 +793,7 @@ ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE);
        set_dout_dlli(&desc[idx], state->digest_result_dma_addr, digestsize,
                      NS_BIT, (async_req ? 1 : 0));
        if (async_req) {
-               set_queue_last_ind(&desc[idx]);
+               set_queue_last_ind(ctx->drvdata, &desc[idx]);
        }
        set_flow_mode(&desc[idx], S_HASH_to_DOUT);
        set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED);
@@ -867,7 +873,7 @@ static int ssi_hash_final(struct ahash_req_ctx *state,
        set_cipher_mode(&desc[idx], ctx->hw_mode);
        set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED);
        set_din_type(&desc[idx], DMA_DLLI, state->digest_bytes_len_dma_addr,
-                    HASH_LEN_SIZE, NS_BIT);
+                    ctx->drvdata->hash_len_sz, NS_BIT);
        set_flow_mode(&desc[idx], S_DIN_to_HASH);
        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
        idx++;
@@ -879,7 +885,7 @@ static int ssi_hash_final(struct ahash_req_ctx *state,
        set_cipher_do(&desc[idx], DO_PAD);
        set_cipher_mode(&desc[idx], ctx->hw_mode);
        set_dout_dlli(&desc[idx], state->digest_bytes_len_dma_addr,
-                     HASH_LEN_SIZE, NS_BIT, 0);
+                     ctx->drvdata->hash_len_sz, NS_BIT, 0);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE1);
        set_flow_mode(&desc[idx], S_HASH_to_DOUT);
        idx++;
@@ -909,7 +915,7 @@ static int ssi_hash_final(struct ahash_req_ctx *state,
                set_cipher_mode(&desc[idx], ctx->hw_mode);
                set_din_sram(&desc[idx],
                             ssi_ahash_get_initial_digest_len_sram_addr(
-ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE);
+ctx->drvdata, ctx->hash_mode), ctx->drvdata->hash_len_sz);
                set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
                set_flow_mode(&desc[idx], S_DIN_to_HASH);
                set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
@@ -934,7 +940,7 @@ ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE);
        set_dout_dlli(&desc[idx], state->digest_result_dma_addr, digestsize,
                      NS_BIT, (async_req ? 1 : 0));
        if (async_req) {
-               set_queue_last_ind(&desc[idx]);
+               set_queue_last_ind(ctx->drvdata, &desc[idx]);
        }
        set_flow_mode(&desc[idx], S_HASH_to_DOUT);
        set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED);
@@ -1036,7 +1042,7 @@ static int ssi_hash_setkey(void *hash,
                        /* Load the hash current length*/
                        hw_desc_init(&desc[idx]);
                        set_cipher_mode(&desc[idx], ctx->hw_mode);
-                       set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
+                       set_din_const(&desc[idx], 0, ctx->drvdata->hash_len_sz);
                        set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED);
                        set_flow_mode(&desc[idx], S_DIN_to_HASH);
                        set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
@@ -1117,7 +1123,7 @@ static int ssi_hash_setkey(void *hash,
                /* Load the hash current length*/
                hw_desc_init(&desc[idx]);
                set_cipher_mode(&desc[idx], ctx->hw_mode);
-               set_din_const(&desc[idx], 0, HASH_LEN_SIZE);
+               set_din_const(&desc[idx], 0, ctx->drvdata->hash_len_sz);
                set_flow_mode(&desc[idx], S_DIN_to_HASH);
                set_setup_mode(&desc[idx], SETUP_LOAD_KEY0);
                idx++;
@@ -1437,7 +1443,7 @@ static int ssi_mac_update(struct ahash_request *req)
        set_cipher_mode(&desc[idx], ctx->hw_mode);
        set_dout_dlli(&desc[idx], state->digest_buff_dma_addr,
                      ctx->inter_digestsize, NS_BIT, 1);
-       set_queue_last_ind(&desc[idx]);
+       set_queue_last_ind(ctx->drvdata, &desc[idx]);
        set_flow_mode(&desc[idx], S_AES_to_DOUT);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
        idx++;
@@ -1553,7 +1559,7 @@ static int ssi_mac_final(struct ahash_request *req)
        /* TODO */
        set_dout_dlli(&desc[idx], state->digest_result_dma_addr,
                      digestsize, NS_BIT, 1);
-       set_queue_last_ind(&desc[idx]);
+       set_queue_last_ind(ctx->drvdata, &desc[idx]);
        set_flow_mode(&desc[idx], S_AES_to_DOUT);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
        set_cipher_mode(&desc[idx], ctx->hw_mode);
@@ -1625,7 +1631,7 @@ static int ssi_mac_finup(struct ahash_request *req)
        /* TODO */
        set_dout_dlli(&desc[idx], state->digest_result_dma_addr,
                      digestsize, NS_BIT, 1);
-       set_queue_last_ind(&desc[idx]);
+       set_queue_last_ind(ctx->drvdata, &desc[idx]);
        set_flow_mode(&desc[idx], S_AES_to_DOUT);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
        set_cipher_mode(&desc[idx], ctx->hw_mode);
@@ -1697,7 +1703,7 @@ static int ssi_mac_digest(struct ahash_request *req)
        hw_desc_init(&desc[idx]);
        set_dout_dlli(&desc[idx], state->digest_result_dma_addr,
                      CC_AES_BLOCK_SIZE, NS_BIT, 1);
-       set_queue_last_ind(&desc[idx]);
+       set_queue_last_ind(ctx->drvdata, &desc[idx]);
        set_flow_mode(&desc[idx], S_AES_to_DOUT);
        set_setup_mode(&desc[idx], SETUP_WRITE_STATE0);
        set_cipher_config0(&desc[idx], DESC_DIRECTION_ENCRYPT_ENCRYPT);
@@ -1789,10 +1795,12 @@ static int ssi_ahash_export(struct ahash_request *req, 
void *out)
 
        if (state->digest_bytes_len_dma_addr) {
                dma_sync_single_for_cpu(dev, state->digest_bytes_len_dma_addr,
-                                       HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
-               memcpy(out, state->digest_bytes_len, HASH_LEN_SIZE);
+                                       ctx->drvdata->hash_len_sz,
+                                       DMA_BIDIRECTIONAL);
+               memcpy(out, state->digest_bytes_len,
+                      ctx->drvdata->hash_len_sz);
        }
-       out += HASH_LEN_SIZE;
+       out += ctx->drvdata->hash_len_sz;
 
        memcpy(out, &curr_buff_cnt, sizeof(u32));
        out += sizeof(u32);
@@ -1835,10 +1843,11 @@ static int ssi_ahash_import(struct ahash_request *req, 
const void *in)
 
        if (state->digest_bytes_len_dma_addr) {
                dma_sync_single_for_cpu(dev, state->digest_bytes_len_dma_addr,
-                                       HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
-               memcpy(state->digest_bytes_len, in, HASH_LEN_SIZE);
+                                       ctx->drvdata->hash_len_sz,
+                                       DMA_BIDIRECTIONAL);
+               memcpy(state->digest_bytes_len, in, ctx->drvdata->hash_len_sz);
        }
-       in += HASH_LEN_SIZE;
+       in += ctx->drvdata->hash_len_sz;
 
        dma_sync_single_for_device(dev, state->digest_buff_dma_addr,
                                   ctx->inter_digestsize, DMA_BIDIRECTIONAL);
@@ -1846,7 +1855,8 @@ static int ssi_ahash_import(struct ahash_request *req, 
const void *in)
        if (state->digest_bytes_len_dma_addr)
                dma_sync_single_for_device(dev,
                                           state->digest_bytes_len_dma_addr,
-                                          HASH_LEN_SIZE, DMA_BIDIRECTIONAL);
+                                          ctx->drvdata->hash_len_sz,
+                                          DMA_BIDIRECTIONAL);
 
        state->buff_index = 0;
 
@@ -1883,10 +1893,11 @@ struct ssi_hash_template {
        int hw_mode;
        int inter_digestsize;
        struct ssi_drvdata *drvdata;
+       u32 min_hw_rev;
 };
 
 #define CC_STATE_SIZE(_x) \
-       ((_x) + HASH_LEN_SIZE + SSI_MAX_HASH_BLCK_SIZE + (2 * sizeof(u32)))
+       ((_x) + HASH_MAX_LEN_SIZE + SSI_MAX_HASH_BLCK_SIZE + (2 * sizeof(u32)))
 
 /* hash descriptors */
 static struct ssi_hash_template driver_hash[] = {
@@ -1915,6 +1926,7 @@ static struct ssi_hash_template driver_hash[] = {
                .hash_mode = DRV_HASH_SHA1,
                .hw_mode = DRV_HASH_HW_SHA1,
                .inter_digestsize = SHA1_DIGEST_SIZE,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "sha256",
@@ -1939,6 +1951,7 @@ static struct ssi_hash_template driver_hash[] = {
                .hash_mode = DRV_HASH_SHA256,
                .hw_mode = DRV_HASH_HW_SHA256,
                .inter_digestsize = SHA256_DIGEST_SIZE,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .name = "sha224",
@@ -1963,8 +1976,8 @@ static struct ssi_hash_template driver_hash[] = {
                .hash_mode = DRV_HASH_SHA224,
                .hw_mode = DRV_HASH_HW_SHA256,
                .inter_digestsize = SHA256_DIGEST_SIZE,
+               .min_hw_rev = CC_HW_REV_630,
        },
-#if (DX_DEV_SHA_MAX > 256)
        {
                .name = "sha384",
                .driver_name = "sha384-dx",
@@ -1988,6 +2001,7 @@ static struct ssi_hash_template driver_hash[] = {
                .hash_mode = DRV_HASH_SHA384,
                .hw_mode = DRV_HASH_HW_SHA512,
                .inter_digestsize = SHA512_DIGEST_SIZE,
+               .min_hw_rev = CC_HW_REV_712,
        },
        {
                .name = "sha512",
@@ -2012,8 +2026,8 @@ static struct ssi_hash_template driver_hash[] = {
                .hash_mode = DRV_HASH_SHA512,
                .hw_mode = DRV_HASH_HW_SHA512,
                .inter_digestsize = SHA512_DIGEST_SIZE,
+               .min_hw_rev = CC_HW_REV_712,
        },
-#endif
        {
                .name = "md5",
                .driver_name = "md5-dx",
@@ -2037,6 +2051,7 @@ static struct ssi_hash_template driver_hash[] = {
                .hash_mode = DRV_HASH_MD5,
                .hw_mode = DRV_HASH_HW_MD5,
                .inter_digestsize = MD5_DIGEST_SIZE,
+               .min_hw_rev = CC_HW_REV_630,
        },
        {
                .mac_name = "xcbc(aes)",
@@ -2059,6 +2074,7 @@ static struct ssi_hash_template driver_hash[] = {
                .hash_mode = DRV_HASH_NULL,
                .hw_mode = DRV_CIPHER_XCBC_MAC,
                .inter_digestsize = AES_BLOCK_SIZE,
+               .min_hw_rev = CC_HW_REV_630,
        },
 #if SSI_CC_HAS_CMAC
        {
@@ -2082,6 +2098,7 @@ static struct ssi_hash_template driver_hash[] = {
                .hash_mode = DRV_HASH_NULL,
                .hw_mode = DRV_CIPHER_CMAC,
                .inter_digestsize = AES_BLOCK_SIZE,
+               .min_hw_rev = CC_HW_REV_630,
        },
 #endif
 
@@ -2142,9 +2159,8 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata 
*drvdata)
        unsigned int larval_seq_len = 0;
        struct cc_hw_desc larval_seq[CC_DIGEST_SIZE_MAX/sizeof(u32)];
        int rc = 0;
-#if (DX_DEV_SHA_MAX > 256)
+       bool large_sha_supported = (drvdata->hw_rev >= CC_HW_REV_712);
        int i;
-#endif
 
        /* Copy-to-sram digest-len */
        ssi_sram_mgr_const2sram_desc(digest_len_init, sram_buff_ofs,
@@ -2156,17 +2172,19 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata 
*drvdata)
        sram_buff_ofs += sizeof(digest_len_init);
        larval_seq_len = 0;
 
-#if (DX_DEV_SHA_MAX > 256)
-       /* Copy-to-sram digest-len for sha384/512 */
-       ssi_sram_mgr_const2sram_desc(digest_len_sha512_init, sram_buff_ofs,
-               ARRAY_SIZE(digest_len_sha512_init), larval_seq, 
&larval_seq_len);
-       rc = send_request_init(drvdata, larval_seq, larval_seq_len);
-       if (unlikely(rc != 0))
-               goto init_digest_const_err;
+       if (large_sha_supported) {
+               /* Copy-to-sram digest-len for sha384/512 */
+               ssi_sram_mgr_const2sram_desc(digest_len_sha512_init,
+                                            sram_buff_ofs,
+                                            ARRAY_SIZE(digest_len_sha512_init),
+                                            larval_seq, &larval_seq_len);
+               rc = send_request_init(drvdata, larval_seq, larval_seq_len);
+               if (unlikely(rc != 0))
+                       goto init_digest_const_err;
 
-       sram_buff_ofs += sizeof(digest_len_sha512_init);
-       larval_seq_len = 0;
-#endif
+               sram_buff_ofs += sizeof(digest_len_sha512_init);
+               larval_seq_len = 0;
+       }
 
        /* The initial digests offset */
        hash_handle->larval_digest_sram_addr = sram_buff_ofs;
@@ -2204,43 +2222,53 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata 
*drvdata)
        sram_buff_ofs += sizeof(sha256_init);
        larval_seq_len = 0;
 
-#if (DX_DEV_SHA_MAX > 256)
-       /* We are forced to swap each double-word larval before copying to sram 
*/
-       for (i = 0; i < ARRAY_SIZE(sha384_init); i++) {
-               const u32 const0 = ((u32 *)((u64 *)&sha384_init[i]))[1];
-               const u32 const1 = ((u32 *)((u64 *)&sha384_init[i]))[0];
-
-               ssi_sram_mgr_const2sram_desc(&const0, sram_buff_ofs, 1,
-                       larval_seq, &larval_seq_len);
-               sram_buff_ofs += sizeof(u32);
-               ssi_sram_mgr_const2sram_desc(&const1, sram_buff_ofs, 1,
-                       larval_seq, &larval_seq_len);
-               sram_buff_ofs += sizeof(u32);
-       }
-       rc = send_request_init(drvdata, larval_seq, larval_seq_len);
-       if (unlikely(rc != 0)) {
-               SSI_LOG_ERR("send_request() failed (rc = %d)\n", rc);
-               goto init_digest_const_err;
-       }
-       larval_seq_len = 0;
-
-       for (i = 0; i < ARRAY_SIZE(sha512_init); i++) {
-               const u32 const0 = ((u32 *)((u64 *)&sha512_init[i]))[1];
-               const u32 const1 = ((u32 *)((u64 *)&sha512_init[i]))[0];
-
-               ssi_sram_mgr_const2sram_desc(&const0, sram_buff_ofs, 1,
-                       larval_seq, &larval_seq_len);
-               sram_buff_ofs += sizeof(u32);
-               ssi_sram_mgr_const2sram_desc(&const1, sram_buff_ofs, 1,
-                       larval_seq, &larval_seq_len);
-               sram_buff_ofs += sizeof(u32);
-       }
-       rc = send_request_init(drvdata, larval_seq, larval_seq_len);
-       if (unlikely(rc != 0)) {
-               SSI_LOG_ERR("send_request() failed (rc = %d)\n", rc);
-               goto init_digest_const_err;
+       if (large_sha_supported) {
+               /* We are forced to swap each double-word larval before
+                * copying to sram
+                */
+               for (i = 0; i < ARRAY_SIZE(sha384_init); i++) {
+                       const u32 const0 =
+                               ((u32 *)((u64 *)&sha384_init[i]))[1];
+                       const u32 const1 =
+                               ((u32 *)((u64 *)&sha384_init[i]))[0];
+
+                       ssi_sram_mgr_const2sram_desc(&const0, sram_buff_ofs, 1,
+                                                    larval_seq,
+                                                    &larval_seq_len);
+                       sram_buff_ofs += sizeof(u32);
+                       ssi_sram_mgr_const2sram_desc(&const1, sram_buff_ofs, 1,
+                                                    larval_seq,
+                                                    &larval_seq_len);
+                       sram_buff_ofs += sizeof(u32);
+               }
+               rc = send_request_init(drvdata, larval_seq, larval_seq_len);
+               if (unlikely(rc != 0)) {
+                       SSI_LOG_ERR("send_request() failed (rc = %d)\n", rc);
+                       goto init_digest_const_err;
+               }
+               larval_seq_len = 0;
+
+               for (i = 0; i < ARRAY_SIZE(sha512_init); i++) {
+                       const u32 const0 =
+                               ((u32 *)((u64 *)&sha512_init[i]))[1];
+                       const u32 const1 =
+                               ((u32 *)((u64 *)&sha512_init[i]))[0];
+
+                       ssi_sram_mgr_const2sram_desc(&const0, sram_buff_ofs, 1,
+                                                    larval_seq,
+                                                    &larval_seq_len);
+                       sram_buff_ofs += sizeof(u32);
+                       ssi_sram_mgr_const2sram_desc(&const1, sram_buff_ofs, 1,
+                                                    larval_seq,
+                                                    &larval_seq_len);
+                       sram_buff_ofs += sizeof(u32);
+               }
+               rc = send_request_init(drvdata, larval_seq, larval_seq_len);
+               if (unlikely(rc != 0)) {
+                       SSI_LOG_ERR("send_request() failed (rc = %d)\n", rc);
+                       goto init_digest_const_err;
+               }
        }
-#endif
 
 init_digest_const_err:
        return rc;
@@ -2265,16 +2293,16 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata)
        drvdata->hash_handle = hash_handle;
 
        sram_size_to_alloc = sizeof(digest_len_init) +
-#if (DX_DEV_SHA_MAX > 256)
-                       sizeof(digest_len_sha512_init) +
-                       sizeof(sha384_init) +
-                       sizeof(sha512_init) +
-#endif
                        sizeof(md5_init) +
                        sizeof(sha1_init) +
                        sizeof(sha224_init) +
                        sizeof(sha256_init);
 
+       if (drvdata->hw_rev >= CC_HW_REV_712)
+               sram_size_to_alloc += sizeof(digest_len_sha512_init) +
+                                       sizeof(sha384_init) +
+                                       sizeof(sha512_init);
+
        sram_buff = ssi_sram_mgr_alloc(drvdata, sram_size_to_alloc);
        if (sram_buff == NULL_SRAM_ADDR) {
                SSI_LOG_ERR("SRAM pool exhausted\n");
@@ -2299,6 +2327,10 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata)
                struct ssi_hash_alg *t_alg;
                int hw_mode = driver_hash[alg].hw_mode;
 
+               /* We either support both HASH and MAC or none */
+               if (driver_hash[alg].min_hw_rev > drvdata->hw_rev)
+                       continue;
+
                /* register hmac version */
                t_alg = ssi_hash_create_alg(&driver_hash[alg], true);
                if (IS_ERR(t_alg)) {
@@ -2543,7 +2575,6 @@ ssi_sram_addr_t 
ssi_ahash_get_larval_digest_sram_addr(void *drvdata, u32 mode)
                        sizeof(md5_init) +
                        sizeof(sha1_init) +
                        sizeof(sha224_init));
-#if (DX_DEV_SHA_MAX > 256)
        case DRV_HASH_SHA384:
                return (hash_handle->larval_digest_sram_addr +
                        sizeof(md5_init) +
@@ -2557,7 +2588,6 @@ ssi_sram_addr_t 
ssi_ahash_get_larval_digest_sram_addr(void *drvdata, u32 mode)
                        sizeof(sha224_init) +
                        sizeof(sha256_init) +
                        sizeof(sha384_init));
-#endif
        default:
                SSI_LOG_ERR("Invalid hash mode (%d)\n", mode);
        }
@@ -2579,11 +2609,9 @@ ssi_ahash_get_initial_digest_len_sram_addr(void 
*drvdata, u32 mode)
        case DRV_HASH_SHA256:
        case DRV_HASH_MD5:
                return digest_len_addr;
-#if (DX_DEV_SHA_MAX > 256)
        case DRV_HASH_SHA384:
        case DRV_HASH_SHA512:
                return  digest_len_addr + sizeof(digest_len_init);
-#endif
        default:
                return digest_len_addr; /*to avoid kernel crash*/
        }
diff --git a/drivers/staging/ccree/ssi_hash.h b/drivers/staging/ccree/ssi_hash.h
index 0bb99cb..1c12ab9 100644
--- a/drivers/staging/ccree/ssi_hash.h
+++ b/drivers/staging/ccree/ssi_hash.h
@@ -25,15 +25,11 @@
 
 #define HMAC_IPAD_CONST        0x36363636
 #define HMAC_OPAD_CONST        0x5C5C5C5C
-#if (DX_DEV_SHA_MAX > 256)
-#define HASH_LEN_SIZE 16
+#define HASH_LEN_SIZE_712 16
+#define HASH_LEN_SIZE_630 8
+#define HASH_MAX_LEN_SIZE HASH_LEN_SIZE_712
 #define SSI_MAX_HASH_DIGEST_SIZE       SHA512_DIGEST_SIZE
 #define SSI_MAX_HASH_BLCK_SIZE SHA512_BLOCK_SIZE
-#else
-#define HASH_LEN_SIZE 8
-#define SSI_MAX_HASH_DIGEST_SIZE       SHA256_DIGEST_SIZE
-#define SSI_MAX_HASH_BLCK_SIZE SHA256_BLOCK_SIZE
-#endif
 
 #define XCBC_MAC_K1_OFFSET 0
 #define XCBC_MAC_K2_OFFSET 16
diff --git a/drivers/staging/ccree/ssi_request_mgr.c 
b/drivers/staging/ccree/ssi_request_mgr.c
index 7c2d88a..cffc8de 100644
--- a/drivers/staging/ccree/ssi_request_mgr.c
+++ b/drivers/staging/ccree/ssi_request_mgr.c
@@ -152,7 +152,7 @@ int request_mgr_init(struct ssi_drvdata *drvdata)
        set_dout_dlli(&req_mgr_h->compl_desc, req_mgr_h->dummy_comp_buff_dma,
                      sizeof(u32), NS_BIT, 1);
        set_flow_mode(&req_mgr_h->compl_desc, BYPASS);
-       set_queue_last_ind(&req_mgr_h->compl_desc);
+       set_queue_last_ind(drvdata, &req_mgr_h->compl_desc);
 
        return 0;
 
@@ -414,7 +414,7 @@ int send_request_init(
        if (unlikely(rc != 0 )) {
                return rc;
        }
-       set_queue_last_ind(&desc[(len - 1)]);
+       set_queue_last_ind(drvdata, &desc[(len - 1)]);
 
        enqueue_seq(cc_base, desc, len);
 
@@ -500,13 +500,15 @@ static void proc_completions(struct ssi_drvdata *drvdata)
        }
 }
 
-static inline u32 cc_axi_comp_count(void __iomem *cc_base)
+static inline u32 cc_axi_comp_count(struct ssi_drvdata *drvdata)
 {
        /* The CC_HAL_READ_REGISTER macro implictly requires and uses
         * a base MMIO register address variable named cc_base.
         */
+       void __iomem *cc_base = drvdata->cc_base;
+
        return FIELD_GET(AXIM_MON_COMP_VALUE,
-                        CC_HAL_READ_REGISTER(AXIM_MON_BASE_OFFSET));
+                        CC_HAL_READ_REGISTER(drvdata->axim_mon_offset));
 }
 
 /* Deferred service handler, run as interrupt-fired tasklet */
@@ -516,11 +518,8 @@ static void comp_handler(unsigned long devarg)
        void __iomem *cc_base = drvdata->cc_base;
        struct ssi_request_mgr_handle * request_mgr_handle =
                                                drvdata->request_mgr_handle;
-
        u32 irq;
 
-
-
        irq = (drvdata->irq & SSI_COMP_IRQ_MASK);
 
        if (irq & SSI_COMP_IRQ_MASK) {
@@ -529,7 +528,7 @@ static void comp_handler(unsigned long devarg)
 
                /* Avoid race with above clear: Test completion counter once 
more */
                request_mgr_handle->axi_completed +=
-                               cc_axi_comp_count(cc_base);
+                               cc_axi_comp_count(drvdata);
 
                while (request_mgr_handle->axi_completed) {
                        do {
@@ -538,7 +537,7 @@ static void comp_handler(unsigned long devarg)
                                 * request_mgr_handle->axi_completed is 0.
                                 */
                                request_mgr_handle->axi_completed =
-                                               cc_axi_comp_count(cc_base);
+                                               cc_axi_comp_count(drvdata);
                        } while (request_mgr_handle->axi_completed > 0);
 
                        /* To avoid the interrupt from firing as we unmask it, 
we clear it now */
@@ -546,7 +545,7 @@ static void comp_handler(unsigned long devarg)
 
                        /* Avoid race with above clear: Test completion counter 
once more */
                        request_mgr_handle->axi_completed +=
-                                       cc_axi_comp_count(cc_base);
+                                       cc_axi_comp_count(drvdata);
                }
 
        }
diff --git a/drivers/staging/ccree/ssi_sram_mgr.c 
b/drivers/staging/ccree/ssi_sram_mgr.c
index c8ab55e..589638c 100644
--- a/drivers/staging/ccree/ssi_sram_mgr.c
+++ b/drivers/staging/ccree/ssi_sram_mgr.c
@@ -53,6 +53,8 @@ void ssi_sram_mgr_fini(struct ssi_drvdata *drvdata)
 int ssi_sram_mgr_init(struct ssi_drvdata *drvdata)
 {
        struct ssi_sram_mgr_ctx *smgr_ctx;
+       void *cc_base = drvdata->cc_base;
+       dma_addr_t start = 0;
        int rc;
 
        /* Allocate "this" context */
@@ -66,9 +68,18 @@ int ssi_sram_mgr_init(struct ssi_drvdata *drvdata)
        }
        smgr_ctx = drvdata->sram_mgr_handle;
 
-       /* Pool starts at start of SRAM */
-       smgr_ctx->sram_free_offset = 0;
+       if (drvdata->hw_rev < CC_HW_REV_712) {
+               /* Pool starts after ROM bytes */
+               start = (dma_addr_t)CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF,
+HOST_SEP_SRAM_THRESHOLD));
+               if ((start & 0x3) != 0) {
+                       SSI_LOG_ERR("Invalid SRAM offset 0x%x\n", start);
+                       rc = -ENODEV;
+                       goto out;
+               }
+       }
 
+       smgr_ctx->sram_free_offset = start;
        return 0;
 
 out:
-- 
2.1.4

Reply via email to