]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
crypto: inside-secure - add multiple processing engine support
authorOfer Heifetz <oferh@marvell.com>
Thu, 28 Jun 2018 15:15:37 +0000 (17:15 +0200)
committerHerbert Xu <herbert@gondor.apana.org.au>
Sun, 8 Jul 2018 16:30:13 +0000 (00:30 +0800)
So far a single processing engine (PE) was configured and used in the
Inside Secure SafeXcel cryptographic engine driver. Some versions have
more than a single PE. This patch rework the driver's initialization to
take this into account and to allow configuring more than one PE.

Signed-off-by: Ofer Heifetz <oferh@marvell.com>
[Antoine: some reworks and commit message.]
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/inside-secure/safexcel.c
drivers/crypto/inside-secure/safexcel.h

index baf8320d9c84759bdf214ff75df505ba675ad1bc..eefa6221533b027eaa28be9e4dcd7a3f66308dab 100644 (file)
@@ -98,7 +98,7 @@ static void eip197_trc_cache_init(struct safexcel_crypto_priv *priv)
 }
 
 static void eip197_write_firmware(struct safexcel_crypto_priv *priv,
-                                 const struct firmware *fw, u32 ctrl,
+                                 const struct firmware *fw, int pe, u32 ctrl,
                                  u32 prog_en)
 {
        const u32 *data = (const u32 *)fw->data;
@@ -112,7 +112,7 @@ static void eip197_write_firmware(struct safexcel_crypto_priv *priv,
               EIP197_PE(priv) + ctrl);
 
        /* Enable access to the program memory */
-       writel(prog_en, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL);
+       writel(prog_en, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL(pe));
 
        /* Write the firmware */
        for (i = 0; i < fw->size / sizeof(u32); i++)
@@ -120,7 +120,7 @@ static void eip197_write_firmware(struct safexcel_crypto_priv *priv,
                       priv->base + EIP197_CLASSIFICATION_RAMS + i * sizeof(u32));
 
        /* Disable access to the program memory */
-       writel(0, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL);
+       writel(0, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL(pe));
 
        /* Release engine from reset */
        val = readl(EIP197_PE(priv) + ctrl);
@@ -133,7 +133,7 @@ static int eip197_load_firmwares(struct safexcel_crypto_priv *priv)
        const char *fw_name[] = {"ifpp.bin", "ipue.bin"};
        const struct firmware *fw[FW_NB];
        char fw_path[31];
-       int i, j, ret = 0;
+       int i, j, ret = 0, pe;
        u32 val;
 
        for (i = 0; i < FW_NB; i++) {
@@ -151,22 +151,26 @@ static int eip197_load_firmwares(struct safexcel_crypto_priv *priv)
                }
        }
 
-       /* Clear the scratchpad memory */
-       val = readl(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL);
-       val |= EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_TIMER |
-              EIP197_PE_ICE_SCRATCH_CTRL_TIMER_EN |
-              EIP197_PE_ICE_SCRATCH_CTRL_SCRATCH_ACCESS |
-              EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_ACCESS;
-       writel(val, EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL);
-
-       memset_io(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_RAM, 0,
-                 EIP197_NUM_OF_SCRATCH_BLOCKS * sizeof(u32));
-
-       eip197_write_firmware(priv, fw[FW_IFPP], EIP197_PE_ICE_FPP_CTRL,
-                             EIP197_PE_ICE_RAM_CTRL_FPP_PROG_EN);
-
-       eip197_write_firmware(priv, fw[FW_IPUE], EIP197_PE_ICE_PUE_CTRL,
-                             EIP197_PE_ICE_RAM_CTRL_PUE_PROG_EN);
+       for (pe = 0; pe < priv->config.pes; pe++) {
+               /* Clear the scratchpad memory */
+               val = readl(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL(pe));
+               val |= EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_TIMER |
+                      EIP197_PE_ICE_SCRATCH_CTRL_TIMER_EN |
+                      EIP197_PE_ICE_SCRATCH_CTRL_SCRATCH_ACCESS |
+                      EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_ACCESS;
+               writel(val, EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL(pe));
+
+               memset_io(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_RAM(pe), 0,
+                         EIP197_NUM_OF_SCRATCH_BLOCKS * sizeof(u32));
+
+               eip197_write_firmware(priv, fw[FW_IFPP], pe,
+                                     EIP197_PE_ICE_FPP_CTRL(pe),
+                                     EIP197_PE_ICE_RAM_CTRL_FPP_PROG_EN);
+
+               eip197_write_firmware(priv, fw[FW_IPUE], pe,
+                                     EIP197_PE_ICE_PUE_CTRL(pe),
+                                     EIP197_PE_ICE_RAM_CTRL_PUE_PROG_EN);
+       }
 
 release_fw:
        for (j = 0; j < i; j++)
