[PATCH v3 23/26] crypto: rockchip: Check for maximum frequency of clocks

From: Corentin Labbe
Date: Mon Mar 21 2022 - 16:10:07 EST


Rockchip's datasheet give maximum frequencies for some clocks, so add
checks for verifying they are within limits.

Signed-off-by: Corentin Labbe <clabbe@xxxxxxxxxxxx>
---
drivers/crypto/rockchip/rk3288_crypto.c | 57 +++++++++++++++++++++----
drivers/crypto/rockchip/rk3288_crypto.h | 9 ++++
2 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index bb1adbe947f9..ededae9f2671 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -21,16 +21,58 @@

static const struct rk_variant rk3328_variant = {
.num_instance = 1,
+ .num_clks = 3,
};

static const struct rk_variant rk3288_variant = {
- .num_instance = 1
+ .num_instance = 1,
+ .num_clks = 3,
+ .rkclks = {
+ { "sclk", 150000000},
+ }
};

static const struct rk_variant rk3399_variant = {
- .num_instance = 2
+ .num_instance = 2,
+ .num_clks = 6,
};

+static int rk_crypto_get_clks(struct rk_crypto_info *dev)
+{
+ int i, j, err;
+ unsigned long cr;
+
+ dev->num_clks = devm_clk_bulk_get_all(dev->dev, &dev->clks);
+ if (dev->num_clks < dev->variant->num_clks) {
+ dev_err(dev->dev, "Missing clocks, got %d instead of %d\n",
+ dev->num_clks, dev->variant->num_clks);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < dev->num_clks; i++) {
+ cr = clk_get_rate(dev->clks[i].clk);
+ for (j = 0; j < ARRAY_SIZE(dev->variant->rkclks); j++) {
+ if (dev->variant->rkclks[j].max == 0)
+ continue;
+ if (strcmp(dev->variant->rkclks[j].name, dev->clks[i].id))
+ continue;
+ if (cr > dev->variant->rkclks[j].max) {
+ err = clk_set_rate(dev->clks[i].clk,
+ dev->variant->rkclks[j].max);
+ if (err)
+ dev_err(dev->dev, "Fail downclocking %s from %lu to %lu\n",
+ dev->variant->rkclks[j].name, cr,
+ dev->variant->rkclks[j].max);
+ else
+ dev_info(dev->dev, "Downclocking %s from %lu to %lu\n",
+ dev->variant->rkclks[j].name, cr,
+ dev->variant->rkclks[j].max);
+ }
+ }
+ }
+ return 0;
+}
+
static int rk_crypto_enable_clk(struct rk_crypto_info *dev)
{
int err;
@@ -281,16 +323,13 @@ static int rk_crypto_probe(struct platform_device *pdev)
goto err_crypto;
}

- crypto_info->num_clks = devm_clk_bulk_get_all(&pdev->dev,
- &crypto_info->clks);
- if (crypto_info->num_clks < 3) {
- err = -EINVAL;
- goto err_crypto;
- }
-
crypto_info->dev = &pdev->dev;
platform_set_drvdata(pdev, crypto_info);

+ err = rk_crypto_get_clks(crypto_info);
+ if (err)
+ goto err_crypto;
+
err = rk_crypto_pm_init(crypto_info);
if (err)
goto err_pm;
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index e1dac351bc64..8fd46cda5189 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -183,8 +183,17 @@
#define RK_CRYPTO_HASH_DOUT_6 0x01a4
#define RK_CRYPTO_HASH_DOUT_7 0x01a8

+#define RK_MAX_CLKS 6
+
+struct rk_clks {
+ const char *name;
+ unsigned long max;
+};
+
struct rk_variant {
int num_instance;
+ int num_clks;
+ struct rk_clks rkclks[RK_MAX_CLKS];
};

struct rk_instance {
--
2.34.1