b71edd0306da2bc47641f931365d71b8b8b1e71f
[openwrt/staging/mans0n.git] /
1 From 7b808449f572d07bee840cd9da7e2fe6a1b8f4b5 Mon Sep 17 00:00:00 2001
2 From: Rajendra Nayak <rnayak@codeaurora.org>
3 Date: Fri, 6 Aug 2021 09:59:46 +0100
4 Subject: [PATCH] nvmem: qfprom: sc7280: Handle the additional power-domains
5 vote
6
7 On sc7280, to reliably blow fuses, we need an additional vote
8 on max performance state of 'MX' power-domain.
9 Add support for power-domain performance state voting in the
10 driver.
11
12 Reviewed-by: Douglas Anderson <dianders@chromium.org>
13 Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
14 Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
15 Link: https://lore.kernel.org/r/20210806085947.22682-4-srinivas.kandagatla@linaro.org
16 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
17 ---
18 drivers/nvmem/qfprom.c | 25 +++++++++++++++++++++++++
19 1 file changed, 25 insertions(+)
20
21 --- a/drivers/nvmem/qfprom.c
22 +++ b/drivers/nvmem/qfprom.c
23 @@ -12,6 +12,8 @@
24 #include <linux/mod_devicetable.h>
25 #include <linux/nvmem-provider.h>
26 #include <linux/platform_device.h>
27 +#include <linux/pm_domain.h>
28 +#include <linux/pm_runtime.h>
29 #include <linux/property.h>
30 #include <linux/regulator/consumer.h>
31
32 @@ -142,6 +144,9 @@ static void qfprom_disable_fuse_blowing(
33 writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
34 writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET);
35
36 + dev_pm_genpd_set_performance_state(priv->dev, 0);
37 + pm_runtime_put(priv->dev);
38 +
39 /*
40 * This may be a shared rail and may be able to run at a lower rate
41 * when we're not blowing fuses. At the moment, the regulator framework
42 @@ -212,6 +217,14 @@ static int qfprom_enable_fuse_blowing(co
43 goto err_clk_rate_set;
44 }
45
46 + ret = pm_runtime_get_sync(priv->dev);
47 + if (ret < 0) {
48 + pm_runtime_put_noidle(priv->dev);
49 + dev_err(priv->dev, "Failed to enable power-domain\n");
50 + goto err_reg_enable;
51 + }
52 + dev_pm_genpd_set_performance_state(priv->dev, INT_MAX);
53 +
54 old->timer_val = readl(priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
55 old->accel_val = readl(priv->qfpconf + QFPROM_ACCEL_OFFSET);
56 writel(priv->soc_data->qfprom_blow_timer_value,
57 @@ -221,6 +234,8 @@ static int qfprom_enable_fuse_blowing(co
58
59 return 0;
60
61 +err_reg_enable:
62 + regulator_disable(priv->vcc);
63 err_clk_rate_set:
64 clk_set_rate(priv->secclk, old->clk_rate);
65 err_clk_prepared:
66 @@ -320,6 +335,11 @@ static int qfprom_reg_read(void *context
67 return 0;
68 }
69
70 +static void qfprom_runtime_disable(void *data)
71 +{
72 + pm_runtime_disable(data);
73 +}
74 +
75 static const struct qfprom_soc_data qfprom_7_8_data = {
76 .accel_value = 0xD10,
77 .qfprom_blow_timer_value = 25,
78 @@ -420,6 +440,11 @@ static int qfprom_probe(struct platform_
79 econfig.reg_write = qfprom_reg_write;
80 }
81
82 + pm_runtime_enable(dev);
83 + ret = devm_add_action_or_reset(dev, qfprom_runtime_disable, dev);
84 + if (ret)
85 + return ret;
86 +
87 nvmem = devm_nvmem_register(dev, &econfig);
88
89 return PTR_ERR_OR_ZERO(nvmem);