apm821xx: don't select swconfig for the MR24
[openwrt/openwrt.git] / target / linux / apm821xx / patches-4.14 / 120-0002-crypto-crypto4xx-support-Revision-B-parts.patch
1 From 1e932b627e79aa2c70e2c7278e4ac930303faa3f Mon Sep 17 00:00:00 2001
2 From: Christian Lamparter <chunkeey@gmail.com>
3 Date: Thu, 21 Dec 2017 15:09:18 +0100
4 Subject: [PATCH 2/6] crypto: crypto4xx - support Revision B parts
5
6 This patch adds support for the crypto4xx RevB cores
7 found in the 460EX, 460SX and later cores (like the APM821xx).
8
9 Without this patch, the crypto4xx driver will not be
10 able to process any offloaded requests and simply hang
11 indefinitely.
12
13 Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
14 ---
15 drivers/crypto/amcc/crypto4xx_core.c | 48 +++++++++++++++++++++++++++++----
16 drivers/crypto/amcc/crypto4xx_core.h | 1 +
17 drivers/crypto/amcc/crypto4xx_reg_def.h | 4 ++-
18 3 files changed, 47 insertions(+), 6 deletions(-)
19
20 --- a/drivers/crypto/amcc/crypto4xx_core.c
21 +++ b/drivers/crypto/amcc/crypto4xx_core.c
22 @@ -128,7 +128,14 @@ static void crypto4xx_hw_init(struct cry
23 writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT);
24 writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT);
25 writel(PPC4XX_INT_CFG, dev->ce_base + CRYPTO4XX_INT_CFG);
26 - writel(PPC4XX_PD_DONE_INT, dev->ce_base + CRYPTO4XX_INT_EN);
27 + if (dev->is_revb) {
28 + writel(PPC4XX_INT_TIMEOUT_CNT_REVB << 10,
29 + dev->ce_base + CRYPTO4XX_INT_TIMEOUT_CNT);
30 + writel(PPC4XX_PD_DONE_INT | PPC4XX_TMO_ERR_INT,
31 + dev->ce_base + CRYPTO4XX_INT_EN);
32 + } else {
33 + writel(PPC4XX_PD_DONE_INT, dev->ce_base + CRYPTO4XX_INT_EN);
34 + }
35 }
36
37 int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size)
38 @@ -1070,18 +1077,29 @@ static void crypto4xx_bh_tasklet_cb(unsi
39 /**
40 * Top Half of isr.
41 */
42 -static irqreturn_t crypto4xx_ce_interrupt_handler(int irq, void *data)
43 +static inline irqreturn_t crypto4xx_interrupt_handler(int irq, void *data,
44 + u32 clr_val)
45 {
46 struct device *dev = (struct device *)data;
47 struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
48
49 - writel(PPC4XX_INTERRUPT_CLR,
50 - core_dev->dev->ce_base + CRYPTO4XX_INT_CLR);
51 + writel(clr_val, core_dev->dev->ce_base + CRYPTO4XX_INT_CLR);
52 tasklet_schedule(&core_dev->tasklet);
53
54 return IRQ_HANDLED;
55 }
56
57 +static irqreturn_t crypto4xx_ce_interrupt_handler(int irq, void *data)
58 +{
59 + return crypto4xx_interrupt_handler(irq, data, PPC4XX_INTERRUPT_CLR);
60 +}
61 +
62 +static irqreturn_t crypto4xx_ce_interrupt_handler_revb(int irq, void *data)
63 +{
64 + return crypto4xx_interrupt_handler(irq, data, PPC4XX_INTERRUPT_CLR |
65 + PPC4XX_TMO_ERR_INT);
66 +}
67 +
68 /**
69 * Supported Crypto Algorithms
70 */
71 @@ -1263,6 +1281,8 @@ static int crypto4xx_probe(struct platfo
72 struct resource res;
73 struct device *dev = &ofdev->dev;
74 struct crypto4xx_core_device *core_dev;
75 + u32 pvr;
76 + bool is_revb = true;
77
78 rc = of_address_to_resource(ofdev->dev.of_node, 0, &res);
79 if (rc)
80 @@ -1279,6 +1299,7 @@ static int crypto4xx_probe(struct platfo
81 mfdcri(SDR0, PPC405EX_SDR0_SRST) | PPC405EX_CE_RESET);
82 mtdcri(SDR0, PPC405EX_SDR0_SRST,
83 mfdcri(SDR0, PPC405EX_SDR0_SRST) & ~PPC405EX_CE_RESET);
84 + is_revb = false;
85 } else if (of_find_compatible_node(NULL, NULL,
86 "amcc,ppc460sx-crypto")) {
87 mtdcri(SDR0, PPC460SX_SDR0_SRST,
88 @@ -1301,7 +1322,22 @@ static int crypto4xx_probe(struct platfo
89 if (!core_dev->dev)
90 goto err_alloc_dev;
91
92 + /*
93 + * Older version of 460EX/GT have a hardware bug.
94 + * Hence they do not support H/W based security intr coalescing
95 + */
96 + pvr = mfspr(SPRN_PVR);
97 + if (is_revb && ((pvr >> 4) == 0x130218A)) {
98 + u32 min = PVR_MIN(pvr);
99 +
100 + if (min < 4) {
101 + dev_info(dev, "RevA detected - disable interrupt coalescing\n");
102 + is_revb = false;
103 + }
104 + }
105 +
106 core_dev->dev->core_dev = core_dev;
107 + core_dev->dev->is_revb = is_revb;
108 core_dev->device = dev;
109 spin_lock_init(&core_dev->lock);
110 INIT_LIST_HEAD(&core_dev->dev->alg_list);
111 @@ -1331,7 +1367,9 @@ static int crypto4xx_probe(struct platfo
112
113 /* Register for Crypto isr, Crypto Engine IRQ */
114 core_dev->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
115 - rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0,
116 + rc = request_irq(core_dev->irq, is_revb ?
117 + crypto4xx_ce_interrupt_handler_revb :
118 + crypto4xx_ce_interrupt_handler, 0,
119 core_dev->dev->name, dev);
120 if (rc)
121 goto err_request_irq;
122 --- a/drivers/crypto/amcc/crypto4xx_core.h
123 +++ b/drivers/crypto/amcc/crypto4xx_core.h
124 @@ -109,6 +109,7 @@ struct crypto4xx_device {
125 struct list_head alg_list; /* List of algorithm supported
126 by this device */
127 struct ratelimit_state aead_ratelimit;
128 + bool is_revb;
129 };
130
131 struct crypto4xx_core_device {
132 --- a/drivers/crypto/amcc/crypto4xx_reg_def.h
133 +++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
134 @@ -121,13 +121,15 @@
135 #define PPC4XX_PD_SIZE 6
136 #define PPC4XX_CTX_DONE_INT 0x2000
137 #define PPC4XX_PD_DONE_INT 0x8000
138 +#define PPC4XX_TMO_ERR_INT 0x40000
139 #define PPC4XX_BYTE_ORDER 0x22222
140 #define PPC4XX_INTERRUPT_CLR 0x3ffff
141 #define PPC4XX_PRNG_CTRL_AUTO_EN 0x3
142 #define PPC4XX_DC_3DES_EN 1
143 #define PPC4XX_TRNG_EN 0x00020000
144 -#define PPC4XX_INT_DESCR_CNT 4
145 +#define PPC4XX_INT_DESCR_CNT 7
146 #define PPC4XX_INT_TIMEOUT_CNT 0
147 +#define PPC4XX_INT_TIMEOUT_CNT_REVB 0x3FF
148 #define PPC4XX_INT_CFG 1
149 /**
150 * all follow define are ad hoc