lantiq: complete AVM FRITZ!Box 3370 support
[oweals/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