@@ -262,7 +266,7 @@ static int safexcel_hw_setup_rdesc_rings(struct safexcel_crypto_priv *priv)
 static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
 {
        u32 version, val;
-       int i, ret;
+       int i, ret, pe;
 
        /* Determine endianess and configure byte swap */
        version = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_VERSION);
@@ -288,83 +292,92 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
        /* Clear any pending interrupt */
        writel(GENMASK(31, 0), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK);
 
-       /* Data Fetch Engine configuration */
-
-       /* Reset all DFE threads */
-       writel(EIP197_DxE_THR_CTRL_RESET_PE,
-              EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL);
-
-       if (priv->version == EIP197B) {
-               /* Reset HIA input interface arbiter */
-               writel(EIP197_HIA_RA_PE_CTRL_RESET,
-                      EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL);
-       }
+       /* Processing Engine configuration */
+       for (pe = 0; pe < priv->config.pes; pe++) {
+               /* Data Fetch Engine configuration */
 
-       /* DMA transfer size to use */
-       val = EIP197_HIA_DFE_CFG_DIS_DEBUG;
-       val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(6) | EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(9);
-       val |= EIP197_HIA_DxE_CFG_MIN_CTRL_SIZE(6) | EIP197_HIA_DxE_CFG_MAX_CTRL_SIZE(7);
-       val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(RD_CACHE_3BITS);
-       val |= EIP197_HIA_DxE_CFG_CTRL_CACHE_CTRL(RD_CACHE_3BITS);
-       writel(val, EIP197_HIA_DFE(priv) + EIP197_HIA_DFE_CFG);
+               /* Reset all DFE threads */
+               writel(EIP197_DxE_THR_CTRL_RESET_PE,
+                      EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe));
 
-       /* Leave the DFE threads reset state */
-       writel(0, EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL);
+               if (priv->version == EIP197B) {
+                       /* Reset HIA input interface arbiter */
+                       writel(EIP197_HIA_RA_PE_CTRL_RESET,
+                              EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe));
+               }
 
-       /* Configure the procesing engine thresholds */
-       writel(EIP197_PE_IN_xBUF_THRES_MIN(6) | EIP197_PE_IN_xBUF_THRES_MAX(9),
-              EIP197_PE(priv) + EIP197_PE_IN_DBUF_THRES);
-       writel(EIP197_PE_IN_xBUF_THRES_MIN(6) | EIP197_PE_IN_xBUF_THRES_MAX(7),
-              EIP197_PE(priv) + EIP197_PE_IN_TBUF_THRES);
+               /* DMA transfer size to use */
+               val = EIP197_HIA_DFE_CFG_DIS_DEBUG;
+               val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(6) |
+                      EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(9);
+               val |= EIP197_HIA_DxE_CFG_MIN_CTRL_SIZE(6) |
+                      EIP197_HIA_DxE_CFG_MAX_CTRL_SIZE(7);
+               val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(RD_CACHE_3BITS);
+               val |= EIP197_HIA_DxE_CFG_CTRL_CACHE_CTRL(RD_CACHE_3BITS);
+               writel(val, EIP197_HIA_DFE(priv) + EIP197_HIA_DFE_CFG(pe));
+
+               /* Leave the DFE threads reset state */
+               writel(0, EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe));
+
+               /* Configure the processing engine thresholds */
+               writel(EIP197_PE_IN_xBUF_THRES_MIN(6) |
+                      EIP197_PE_IN_xBUF_THRES_MAX(9),
+                      EIP197_PE(priv) + EIP197_PE_IN_DBUF_THRES(pe));
+               writel(EIP197_PE_IN_xBUF_THRES_MIN(6) |
+                      EIP197_PE_IN_xBUF_THRES_MAX(7),
+                      EIP197_PE(priv) + EIP197_PE_IN_TBUF_THRES(pe));
+
+               if (priv->version == EIP197B) {
+                       /* enable HIA input interface arbiter and rings */
+                       writel(EIP197_HIA_RA_PE_CTRL_EN |
+                              GENMASK(priv->config.rings - 1, 0),
+                              EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe));
+               }
 
