crypto: sun4i-ss - add the A33 variant of SS
authorCorentin Labbe <clabbe.montjoie@gmail.com>
Wed, 20 Nov 2019 15:28:33 +0000 (16:28 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 11 Dec 2019 08:36:05 +0000 (16:36 +0800)
The A33 SS has a difference with all other SS, it give SHA1 digest
directly in BE.
So this patch adds variant support in sun4i-ss.

Fixes: 6298e948215f ("crypto: sunxi-ss - Add Allwinner Security System crypto accelerator")
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Acked-by: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/allwinner/sun4i-ss/sun4i-ss-core.c
drivers/crypto/allwinner/sun4i-ss/sun4i-ss-hash.c
drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h

index 814cd12..d35a058 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <crypto/scatterwalk.h>
 #include <linux/scatterlist.h>
 
 #include "sun4i-ss.h"
 
+static const struct ss_variant ss_a10_variant = {
+       .sha1_in_be = false,
+};
+
+static const struct ss_variant ss_a33_variant = {
+       .sha1_in_be = true,
+};
+
 static struct sun4i_ss_alg_template ss_algs[] = {
 {       .type = CRYPTO_ALG_TYPE_AHASH,
        .mode = SS_OP_MD5,
@@ -323,6 +332,12 @@ static int sun4i_ss_probe(struct platform_device *pdev)
                return PTR_ERR(ss->base);
        }
 
+       ss->variant = of_device_get_match_data(&pdev->dev);
+       if (!ss->variant) {
+               dev_err(&pdev->dev, "Missing Security System variant\n");
+               return -EINVAL;
+       }
+
        ss->ssclk = devm_clk_get(&pdev->dev, "mod");
        if (IS_ERR(ss->ssclk)) {
                err = PTR_ERR(ss->ssclk);
@@ -484,7 +499,12 @@ static int sun4i_ss_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id a20ss_crypto_of_match_table[] = {
-       { .compatible = "allwinner,sun4i-a10-crypto" },
+       { .compatible = "allwinner,sun4i-a10-crypto",
+         .data = &ss_a10_variant
+       },
+       { .compatible = "allwinner,sun8i-a33-crypto",
+         .data = &ss_a33_variant
+       },
        {}
 };
 MODULE_DEVICE_TABLE(of, a20ss_crypto_of_match_table);
index fdc0e6c..dc35edd 100644 (file)
@@ -479,7 +479,10 @@ hash_final:
        /* Get the hash from the device */
        if (op->mode == SS_OP_SHA1) {
                for (i = 0; i < 5; i++) {
-                       v = cpu_to_be32(readl(ss->base + SS_MD0 + i * 4));
+                       if (ss->variant->sha1_in_be)
+                               v = cpu_to_le32(readl(ss->base + SS_MD0 + i * 4));
+                       else
+                               v = cpu_to_be32(readl(ss->base + SS_MD0 + i * 4));
                        memcpy(areq->result + i * 4, &v, 4);
                }
        } else {
index 60425ac..2b4c633 100644 (file)
 #define SS_SEED_LEN 192
 #define SS_DATA_LEN 160
 
+/*
+ * struct ss_variant - Describe SS hardware variant
+ * @sha1_in_be:                The SHA1 digest is given by SS in BE, and so need to be inverted.
+ */
+struct ss_variant {
+       bool sha1_in_be;
+};
+
 struct sun4i_ss_ctx {
+       const struct ss_variant *variant;
        void __iomem *base;
        int irq;
        struct clk *busclk;