All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.