linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC
@ 2020-09-15  7:24 Manivannan Sadhasivam
  2020-09-15  7:24 ` [PATCH v2 1/5] dt-bindings: cpufreq: cpufreq-qcom-hw: Document Qcom EPSS compatible Manivannan Sadhasivam
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Manivannan Sadhasivam @ 2020-09-15  7:24 UTC (permalink / raw)
  To: rjw, viresh.kumar, robh+dt, agross, bjorn.andersson
  Cc: amitk, linux-pm, devicetree, linux-kernel, linux-arm-msm,
	dmitry.baryshkov, tdas, Manivannan Sadhasivam

Hello,

This series adds CPUFreq support for Qualcomm SM8250 SoC. The existing
qcom-hw driver is reworked to support the EPSS block on this SoC which
handles the CPUFreq duties.

The EPSS block supports additional features for which incremental patches
will be submitted on top of this series!

Thanks,
Mani

Changes in v2:

* Dropped the regmap conversion patch
* Used "qcom,cpufreq-epss" compatible and "epss_soc_data" for dev data
* Switched to "of_device_get_match_data" API
* Collected reviews from Amit, Viresh and Bjorn
* Dropped patch [3/7] which got applied by Viresh

Bjorn Andersson (1):
  arm64: dts: qcom: sm8250: Add cpufreq hw node

Manivannan Sadhasivam (4):
  dt-bindings: cpufreq: cpufreq-qcom-hw: Document Qcom EPSS compatible
  cpufreq: qcom-hw: Use devm_platform_ioremap_resource() to simplify
    code
  cpufreq: qcom-hw: Use of_device_get_match_data for offsets and row
    size
  cpufreq: qcom-hw: Add cpufreq support for SM8250 SoC

 .../bindings/cpufreq/cpufreq-qcom-hw.txt      |   2 +-
 arch/arm64/boot/dts/qcom/sm8250.dtsi          |  22 ++++
 drivers/cpufreq/qcom-cpufreq-hw.c             | 107 ++++++++++++------
 3 files changed, 93 insertions(+), 38 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/5] dt-bindings: cpufreq: cpufreq-qcom-hw: Document Qcom EPSS compatible
  2020-09-15  7:24 [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC Manivannan Sadhasivam
@ 2020-09-15  7:24 ` Manivannan Sadhasivam
  2020-09-15  7:24 ` [PATCH v2 2/5] arm64: dts: qcom: sm8250: Add cpufreq hw node Manivannan Sadhasivam
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Manivannan Sadhasivam @ 2020-09-15  7:24 UTC (permalink / raw)
  To: rjw, viresh.kumar, robh+dt, agross, bjorn.andersson
  Cc: amitk, linux-pm, devicetree, linux-kernel, linux-arm-msm,
	dmitry.baryshkov, tdas, Manivannan Sadhasivam

The hardware block which carries out CPUFreq operations on SM8250 SoC is
called EPSS. Hence, document the compatible.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Amit Kucheria <amitk@kernel.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
 Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
index 33856947c561..9299028ee712 100644
--- a/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-qcom-hw.txt
@@ -8,7 +8,7 @@ Properties:
 - compatible
 	Usage:		required
 	Value type:	<string>
-	Definition:	must be "qcom,cpufreq-hw".
+	Definition:	must be "qcom,cpufreq-hw" or "qcom,cpufreq-epss".
 
 - clocks
 	Usage:		required
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/5] arm64: dts: qcom: sm8250: Add cpufreq hw node
  2020-09-15  7:24 [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC Manivannan Sadhasivam
  2020-09-15  7:24 ` [PATCH v2 1/5] dt-bindings: cpufreq: cpufreq-qcom-hw: Document Qcom EPSS compatible Manivannan Sadhasivam
@ 2020-09-15  7:24 ` Manivannan Sadhasivam
  2020-09-15  7:24 ` [PATCH v2 3/5] cpufreq: qcom-hw: Use devm_platform_ioremap_resource() to simplify code Manivannan Sadhasivam
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Manivannan Sadhasivam @ 2020-09-15  7:24 UTC (permalink / raw)
  To: rjw, viresh.kumar, robh+dt, agross, bjorn.andersson
  Cc: amitk, linux-pm, devicetree, linux-kernel, linux-arm-msm,
	dmitry.baryshkov, tdas, Manivannan Sadhasivam

