ipq806x: 5.15: add krait-cc modernization patch and fixup

Add multiple patch for krait-cc modernization and multiple fixup for the
driver. Also modify a patch to enable the qsb fixed clock and add pxo to
krait-cc node.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
Christian Marangi 2022-09-15 04:01:22 +02:00
parent e5a3720a56
commit 6f1b89baba
No known key found for this signature in database
GPG Key ID: AC001D09ADBFEAD7
10 changed files with 760 additions and 8 deletions

View File

@ -20,11 +20,11 @@ Tested-by: Jonathan McDowell <noodles@earth.li>
};
clocks {
+// qsb: qsb {
+// compatible = "fixed-clock";
+// clock-frequency = <384000000>;
+// #clock-cells = <0>;
+// };
+ qsb: qsb {
+ compatible = "fixed-clock";
+ clock-frequency = <225000000>;
+ #clock-cells = <0>;
+ };
+
cxo_board: cxo_board {
compatible = "fixed-clock";
@ -85,10 +85,10 @@ Tested-by: Jonathan McDowell <noodles@earth.li>
+ kraitcc: clock-controller {
+ compatible = "qcom,krait-cc-v1";
+ clocks = <&gcc PLL9>, <&gcc PLL10>, <&gcc PLL12>,
+ <&acc0>, <&acc1>, <&l2cc>; // <&qsb>
+ <&acc0>, <&acc1>, <&l2cc>, <&qsb>, <&pxo_board>;
+ clock-names = "hfpll0", "hfpll1", "hfpll_l2",
+ "acpu0_aux", "acpu1_aux", "acpu_l2_aux";
+// "qsb";
+ "acpu0_aux", "acpu1_aux", "acpu_l2_aux",
+ "qsb", "pxo";
+ #clock-cells = <1>;
};

View File

@ -0,0 +1,64 @@
From 09930efb4f4fb81019ca33bf64827ce258eca66f Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 15 Sep 2022 01:58:12 +0200
Subject: [PATCH 1/9] clk: qcom: kpss-xcc: register it as clk provider
krait-cc use this driver for the secondary mux. Register it as a clk
provider to correctly use this clk in other drivers.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/kpss-xcc.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c
index b1b370274ec4..97358c98c6c9 100644
--- a/drivers/clk/qcom/kpss-xcc.c
+++ b/drivers/clk/qcom/kpss-xcc.c
@@ -31,13 +31,14 @@ MODULE_DEVICE_TABLE(of, kpss_xcc_match_table);
static int kpss_xcc_driver_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
const struct of_device_id *id;
struct resource *res;
void __iomem *base;
struct clk_hw *hw;
const char *name;
- id = of_match_device(kpss_xcc_match_table, &pdev->dev);
+ id = of_match_device(kpss_xcc_match_table, dev);
if (!id)
return -ENODEV;
@@ -45,7 +46,7 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev)
return PTR_ERR(base);
if (id->data) {
- if (of_property_read_string_index(pdev->dev.of_node,
+ if (of_property_read_string_index(dev->of_node,
"clock-output-names",
0, &name))
return -ENODEV;
@@ -55,12 +56,16 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev)
base += 0x28;
}
- hw = devm_clk_hw_register_mux_parent_data_table(&pdev->dev, name, aux_parents,
+ hw = devm_clk_hw_register_mux_parent_data_table(dev, name, aux_parents,
ARRAY_SIZE(aux_parents), 0,
base, 0, 0x3,
0, aux_parent_map, NULL);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
- return PTR_ERR_OR_ZERO(hw);
+ of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw);
+
+ return 0;
}
static struct platform_driver kpss_xcc_driver = {
--
2.37.2

View File

@ -0,0 +1,269 @@
From 334c1540d5753a3c83a4cb84d935d606cb47a03b Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 17 Feb 2022 23:02:59 +0100
Subject: [PATCH 2/9] clk: qcom: krait-cc: convert to parent_data API
Modernize the krait-cc driver to parent-data API and refactor to drop
any use of clk_names. From Documentation all the required clocks should
be declared in DTS so fw_name can be correctly used to get the parents
for all the muxes. .name is also declared to save compatibility with old
implementation.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/krait-cc.c | 126 +++++++++++++++++++-----------------
1 file changed, 66 insertions(+), 60 deletions(-)
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index cfd961d5cc45..84f0048961f5 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -69,21 +69,22 @@ static int krait_notifier_register(struct device *dev, struct clk *clk,
return ret;
}
-static int
+static struct clk *
krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
{
struct krait_div2_clk *div;
+ static struct clk_parent_data p_data[1];
struct clk_init_data init = {
- .num_parents = 1,
+ .num_parents = ARRAY_SIZE(p_data),
.ops = &krait_div2_clk_ops,
.flags = CLK_SET_RATE_PARENT,
};
- const char *p_names[1];
struct clk *clk;
+ char *parent_name;
div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
if (!div)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
div->width = 2;
div->shift = 6;
@@ -93,43 +94,49 @@ krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
if (!init.name)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
- init.parent_names = p_names;
- p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
- if (!p_names[0]) {
- kfree(init.name);
- return -ENOMEM;
+ init.parent_data = p_data;
+ parent_name = kasprintf(GFP_KERNEL, "hfpll%s", s);
+ if (!parent_name) {
+ clk = ERR_PTR(-ENOMEM);
+ goto err_parent_name;
}
+ p_data[0].fw_name = parent_name;
+ p_data[0].name = parent_name;
+
clk = devm_clk_register(dev, &div->hw);
- kfree(p_names[0]);
+
+ kfree(parent_name);
+err_parent_name:
kfree(init.name);
- return PTR_ERR_OR_ZERO(clk);
+ return clk;
}
-static int
+static struct clk *
krait_add_sec_mux(struct device *dev, int id, const char *s,
unsigned int offset, bool unique_aux)
{
int ret;
struct krait_mux_clk *mux;
- static const char *sec_mux_list[] = {
- "acpu_aux",
- "qsb",
+ static struct clk_parent_data sec_mux_list[2] = {
+ { .name = "qsb", .fw_name = "qsb" },
+ {},
};
struct clk_init_data init = {
- .parent_names = sec_mux_list,
+ .parent_data = sec_mux_list,
.num_parents = ARRAY_SIZE(sec_mux_list),
.ops = &krait_mux_clk_ops,
.flags = CLK_SET_RATE_PARENT,
};
struct clk *clk;
+ char *parent_name;
mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
if (!mux)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
mux->offset = offset;
mux->lpl = id >= 0;
@@ -149,44 +156,51 @@ krait_add_sec_mux(struct device *dev, int id, const char *s,
init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
if (!init.name)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
if (unique_aux) {
- sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
- if (!sec_mux_list[0]) {
+ parent_name = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
+ if (!parent_name) {
clk = ERR_PTR(-ENOMEM);
goto err_aux;
}
+ sec_mux_list[1].fw_name = parent_name;
+ sec_mux_list[1].name = parent_name;
+ } else {
+ sec_mux_list[1].name = "apu_aux";
}
clk = devm_clk_register(dev, &mux->hw);
+ if (IS_ERR(clk))
+ goto err_clk;
ret = krait_notifier_register(dev, clk, mux);
if (ret)
- goto unique_aux;
+ clk = ERR_PTR(ret);
-unique_aux:
+err_clk:
if (unique_aux)
- kfree(sec_mux_list[0]);
+ kfree(parent_name);
err_aux:
kfree(init.name);
- return PTR_ERR_OR_ZERO(clk);
+ return clk;
}
static struct clk *
-krait_add_pri_mux(struct device *dev, int id, const char *s,
- unsigned int offset)
+krait_add_pri_mux(struct device *dev, struct clk *hfpll_div, struct clk *sec_mux,
+ int id, const char *s, unsigned int offset)
{
int ret;
struct krait_mux_clk *mux;
- const char *p_names[3];
+ static struct clk_parent_data p_data[3];
struct clk_init_data init = {
- .parent_names = p_names,
- .num_parents = ARRAY_SIZE(p_names),
+ .parent_data = p_data,
+ .num_parents = ARRAY_SIZE(p_data),
.ops = &krait_mux_clk_ops,
.flags = CLK_SET_RATE_PARENT,
};
struct clk *clk;
+ char *hfpll_name;
mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
if (!mux)
@@ -204,36 +218,29 @@ krait_add_pri_mux(struct device *dev, int id, const char *s,
if (!init.name)
return ERR_PTR(-ENOMEM);
- p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
- if (!p_names[0]) {
+ hfpll_name = kasprintf(GFP_KERNEL, "hfpll%s", s);
+ if (!hfpll_name) {
clk = ERR_PTR(-ENOMEM);
- goto err_p0;
+ goto err_hfpll;
}
- p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
- if (!p_names[1]) {
- clk = ERR_PTR(-ENOMEM);
- goto err_p1;
- }
+ p_data[0].fw_name = hfpll_name;
+ p_data[0].name = hfpll_name;
- p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
- if (!p_names[2]) {
- clk = ERR_PTR(-ENOMEM);
- goto err_p2;
- }
+ p_data[1].hw = __clk_get_hw(hfpll_div);
+ p_data[2].hw = __clk_get_hw(sec_mux);
clk = devm_clk_register(dev, &mux->hw);
+ if (IS_ERR(clk))
+ goto err_clk;
ret = krait_notifier_register(dev, clk, mux);
if (ret)
- goto err_p3;
-err_p3:
- kfree(p_names[2]);
-err_p2:
- kfree(p_names[1]);
-err_p1:
- kfree(p_names[0]);
-err_p0:
+ clk = ERR_PTR(ret);
+
+err_clk:
+ kfree(hfpll_name);
+err_hfpll:
kfree(init.name);
return clk;
}
@@ -241,11 +248,10 @@ krait_add_pri_mux(struct device *dev, int id, const char *s,
/* id < 0 for L2, otherwise id == physical CPU number */
static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux)
{
- int ret;
unsigned int offset;
void *p = NULL;
const char *s;
- struct clk *clk;
+ struct clk *hfpll_div, *sec_mux, *clk;
if (id >= 0) {
offset = 0x4501 + (0x1000 * id);
@@ -257,19 +263,19 @@ static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux)
s = "_l2";
}
- ret = krait_add_div(dev, id, s, offset);
- if (ret) {
- clk = ERR_PTR(ret);
+ hfpll_div = krait_add_div(dev, id, s, offset);
+ if (IS_ERR(hfpll_div)) {
+ clk = hfpll_div;
goto err;
}
- ret = krait_add_sec_mux(dev, id, s, offset, unique_aux);
- if (ret) {
- clk = ERR_PTR(ret);
+ sec_mux = krait_add_sec_mux(dev, id, s, offset, unique_aux);
+ if (IS_ERR(sec_mux)) {
+ clk = sec_mux;
goto err;
}
- clk = krait_add_pri_mux(dev, id, s, offset);
+ clk = krait_add_pri_mux(dev, hfpll_div, sec_mux, id, s, offset);
err:
kfree(p);
return clk;
--
2.37.2

View File

@ -0,0 +1,52 @@
From 666c1b745e93ccddde841d5057c33f97b29a316a Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 15 Sep 2022 02:19:28 +0200
Subject: [PATCH 3/9] clk: qcom: krait-cc: handle qsb clock defined in DTS
qsb fixed clk may be defined in DTS and correctly passed in the clocks
list. Add related code to handle this and modify the logic to
dynamically read qsb clock frequency.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/krait-cc.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index 84f0048961f5..f1d64b16cac3 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -305,7 +305,7 @@ static int krait_cc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *id;
- unsigned long cur_rate, aux_rate;
+ unsigned long cur_rate, aux_rate, qsb_rate;
int cpu;
struct clk *clk;
struct clk **clks;
@@ -315,11 +315,19 @@ static int krait_cc_probe(struct platform_device *pdev)
if (!id)
return -ENODEV;
- /* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */
- clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, 1);
+ /*
+ * Per Documentation qsb should be provided from DTS.
+ * To address old implementation, register the fixed clock anyway.
+ * Rate is 1 because 0 causes problems for __clk_mux_determine_rate
+ */
+ clk = clk_get(dev, "qsb");
+ if (IS_ERR(clk))
+ clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, 1);
if (IS_ERR(clk))
return PTR_ERR(clk);
+ qsb_rate = clk_get_rate(clk);
+
if (!id->data) {
clk = clk_register_fixed_factor(dev, "acpu_aux",
"gpll0_vote", 0, 1, 2);
--
2.37.2

View File

@ -0,0 +1,59 @@
From fca6f185a9d9ef0892a719bc6da955b22d326ec7 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 15 Sep 2022 02:24:33 +0200
Subject: [PATCH 4/9] clk: qcom: krait-cc: register REAL qsb fixed clock
With some tools it was discovered the real frequency of the qsb fixed
clock. While not 100% correct it's still better than using 1 as a dummy
frequency.
Correctly register the qsb fixed clock with the frequency of 225 MHz
instead of 1.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/krait-cc.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index f1d64b16cac3..e91275663973 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -15,6 +15,8 @@
#include "clk-krait.h"
+#define QSB_RATE 2250000000
+
static unsigned int sec_mux_map[] = {
2,
0,
@@ -322,7 +324,7 @@ static int krait_cc_probe(struct platform_device *pdev)
*/
clk = clk_get(dev, "qsb");
if (IS_ERR(clk))
- clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, 1);
+ clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, QSB_RATE);
if (IS_ERR(clk))
return PTR_ERR(clk);
@@ -378,7 +380,7 @@ static int krait_cc_probe(struct platform_device *pdev)
*/
cur_rate = clk_get_rate(l2_pri_mux_clk);
aux_rate = 384000000;
- if (cur_rate == 1) {
+ if (cur_rate == qsb_rate) {
pr_info("L2 @ QSB rate. Forcing new rate.\n");
cur_rate = aux_rate;
}
@@ -389,7 +391,7 @@ static int krait_cc_probe(struct platform_device *pdev)
for_each_possible_cpu(cpu) {
clk = clks[cpu];
cur_rate = clk_get_rate(clk);
- if (cur_rate == 1) {
+ if (cur_rate == qsb_rate) {
pr_info("CPU%d @ QSB rate. Forcing new rate.\n", cpu);
cur_rate = aux_rate;
}
--
2.37.2

View File

@ -0,0 +1,30 @@
From ff65b60fa89be06ba68e3e22702dd71700afb6a5 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 15 Sep 2022 02:34:58 +0200
Subject: [PATCH 5/9] clk: qcom: krait-cc: use devm variant for clk notifier
register
Use devm variant for clk notifier register and correctly handle free
resource on driver remove.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/krait-cc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index e91275663973..33a78b7de0bd 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -64,7 +64,7 @@ static int krait_notifier_register(struct device *dev, struct clk *clk,
int ret = 0;
mux->clk_nb.notifier_call = krait_notifier_cb;
- ret = clk_notifier_register(clk, &mux->clk_nb);
+ ret = devm_clk_notifier_register(dev, clk, &mux->clk_nb);
if (ret)
dev_err(dev, "failed to register clock notifier: %d\n", ret);
--
2.37.2

View File

@ -0,0 +1,52 @@
From a0f6d7abe7f5da1a9b435eed89acace7cde4add6 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 15 Sep 2022 02:39:11 +0200
Subject: [PATCH 6/9] clk: qcom: krait-cc: fix never enabled secondary mux
While never actually used as a pure mux, the secondary mux is used as a
safe selection for the primary mux to switch while the hfpll are
reprogrammed.
The secondary muxes were never enabled and this cause the krait-clk
drivers to silently ignore any set parent request without any error.
Enable the secondary mux to actually apply the parent and apply the
requested frequency.
Fixes: bb5c4a85051e ("clk: qcom: Add Krait clock controller driver")
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/krait-cc.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index 33a78b7de0bd..b71067a49ee7 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -121,7 +121,7 @@ static struct clk *
krait_add_sec_mux(struct device *dev, int id, const char *s,
unsigned int offset, bool unique_aux)
{
- int ret;
+ int ret, cpu;
struct krait_mux_clk *mux;
static struct clk_parent_data sec_mux_list[2] = {
{ .name = "qsb", .fw_name = "qsb" },
@@ -180,6 +180,16 @@ krait_add_sec_mux(struct device *dev, int id, const char *s,
if (ret)
clk = ERR_PTR(ret);
+ /* The secondary mux MUST be enabled or clk-krait silently
+ * ignore any request.
+ * Increase refcount for every CPU if it's the L2 secondary mux.
+ */
+ if (id < 0)
+ for_each_possible_cpu(cpu)
+ clk_prepare_enable(clk);
+ else
+ clk_prepare_enable(clk);
+
err_clk:
if (unique_aux)
kfree(parent_name);
--
2.37.2

View File

@ -0,0 +1,49 @@
From 2399d181557d94ae9a2686926cd25768f132e4b4 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Fri, 18 Mar 2022 16:12:14 +0100
Subject: [PATCH 7/9] clk: qcom: krait-cc: drop pr_info and use dev_info
Replace pr_info() with dev_info() to provide better diagnostics.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/krait-cc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index b71067a49ee7..e4fb3ff2b5b5 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -391,25 +391,25 @@ static int krait_cc_probe(struct platform_device *pdev)
cur_rate = clk_get_rate(l2_pri_mux_clk);
aux_rate = 384000000;
if (cur_rate == qsb_rate) {
- pr_info("L2 @ QSB rate. Forcing new rate.\n");
+ dev_info(dev, "L2 @ QSB rate. Forcing new rate.\n");
cur_rate = aux_rate;
}
clk_set_rate(l2_pri_mux_clk, aux_rate);
clk_set_rate(l2_pri_mux_clk, 2);
clk_set_rate(l2_pri_mux_clk, cur_rate);
- pr_info("L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000);
+ dev_info(dev, "L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000);
for_each_possible_cpu(cpu) {
clk = clks[cpu];
cur_rate = clk_get_rate(clk);
if (cur_rate == qsb_rate) {
- pr_info("CPU%d @ QSB rate. Forcing new rate.\n", cpu);
+ dev_info(dev, "CPU%d @ QSB rate. Forcing new rate.\n", cpu);
cur_rate = aux_rate;
}
clk_set_rate(clk, aux_rate);
clk_set_rate(clk, 2);
clk_set_rate(clk, cur_rate);
- pr_info("CPU%d @ %lu KHz\n", cpu, clk_get_rate(clk) / 1000);
+ dev_info(dev, "CPU%d @ %lu KHz\n", cpu, clk_get_rate(clk) / 1000);
}
of_clk_add_provider(dev->of_node, krait_of_get, clks);
--
2.37.2

View File

@ -0,0 +1,75 @@
From b6655ca513b3f1b40417287ab7f706409455fe48 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 15 Sep 2022 02:56:47 +0200
Subject: [PATCH 8/9] clk: qcom: krait-cc: handle secondary mux sourcing out of
PXO
The secondary mux can sourc out of PXO as the secondary MUX is attached
to QSB and to another mux that can source out of PXO or PLL8_VOTE.
Many device may run with uncorrect configuration with the mux sourcing
out of PXO instead of PLL8_VOTE.
To handle this case we add also PXO as required clocks and we check if
the frequency is currently set to PXO and force a correct rate if it's
the case.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/krait-cc.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index e4fb3ff2b5b5..717eff44b6a4 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -317,7 +317,7 @@ static int krait_cc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *id;
- unsigned long cur_rate, aux_rate, qsb_rate;
+ unsigned long cur_rate, aux_rate, qsb_rate, pxo_rate;
int cpu;
struct clk *clk;
struct clk **clks;
@@ -327,6 +327,15 @@ static int krait_cc_probe(struct platform_device *pdev)
if (!id)
return -ENODEV;
+ clk = clk_get(dev, "pxo");
+ if (IS_ERR(clk))
+ clk = __clk_lookup("pxo_board");
+
+ if (IS_ERR_OR_NULL(clk))
+ return clk == NULL ? -ENODEV : PTR_ERR(clk);
+
+ pxo_rate = clk_get_rate(clk);
+
/*
* Per Documentation qsb should be provided from DTS.
* To address old implementation, register the fixed clock anyway.
@@ -394,6 +403,10 @@ static int krait_cc_probe(struct platform_device *pdev)
dev_info(dev, "L2 @ QSB rate. Forcing new rate.\n");
cur_rate = aux_rate;
}
+ if (cur_rate == pxo_rate) {
+ dev_info(dev, "L2 @ PXO rate. Forcing new rate.\n");
+ cur_rate = aux_rate;
+ }
clk_set_rate(l2_pri_mux_clk, aux_rate);
clk_set_rate(l2_pri_mux_clk, 2);
clk_set_rate(l2_pri_mux_clk, cur_rate);
@@ -405,6 +418,10 @@ static int krait_cc_probe(struct platform_device *pdev)
dev_info(dev, "CPU%d @ QSB rate. Forcing new rate.\n", cpu);
cur_rate = aux_rate;
}
+ if (cur_rate ==pxo_rate) {
+ dev_info(dev, "CPU%d @ PXO rate. Forcing new rate.\n", cpu);
+ cur_rate = aux_rate;
+ }
clk_set_rate(clk, aux_rate);
clk_set_rate(clk, 2);
--
2.37.2

View File

@ -0,0 +1,102 @@
From 6a77cf3f5f95ec0058e1b4d1ada018748cb0b83b Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 15 Sep 2022 03:33:13 +0200
Subject: [PATCH 9/9] clk: qcom: krait-cc: rework mux reset logic and reset
hfpll
Rework and clean mux reset logic.
Compact it to a for loop to handle both CPU and L2 in one place.
Move hardcoded aux_rate to define and add a new hfpll_rate value to
reset hfpll settings.
Change logic to now reset the hfpll to the lowest value of 600 Mhz and
then restoring the previous frequency. This permits to reset the hfpll if
the primary mux was set to source out of the secondary mux.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/krait-cc.c | 50 +++++++++++++++++--------------------
1 file changed, 23 insertions(+), 27 deletions(-)
diff --git a/drivers/clk/qcom/krait-cc.c b/drivers/clk/qcom/krait-cc.c
index 717eff44b6a4..90dee71e7c38 100644
--- a/drivers/clk/qcom/krait-cc.c
+++ b/drivers/clk/qcom/krait-cc.c
@@ -15,7 +15,9 @@
#include "clk-krait.h"
-#define QSB_RATE 2250000000
+#define QSB_RATE 225000000
+#define AUX_RATE 384000000
+#define HFPLL_RATE 600000000
static unsigned int sec_mux_map[] = {
2,
@@ -317,7 +319,7 @@ static int krait_cc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *id;
- unsigned long cur_rate, aux_rate, qsb_rate, pxo_rate;
+ unsigned long cur_rate, qsb_rate, pxo_rate;
int cpu;
struct clk *clk;
struct clk **clks;
@@ -397,36 +399,30 @@ static int krait_cc_probe(struct platform_device *pdev)
* two different rates to force a HFPLL reinit under all
* circumstances.
*/
- cur_rate = clk_get_rate(l2_pri_mux_clk);
- aux_rate = 384000000;
- if (cur_rate == qsb_rate) {
- dev_info(dev, "L2 @ QSB rate. Forcing new rate.\n");
- cur_rate = aux_rate;
- }
- if (cur_rate == pxo_rate) {
- dev_info(dev, "L2 @ PXO rate. Forcing new rate.\n");
- cur_rate = aux_rate;
- }
- clk_set_rate(l2_pri_mux_clk, aux_rate);
- clk_set_rate(l2_pri_mux_clk, 2);
- clk_set_rate(l2_pri_mux_clk, cur_rate);
- dev_info(dev, "L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000);
- for_each_possible_cpu(cpu) {
+ for (cpu = 0; cpu < 5; cpu++) {
+ const char *l2_s = "L2";
+ char cpu_s[5];
+
clk = clks[cpu];
+ if (!clk)
+ continue;
+
+ if (cpu < 4)
+ snprintf(cpu_s, 5, "CPU%d", cpu);
+
cur_rate = clk_get_rate(clk);
- if (cur_rate == qsb_rate) {
- dev_info(dev, "CPU%d @ QSB rate. Forcing new rate.\n", cpu);
- cur_rate = aux_rate;
- }
- if (cur_rate ==pxo_rate) {
- dev_info(dev, "CPU%d @ PXO rate. Forcing new rate.\n", cpu);
- cur_rate = aux_rate;
+ if (cur_rate == qsb_rate || cur_rate == pxo_rate) {
+ dev_info(dev, "%s @ %s rate. Forcing new rate.\n",
+ cpu < 4 ? cpu_s : l2_s,
+ cur_rate == qsb_rate ? "QSB" : "PXO");
+ cur_rate = AUX_RATE;
}
- clk_set_rate(clk, aux_rate);
- clk_set_rate(clk, 2);
+ clk_set_rate(clk, AUX_RATE);
+ clk_set_rate(clk, HFPLL_RATE);
clk_set_rate(clk, cur_rate);
- dev_info(dev, "CPU%d @ %lu KHz\n", cpu, clk_get_rate(clk) / 1000);
+ dev_info(dev, "%s @ %lu KHz\n", cpu < 4 ? cpu_s : l2_s,
+ clk_get_rate(clk) / 1000);
}
of_clk_add_provider(dev->of_node, krait_of_get, clks);
--
2.37.2