-       if (priv->version == EIP197B) {
-               /* enable HIA input interface arbiter and rings */
-               writel(EIP197_HIA_RA_PE_CTRL_EN |
-                      GENMASK(priv->config.rings - 1, 0),
-                      EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL);
+               /* Data Store Engine configuration */
+
+               /* Reset all DSE threads */
+               writel(EIP197_DxE_THR_CTRL_RESET_PE,
+                      EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL(pe));
+
+               /* Wait for all DSE threads to complete */
+               while ((readl(EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_STAT(pe)) &
+                       GENMASK(15, 12)) != GENMASK(15, 12))
+                       ;
+
+               /* DMA transfer size to use */
+               val = EIP197_HIA_DSE_CFG_DIS_DEBUG;
+               val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(7) |
+                      EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(8);
+               val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS);
+               val |= EIP197_HIA_DSE_CFG_ALWAYS_BUFFERABLE;
+               /* FIXME: instability issues can occur for EIP97 but disabling it impact
+                * performances.
+                */
+               if (priv->version == EIP197B)
+                       val |= EIP197_HIA_DSE_CFG_EN_SINGLE_WR;
+               writel(val, EIP197_HIA_DSE(priv) + EIP197_HIA_DSE_CFG(pe));
+
+               /* Leave the DSE threads reset state */
+               writel(0, EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL(pe));
+
+               /* Configure the procesing engine thresholds */
+               writel(EIP197_PE_OUT_DBUF_THRES_MIN(7) |
+                      EIP197_PE_OUT_DBUF_THRES_MAX(8),
+                      EIP197_PE(priv) + EIP197_PE_OUT_DBUF_THRES(pe));
+
+               /* Processing Engine configuration */
+
+               /* H/W capabilities selection */
+               val = EIP197_FUNCTION_RSVD;
+               val |= EIP197_PROTOCOL_ENCRYPT_ONLY | EIP197_PROTOCOL_HASH_ONLY;
+               val |= EIP197_PROTOCOL_ENCRYPT_HASH | EIP197_PROTOCOL_HASH_DECRYPT;
+               val |= EIP197_ALG_AES_ECB | EIP197_ALG_AES_CBC;
+               val |= EIP197_ALG_SHA1 | EIP197_ALG_HMAC_SHA1;
+               val |= EIP197_ALG_SHA2 | EIP197_ALG_HMAC_SHA2;
+               writel(val, EIP197_PE(priv) + EIP197_PE_EIP96_FUNCTION_EN(pe));
        }
 
