clk: qcom: clk-rcg2: add rcg2 mux ops
Subsystems (5)
PATCH v3 1/9 clk: qcom: clk-rcg2: add rcg2 mux ops
From: Christian Marangi <[email protected]>
An RCG may act as a mux that switch between 2 parents.
This is the case on IPQ6018 and IPQ8074 where the APCS core clk that feeds the CPU cluster clock just switches between XO and the PLL that feeds it.
Add the required ops to add support for this special configuration and use the generic mux function to determine the rate.
This way we dont have to keep a essentially dummy frequency table to use RCG2 as a mux.
--- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 7 +++++++ 2 files changed, 8 insertions(+)
drivers/clk/qcom/clk-rcg.h +1 -0
@@ -167,6 +167,7 @@ struct clk_rcg2_gfx3d {extern const struct clk_ops clk_rcg2_ops;extern const struct clk_ops clk_rcg2_floor_ops; +extern const struct clk_ops clk_rcg2_mux_closest_ops;extern const struct clk_ops clk_edp_pixel_ops;extern const struct clk_ops clk_byte_ops;extern const struct clk_ops clk_byte2_ops;
drivers/clk/qcom/clk-rcg2.c +7 -0
@@ -509,6 +509,13 @@ const struct clk_ops clk_rcg2_floor_ops = { };EXPORT_SYMBOL_GPL (clk_rcg2_floor_ops); +const struct clk_ops clk_rcg2_mux_closest_ops = { + .determine_rate = __clk_mux_determine_rate_closest, + .get_parent = clk_rcg2_get_parent, + .set_parent = clk_rcg2_set_parent, +}; +EXPORT_SYMBOL_GPL (clk_rcg2_mux_closest_ops); +struct frac_entry {int num;int den;
Signature · 1 line
2.37.2
PATCH v3 2/9 clk: qcom: apss-ipq6018: fix apcs_alias0_clk_src
While working on IPQ8074 APSS driver it was discovered that IPQ6018 and IPQ8074 use almost the same PLL and APSS clocks, however APSS driver is currently broken.
More precisely apcs_alias0_clk_src is broken, it was added as regmap_mux clock.
However after debugging why it was always stuck at 800Mhz, it was figured out that its not regmap_mux compatible at all.
It is a simple mux but it uses RCG2 register layout and control bits, so utilize the new clk_rcg2_mux_closest_ops to correctly drive it while not having to provide a dummy frequency table.
While we are here, use ARRAY_SIZE for number of parents.
Tested on IPQ6018-CP01-C1 reference board and multiple IPQ8074 boards.
--- drivers/clk/qcom/apss-ipq6018.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/clk/qcom/apss-ipq6018.c +6 -7
@@ -16,7 +16,7 @@#include "clk-regmap.h" #include "clk-branch.h" #include "clk-alpha-pll.h" -#include "clk-regmap-mux.h" +#include "clk-rcg.h" enum {P_XO ,
@@ -33,16 +33,15 @@ static const struct parent_map parents_apcs_alias0_clk_src_map[] = { { P_APSS_PLL_EARLY, 5 }, }; -static struct clk_regmap_mux apcs_alias0_clk_src = { - .reg =0x0050 , - .width =3 , - .shift =7 , +static struct clk_rcg2 apcs_alias0_clk_src = { + .cmd_rcgr =0x0050 , + .hid_width =5 , .parent_map = parents_apcs_alias0_clk_src_map, .clkr.hw.init = &(struct clk_init_data ){ .name ="apcs_alias0_clk_src" , .parent_data = parents_apcs_alias0_clk_src, - .num_parents =2 , - .ops = &clk_regmap_mux_closest_ops, + .num_parents =ARRAY_SIZE (parents_apcs_alias0_clk_src), + .ops = &clk_rcg2_mux_closest_ops, .flags =CLK_SET_RATE_PARENT , }, };
Signature · 1 line
2.37.2
PATCH v3 3/9 clk: qcom: apss-ipq6018: mark apcs_alias0_core_clk as critical
In reply to Robert MarkoWhile fixing up the driver I noticed that my IPQ8074 board was hanging after CPUFreq switched the frequency during boot, WDT would eventually reset it.
So mark apcs_alias0_core_clk as critical since its the clock feeding the CPU cluster and must never be disabled.
--- drivers/clk/qcom/apss-ipq6018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/apss-ipq6018.c +1 -1
@@ -56,7 +56,7 @@ static struct clk_branch apcs_alias0_core_clk = { .parent_hws = (const struct clk_hw *[]){ &apcs_alias0_clk_src.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, },
Signature · 1 line
2.37.2
PATCH v3 4/9 dt-bindings: clock: qcom,a53pll: add IPQ8074 compatible
In reply to Robert MarkoAdd IPQ8074 compatible to A53 PLL bindings.
--- Documentation/devicetree/bindings/clock/qcom,a53pll.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/clock/qcom,a53pll.yaml +1 -0
@@ -17,6 +17,7 @@ properties: compatible: enum: - qcom,ipq6018-a53pll + - qcom,ipq8074-a53pll - qcom,msm8916-a53pll - qcom,msm8939-a53pll
Signature · 1 line
2.37.2
PATCH v3 5/9 clk: qcom: apss-ipq-pll: use OF match data for Alpha PLL config
In reply to Robert MarkoConvert the driver to use OF match data for providing the Alpha PLL config per compatible.
This is required for IPQ8074 support since it uses a different Alpha PLL config.
While we are here rename "ipq_pll_config" to "ipq6018_pll_config" to make it clear that it is for IPQ6018 only.
--- drivers/clk/qcom/apss-ipq-pll.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/clk/qcom/apss-ipq-pll.c +9 -3
@@ -2,6 +2,7 @@// Copyright (c) 2018, The Linux Foundation. All rights reserved. #include <linux/clk-provider.h> #include <linux/module.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/regmap.h>
@@ -36,7 +37,7 @@ static struct clk_alpha_pll ipq_pll = { }, }; -static const struct alpha_pll_config ipq_pll_config = { +static const struct alpha_pll_config ipq6018_pll_config = { .l =0x37 , .config_ctl_val =0x04141200 , .config_ctl_hi_val =0x0 ,
@@ -54,6 +55,7 @@ static const struct regmap_config ipq_pll_regmap_config = {static int apss_ipq_pll_probe (struct platform_device *pdev) { +const struct alpha_pll_config *ipq_pll_config;struct device *dev = &pdev->dev;struct regmap *regmap;void __iomem *base;
@@ -67,7 +69,11 @@ static int apss_ipq_pll_probe(struct platform_device *pdev)if (IS_ERR (regmap))return PTR_ERR (regmap); -clk_alpha_pll_configure (&ipq_pll, regmap, &ipq_pll_config); + ipq_pll_config =of_device_get_match_data (&pdev->dev); +if (!ipq_pll_config) +return -ENODEV ; + +clk_alpha_pll_configure (&ipq_pll, regmap, ipq_pll_config); ret =devm_clk_register_regmap (dev, &ipq_pll.clkr);if (ret)
@@ -78,7 +84,7 @@ static int apss_ipq_pll_probe(struct platform_device *pdev) }static const struct of_device_id apss_ipq_pll_match_table[] = { - { .compatible ="qcom,ipq6018-a53pll" }, + { .compatible ="qcom,ipq6018-a53pll" , .data = &ipq6018_pll_config }, { } };MODULE_DEVICE_TABLE (of, apss_ipq_pll_match_table);
Signature · 1 line
2.37.2
PATCH v3 6/9 clk: qcom: apss-ipq-pll: update IPQ6018 Alpha PLL config
In reply to Robert MarkoUpdate the IPQ6018 Alpha PLL config to the latest one from the downstream 5.4 kernel[1].
This one should match the production SoC-s.
Tested on IPQ6018 CP01-C1 reference board.
--- drivers/clk/qcom/apss-ipq-pll.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/clk/qcom/apss-ipq-pll.c +6 -2
@@ -39,10 +39,14 @@ static struct clk_alpha_pll ipq_pll = {static const struct alpha_pll_config ipq6018_pll_config = { .l =0x37 , - .config_ctl_val =0x04141200 , - .config_ctl_hi_val =0x0 , + .config_ctl_val =0x240d4828 , + .config_ctl_hi_val =0x6 , .early_output_mask =BIT (3 ), + .aux2_output_mask =BIT (2 ), + .aux_output_mask =BIT (1 ), .main_output_mask =BIT (0 ), + .test_ctl_val =0x1c0000C0 , + .test_ctl_hi_val =0x4000 , };static const struct regmap_config ipq_pll_regmap_config = {
Signature · 1 line
2.37.2
PATCH v3 7/9 clk: qcom: apss-ipq-pll: add support for IPQ8074
In reply to Robert MarkoAdd support for IPQ8074 since it uses the same PLL setup, however it uses slightly different Alpha PLL config.
Alpha PLL config was obtained by dumping PLL registers from a running device.
---
Changes in v2:
* Drop hardcoded compatible check for IPQ6018 to do the PLL config and utilize match data provided by previous commit
* Add IPQ8074 Alpha PLL config using match data
* Update commit description to reflect changes
--- drivers/clk/qcom/apss-ipq-pll.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/clk/qcom/apss-ipq-pll.c +13 -0
@@ -49,6 +49,18 @@ static const struct alpha_pll_config ipq6018_pll_config = { .test_ctl_hi_val = 0x4000, }; +static const struct alpha_pll_config ipq8074_pll_config = { + .l =0x48 , + .config_ctl_val =0x200d4828 , + .config_ctl_hi_val =0x6 , + .early_output_mask =BIT (3 ), + .aux2_output_mask =BIT (2 ), + .aux_output_mask =BIT (1 ), + .main_output_mask =BIT (0 ), + .test_ctl_val =0x1c000000 , + .test_ctl_hi_val =0x4000 , +}; +static const struct regmap_config ipq_pll_regmap_config = { .reg_bits =32 , .reg_stride =4 ,
@@ -89,6 +101,7 @@ static int apss_ipq_pll_probe(struct platform_device *pdev)static const struct of_device_id apss_ipq_pll_match_table[] = { { .compatible ="qcom,ipq6018-a53pll" , .data = &ipq6018_pll_config }, + { .compatible ="qcom,ipq8074-a53pll" , .data = &ipq8074_pll_config }, { } };MODULE_DEVICE_TABLE (of, apss_ipq_pll_match_table);
Signature · 1 line
2.37.2
PATCH v3 8/9 arm64: dts: qcom: ipq8074: correct APCS register space size
In reply to Robert MarkoAPCS DTS addition that was merged, was not supposed to get merged as it was part of patch series that was superseded by 2 more patch series that resolved issues with this one and greatly simplified things.
Since it already got merged, start by correcting the register space size as APCS will not be providing regmap for PLL and it will conflict with the standalone A53 PLL node.
--- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/ipq8074.dtsi +1 -1
@@ -703,7 +703,7 @@ watchdog: watchdog@b017000 { apcs_glb: mailbox@b111000 { compatible = "qcom,ipq8074-apcs-apps-global"; - reg = <0x0b111000 0x6000>; + reg = <0x0b111000 0x1000>; #clock-cells = <1>; #mbox-cells = <1>;
Signature · 1 line
2.37.2
PATCH v3 9/9 arm64: dts: qcom: ipq8074: add A53 PLL node
In reply to Robert MarkoAdd the required node for A53 PLL which will be used to provide the CPU clock via APCS for APSS scaling.
--- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm64/boot/dts/qcom/ipq8074.dtsi +8 -0
@@ -709,6 +709,14 @@ apcs_glb: mailbox@b111000 { #mbox-cells = <1>; }; + a53pll: clock@b116000 { + compatible = "qcom,ipq8074-a53pll"; + reg = <0x0b116000 0x40>; + #clock-cells = <0>; + clocks = <&xo>; + clock-names = "xo"; + }; + timer@b120000 { #address-cells = <1>; #size-cells = <1>;
Signature · 1 line
2.37.2
Re: (subset) [PATCH v3 1/9] clk: qcom: clk-rcg2: add rcg2 mux ops
In reply to Robert MarkoQuoted 10 lines · Robert Marko
From: Christian Marangi <[email protected]>
An RCG may act as a mux that switch between 2 parents.
This is the case on IPQ6018 and IPQ8074 where the APCS core clk that feeds the CPU cluster clock just switches between XO and the PLL that feeds it.Add the required ops to add support for this special configuration and use the generic mux function to determine the rate.
[...]
Applied, thanks!
[9/9] arm64: dts: qcom: ipq8074: add A53 PLL node
commit: fe6d5b8de04780e7ec27037b836324b59fade45b
Best regards,
Signature · 1 line
Bjorn Andersson <[email protected]>