* [PATCH v2 0/3] MSM8996 Coherent Bus Fabric clock support
@ 2022-05-10 15:57 Yassine Oudjana
2022-05-10 15:58 ` [PATCH v2 1/3] dt-bindings: clk: qcom: msm8996-apcc: Add CBF Yassine Oudjana
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Yassine Oudjana @ 2022-05-10 15:57 UTC (permalink / raw)
To: Andy Gross, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Loic Poulain
Cc: Yassine Oudjana, Konrad Dybcio, AngeloGioacchino Del Regno,
Martin Botka, Marijn Suijten, Jami Kettunen, linux-arm-msm,
linux-clk, devicetree, linux-kernel, ~postmarketos/upstreaming
From: Yassine Oudjana <yassine.oudjana@gmail.com>
This series adds support for the CBF clock found on MSM8996 and sets it to
a high enough frequency to fix some devices not being able to boot with all
4 cores enabled.
(I'm picking this up and adding DT bindings following a discussion on
another series[1] since Konrad is fine with it.)
Changes since v1:
- Update DT bindings with the CBF clock and reg.
[1] https://lore.kernel.org/linux-arm-msm/aa54cc23-e479-688c-6a3c-b9c73babd9b4@linaro.org/
Konrad Dybcio (2):
clk: qcom: msm8996-cpu: Add CBF support
arm64: dts: qcom: msm8996: Add support for the CBF clock
Yassine Oudjana (1):
dt-bindings: clk: qcom: msm8996-apcc: Add CBF
.../bindings/clock/qcom,msm8996-apcc.yaml | 10 +-
arch/arm64/boot/dts/qcom/msm8996.dtsi | 5 +-
drivers/clk/qcom/clk-cpu-8996.c | 162 +++++++++++++++++-
3 files changed, 169 insertions(+), 8 deletions(-)
--
2.36.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/3] dt-bindings: clk: qcom: msm8996-apcc: Add CBF
2022-05-10 15:57 [PATCH v2 0/3] MSM8996 Coherent Bus Fabric clock support Yassine Oudjana
@ 2022-05-10 15:58 ` Yassine Oudjana
2022-05-10 15:59 ` [PATCH v2 2/3] clk: qcom: msm8996-cpu: Add CBF support Yassine Oudjana
2022-05-10 16:02 ` [PATCH v2 3/3] arm64: dts: qcom: msm8996: Add support for the CBF clock Yassine Oudjana
2 siblings, 0 replies; 5+ messages in thread
From: Yassine Oudjana @ 2022-05-10 15:58 UTC (permalink / raw)
To: Andy Gross, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Loic Poulain
Cc: Yassine Oudjana, Konrad Dybcio, AngeloGioacchino Del Regno,
Martin Botka, Marijn Suijten, Jami Kettunen, linux-arm-msm,
linux-clk, devicetree, linux-kernel, ~postmarketos/upstreaming,
Rob Herring
From: Yassine Oudjana <yassine.oudjana@gmail.com>
Add CBF clock and reg. This breaks the ABI and requires existing
device trees to be updated, which will be done in a later patch.
Signed-off-by: Yassine Oudjana <yassine.oudjana@gmail.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/clock/qcom,msm8996-apcc.yaml | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml b/Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml
index a20cb10636dd..325f8aef53b2 100644
--- a/Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,msm8996-apcc.yaml
@@ -10,8 +10,8 @@ maintainers:
- Loic Poulain <loic.poulain@linaro.org>
description: |
- Qualcomm CPU clock controller for MSM8996 CPUs, clock 0 is for Power cluster
- and clock 1 is for Perf cluster.
+ Qualcomm CPU clock controller for MSM8996 CPUs, clock 0 is for Power cluster,
+ clock 1 is for Perf cluster, and clock 2 is for Coherent bus fabric (CBF).
properties:
compatible:
@@ -19,7 +19,9 @@ properties:
- qcom,msm8996-apcc
reg:
- maxItems: 1
+ items:
+ - description: Cluster clock registers
+ - description: CBF clock registers
'#clock-cells':
const: 1
@@ -49,6 +51,6 @@ examples:
- |
kryocc: clock-controller@6400000 {
compatible = "qcom,msm8996-apcc";
- reg = <0x6400000 0x90000>;
+ reg = <0x6400000 0x90000>, <0x09a11000 0x10000>;
#clock-cells = <1>;
};
--
2.36.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] clk: qcom: msm8996-cpu: Add CBF support
2022-05-10 15:57 [PATCH v2 0/3] MSM8996 Coherent Bus Fabric clock support Yassine Oudjana
2022-05-10 15:58 ` [PATCH v2 1/3] dt-bindings: clk: qcom: msm8996-apcc: Add CBF Yassine Oudjana
@ 2022-05-10 15:59 ` Yassine Oudjana
2022-05-11 10:17 ` Dmitry Baryshkov
2022-05-10 16:02 ` [PATCH v2 3/3] arm64: dts: qcom: msm8996: Add support for the CBF clock Yassine Oudjana
2 siblings, 1 reply; 5+ messages in thread
From: Yassine Oudjana @ 2022-05-10 15:59 UTC (permalink / raw)
To: Andy Gross, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Loic Poulain
Cc: Konrad Dybcio, AngeloGioacchino Del Regno, Martin Botka,
Marijn Suijten, Jami Kettunen, linux-arm-msm, linux-clk,
devicetree, linux-kernel, ~postmarketos/upstreaming,
Yassine Oudjana
From: Konrad Dybcio <konrad.dybcio@somainline.org>
Add the required code to support the CBF clock, which is responsible for
core cluster interconnect frequency on msm8996.
Somewhat based on AngeloGioacchino del Regno's work at:
https://github.com/sonyxperiadev/kernel/blob/aosp/LE.UM.2.3.2.r1.4/drivers/clk/qcom/clk-cpu-8996.c
This fixes the issue with booting with all 4 cores enabled.
Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
Signed-off-by: Yassine Oudjana <yassine.oudjana@gmail.com>
---
drivers/clk/qcom/clk-cpu-8996.c | 162 +++++++++++++++++++++++++++++++-
1 file changed, 159 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
index 4a4fde8dd12d..8afc271f92d0 100644
--- a/drivers/clk/qcom/clk-cpu-8996.c
+++ b/drivers/clk/qcom/clk-cpu-8996.c
@@ -68,10 +68,19 @@ enum _pmux_input {
NUM_OF_PMUX_INPUTS
};
+enum {
+ CBF_PLL_INDEX = 1,
+ CBF_DIV_2_INDEX,
+ CBF_SAFE_INDEX
+};
+
#define DIV_2_THRESHOLD 600000000
#define PWRCL_REG_OFFSET 0x0
#define PERFCL_REG_OFFSET 0x80000
#define MUX_OFFSET 0x40
+#define CBF_REG_OFFSET 0x0
+#define CBF_PLL_OFFSET 0xf000
+#define CBF_MUX_OFFSET 0x18
#define ALT_PLL_OFFSET 0x100
#define SSSCTL_OFFSET 0x160
@@ -98,6 +107,17 @@ static const u8 alt_pll_regs[PLL_OFF_MAX_REGS] = {
[PLL_OFF_STATUS] = 0x28,
};
+static const u8 cbf_pll_regs[PLL_OFF_MAX_REGS] = {
+ [PLL_OFF_L_VAL] = 0x08,
+ [PLL_OFF_ALPHA_VAL] = 0x10,
+ [PLL_OFF_USER_CTL] = 0x18,
+ [PLL_OFF_CONFIG_CTL] = 0x20,
+ [PLL_OFF_CONFIG_CTL_U] = 0x24,
+ [PLL_OFF_TEST_CTL] = 0x30,
+ [PLL_OFF_TEST_CTL_U] = 0x34,
+ [PLL_OFF_STATUS] = 0x28,
+};
+
/* PLLs */
static const struct alpha_pll_config hfpll_config = {
@@ -111,6 +131,17 @@ static const struct alpha_pll_config hfpll_config = {
.early_output_mask = BIT(3),
};
+static const struct alpha_pll_config cbfpll_config = {
+ .l = 72,
+ .config_ctl_val = 0x200d4aa8,
+ .config_ctl_hi_val = 0x006,
+ .pre_div_mask = BIT(12),
+ .post_div_mask = 0x3 << 8,
+ .post_div_val = 0x1 << 8,
+ .main_output_mask = BIT(0),
+ .early_output_mask = BIT(3),
+};
+
static struct clk_alpha_pll perfcl_pll = {
.offset = PERFCL_REG_OFFSET,
.regs = prim_pll_regs,
@@ -135,6 +166,18 @@ static struct clk_alpha_pll pwrcl_pll = {
},
};
+static struct clk_alpha_pll cbf_pll = {
+ .offset = CBF_PLL_OFFSET,
+ .regs = cbf_pll_regs,
+ .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "cbf_pll",
+ .parent_names = (const char *[]){ "xo" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+};
+
static const struct pll_vco alt_pll_vco_modes[] = {
VCO(3, 250000000, 500000000),
VCO(2, 500000000, 750000000),
@@ -194,6 +237,9 @@ struct clk_cpu_8996_mux {
static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
void *data);
+static int cbf_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+ void *data);
+
#define to_clk_cpu_8996_mux_nb(_nb) \
container_of(_nb, struct clk_cpu_8996_mux, nb)
@@ -329,6 +375,35 @@ static struct clk_cpu_8996_mux perfcl_pmux = {
},
};
+static struct clk_cpu_8996_mux cbf_mux = {
+ .reg = CBF_REG_OFFSET + CBF_MUX_OFFSET,
+ .shift = 0,
+ .width = 2,
+ .pll = &cbf_pll.clkr.hw,
+ .nb.notifier_call = cbf_clk_notifier_cb,
+ .clkr.hw.init = &(struct clk_init_data) {
+ .name = "cbf_mux",
+ .parent_names = (const char *[]){
+ "xo",
+ "cbf_pll",
+ "cbf_pll_main",
+ },
+ .num_parents = 3,
+ .ops = &clk_cpu_8996_mux_ops,
+ /* CPU clock is critical and should never be gated */
+ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+ },
+};
+
+static const struct regmap_config cbf_msm8996_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x10000,
+ .fast_io = true,
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
static const struct regmap_config cpu_msm8996_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -397,6 +472,35 @@ static int qcom_cpu_clk_msm8996_register_clks(struct device *dev,
return ret;
}
+static struct clk_regmap *cbf_msm8996_clks[] = {
+ &cbf_pll.clkr,
+ &cbf_mux.clkr,
+};
+
+static int qcom_cbf_clk_msm8996_register_clks(struct device *dev,
+ struct regmap *regmap)
+{
+ int ret;
+
+ cbf_mux.pll_div_2 = clk_hw_register_fixed_factor(dev, "cbf_pll_main",
+ "cbf_pll", CLK_SET_RATE_PARENT,
+ 1, 2);
+ if (IS_ERR(cbf_mux.pll_div_2)) {
+ dev_err(dev, "Failed to initialize cbf_pll_main\n");
+ return PTR_ERR(cbf_mux.pll_div_2);
+ }
+
+ ret = devm_clk_register_regmap(dev, cbf_msm8996_clks[0]);
+ ret = devm_clk_register_regmap(dev, cbf_msm8996_clks[1]);
+
+ clk_alpha_pll_configure(&cbf_pll, regmap, &cbfpll_config);
+ clk_set_rate(cbf_pll.clkr.hw.clk, 614400000);
+ clk_prepare_enable(cbf_pll.clkr.hw.clk);
+ clk_notifier_register(cbf_mux.clkr.hw.clk, &cbf_mux.nb);
+
+ return ret;
+}
+
static int qcom_cpu_clk_msm8996_unregister_clks(void)
{
int ret = 0;
@@ -409,8 +513,13 @@ static int qcom_cpu_clk_msm8996_unregister_clks(void)
if (ret)
return ret;
+ ret = clk_notifier_unregister(cbf_mux.clkr.hw.clk, &cbf_mux.nb);
+ if (ret)
+ return ret;
+
clk_hw_unregister(perfcl_smux.pll);
clk_hw_unregister(pwrcl_smux.pll);
+ clk_hw_unregister(cbf_mux.pll);
return 0;
}
@@ -481,14 +590,48 @@ static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
return notifier_from_errno(ret);
};
+static int cbf_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ struct clk_cpu_8996_mux *cbfclk = to_clk_cpu_8996_mux_nb(nb);
+ struct clk_notifier_data *cnd = data;
+ struct clk_hw *parent;
+ int ret;
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ parent = clk_hw_get_parent_by_index(&cbfclk->clkr.hw, CBF_DIV_2_INDEX);
+ ret = clk_cpu_8996_mux_set_parent(&cbfclk->clkr.hw, CBF_DIV_2_INDEX);
+
+ if (cnd->old_rate > DIV_2_THRESHOLD && cnd->new_rate < DIV_2_THRESHOLD)
+ ret = clk_set_rate(parent->clk, cnd->old_rate / 2);
+ break;
+ case POST_RATE_CHANGE:
+ if (cnd->new_rate < DIV_2_THRESHOLD)
+ ret = clk_cpu_8996_mux_set_parent(&cbfclk->clkr.hw, CBF_DIV_2_INDEX);
+ else {
+ parent = clk_hw_get_parent_by_index(&cbfclk->clkr.hw, CBF_PLL_INDEX);
+ ret = clk_set_rate(parent->clk, cnd->new_rate);
+ ret = clk_cpu_8996_mux_set_parent(&cbfclk->clkr.hw, CBF_PLL_INDEX);
+ }
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return notifier_from_errno(ret);
+};
+
static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
{
- struct regmap *regmap;
+ struct regmap *regmap, *regmap_cbf;
struct clk_hw_onecell_data *data;
struct device *dev = &pdev->dev;
+ static void __iomem *cbf_base;
int ret;
- data = devm_kzalloc(dev, struct_size(data, hws, 2), GFP_KERNEL);
+ data = devm_kzalloc(dev, struct_size(data, hws, 3), GFP_KERNEL);
if (!data)
return -ENOMEM;
@@ -506,9 +649,22 @@ static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
qcom_cpu_clk_msm8996_acd_init(base);
+ cbf_base = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(cbf_base))
+ return PTR_ERR(cbf_base);
+
+ regmap_cbf = devm_regmap_init_mmio(dev, cbf_base, &cbf_msm8996_regmap_config);
+ if (IS_ERR(regmap_cbf))
+ return PTR_ERR(regmap_cbf);
+
+ ret = qcom_cbf_clk_msm8996_register_clks(dev, regmap_cbf);
+ if (ret)
+ return ret;
+
data->hws[0] = &pwrcl_pmux.clkr.hw;
data->hws[1] = &perfcl_pmux.clkr.hw;
- data->num = 2;
+ data->hws[2] = &cbf_mux.clkr.hw;
+ data->num = 3;
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data);
}
--
2.36.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] arm64: dts: qcom: msm8996: Add support for the CBF clock
2022-05-10 15:57 [PATCH v2 0/3] MSM8996 Coherent Bus Fabric clock support Yassine Oudjana
2022-05-10 15:58 ` [PATCH v2 1/3] dt-bindings: clk: qcom: msm8996-apcc: Add CBF Yassine Oudjana
2022-05-10 15:59 ` [PATCH v2 2/3] clk: qcom: msm8996-cpu: Add CBF support Yassine Oudjana
@ 2022-05-10 16:02 ` Yassine Oudjana
2 siblings, 0 replies; 5+ messages in thread
From: Yassine Oudjana @ 2022-05-10 16:02 UTC (permalink / raw)
To: Andy Gross, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Loic Poulain
Cc: Konrad Dybcio, AngeloGioacchino Del Regno, Martin Botka,
Marijn Suijten, Jami Kettunen, linux-arm-msm, linux-clk,
devicetree, linux-kernel, ~postmarketos/upstreaming,
Yassine Oudjana
From: Konrad Dybcio <konrad.dybcio@somainline.org>
Add the CBF PLL register to the kryocc node and assign a frequency
to the clock.
This makes sure the core cluster interconnect is running at a decent
speed, so that it's no longer a pain to use the device with all cores
enabled.
Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
Signed-off-by: Yassine Oudjana <yassine.oudjana@gmail.com>
---
arch/arm64/boot/dts/qcom/msm8996.dtsi | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 205af7b479a8..51ae3cbe75d3 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -2698,7 +2698,10 @@ apss_merge_funnel_out: endpoint {
kryocc: clock-controller@6400000 {
compatible = "qcom,msm8996-apcc";
- reg = <0x06400000 0x90000>;
+ reg = <0x06400000 0x90000>, <0x09a11000 0x10000>;
+
+ assigned-clocks = <&kryocc 2>;
+ assigned-clock-rates = <1382400000>;
clock-names = "xo";
clocks = <&rpmcc RPM_SMD_BB_CLK1>;
--
2.36.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/3] clk: qcom: msm8996-cpu: Add CBF support
2022-05-10 15:59 ` [PATCH v2 2/3] clk: qcom: msm8996-cpu: Add CBF support Yassine Oudjana
@ 2022-05-11 10:17 ` Dmitry Baryshkov
0 siblings, 0 replies; 5+ messages in thread
From: Dmitry Baryshkov @ 2022-05-11 10:17 UTC (permalink / raw)
To: Yassine Oudjana
Cc: Andy Gross, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Loic Poulain, Konrad Dybcio,
AngeloGioacchino Del Regno, Martin Botka, Marijn Suijten,
Jami Kettunen, linux-arm-msm, linux-clk, devicetree,
linux-kernel, ~postmarketos/upstreaming
Hi,
On Tue, 10 May 2022 at 19:05, Yassine Oudjana <yassine.oudjana@gmail.com> wrote:
>
> From: Konrad Dybcio <konrad.dybcio@somainline.org>
>
> Add the required code to support the CBF clock, which is responsible for
> core cluster interconnect frequency on msm8996.
>
> Somewhat based on AngeloGioacchino del Regno's work at:
> https://github.com/sonyxperiadev/kernel/blob/aosp/LE.UM.2.3.2.r1.4/drivers/clk/qcom/clk-cpu-8996.c
>
> This fixes the issue with booting with all 4 cores enabled.
>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
> Signed-off-by: Yassine Oudjana <yassine.oudjana@gmail.com>
> ---
> drivers/clk/qcom/clk-cpu-8996.c | 162 +++++++++++++++++++++++++++++++-
> 1 file changed, 159 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/qcom/clk-cpu-8996.c b/drivers/clk/qcom/clk-cpu-8996.c
> index 4a4fde8dd12d..8afc271f92d0 100644
> --- a/drivers/clk/qcom/clk-cpu-8996.c
> +++ b/drivers/clk/qcom/clk-cpu-8996.c
> @@ -68,10 +68,19 @@ enum _pmux_input {
> NUM_OF_PMUX_INPUTS
> };
>
> +enum {
> + CBF_PLL_INDEX = 1,
> + CBF_DIV_2_INDEX,
> + CBF_SAFE_INDEX
> +};
> +
> #define DIV_2_THRESHOLD 600000000
> #define PWRCL_REG_OFFSET 0x0
> #define PERFCL_REG_OFFSET 0x80000
> #define MUX_OFFSET 0x40
> +#define CBF_REG_OFFSET 0x0
> +#define CBF_PLL_OFFSET 0xf000
> +#define CBF_MUX_OFFSET 0x18
> #define ALT_PLL_OFFSET 0x100
> #define SSSCTL_OFFSET 0x160
>
> @@ -98,6 +107,17 @@ static const u8 alt_pll_regs[PLL_OFF_MAX_REGS] = {
> [PLL_OFF_STATUS] = 0x28,
> };
>
> +static const u8 cbf_pll_regs[PLL_OFF_MAX_REGS] = {
> + [PLL_OFF_L_VAL] = 0x08,
> + [PLL_OFF_ALPHA_VAL] = 0x10,
> + [PLL_OFF_USER_CTL] = 0x18,
> + [PLL_OFF_CONFIG_CTL] = 0x20,
> + [PLL_OFF_CONFIG_CTL_U] = 0x24,
> + [PLL_OFF_TEST_CTL] = 0x30,
> + [PLL_OFF_TEST_CTL_U] = 0x34,
> + [PLL_OFF_STATUS] = 0x28,
> +};
> +
> /* PLLs */
>
> static const struct alpha_pll_config hfpll_config = {
> @@ -111,6 +131,17 @@ static const struct alpha_pll_config hfpll_config = {
> .early_output_mask = BIT(3),
> };
>
> +static const struct alpha_pll_config cbfpll_config = {
> + .l = 72,
> + .config_ctl_val = 0x200d4aa8,
> + .config_ctl_hi_val = 0x006,
> + .pre_div_mask = BIT(12),
> + .post_div_mask = 0x3 << 8,
> + .post_div_val = 0x1 << 8,
> + .main_output_mask = BIT(0),
> + .early_output_mask = BIT(3),
> +};
> +
> static struct clk_alpha_pll perfcl_pll = {
> .offset = PERFCL_REG_OFFSET,
> .regs = prim_pll_regs,
> @@ -135,6 +166,18 @@ static struct clk_alpha_pll pwrcl_pll = {
> },
> };
>
> +static struct clk_alpha_pll cbf_pll = {
> + .offset = CBF_PLL_OFFSET,
> + .regs = cbf_pll_regs,
> + .flags = SUPPORTS_DYNAMIC_UPDATE | SUPPORTS_FSM_MODE,
> + .clkr.hw.init = &(struct clk_init_data){
> + .name = "cbf_pll",
> + .parent_names = (const char *[]){ "xo" },
> + .num_parents = 1,
> + .ops = &clk_alpha_pll_huayra_ops,
> + },
> +};
> +
> static const struct pll_vco alt_pll_vco_modes[] = {
> VCO(3, 250000000, 500000000),
> VCO(2, 500000000, 750000000),
> @@ -194,6 +237,9 @@ struct clk_cpu_8996_mux {
> static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
> void *data);
>
> +static int cbf_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
> + void *data);
> +
> #define to_clk_cpu_8996_mux_nb(_nb) \
> container_of(_nb, struct clk_cpu_8996_mux, nb)
>
> @@ -329,6 +375,35 @@ static struct clk_cpu_8996_mux perfcl_pmux = {
> },
> };
>
> +static struct clk_cpu_8996_mux cbf_mux = {
> + .reg = CBF_REG_OFFSET + CBF_MUX_OFFSET,
> + .shift = 0,
> + .width = 2,
> + .pll = &cbf_pll.clkr.hw,
> + .nb.notifier_call = cbf_clk_notifier_cb,
> + .clkr.hw.init = &(struct clk_init_data) {
> + .name = "cbf_mux",
> + .parent_names = (const char *[]){
> + "xo",
> + "cbf_pll",
> + "cbf_pll_main",
> + },
parent_data please.
> + .num_parents = 3,
> + .ops = &clk_cpu_8996_mux_ops,
> + /* CPU clock is critical and should never be gated */
> + .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
> + },
> +};
> +
> +static const struct regmap_config cbf_msm8996_regmap_config = {
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .max_register = 0x10000,
> + .fast_io = true,
> + .val_format_endian = REGMAP_ENDIAN_LITTLE,
> +};
> +
> static const struct regmap_config cpu_msm8996_regmap_config = {
> .reg_bits = 32,
> .reg_stride = 4,
> @@ -397,6 +472,35 @@ static int qcom_cpu_clk_msm8996_register_clks(struct device *dev,
> return ret;
> }
>
> +static struct clk_regmap *cbf_msm8996_clks[] = {
> + &cbf_pll.clkr,
> + &cbf_mux.clkr,
> +};
> +
> +static int qcom_cbf_clk_msm8996_register_clks(struct device *dev,
> + struct regmap *regmap)
> +{
> + int ret;
> +
> + cbf_mux.pll_div_2 = clk_hw_register_fixed_factor(dev, "cbf_pll_main",
> + "cbf_pll", CLK_SET_RATE_PARENT,
> + 1, 2);
> + if (IS_ERR(cbf_mux.pll_div_2)) {
> + dev_err(dev, "Failed to initialize cbf_pll_main\n");
> + return PTR_ERR(cbf_mux.pll_div_2);
> + }
> +
> + ret = devm_clk_register_regmap(dev, cbf_msm8996_clks[0]);
> + ret = devm_clk_register_regmap(dev, cbf_msm8996_clks[1]);
> +
> + clk_alpha_pll_configure(&cbf_pll, regmap, &cbfpll_config);
> + clk_set_rate(cbf_pll.clkr.hw.clk, 614400000);
> + clk_prepare_enable(cbf_pll.clkr.hw.clk);
> + clk_notifier_register(cbf_mux.clkr.hw.clk, &cbf_mux.nb);
> +
> + return ret;
> +}
> +
> static int qcom_cpu_clk_msm8996_unregister_clks(void)
> {
> int ret = 0;
> @@ -409,8 +513,13 @@ static int qcom_cpu_clk_msm8996_unregister_clks(void)
> if (ret)
> return ret;
>
> + ret = clk_notifier_unregister(cbf_mux.clkr.hw.clk, &cbf_mux.nb);
> + if (ret)
> + return ret;
> +
> clk_hw_unregister(perfcl_smux.pll);
> clk_hw_unregister(pwrcl_smux.pll);
> + clk_hw_unregister(cbf_mux.pll);
>
> return 0;
> }
> @@ -481,14 +590,48 @@ static int cpu_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
> return notifier_from_errno(ret);
> };
>
> +static int cbf_clk_notifier_cb(struct notifier_block *nb, unsigned long event,
> + void *data)
> +{
> + struct clk_cpu_8996_mux *cbfclk = to_clk_cpu_8996_mux_nb(nb);
> + struct clk_notifier_data *cnd = data;
> + struct clk_hw *parent;
> + int ret;
> +
> + switch (event) {
> + case PRE_RATE_CHANGE:
> + parent = clk_hw_get_parent_by_index(&cbfclk->clkr.hw, CBF_DIV_2_INDEX);
> + ret = clk_cpu_8996_mux_set_parent(&cbfclk->clkr.hw, CBF_DIV_2_INDEX);
> +
> + if (cnd->old_rate > DIV_2_THRESHOLD && cnd->new_rate < DIV_2_THRESHOLD)
> + ret = clk_set_rate(parent->clk, cnd->old_rate / 2);
> + break;
> + case POST_RATE_CHANGE:
> + if (cnd->new_rate < DIV_2_THRESHOLD)
> + ret = clk_cpu_8996_mux_set_parent(&cbfclk->clkr.hw, CBF_DIV_2_INDEX);
> + else {
> + parent = clk_hw_get_parent_by_index(&cbfclk->clkr.hw, CBF_PLL_INDEX);
> + ret = clk_set_rate(parent->clk, cnd->new_rate);
> + ret = clk_cpu_8996_mux_set_parent(&cbfclk->clkr.hw, CBF_PLL_INDEX);
> + }
> + break;
> + default:
> + ret = 0;
> + break;
> + }
> +
> + return notifier_from_errno(ret);
> +};
> +
> static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
> {
> - struct regmap *regmap;
> + struct regmap *regmap, *regmap_cbf;
> struct clk_hw_onecell_data *data;
> struct device *dev = &pdev->dev;
> + static void __iomem *cbf_base;
> int ret;
>
> - data = devm_kzalloc(dev, struct_size(data, hws, 2), GFP_KERNEL);
> + data = devm_kzalloc(dev, struct_size(data, hws, 3), GFP_KERNEL);
> if (!data)
> return -ENOMEM;
>
> @@ -506,9 +649,22 @@ static int qcom_cpu_clk_msm8996_driver_probe(struct platform_device *pdev)
>
> qcom_cpu_clk_msm8996_acd_init(base);
>
> + cbf_base = devm_platform_ioremap_resource(pdev, 1);
> + if (IS_ERR(cbf_base))
> + return PTR_ERR(cbf_base);
So, if the reg1 is not provided, thr driver will error out, breaking
the compatibility with existing dts files.
I'd suggest making reg1 optional (you can add a warning printk
demanding the dts to be updated).
> + regmap_cbf = devm_regmap_init_mmio(dev, cbf_base, &cbf_msm8996_regmap_config);
> + if (IS_ERR(regmap_cbf))
> + return PTR_ERR(regmap_cbf);
> +
> + ret = qcom_cbf_clk_msm8996_register_clks(dev, regmap_cbf);
> + if (ret)
> + return ret;
> +
> data->hws[0] = &pwrcl_pmux.clkr.hw;
> data->hws[1] = &perfcl_pmux.clkr.hw;
> - data->num = 2;
> + data->hws[2] = &cbf_mux.clkr.hw;
> + data->num = 3;
>
> return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, data);
> }
> --
> 2.36.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-05-11 10:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-10 15:57 [PATCH v2 0/3] MSM8996 Coherent Bus Fabric clock support Yassine Oudjana
2022-05-10 15:58 ` [PATCH v2 1/3] dt-bindings: clk: qcom: msm8996-apcc: Add CBF Yassine Oudjana
2022-05-10 15:59 ` [PATCH v2 2/3] clk: qcom: msm8996-cpu: Add CBF support Yassine Oudjana
2022-05-11 10:17 ` Dmitry Baryshkov
2022-05-10 16:02 ` [PATCH v2 3/3] arm64: dts: qcom: msm8996: Add support for the CBF clock Yassine Oudjana
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).