-       /* Data Store Engine configuration */
-
-       /* Reset all DSE threads */
-       writel(EIP197_DxE_THR_CTRL_RESET_PE,
-              EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL);
-
-       /* Wait for all DSE threads to complete */
-       while ((readl(EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_STAT) &
-               GENMASK(15, 12)) != GENMASK(15, 12))
-               ;
-
-       /* DMA transfer size to use */
-       val = EIP197_HIA_DSE_CFG_DIS_DEBUG;
-       val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(7) | EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(8);
-       val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS);
-       val |= EIP197_HIA_DSE_CFG_ALWAYS_BUFFERABLE;
-       /* FIXME: instability issues can occur for EIP97 but disabling it impact
-        * performances.
-        */
-       if (priv->version == EIP197B)
-               val |= EIP197_HIA_DSE_CFG_EN_SINGLE_WR;
-       writel(val, EIP197_HIA_DSE(priv) + EIP197_HIA_DSE_CFG);
-
-       /* Leave the DSE threads reset state */
-       writel(0, EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL);
-
-       /* Configure the procesing engine thresholds */
-       writel(EIP197_PE_OUT_DBUF_THRES_MIN(7) | EIP197_PE_OUT_DBUF_THRES_MAX(8),
-              EIP197_PE(priv) + EIP197_PE_OUT_DBUF_THRES);
-
-       /* Processing Engine configuration */
-
-       /* H/W capabilities selection */
-       val = EIP197_FUNCTION_RSVD;
-       val |= EIP197_PROTOCOL_ENCRYPT_ONLY | EIP197_PROTOCOL_HASH_ONLY;
-       val |= EIP197_PROTOCOL_ENCRYPT_HASH | EIP197_PROTOCOL_HASH_DECRYPT;
-       val |= EIP197_ALG_AES_ECB | EIP197_ALG_AES_CBC;
-       val |= EIP197_ALG_SHA1 | EIP197_ALG_HMAC_SHA1;
-       val |= EIP197_ALG_SHA2 | EIP197_ALG_HMAC_SHA2;
-       writel(val, EIP197_PE(priv) + EIP197_PE_EIP96_FUNCTION_EN);
-
        /* Command Descriptor Rings prepare */
        for (i = 0; i < priv->config.rings; i++) {
                /* Clear interrupts for this ring */
@@ -414,13 +427,15 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
                       EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_SIZE);
        }
 
-       /* Enable command descriptor rings */
-       writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0),
-              EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL);
+       for (pe = 0; pe < priv->config.pes; pe++) {
+               /* Enable command descriptor rings */
+               writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0),
+                      EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe));
 
-       /* Enable result descriptor rings */
-       writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0),
-              EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL);
+               /* Enable result descriptor rings */
+               writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0),
+                      EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL(pe));
+       }
 
        /* Clear any HIA interrupt */
        writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK);
@@ -868,9 +883,20 @@ static void safexcel_unregister_algorithms(struct safexcel_crypto_priv *priv)
 
 static void safexcel_configure(struct safexcel_crypto_priv *priv)
 {
-       u32 val, mask;
+       u32 val, mask = 0;
 
        val = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS);
+
+       /* Read number of PEs from the engine */
+       switch (priv->version) {
+       case EIP197B:
+               mask = EIP197_N_PES_MASK;
+               break;
+       default:
+               mask = EIP97_N_PES_MASK;
+       }
+       priv->config.pes = (val >> EIP197_N_PES_OFFSET) & mask;
+
        val = (val & GENMASK(27, 25)) >> 25;
        mask = BIT(val) - 1;
 
index f370f055fd80c40f589d18a54531fd98489cae78..4b7445b1af220bf152d0d9803273ad20cf381c23 100644 (file)
 #define EIP197_HIA_xDR_STAT                    0x003c
 
 /* register offsets */
-#define EIP197_HIA_DFE_CFG                     0x0000
-#define EIP197_HIA_DFE_THR_CTRL                        0x0000
-#define EIP197_HIA_DFE_THR_STAT                        0x0004
-#define EIP197_HIA_DSE_CFG                     0x0000
-#define EIP197_HIA_DSE_THR_CTRL                        0x0000
-#define EIP197_HIA_DSE_THR_STAT                        0x0004
-#define EIP197_HIA_RA_PE_CTRL                  0x0010
+#define EIP197_HIA_DFE_CFG(n)                  (0x0000 + (128 * (n)))
+#define EIP197_HIA_DFE_THR_CTRL(n)             (0x0000 + (128 * (n)))
+#define EIP197_HIA_DFE_THR_STAT(n)             (0x0004 + (128 * (n)))
+#define EIP197_HIA_DSE_CFG(n)                  (0x0000 + (128 * (n)))
+#define EIP197_HIA_DSE_THR_CTRL(n)             (0x0000 + (128 * (n)))
+#define EIP197_HIA_DSE_THR_STAT(n)             (0x0004 + (128 * (n)))
+#define EIP197_HIA_RA_PE_CTRL(n)               (0x0010 + (8   * (n)))
 #define EIP197_HIA_RA_PE_STAT                  0x0014
 #define EIP197_HIA_AIC_R_OFF(r)                        ((r) * 0x1000)
 #define EIP197_HIA_AIC_R_ENABLE_CTRL(r)                (0xe008 - EIP197_HIA_AIC_R_OFF(r))
 #define EIP197_HIA_MST_CTRL                    0xfff4
 #define EIP197_HIA_OPTIONS                     0xfff8
 #define EIP197_HIA_VERSION                     0xfffc
