diff options
Diffstat (limited to 'target/linux/apm821xx/patches-4.14/120-0002-crypto-crypto4xx-support-Revision-B-parts.patch')
-rw-r--r-- | target/linux/apm821xx/patches-4.14/120-0002-crypto-crypto4xx-support-Revision-B-parts.patch | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/target/linux/apm821xx/patches-4.14/120-0002-crypto-crypto4xx-support-Revision-B-parts.patch b/target/linux/apm821xx/patches-4.14/120-0002-crypto-crypto4xx-support-Revision-B-parts.patch new file mode 100644 index 0000000000..1adad96fe1 --- /dev/null +++ b/target/linux/apm821xx/patches-4.14/120-0002-crypto-crypto4xx-support-Revision-B-parts.patch @@ -0,0 +1,150 @@ +From 1e932b627e79aa2c70e2c7278e4ac930303faa3f Mon Sep 17 00:00:00 2001 +From: Christian Lamparter <chunkeey@gmail.com> +Date: Thu, 21 Dec 2017 15:09:18 +0100 +Subject: [PATCH 2/6] crypto: crypto4xx - support Revision B parts + +This patch adds support for the crypto4xx RevB cores +found in the 460EX, 460SX and later cores (like the APM821xx). + +Without this patch, the crypto4xx driver will not be +able to process any offloaded requests and simply hang +indefinitely. + +Signed-off-by: Christian Lamparter <chunkeey@gmail.com> +--- + drivers/crypto/amcc/crypto4xx_core.c | 48 +++++++++++++++++++++++++++++---- + drivers/crypto/amcc/crypto4xx_core.h | 1 + + drivers/crypto/amcc/crypto4xx_reg_def.h | 4 ++- + 3 files changed, 47 insertions(+), 6 deletions(-) + +--- a/drivers/crypto/amcc/crypto4xx_core.c ++++ b/drivers/crypto/amcc/crypto4xx_core.c +@@ -128,7 +128,14 @@ static void crypto4xx_hw_init(struct cry + writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT); + writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT); + writel(PPC4XX_INT_CFG, dev->ce_base + CRYPTO4XX_INT_CFG); +- writel(PPC4XX_PD_DONE_INT, dev->ce_base + CRYPTO4XX_INT_EN); ++ if (dev->is_revb) { ++ writel(PPC4XX_INT_TIMEOUT_CNT_REVB << 10, ++ dev->ce_base + CRYPTO4XX_INT_TIMEOUT_CNT); ++ writel(PPC4XX_PD_DONE_INT | PPC4XX_TMO_ERR_INT, ++ dev->ce_base + CRYPTO4XX_INT_EN); ++ } else { ++ writel(PPC4XX_PD_DONE_INT, dev->ce_base + CRYPTO4XX_INT_EN); ++ } + } + + int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size) +@@ -1070,18 +1077,29 @@ static void crypto4xx_bh_tasklet_cb(unsi + /** + * Top Half of isr. + */ +-static irqreturn_t crypto4xx_ce_interrupt_handler(int irq, void *data) ++static inline irqreturn_t crypto4xx_interrupt_handler(int irq, void *data, ++ u32 clr_val) + { + struct device *dev = (struct device *)data; + struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev); + +- writel(PPC4XX_INTERRUPT_CLR, +- core_dev->dev->ce_base + CRYPTO4XX_INT_CLR); ++ writel(clr_val, core_dev->dev->ce_base + CRYPTO4XX_INT_CLR); + tasklet_schedule(&core_dev->tasklet); + + return IRQ_HANDLED; + } + ++static irqreturn_t crypto4xx_ce_interrupt_handler(int irq, void *data) ++{ ++ return crypto4xx_interrupt_handler(irq, data, PPC4XX_INTERRUPT_CLR); ++} ++ ++static irqreturn_t crypto4xx_ce_interrupt_handler_revb(int irq, void *data) ++{ ++ return crypto4xx_interrupt_handler(irq, data, PPC4XX_INTERRUPT_CLR | ++ PPC4XX_TMO_ERR_INT); ++} ++ + /** + * Supported Crypto Algorithms + */ +@@ -1263,6 +1281,8 @@ static int crypto4xx_probe(struct platfo + struct resource res; + struct device *dev = &ofdev->dev; + struct crypto4xx_core_device *core_dev; ++ u32 pvr; ++ bool is_revb = true; + + rc = of_address_to_resource(ofdev->dev.of_node, 0, &res); + if (rc) +@@ -1279,6 +1299,7 @@ static int crypto4xx_probe(struct platfo + mfdcri(SDR0, PPC405EX_SDR0_SRST) | PPC405EX_CE_RESET); + mtdcri(SDR0, PPC405EX_SDR0_SRST, + mfdcri(SDR0, PPC405EX_SDR0_SRST) & ~PPC405EX_CE_RESET); ++ is_revb = false; + } else if (of_find_compatible_node(NULL, NULL, + "amcc,ppc460sx-crypto")) { + mtdcri(SDR0, PPC460SX_SDR0_SRST, +@@ -1301,7 +1322,22 @@ static int crypto4xx_probe(struct platfo + if (!core_dev->dev) + goto err_alloc_dev; + ++ /* ++ * Older version of 460EX/GT have a hardware bug. ++ * Hence they do not support H/W based security intr coalescing ++ */ ++ pvr = mfspr(SPRN_PVR); ++ if (is_revb && ((pvr >> 4) == 0x130218A)) { ++ u32 min = PVR_MIN(pvr); ++ ++ if (min < 4) { ++ dev_info(dev, "RevA detected - disable interrupt coalescing\n"); ++ is_revb = false; ++ } ++ } ++ + core_dev->dev->core_dev = core_dev; ++ core_dev->dev->is_revb = is_revb; + core_dev->device = dev; + spin_lock_init(&core_dev->lock); + INIT_LIST_HEAD(&core_dev->dev->alg_list); +@@ -1331,7 +1367,9 @@ static int crypto4xx_probe(struct platfo + + /* Register for Crypto isr, Crypto Engine IRQ */ + core_dev->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); +- rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0, ++ rc = request_irq(core_dev->irq, is_revb ? ++ crypto4xx_ce_interrupt_handler_revb : ++ crypto4xx_ce_interrupt_handler, 0, + core_dev->dev->name, dev); + if (rc) + goto err_request_irq; +--- a/drivers/crypto/amcc/crypto4xx_core.h ++++ b/drivers/crypto/amcc/crypto4xx_core.h +@@ -109,6 +109,7 @@ struct crypto4xx_device { + struct list_head alg_list; /* List of algorithm supported + by this device */ + struct ratelimit_state aead_ratelimit; ++ bool is_revb; + }; + + struct crypto4xx_core_device { +--- a/drivers/crypto/amcc/crypto4xx_reg_def.h ++++ b/drivers/crypto/amcc/crypto4xx_reg_def.h +@@ -121,13 +121,15 @@ + #define PPC4XX_PD_SIZE 6 + #define PPC4XX_CTX_DONE_INT 0x2000 + #define PPC4XX_PD_DONE_INT 0x8000 ++#define PPC4XX_TMO_ERR_INT 0x40000 + #define PPC4XX_BYTE_ORDER 0x22222 + #define PPC4XX_INTERRUPT_CLR 0x3ffff + #define PPC4XX_PRNG_CTRL_AUTO_EN 0x3 + #define PPC4XX_DC_3DES_EN 1 + #define PPC4XX_TRNG_EN 0x00020000 +-#define PPC4XX_INT_DESCR_CNT 4 ++#define PPC4XX_INT_DESCR_CNT 7 + #define PPC4XX_INT_TIMEOUT_CNT 0 ++#define PPC4XX_INT_TIMEOUT_CNT_REVB 0x3FF + #define PPC4XX_INT_CFG 1 + /** + * all follow define are ad hoc |