Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: inside-secure - add multiple processing engine support

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>

authored by

Ofer Heifetz and committed by
Herbert Xu
367571e4 18e0e95b

+150 -118
+125 -99
drivers/crypto/inside-secure/safexcel.c
··· 98 98 } 99 99 100 100 static void eip197_write_firmware(struct safexcel_crypto_priv *priv, 101 - const struct firmware *fw, u32 ctrl, 101 + const struct firmware *fw, int pe, u32 ctrl, 102 102 u32 prog_en) 103 103 { 104 104 const u32 *data = (const u32 *)fw->data; ··· 112 112 EIP197_PE(priv) + ctrl); 113 113 114 114 /* Enable access to the program memory */ 115 - writel(prog_en, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL); 115 + writel(prog_en, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL(pe)); 116 116 117 117 /* Write the firmware */ 118 118 for (i = 0; i < fw->size / sizeof(u32); i++) ··· 120 120 priv->base + EIP197_CLASSIFICATION_RAMS + i * sizeof(u32)); 121 121 122 122 /* Disable access to the program memory */ 123 - writel(0, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL); 123 + writel(0, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL(pe)); 124 124 125 125 /* Release engine from reset */ 126 126 val = readl(EIP197_PE(priv) + ctrl); ··· 133 133 const char *fw_name[] = {"ifpp.bin", "ipue.bin"}; 134 134 const struct firmware *fw[FW_NB]; 135 135 char fw_path[31]; 136 - int i, j, ret = 0; 136 + int i, j, ret = 0, pe; 137 137 u32 val; 138 138 139 139 for (i = 0; i < FW_NB; i++) { ··· 151 151 } 152 152 } 153 153 154 - /* Clear the scratchpad memory */ 155 - val = readl(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL); 156 - val |= EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_TIMER | 157 - EIP197_PE_ICE_SCRATCH_CTRL_TIMER_EN | 158 - EIP197_PE_ICE_SCRATCH_CTRL_SCRATCH_ACCESS | 159 - EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_ACCESS; 160 - writel(val, EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL); 154 + for (pe = 0; pe < priv->config.pes; pe++) { 155 + /* Clear the scratchpad memory */ 156 + val = readl(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL(pe)); 157 + val |= EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_TIMER | 158 + EIP197_PE_ICE_SCRATCH_CTRL_TIMER_EN | 159 + EIP197_PE_ICE_SCRATCH_CTRL_SCRATCH_ACCESS | 160 + EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_ACCESS; 161 + writel(val, EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL(pe)); 161 162 162 - memset_io(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_RAM, 0, 163 - EIP197_NUM_OF_SCRATCH_BLOCKS * sizeof(u32)); 163 + memset_io(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_RAM(pe), 0, 164 + EIP197_NUM_OF_SCRATCH_BLOCKS * sizeof(u32)); 164 165 165 - eip197_write_firmware(priv, fw[FW_IFPP], EIP197_PE_ICE_FPP_CTRL, 166 - EIP197_PE_ICE_RAM_CTRL_FPP_PROG_EN); 166 + eip197_write_firmware(priv, fw[FW_IFPP], pe, 167 + EIP197_PE_ICE_FPP_CTRL(pe), 168 + EIP197_PE_ICE_RAM_CTRL_FPP_PROG_EN); 167 169 168 - eip197_write_firmware(priv, fw[FW_IPUE], EIP197_PE_ICE_PUE_CTRL, 169 - EIP197_PE_ICE_RAM_CTRL_PUE_PROG_EN); 170 + eip197_write_firmware(priv, fw[FW_IPUE], pe, 171 + EIP197_PE_ICE_PUE_CTRL(pe), 172 + EIP197_PE_ICE_RAM_CTRL_PUE_PROG_EN); 173 + } 170 174 171 175 release_fw: 172 176 for (j = 0; j < i; j++) ··· 266 262 static int safexcel_hw_init(struct safexcel_crypto_priv *priv) 267 263 { 268 264 u32 version, val; 269 - int i, ret; 265 + int i, ret, pe; 270 266 271 267 /* Determine endianess and configure byte swap */ 272 268 version = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_VERSION); ··· 292 288 /* Clear any pending interrupt */ 293 289 writel(GENMASK(31, 0), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK); 294 290 295 - /* Data Fetch Engine configuration */ 296 - 297 - /* Reset all DFE threads */ 298 - writel(EIP197_DxE_THR_CTRL_RESET_PE, 299 - EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL); 300 - 301 - if (priv->version == EIP197B) { 302 - /* Reset HIA input interface arbiter */ 303 - writel(EIP197_HIA_RA_PE_CTRL_RESET, 304 - EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL); 305 - } 306 - 307 - /* DMA transfer size to use */ 308 - val = EIP197_HIA_DFE_CFG_DIS_DEBUG; 309 - val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(6) | EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(9); 310 - val |= EIP197_HIA_DxE_CFG_MIN_CTRL_SIZE(6) | EIP197_HIA_DxE_CFG_MAX_CTRL_SIZE(7); 311 - val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(RD_CACHE_3BITS); 312 - val |= EIP197_HIA_DxE_CFG_CTRL_CACHE_CTRL(RD_CACHE_3BITS); 313 - writel(val, EIP197_HIA_DFE(priv) + EIP197_HIA_DFE_CFG); 314 - 315 - /* Leave the DFE threads reset state */ 316 - writel(0, EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL); 317 - 318 - /* Configure the procesing engine thresholds */ 319 - writel(EIP197_PE_IN_xBUF_THRES_MIN(6) | EIP197_PE_IN_xBUF_THRES_MAX(9), 320 - EIP197_PE(priv) + EIP197_PE_IN_DBUF_THRES); 321 - writel(EIP197_PE_IN_xBUF_THRES_MIN(6) | EIP197_PE_IN_xBUF_THRES_MAX(7), 322 - EIP197_PE(priv) + EIP197_PE_IN_TBUF_THRES); 323 - 324 - if (priv->version == EIP197B) { 325 - /* enable HIA input interface arbiter and rings */ 326 - writel(EIP197_HIA_RA_PE_CTRL_EN | 327 - GENMASK(priv->config.rings - 1, 0), 328 - EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL); 329 - } 330 - 331 - /* Data Store Engine configuration */ 332 - 333 - /* Reset all DSE threads */ 334 - writel(EIP197_DxE_THR_CTRL_RESET_PE, 335 - EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL); 336 - 337 - /* Wait for all DSE threads to complete */ 338 - while ((readl(EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_STAT) & 339 - GENMASK(15, 12)) != GENMASK(15, 12)) 340 - ; 341 - 342 - /* DMA transfer size to use */ 343 - val = EIP197_HIA_DSE_CFG_DIS_DEBUG; 344 - val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(7) | EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(8); 345 - val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS); 346 - val |= EIP197_HIA_DSE_CFG_ALWAYS_BUFFERABLE; 347 - /* FIXME: instability issues can occur for EIP97 but disabling it impact 348 - * performances. 349 - */ 350 - if (priv->version == EIP197B) 351 - val |= EIP197_HIA_DSE_CFG_EN_SINGLE_WR; 352 - writel(val, EIP197_HIA_DSE(priv) + EIP197_HIA_DSE_CFG); 353 - 354 - /* Leave the DSE threads reset state */ 355 - writel(0, EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL); 356 - 357 - /* Configure the procesing engine thresholds */ 358 - writel(EIP197_PE_OUT_DBUF_THRES_MIN(7) | EIP197_PE_OUT_DBUF_THRES_MAX(8), 359 - EIP197_PE(priv) + EIP197_PE_OUT_DBUF_THRES); 360 - 361 291 /* Processing Engine configuration */ 292 + for (pe = 0; pe < priv->config.pes; pe++) { 293 + /* Data Fetch Engine configuration */ 362 294 363 - /* H/W capabilities selection */ 364 - val = EIP197_FUNCTION_RSVD; 365 - val |= EIP197_PROTOCOL_ENCRYPT_ONLY | EIP197_PROTOCOL_HASH_ONLY; 366 - val |= EIP197_PROTOCOL_ENCRYPT_HASH | EIP197_PROTOCOL_HASH_DECRYPT; 367 - val |= EIP197_ALG_AES_ECB | EIP197_ALG_AES_CBC; 368 - val |= EIP197_ALG_SHA1 | EIP197_ALG_HMAC_SHA1; 369 - val |= EIP197_ALG_SHA2 | EIP197_ALG_HMAC_SHA2; 370 - writel(val, EIP197_PE(priv) + EIP197_PE_EIP96_FUNCTION_EN); 295 + /* Reset all DFE threads */ 296 + writel(EIP197_DxE_THR_CTRL_RESET_PE, 297 + EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe)); 298 + 299 + if (priv->version == EIP197B) { 300 + /* Reset HIA input interface arbiter */ 301 + writel(EIP197_HIA_RA_PE_CTRL_RESET, 302 + EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe)); 303 + } 304 + 305 + /* DMA transfer size to use */ 306 + val = EIP197_HIA_DFE_CFG_DIS_DEBUG; 307 + val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(6) | 308 + EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(9); 309 + val |= EIP197_HIA_DxE_CFG_MIN_CTRL_SIZE(6) | 310 + EIP197_HIA_DxE_CFG_MAX_CTRL_SIZE(7); 311 + val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(RD_CACHE_3BITS); 312 + val |= EIP197_HIA_DxE_CFG_CTRL_CACHE_CTRL(RD_CACHE_3BITS); 313 + writel(val, EIP197_HIA_DFE(priv) + EIP197_HIA_DFE_CFG(pe)); 314 + 315 + /* Leave the DFE threads reset state */ 316 + writel(0, EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe)); 317 + 318 + /* Configure the processing engine thresholds */ 319 + writel(EIP197_PE_IN_xBUF_THRES_MIN(6) | 320 + EIP197_PE_IN_xBUF_THRES_MAX(9), 321 + EIP197_PE(priv) + EIP197_PE_IN_DBUF_THRES(pe)); 322 + writel(EIP197_PE_IN_xBUF_THRES_MIN(6) | 323 + EIP197_PE_IN_xBUF_THRES_MAX(7), 324 + EIP197_PE(priv) + EIP197_PE_IN_TBUF_THRES(pe)); 325 + 326 + if (priv->version == EIP197B) { 327 + /* enable HIA input interface arbiter and rings */ 328 + writel(EIP197_HIA_RA_PE_CTRL_EN | 329 + GENMASK(priv->config.rings - 1, 0), 330 + EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL(pe)); 331 + } 332 + 333 + /* Data Store Engine configuration */ 334 + 335 + /* Reset all DSE threads */ 336 + writel(EIP197_DxE_THR_CTRL_RESET_PE, 337 + EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL(pe)); 338 + 339 + /* Wait for all DSE threads to complete */ 340 + while ((readl(EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_STAT(pe)) & 341 + GENMASK(15, 12)) != GENMASK(15, 12)) 342 + ; 343 + 344 + /* DMA transfer size to use */ 345 + val = EIP197_HIA_DSE_CFG_DIS_DEBUG; 346 + val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(7) | 347 + EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(8); 348 + val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS); 349 + val |= EIP197_HIA_DSE_CFG_ALWAYS_BUFFERABLE; 350 + /* FIXME: instability issues can occur for EIP97 but disabling it impact 351 + * performances. 352 + */ 353 + if (priv->version == EIP197B) 354 + val |= EIP197_HIA_DSE_CFG_EN_SINGLE_WR; 355 + writel(val, EIP197_HIA_DSE(priv) + EIP197_HIA_DSE_CFG(pe)); 356 + 357 + /* Leave the DSE threads reset state */ 358 + writel(0, EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL(pe)); 359 + 360 + /* Configure the procesing engine thresholds */ 361 + writel(EIP197_PE_OUT_DBUF_THRES_MIN(7) | 362 + EIP197_PE_OUT_DBUF_THRES_MAX(8), 363 + EIP197_PE(priv) + EIP197_PE_OUT_DBUF_THRES(pe)); 364 + 365 + /* Processing Engine configuration */ 366 + 367 + /* H/W capabilities selection */ 368 + val = EIP197_FUNCTION_RSVD; 369 + val |= EIP197_PROTOCOL_ENCRYPT_ONLY | EIP197_PROTOCOL_HASH_ONLY; 370 + val |= EIP197_PROTOCOL_ENCRYPT_HASH | EIP197_PROTOCOL_HASH_DECRYPT; 371 + val |= EIP197_ALG_AES_ECB | EIP197_ALG_AES_CBC; 372 + val |= EIP197_ALG_SHA1 | EIP197_ALG_HMAC_SHA1; 373 + val |= EIP197_ALG_SHA2 | EIP197_ALG_HMAC_SHA2; 374 + writel(val, EIP197_PE(priv) + EIP197_PE_EIP96_FUNCTION_EN(pe)); 375 + } 371 376 372 377 /* Command Descriptor Rings prepare */ 373 378 for (i = 0; i < priv->config.rings; i++) { ··· 427 414 EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_SIZE); 428 415 } 429 416 430 - /* Enable command descriptor rings */ 431 - writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0), 432 - EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL); 417 + for (pe = 0; pe < priv->config.pes; pe++) { 418 + /* Enable command descriptor rings */ 419 + writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0), 420 + EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL(pe)); 433 421 434 - /* Enable result descriptor rings */ 435 - writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0), 436 - EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL); 422 + /* Enable result descriptor rings */ 423 + writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0), 424 + EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL(pe)); 425 + } 437 426 438 427 /* Clear any HIA interrupt */ 439 428 writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK); ··· 883 868 884 869 static void safexcel_configure(struct safexcel_crypto_priv *priv) 885 870 { 886 - u32 val, mask; 871 + u32 val, mask = 0; 887 872 888 873 val = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS); 874 + 875 + /* Read number of PEs from the engine */ 876 + switch (priv->version) { 877 + case EIP197B: 878 + mask = EIP197_N_PES_MASK; 879 + break; 880 + default: 881 + mask = EIP97_N_PES_MASK; 882 + } 883 + priv->config.pes = (val >> EIP197_N_PES_OFFSET) & mask; 884 + 889 885 val = (val & GENMASK(27, 25)) >> 25; 890 886 mask = BIT(val) - 1; 891 887
+25 -19
drivers/crypto/inside-secure/safexcel.h
··· 95 95 #define EIP197_HIA_xDR_STAT 0x003c 96 96 97 97 /* register offsets */ 98 - #define EIP197_HIA_DFE_CFG 0x0000 99 - #define EIP197_HIA_DFE_THR_CTRL 0x0000 100 - #define EIP197_HIA_DFE_THR_STAT 0x0004 101 - #define EIP197_HIA_DSE_CFG 0x0000 102 - #define EIP197_HIA_DSE_THR_CTRL 0x0000 103 - #define EIP197_HIA_DSE_THR_STAT 0x0004 104 - #define EIP197_HIA_RA_PE_CTRL 0x0010 98 + #define EIP197_HIA_DFE_CFG(n) (0x0000 + (128 * (n))) 99 + #define EIP197_HIA_DFE_THR_CTRL(n) (0x0000 + (128 * (n))) 100 + #define EIP197_HIA_DFE_THR_STAT(n) (0x0004 + (128 * (n))) 101 + #define EIP197_HIA_DSE_CFG(n) (0x0000 + (128 * (n))) 102 + #define EIP197_HIA_DSE_THR_CTRL(n) (0x0000 + (128 * (n))) 103 + #define EIP197_HIA_DSE_THR_STAT(n) (0x0004 + (128 * (n))) 104 + #define EIP197_HIA_RA_PE_CTRL(n) (0x0010 + (8 * (n))) 105 105 #define EIP197_HIA_RA_PE_STAT 0x0014 106 106 #define EIP197_HIA_AIC_R_OFF(r) ((r) * 0x1000) 107 107 #define EIP197_HIA_AIC_R_ENABLE_CTRL(r) (0xe008 - EIP197_HIA_AIC_R_OFF(r)) ··· 114 114 #define EIP197_HIA_MST_CTRL 0xfff4 115 115 #define EIP197_HIA_OPTIONS 0xfff8 116 116 #define EIP197_HIA_VERSION 0xfffc 117 - #define EIP197_PE_IN_DBUF_THRES 0x0000 118 - #define EIP197_PE_IN_TBUF_THRES 0x0100 119 - #define EIP197_PE_ICE_SCRATCH_RAM 0x0800 120 - #define EIP197_PE_ICE_PUE_CTRL 0x0c80 121 - #define EIP197_PE_ICE_SCRATCH_CTRL 0x0d04 122 - #define EIP197_PE_ICE_FPP_CTRL 0x0d80 123 - #define EIP197_PE_ICE_RAM_CTRL 0x0ff0 124 - #define EIP197_PE_EIP96_FUNCTION_EN 0x1004 125 - #define EIP197_PE_EIP96_CONTEXT_CTRL 0x1008 126 - #define EIP197_PE_EIP96_CONTEXT_STAT 0x100c 127 - #define EIP197_PE_OUT_DBUF_THRES 0x1c00 128 - #define EIP197_PE_OUT_TBUF_THRES 0x1d00 117 + #define EIP197_PE_IN_DBUF_THRES(n) (0x0000 + (0x2000 * (n))) 118 + #define EIP197_PE_IN_TBUF_THRES(n) (0x0100 + (0x2000 * (n))) 119 + #define EIP197_PE_ICE_SCRATCH_RAM(n) (0x0800 + (0x2000 * (n))) 120 + #define EIP197_PE_ICE_PUE_CTRL(n) (0x0c80 + (0x2000 * (n))) 121 + #define EIP197_PE_ICE_SCRATCH_CTRL(n) (0x0d04 + (0x2000 * (n))) 122 + #define EIP197_PE_ICE_FPP_CTRL(n) (0x0d80 + (0x2000 * (n))) 123 + #define EIP197_PE_ICE_RAM_CTRL(n) (0x0ff0 + (0x2000 * (n))) 124 + #define EIP197_PE_EIP96_FUNCTION_EN(n) (0x1004 + (0x2000 * (n))) 125 + #define EIP197_PE_EIP96_CONTEXT_CTRL(n) (0x1008 + (0x2000 * (n))) 126 + #define EIP197_PE_EIP96_CONTEXT_STAT(n) (0x100c + (0x2000 * (n))) 127 + #define EIP197_PE_OUT_DBUF_THRES(n) (0x1c00 + (0x2000 * (n))) 128 + #define EIP197_PE_OUT_TBUF_THRES(n) (0x1d00 + (0x2000 * (n))) 129 129 #define EIP197_MST_CTRL 0xfff4 130 130 131 131 /* EIP197-specific registers, no indirection */ ··· 183 183 184 184 #define EIP197_HIA_RA_PE_CTRL_RESET BIT(31) 185 185 #define EIP197_HIA_RA_PE_CTRL_EN BIT(30) 186 + 187 + /* EIP197_HIA_OPTIONS */ 188 + #define EIP197_N_PES_OFFSET 4 189 + #define EIP197_N_PES_MASK GENMASK(4, 0) 190 + #define EIP97_N_PES_MASK GENMASK(2, 0) 186 191 187 192 /* EIP197_HIA_AIC_R_ENABLE_CTRL */ 188 193 #define EIP197_CDR_IRQ(n) BIT((n) * 2) ··· 518 513 }; 519 514 520 515 struct safexcel_config { 516 + u32 pes; 521 517 u32 rings; 522 518 523 519 u32 cd_size;