-#define EIP197_PE_IN_DBUF_THRES                        0x0000
-#define EIP197_PE_IN_TBUF_THRES                        0x0100
-#define EIP197_PE_ICE_SCRATCH_RAM              0x0800
-#define EIP197_PE_ICE_PUE_CTRL                 0x0c80
-#define EIP197_PE_ICE_SCRATCH_CTRL             0x0d04
-#define EIP197_PE_ICE_FPP_CTRL                 0x0d80
-#define EIP197_PE_ICE_RAM_CTRL                 0x0ff0
-#define EIP197_PE_EIP96_FUNCTION_EN            0x1004
-#define EIP197_PE_EIP96_CONTEXT_CTRL           0x1008
-#define EIP197_PE_EIP96_CONTEXT_STAT           0x100c
-#define EIP197_PE_OUT_DBUF_THRES               0x1c00
-#define EIP197_PE_OUT_TBUF_THRES               0x1d00
+#define EIP197_PE_IN_DBUF_THRES(n)             (0x0000 + (0x2000 * (n)))
+#define EIP197_PE_IN_TBUF_THRES(n)             (0x0100 + (0x2000 * (n)))
+#define EIP197_PE_ICE_SCRATCH_RAM(n)           (0x0800 + (0x2000 * (n)))
+#define EIP197_PE_ICE_PUE_CTRL(n)              (0x0c80 + (0x2000 * (n)))
+#define EIP197_PE_ICE_SCRATCH_CTRL(n)          (0x0d04 + (0x2000 * (n)))
+#define EIP197_PE_ICE_FPP_CTRL(n)              (0x0d80 + (0x2000 * (n)))
+#define EIP197_PE_ICE_RAM_CTRL(n)              (0x0ff0 + (0x2000 * (n)))
+#define EIP197_PE_EIP96_FUNCTION_EN(n)         (0x1004 + (0x2000 * (n)))
+#define EIP197_PE_EIP96_CONTEXT_CTRL(n)                (0x1008 + (0x2000 * (n)))
+#define EIP197_PE_EIP96_CONTEXT_STAT(n)                (0x100c + (0x2000 * (n)))
+#define EIP197_PE_OUT_DBUF_THRES(n)            (0x1c00 + (0x2000 * (n)))
+#define EIP197_PE_OUT_TBUF_THRES(n)            (0x1d00 + (0x2000 * (n)))
 #define EIP197_MST_CTRL                                0xfff4
 
 /* EIP197-specific registers, no indirection */
 #define EIP197_HIA_RA_PE_CTRL_RESET            BIT(31)
 #define EIP197_HIA_RA_PE_CTRL_EN               BIT(30)
 
+/* EIP197_HIA_OPTIONS */
+#define EIP197_N_PES_OFFSET                    4
+#define EIP197_N_PES_MASK                      GENMASK(4, 0)
+#define EIP97_N_PES_MASK                       GENMASK(2, 0)
+
 /* EIP197_HIA_AIC_R_ENABLE_CTRL */
 #define EIP197_CDR_IRQ(n)                      BIT((n) * 2)
 #define EIP197_RDR_IRQ(n)                      BIT((n) * 2 + 1)
@@ -513,6 +518,7 @@ struct safexcel_request {
 };
 
 struct safexcel_config {
+       u32 pes;
        u32 rings;
 
        u32 cd_size;