From: Bjorn Andersson <bjorn.andersson@linaro.org>

Add cpufreq HW device node to scale 4-Silver/3-Gold/1-Gold+ cores
on SM8250 SoCs.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Amit Kucheria <amitk@kernel.org>
---
 arch/arm64/boot/dts/qcom/sm8250.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index e7d139e1a6ce..7eb0eda37b26 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -87,6 +87,7 @@
 			reg = <0x0 0x0>;
 			enable-method = "psci";
 			next-level-cache = <&L2_0>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
 			L2_0: l2-cache {
 			      compatible = "cache";
 			      next-level-cache = <&L3_0>;
@@ -102,6 +103,7 @@
 			reg = <0x0 0x100>;
 			enable-method = "psci";
 			next-level-cache = <&L2_100>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
 			L2_100: l2-cache {
 			      compatible = "cache";
 			      next-level-cache = <&L3_0>;
@@ -114,6 +116,7 @@
 			reg = <0x0 0x200>;
 			enable-method = "psci";
 			next-level-cache = <&L2_200>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
 			L2_200: l2-cache {
 			      compatible = "cache";
 			      next-level-cache = <&L3_0>;
@@ -126,6 +129,7 @@
 			reg = <0x0 0x300>;
 			enable-method = "psci";
 			next-level-cache = <&L2_300>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
 			L2_300: l2-cache {
 			      compatible = "cache";
 			      next-level-cache = <&L3_0>;
@@ -138,6 +142,7 @@
 			reg = <0x0 0x400>;
 			enable-method = "psci";
 			next-level-cache = <&L2_400>;
+			qcom,freq-domain = <&cpufreq_hw 1>;
 			L2_400: l2-cache {
 			      compatible = "cache";
 			      next-level-cache = <&L3_0>;
@@ -150,6 +155,7 @@
 			reg = <0x0 0x500>;
 			enable-method = "psci";
 			next-level-cache = <&L2_500>;
+			qcom,freq-domain = <&cpufreq_hw 1>;
 			L2_500: l2-cache {
 			      compatible = "cache";
 			      next-level-cache = <&L3_0>;
@@ -163,6 +169,7 @@
 			reg = <0x0 0x600>;
 			enable-method = "psci";
 			next-level-cache = <&L2_600>;
+			qcom,freq-domain = <&cpufreq_hw 1>;
 			L2_600: l2-cache {
 			      compatible = "cache";
 			      next-level-cache = <&L3_0>;
@@ -175,6 +182,7 @@
 			reg = <0x0 0x700>;
 			enable-method = "psci";
 			next-level-cache = <&L2_700>;
+			qcom,freq-domain = <&cpufreq_hw 2>;
 			L2_700: l2-cache {
 			      compatible = "cache";
 			      next-level-cache = <&L3_0>;
@@ -2076,6 +2084,20 @@
 				};
 			};
 		};
+
+		cpufreq_hw: cpufreq@18591000 {
+			compatible = "qcom,sm8250-cpufreq-epss", "qcom,cpufreq-epss";
+			reg = <0 0x18591000 0 0x1000>,
+			      <0 0x18592000 0 0x1000>,
+			      <0 0x18593000 0 0x1000>;
+			reg-names = "freq-domain0", "freq-domain1",
+				    "freq-domain2";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>;
+			clock-names = "xo", "alternate";
+
+			#freq-domain-cells = <1>;
+		};
 	};
 
 	timer {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/5] cpufreq: qcom-hw: Use devm_platform_ioremap_resource() to simplify code
  2020-09-15  7:24 [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC Manivannan Sadhasivam
  2020-09-15  7:24 ` [PATCH v2 1/5] dt-bindings: cpufreq: cpufreq-qcom-hw: Document Qcom EPSS compatible Manivannan Sadhasivam
  2020-09-15  7:24 ` [PATCH v2 2/5] arm64: dts: qcom: sm8250: Add cpufreq hw node Manivannan Sadhasivam
@ 2020-09-15  7:24 ` Manivannan Sadhasivam
  2020-09-15  7:24 ` [PATCH v2 4/5] cpufreq: qcom-hw: Use of_device_get_match_data for offsets and row size Manivannan Sadhasivam
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Manivannan Sadhasivam @ 2020-09-15  7:24 UTC (permalink / raw)
  To: rjw, viresh.kumar, robh+dt, agross, bjorn.andersson
  Cc: amitk, linux-pm, devicetree, linux-kernel, linux-arm-msm,
	dmitry.baryshkov, tdas, Manivannan Sadhasivam

devm_platform_ioremap_resource() is the combination of
platform_get_resource() and devm_ioremap_resource(). Hence, use it to
simplify the code a bit.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Amit Kucheria <amitk@kernel.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
 drivers/cpufreq/qcom-cpufreq-hw.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index ccea34f61152..8a303783927f 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -244,7 +244,6 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 	struct of_phandle_args args;
 	struct device_node *cpu_np;
 	struct device *cpu_dev;
-	struct resource *res;
 	void __iomem *base;
 	int ret, index;
 
@@ -267,13 +266,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 
 	index = args.args[0];
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, index);
-	if (!res)
-		return -ENODEV;
-
-	base = devm_ioremap(dev, res->start, resource_size(res));
-	if (!base)
-		return -ENOMEM;
+	base = devm_platform_ioremap_resource(pdev, index);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
 
 	/* HW should be in enabled state to proceed */
 	if (!(readl_relaxed(base + REG_ENABLE) & 0x1)) {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/5] cpufreq: qcom-hw: Use of_device_get_match_data for offsets and row size
  2020-09-15  7:24 [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC Manivannan Sadhasivam
                   ` (2 preceding siblings ...)
  2020-09-15  7:24 ` [PATCH v2 3/5] cpufreq: qcom-hw: Use devm_platform_ioremap_resource() to simplify code Manivannan Sadhasivam
@ 2020-09-15  7:24 ` Manivannan Sadhasivam
  2020-09-15 15:21   ` Bjorn Andersson
  2020-09-15  7:24 ` [PATCH v2 5/5] cpufreq: qcom-hw: Add cpufreq support for SM8250 SoC Manivannan Sadhasivam
  2020-09-16  7:10 ` [PATCH v2 0/5] Add CPUFreq " Viresh Kumar
  5 siblings, 1 reply; 8+ messages in thread
From: Manivannan Sadhasivam @ 2020-09-15  7:24 UTC (permalink / raw)
  To: rjw, viresh.kumar, robh+dt, agross, bjorn.andersson
  Cc: amitk, linux-pm, devicetree, linux-kernel, linux-arm-msm,
	dmitry.baryshkov, tdas, Manivannan Sadhasivam

For preparing the driver to handle further SoC revisions, let's use the
of_device_get_match_data() API for getting the device specific offsets
and row size instead of defining them globally.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/cpufreq/qcom-cpufreq-hw.c | 89 ++++++++++++++++++++-----------
 1 file changed, 59 insertions(+), 30 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 8a303783927f..e3c46984a037 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -19,15 +19,21 @@
 #define LUT_L_VAL			GENMASK(7, 0)
 #define LUT_CORE_COUNT			GENMASK(18, 16)
 #define LUT_VOLT			GENMASK(11, 0)
-#define LUT_ROW_SIZE			32
 #define CLK_HW_DIV			2
 #define LUT_TURBO_IND			1
 
-/* Register offsets */
-#define REG_ENABLE			0x0
-#define REG_FREQ_LUT			0x110
-#define REG_VOLT_LUT			0x114
-#define REG_PERF_STATE			0x920
+struct qcom_cpufreq_soc_data {
+	u32 reg_enable;
+	u32 reg_freq_lut;
+	u32 reg_volt_lut;
+	u32 reg_perf_state;
+	u8 lut_row_size;
+};
+
+struct qcom_cpufreq_data {
+	void __iomem *base;
+	const struct qcom_cpufreq_soc_data *soc_data;
+};
 
 static unsigned long cpu_hw_rate, xo_rate;
 static bool icc_scaling_enabled;
@@ -76,10 +82,11 @@ static int qcom_cpufreq_update_opp(struct device *cpu_dev,
 static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
 					unsigned int index)
 {
-	void __iomem *perf_state_reg = policy->driver_data;
+	struct qcom_cpufreq_data *data = policy->driver_data;
+	const struct qcom_cpufreq_soc_data *soc_data = data->soc_data;
 	unsigned long freq = policy->freq_table[index].frequency;
 
-	writel_relaxed(index, perf_state_reg);
+	writel_relaxed(index, data->base + soc_data->reg_perf_state);
 
 	if (icc_scaling_enabled)
 		qcom_cpufreq_set_bw(policy, freq);
@@ -91,7 +98,8 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
 
 static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
 {
-	void __iomem *perf_state_reg;
+	struct qcom_cpufreq_data *data;
+	const struct qcom_cpufreq_soc_data *soc_data;
 	struct cpufreq_policy *policy;
 	unsigned int index;
 
@@ -99,9 +107,10 @@ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
 	if (!policy)
 		return 0;
 
-	perf_state_reg = policy->driver_data;
+	data = policy->driver_data;
+	soc_data = data->soc_data;
 
-	index = readl_relaxed(perf_state_reg);
+	index = readl_relaxed(data->base + soc_data->reg_perf_state);
 	index = min(index, LUT_MAX_ENTRIES - 1);
 
 	return policy->freq_table[index].frequency;
@@ -110,12 +119,13 @@ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
 static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
 						unsigned int target_freq)
 {
-	void __iomem *perf_state_reg = policy->driver_data;
+	struct qcom_cpufreq_data *data = policy->driver_data;
+	const struct qcom_cpufreq_soc_data *soc_data = data->soc_data;
 	unsigned int index;
 	unsigned long freq;
 
 	index = policy->cached_resolved_idx;
-	writel_relaxed(index, perf_state_reg);
+	writel_relaxed(index, data->base + soc_data->reg_perf_state);
 
 	freq = policy->freq_table[index].frequency;
 	arch_set_freq_scale(policy->related_cpus, freq,
@@ -125,8 +135,7 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
 }
 
 static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
-				    struct cpufreq_policy *policy,
-				    void __iomem *base)
+				    struct cpufreq_policy *policy)
 {
 	u32 data, src, lval, i, core_count, prev_freq = 0, freq;
 	u32 volt;
@@ -134,6 +143,8 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 	struct dev_pm_opp *opp;
 	unsigned long rate;
 	int ret;
+	struct qcom_cpufreq_data *drv_data = policy->driver_data;
+	const struct qcom_cpufreq_soc_data *soc_data = drv_data->soc_data;
 
 	table = kcalloc(LUT_MAX_ENTRIES + 1, sizeof(*table), GFP_KERNEL);
 	if (!table)
@@ -160,14 +171,14 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 	}
 
 	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
-		data = readl_relaxed(base + REG_FREQ_LUT +
-				      i * LUT_ROW_SIZE);
+		data = readl_relaxed(drv_data->base + soc_data->reg_freq_lut +
+				      i * soc_data->lut_row_size);
 		src = FIELD_GET(LUT_SRC, data);
 		lval = FIELD_GET(LUT_L_VAL, data);
 		core_count = FIELD_GET(LUT_CORE_COUNT, data);
 
-		data = readl_relaxed(base + REG_VOLT_LUT +
-				      i * LUT_ROW_SIZE);
+		data = readl_relaxed(drv_data->base + soc_data->reg_volt_lut +
+				      i * soc_data->lut_row_size);
 		volt = FIELD_GET(LUT_VOLT, data) * 1000;
 
 		if (src)
@@ -237,6 +248,20 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
 	}
 }
 
+static const struct qcom_cpufreq_soc_data qcom_soc_data = {
+	.reg_enable = 0x0,
+	.reg_freq_lut = 0x110,
+	.reg_volt_lut = 0x114,
+	.reg_perf_state = 0x920,
+	.lut_row_size = 32,
+};
+
+static const struct of_device_id qcom_cpufreq_hw_match[] = {
+	{ .compatible = "qcom,cpufreq-hw", .data = &qcom_soc_data },
+	{}
+};
+MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match);
+
 static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 {
 	struct platform_device *pdev = cpufreq_get_driver_data();
@@ -245,6 +270,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 	struct device_node *cpu_np;
 	struct device *cpu_dev;
 	void __iomem *base;
+	struct qcom_cpufreq_data *data;
 	int ret, index;
 
 	cpu_dev = get_cpu_device(policy->cpu);
@@ -270,8 +296,17 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	data->soc_data = of_device_get_match_data(&pdev->dev);
+	data->base = base;
+
 	/* HW should be in enabled state to proceed */
-	if (!(readl_relaxed(base + REG_ENABLE) & 0x1)) {
+	if (!(readl_relaxed(base + data->soc_data->reg_enable) & 0x1)) {
 		dev_err(dev, "Domain-%d cpufreq hardware not enabled\n", index);
 		ret = -ENODEV;
 		goto error;
@@ -284,9 +319,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 		goto error;
 	}
 
-	policy->driver_data = base + REG_PERF_STATE;
+	policy->driver_data = data;
 
-	ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy, base);
+	ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy);
 	if (ret) {
 		dev_err(dev, "Domain-%d failed to read LUT\n", index);
 		goto error;
@@ -310,13 +345,13 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
 {
 	struct device *cpu_dev = get_cpu_device(policy->cpu);
-	void __iomem *base = policy->driver_data - REG_PERF_STATE;
+	struct qcom_cpufreq_data *data = policy->driver_data;
 	struct platform_device *pdev = cpufreq_get_driver_data();
 
 	dev_pm_opp_remove_all_dynamic(cpu_dev);
 	dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
 	kfree(policy->freq_table);
-	devm_iounmap(&pdev->dev, base);
+	devm_iounmap(&pdev->dev, data->base);
 
 	return 0;
 }
@@ -386,12 +421,6 @@ static int qcom_cpufreq_hw_driver_remove(struct platform_device *pdev)
 	return cpufreq_unregister_driver(&cpufreq_qcom_hw_driver);
 }
 
-static const struct of_device_id qcom_cpufreq_hw_match[] = {
-	{ .compatible = "qcom,cpufreq-hw" },
-	{}
-};
-MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match);
-
 static struct platform_driver qcom_cpufreq_hw_driver = {
 	.probe = qcom_cpufreq_hw_driver_probe,
 	.remove = qcom_cpufreq_hw_driver_remove,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 5/5] cpufreq: qcom-hw: Add cpufreq support for SM8250 SoC
  2020-09-15  7:24 [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC Manivannan Sadhasivam
                   ` (3 preceding siblings ...)
  2020-09-15  7:24 ` [PATCH v2 4/5] cpufreq: qcom-hw: Use of_device_get_match_data for offsets and row size Manivannan Sadhasivam
@ 2020-09-15  7:24 ` Manivannan Sadhasivam
  2020-09-16  7:10 ` [PATCH v2 0/5] Add CPUFreq " Viresh Kumar
  5 siblings, 0 replies; 8+ messages in thread
From: Manivannan Sadhasivam @ 2020-09-15  7:24 UTC (permalink / raw)
  To: rjw, viresh.kumar, robh+dt, agross, bjorn.andersson
  Cc: amitk, linux-pm, devicetree, linux-kernel, linux-arm-msm,
	dmitry.baryshkov, tdas, Manivannan Sadhasivam

SM8250 SoC uses EPSS block for carrying out the cpufreq duties. Hence, add
support for it in the driver with relevant dev data.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Amit Kucheria <amitk@kernel.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
 drivers/cpufreq/qcom-cpufreq-hw.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index e3c46984a037..c485be839172 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -256,8 +256,17 @@ static const struct qcom_cpufreq_soc_data qcom_soc_data = {
 	.lut_row_size = 32,
 };
 
+static const struct qcom_cpufreq_soc_data epss_soc_data = {
+	.reg_enable = 0x0,
+	.reg_freq_lut = 0x100,
+	.reg_volt_lut = 0x200,
+	.reg_perf_state = 0x320,
+	.lut_row_size = 4,
+};
+
 static const struct of_device_id qcom_cpufreq_hw_match[] = {
 	{ .compatible = "qcom,cpufreq-hw", .data = &qcom_soc_data },
+	{ .compatible = "qcom,cpufreq-epss", .data = &epss_soc_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 4/5] cpufreq: qcom-hw: Use of_device_get_match_data for offsets and row size
  2020-09-15  7:24 ` [PATCH v2 4/5] cpufreq: qcom-hw: Use of_device_get_match_data for offsets and row size Manivannan Sadhasivam
@ 2020-09-15 15:21   ` Bjorn Andersson
  0 siblings, 0 replies; 8+ messages in thread
From: Bjorn Andersson @ 2020-09-15 15:21 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: rjw, viresh.kumar, robh+dt, agross, amitk, linux-pm, devicetree,
	linux-kernel, linux-arm-msm, dmitry.baryshkov, tdas

On Tue 15 Sep 07:24 UTC 2020, Manivannan Sadhasivam wrote:

> For preparing the driver to handle further SoC revisions, let's use the
> of_device_get_match_data() API for getting the device specific offsets
> and row size instead of defining them globally.
> 
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

Regards,
Bjorn

> ---
>  drivers/cpufreq/qcom-cpufreq-hw.c | 89 ++++++++++++++++++++-----------
>  1 file changed, 59 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
> index 8a303783927f..e3c46984a037 100644
> --- a/drivers/cpufreq/qcom-cpufreq-hw.c
> +++ b/drivers/cpufreq/qcom-cpufreq-hw.c
> @@ -19,15 +19,21 @@
>  #define LUT_L_VAL			GENMASK(7, 0)
>  #define LUT_CORE_COUNT			GENMASK(18, 16)
>  #define LUT_VOLT			GENMASK(11, 0)
> -#define LUT_ROW_SIZE			32
>  #define CLK_HW_DIV			2
>  #define LUT_TURBO_IND			1
>  
> -/* Register offsets */
> -#define REG_ENABLE			0x0
> -#define REG_FREQ_LUT			0x110
> -#define REG_VOLT_LUT			0x114
> -#define REG_PERF_STATE			0x920
> +struct qcom_cpufreq_soc_data {
> +	u32 reg_enable;
> +	u32 reg_freq_lut;
> +	u32 reg_volt_lut;
> +	u32 reg_perf_state;
> +	u8 lut_row_size;
> +};
> +
> +struct qcom_cpufreq_data {
> +	void __iomem *base;
> +	const struct qcom_cpufreq_soc_data *soc_data;
> +};
>  
>  static unsigned long cpu_hw_rate, xo_rate;
>  static bool icc_scaling_enabled;
> @@ -76,10 +82,11 @@ static int qcom_cpufreq_update_opp(struct device *cpu_dev,
>  static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
>  					unsigned int index)
>  {
> -	void __iomem *perf_state_reg = policy->driver_data;
> +	struct qcom_cpufreq_data *data = policy->driver_data;
> +	const struct qcom_cpufreq_soc_data *soc_data = data->soc_data;
>  	unsigned long freq = policy->freq_table[index].frequency;
>  
> -	writel_relaxed(index, perf_state_reg);
> +	writel_relaxed(index, data->base + soc_data->reg_perf_state);
>  
>  	if (icc_scaling_enabled)
>  		qcom_cpufreq_set_bw(policy, freq);
> @@ -91,7 +98,8 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
>  
>  static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
>  {
> -	void __iomem *perf_state_reg;
> +	struct qcom_cpufreq_data *data;
> +	const struct qcom_cpufreq_soc_data *soc_data;
>  	struct cpufreq_policy *policy;
>  	unsigned int index;
>  
> @@ -99,9 +107,10 @@ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
>  	if (!policy)
>  		return 0;
>  
> -	perf_state_reg = policy->driver_data;
> +	data = policy->driver_data;
> +	soc_data = data->soc_data;
>  
> -	index = readl_relaxed(perf_state_reg);
> +	index = readl_relaxed(data->base + soc_data->reg_perf_state);
>  	index = min(index, LUT_MAX_ENTRIES - 1);
>  
>  	return policy->freq_table[index].frequency;
> @@ -110,12 +119,13 @@ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
>  static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
>  						unsigned int target_freq)
>  {
> -	void __iomem *perf_state_reg = policy->driver_data;
> +	struct qcom_cpufreq_data *data = policy->driver_data;
> +	const struct qcom_cpufreq_soc_data *soc_data = data->soc_data;
>  	unsigned int index;
>  	unsigned long freq;
>  
>  	index = policy->cached_resolved_idx;
> -	writel_relaxed(index, perf_state_reg);
> +	writel_relaxed(index, data->base + soc_data->reg_perf_state);
>  
>  	freq = policy->freq_table[index].frequency;
>  	arch_set_freq_scale(policy->related_cpus, freq,
> @@ -125,8 +135,7 @@ static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
>  }
>  
>  static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
> -				    struct cpufreq_policy *policy,
> -				    void __iomem *base)
> +				    struct cpufreq_policy *policy)
>  {
>  	u32 data, src, lval, i, core_count, prev_freq = 0, freq;
>  	u32 volt;
> @@ -134,6 +143,8 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
>  	struct dev_pm_opp *opp;
>  	unsigned long rate;
>  	int ret;
> +	struct qcom_cpufreq_data *drv_data = policy->driver_data;
> +	const struct qcom_cpufreq_soc_data *soc_data = drv_data->soc_data;
>  
>  	table = kcalloc(LUT_MAX_ENTRIES + 1, sizeof(*table), GFP_KERNEL);
>  	if (!table)
> @@ -160,14 +171,14 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
>  	}
>  
>  	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
> -		data = readl_relaxed(base + REG_FREQ_LUT +
> -				      i * LUT_ROW_SIZE);
> +		data = readl_relaxed(drv_data->base + soc_data->reg_freq_lut +
> +				      i * soc_data->lut_row_size);
>  		src = FIELD_GET(LUT_SRC, data);
>  		lval = FIELD_GET(LUT_L_VAL, data);
>  		core_count = FIELD_GET(LUT_CORE_COUNT, data);
>  
> -		data = readl_relaxed(base + REG_VOLT_LUT +
> -				      i * LUT_ROW_SIZE);
> +		data = readl_relaxed(drv_data->base + soc_data->reg_volt_lut +
> +				      i * soc_data->lut_row_size);
>  		volt = FIELD_GET(LUT_VOLT, data) * 1000;
>  
>  		if (src)
> @@ -237,6 +248,20 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
>  	}
>  }
>  
> +static const struct qcom_cpufreq_soc_data qcom_soc_data = {
> +	.reg_enable = 0x0,
> +	.reg_freq_lut = 0x110,
> +	.reg_volt_lut = 0x114,
> +	.reg_perf_state = 0x920,
> +	.lut_row_size = 32,
> +};
> +
> +static const struct of_device_id qcom_cpufreq_hw_match[] = {
> +	{ .compatible = "qcom,cpufreq-hw", .data = &qcom_soc_data },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match);
> +
>  static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
>  {
>  	struct platform_device *pdev = cpufreq_get_driver_data();
> @@ -245,6 +270,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
>  	struct device_node *cpu_np;
>  	struct device *cpu_dev;
>  	void __iomem *base;
> +	struct qcom_cpufreq_data *data;
>  	int ret, index;
>  
>  	cpu_dev = get_cpu_device(policy->cpu);
> @@ -270,8 +296,17 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
>  	if (IS_ERR(base))
>  		return PTR_ERR(base);
>  
> +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> +	if (!data) {
> +		ret = -ENOMEM;
> +		goto error;
> +	}
> +
> +	data->soc_data = of_device_get_match_data(&pdev->dev);
> +	data->base = base;
> +
>  	/* HW should be in enabled state to proceed */
> -	if (!(readl_relaxed(base + REG_ENABLE) & 0x1)) {
> +	if (!(readl_relaxed(base + data->soc_data->reg_enable) & 0x1)) {
>  		dev_err(dev, "Domain-%d cpufreq hardware not enabled\n", index);
>  		ret = -ENODEV;
>  		goto error;
> @@ -284,9 +319,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
>  		goto error;
>  	}
>  
> -	policy->driver_data = base + REG_PERF_STATE;
> +	policy->driver_data = data;
>  
> -	ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy, base);
> +	ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy);
>  	if (ret) {
>  		dev_err(dev, "Domain-%d failed to read LUT\n", index);
>  		goto error;
> @@ -310,13 +345,13 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
>  static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
>  {
>  	struct device *cpu_dev = get_cpu_device(policy->cpu);
> -	void __iomem *base = policy->driver_data - REG_PERF_STATE;
> +	struct qcom_cpufreq_data *data = policy->driver_data;
>  	struct platform_device *pdev = cpufreq_get_driver_data();
>  
>  	dev_pm_opp_remove_all_dynamic(cpu_dev);
>  	dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
>  	kfree(policy->freq_table);
> -	devm_iounmap(&pdev->dev, base);
> +	devm_iounmap(&pdev->dev, data->base);
>  
>  	return 0;
>  }
> @@ -386,12 +421,6 @@ static int qcom_cpufreq_hw_driver_remove(struct platform_device *pdev)
>  	return cpufreq_unregister_driver(&cpufreq_qcom_hw_driver);
>  }
>  
> -static const struct of_device_id qcom_cpufreq_hw_match[] = {
> -	{ .compatible = "qcom,cpufreq-hw" },
> -	{}
> -};
> -MODULE_DEVICE_TABLE(of, qcom_cpufreq_hw_match);
> -
>  static struct platform_driver qcom_cpufreq_hw_driver = {
>  	.probe = qcom_cpufreq_hw_driver_probe,
>  	.remove = qcom_cpufreq_hw_driver_remove,
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC
  2020-09-15  7:24 [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC Manivannan Sadhasivam
                   ` (4 preceding siblings ...)
  2020-09-15  7:24 ` [PATCH v2 5/5] cpufreq: qcom-hw: Add cpufreq support for SM8250 SoC Manivannan Sadhasivam
@ 2020-09-16  7:10 ` Viresh Kumar
  5 siblings, 0 replies; 8+ messages in thread
From: Viresh Kumar @ 2020-09-16  7:10 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: rjw, robh+dt, agross, bjorn.andersson, amitk, linux-pm,
	devicetree, linux-kernel, linux-arm-msm, dmitry.baryshkov, tdas

On 15-09-20, 12:54, Manivannan Sadhasivam wrote:
> Hello,
> 
> This series adds CPUFreq support for Qualcomm SM8250 SoC. The existing
> qcom-hw driver is reworked to support the EPSS block on this SoC which
> handles the CPUFreq duties.
> 
> The EPSS block supports additional features for which incremental patches
> will be submitted on top of this series!
> 
> Thanks,
> Mani
> 
> Changes in v2:
> 
> * Dropped the regmap conversion patch
> * Used "qcom,cpufreq-epss" compatible and "epss_soc_data" for dev data
> * Switched to "of_device_get_match_data" API
> * Collected reviews from Amit, Viresh and Bjorn
> * Dropped patch [3/7] which got applied by Viresh
> 
> Bjorn Andersson (1):
>   arm64: dts: qcom: sm8250: Add cpufreq hw node

Applied all except this one, as it will go through ARM Soc tree.

-- 
viresh

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-09-16  7:10 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-15  7:24 [PATCH v2 0/5] Add CPUFreq support for SM8250 SoC Manivannan Sadhasivam
2020-09-15  7:24 ` [PATCH v2 1/5] dt-bindings: cpufreq: cpufreq-qcom-hw: Document Qcom EPSS compatible Manivannan Sadhasivam
2020-09-15  7:24 ` [PATCH v2 2/5] arm64: dts: qcom: sm8250: Add cpufreq hw node Manivannan Sadhasivam
2020-09-15  7:24 ` [PATCH v2 3/5] cpufreq: qcom-hw: Use devm_platform_ioremap_resource() to simplify code Manivannan Sadhasivam
2020-09-15  7:24 ` [PATCH v2 4/5] cpufreq: qcom-hw: Use of_device_get_match_data for offsets and row size Manivannan Sadhasivam
2020-09-15 15:21   ` Bjorn Andersson
2020-09-15  7:24 ` [PATCH v2 5/5] cpufreq: qcom-hw: Add cpufreq support for SM8250 SoC Manivannan Sadhasivam
2020-09-16  7:10 ` [PATCH v2 0/5] Add CPUFreq " Viresh Kumar

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).