Skip to content

Commit

Permalink
crypto: rockchip - Check for clocks numbers and their frequencies
Browse files Browse the repository at this point in the history
Add the number of clocks needed for each compatible.
Rockchip's datasheet give maximum frequencies for some clocks, so add
checks for verifying they are within limits. Let's start with rk3288 for
clock frequency check, other will came later.

Signed-off-by: Corentin Labbe <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
montjoie authored and herbertx committed Oct 28, 2022
1 parent 2d3c756 commit e220e67
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 12 deletions.
75 changes: 65 additions & 10 deletions drivers/crypto/rockchip/rk3288_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,58 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/crypto.h>
#include <linux/reset.h>

static const struct rk_variant rk3288_variant = {
.num_clks = 4,
.rkclks = {
{ "sclk", 150000000},
}
};

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

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;
Expand Down Expand Up @@ -201,8 +249,12 @@ static void rk_crypto_unregister(void)
}

static const struct of_device_id crypto_of_id_table[] = {
{ .compatible = "rockchip,rk3288-crypto" },
{ .compatible = "rockchip,rk3328-crypto" },
{ .compatible = "rockchip,rk3288-crypto",
.data = &rk3288_variant,
},
{ .compatible = "rockchip,rk3328-crypto",
.data = &rk3328_variant,
},
{}
};
MODULE_DEVICE_TABLE(of, crypto_of_id_table);
Expand All @@ -220,6 +272,15 @@ static int rk_crypto_probe(struct platform_device *pdev)
goto err_crypto;
}

crypto_info->dev = &pdev->dev;
platform_set_drvdata(pdev, crypto_info);

crypto_info->variant = of_device_get_match_data(&pdev->dev);
if (!crypto_info->variant) {
dev_err(&pdev->dev, "Missing variant\n");
return -EINVAL;
}

crypto_info->rst = devm_reset_control_get(dev, "crypto-rst");
if (IS_ERR(crypto_info->rst)) {
err = PTR_ERR(crypto_info->rst);
Expand All @@ -236,12 +297,9 @@ 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;
err = rk_crypto_get_clks(crypto_info);
if (err)
goto err_crypto;
}

crypto_info->irq = platform_get_irq(pdev, 0);
if (crypto_info->irq < 0) {
Expand All @@ -259,9 +317,6 @@ static int rk_crypto_probe(struct platform_device *pdev)
goto err_crypto;
}

crypto_info->dev = &pdev->dev;
platform_set_drvdata(pdev, crypto_info);

crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true);
crypto_engine_start(crypto_info->engine);
init_completion(&crypto_info->complete);
Expand Down
16 changes: 14 additions & 2 deletions drivers/crypto/rockchip/rk3288_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,26 @@
#define CRYPTO_WRITE(dev, offset, val) \
writel_relaxed((val), ((dev)->reg + (offset)))

#define RK_MAX_CLKS 4

struct rk_clks {
const char *name;
unsigned long max;
};

struct rk_variant {
int num_clks;
struct rk_clks rkclks[RK_MAX_CLKS];
};

struct rk_crypto_info {
struct device *dev;
struct clk_bulk_data *clks;
int num_clks;
int num_clks;
struct reset_control *rst;
void __iomem *reg;
int irq;

const struct rk_variant *variant;
struct crypto_engine *engine;
struct completion complete;
int status;
Expand Down

0 comments on commit e220e67

Please sign in to comment.