Skip to contentSkip to conversation

SDM670 Basic SoC thermal zones

PATCH Superseded Richard Acayan 4 participants 13 messages Mar 28 – Mar 30

Subsystems (5)

v4 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v4 cover SDM670 Basic SoC thermal zones

This adds support for the thermal sensor, for thermal-based CPU throttling via LMh, and for thermal zones.

Changes since v3 (https://lore.kernel.org/r/[email protected]):
- support LMh clusters starting at CPU 6 (dt-bindings tag dropped) (3/4)

Changes since v2 (https://lore.kernel.org/r/[email protected]):
- remove cooling from memory thermal zone (3/3)

Changes since v1 (https://lore.kernel.org/r/[email protected]):
- add review tag from Krzysztof (1/3)
- replace CPU thermal zones with lmh (2/3, 3/3)

Richard Acayan (4):
dt-bindings: thermal: tsens: add SDM670 compatible
dt-bindings: thermal: lmh: Add SDM670 compatible thermal/qcom/lmh: support SDM670 and its CPU clusters
arm64: dts: qcom: sdm670: add thermal zones and thermal devices

 .../devicetree/bindings/thermal/qcom-lmh.yaml |   3 +
 .../bindings/thermal/qcom-tsens.yaml          |   1 +
 arch/arm64/boot/dts/qcom/sdm670.dtsi          | 400 ++++++++++++++++++
 drivers/thermal/qcom/lmh.c                    |  69 ++-
 4 files changed, 460 insertions(+), 13 deletions(-)
Signature · 1 line
2.53.0
#1 lore raw

PATCH v4 1/4 dt-bindings: thermal: tsens: add SDM670 compatible

Add the compatible for the thermal sensors on the SDM670.

---
 Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | 1 +
 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +1 -0
index 3c5256b0cd9f..6c84f22ae322 100644
@@ -71,6 +71,7 @@ properties:
               - qcom,sc8180x-tsens
               - qcom,sc8280xp-tsens
               - qcom,sdm630-tsens
+              - qcom,sdm670-tsens
               - qcom,sdm845-tsens
               - qcom,sm6115-tsens
               - qcom,sm6350-tsens
Signature · 1 line
2.53.0
#2 lore raw

PATCH v4 2/4 dt-bindings: thermal: lmh: Add SDM670 compatible

In reply to Richard Acayan

Document the SDM670 LMh.

---
 Documentation/devicetree/bindings/thermal/qcom-lmh.yaml | 3 +++
 1 file changed, 3 insertions(+)
Documentation/devicetree/bindings/thermal/qcom-lmh.yaml +3 -0
index 1175bb358382..ce72347e29d1 100644
@@ -22,6 +22,9 @@ properties:
           - qcom,sc8180x-lmh
           - qcom,sdm845-lmh
           - qcom,sm8150-lmh
+      - items:
+          - const: qcom,sdm670-lmh
+          - const: qcom,sdm845-lmh
       - items:
           - const: qcom,qcm2290-lmh
           - const: qcom,sm8150-lmh
Signature · 1 line
2.53.0
#4 lore raw

Re: [PATCH v4 2/4] dt-bindings: thermal: lmh: Add SDM670 compatible

Quoted 6 lines · Krzysztof Kozlowski
Quoted 3 lines · Richard Acayan

Document the SDM670 LMh.

Why are you sending patches already applied 18 days ago?

This one in particular was applied with the assumption that there were no driver changes to support SDM670, so I re-sent it in case the different CPU clusters change the suitability of the fallback compatible.

I'll drop them next time, and patch over this if necessary.

#5 lore raw

PATCH v4 3/4 thermal/qcom/lmh: support SDM670 and its CPU clusters

In reply to Richard Acayan

The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but some SoCs divide the CPUs into different sizes of clusters. In SDM670, the first 6 CPUs are in the little cluster and the next 2 are in the big cluster. Define the clusters in the match data and define the different cluster configuration for SDM670.

Currently, this only supports 8 CPUs and tolerates linking to any CPU in the cluster.

---
 drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
 1 file changed, 56 insertions(+), 13 deletions(-)
drivers/thermal/qcom/lmh.c +56 -13
index 3d072b7a4a6d..46c1e301f6c8 100644
@@ -30,14 +30,17 @@
 
 #define LMH_REG_DCVS_INTR_CLR		0x8
 
-#define LMH_ENABLE_ALGOS		1
-
 struct lmh_hw_data {
 	void __iomem *base;
 	struct irq_domain *domain;
 	int irq;
 };
 
+struct lmh_soc_data {
+	bool enable_algos;
+	u32 node_ids[8];
+};
+
 static irqreturn_t lmh_handle_irq(int hw_irq, void *data)
 {
 	struct lmh_hw_data *lmh_data = data;
@@ -100,8 +103,8 @@ static int lmh_probe(struct platform_device *pdev)
 	struct device_node *np = dev->of_node;
 	struct device_node *cpu_node;
 	struct lmh_hw_data *lmh_data;
+	const struct lmh_soc_data *match_data;
 	int temp_low, temp_high, temp_arm, cpu_id, ret;
-	unsigned int enable_alg;
 	u32 node_id;
 
 	if (!qcom_scm_is_available())
@@ -144,10 +147,9 @@ static int lmh_probe(struct platform_device *pdev)
 	 * for other platforms, revisit this to check if the <cpu-id, node-id> should be part
 	 * of a dt match table.
 	 */
-	if (cpu_id == 0) {
-		node_id = LMH_CLUSTER0_NODE_ID;
-	} else if (cpu_id == 4) {
-		node_id = LMH_CLUSTER1_NODE_ID;
+	match_data = of_device_get_match_data(dev);
+	if (cpu_id >= 0 && cpu_id < 8) {
+		node_id = match_data->node_ids[cpu_id];
 	} else {
 		dev_err(dev, "Wrong CPU id associated with LMh node\n");
 		return -EINVAL;
@@ -156,9 +158,7 @@ static int lmh_probe(struct platform_device *pdev)
 	if (!qcom_scm_lmh_dcvsh_available())
 		return -EINVAL;
 
-	enable_alg = (uintptr_t)of_device_get_match_data(dev);
-
-	if (enable_alg) {
+	if (match_data->enable_algos) {
 		ret = qcom_scm_lmh_dcvsh(LMH_SUB_FN_CRNT, LMH_ALGO_MODE_ENABLE, 1,
 					 LMH_NODE_DCVS, node_id, 0);
 		if (ret)
@@ -231,10 +231,53 @@ static int lmh_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct lmh_soc_data sdm670_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};
+
+static const struct lmh_soc_data sdm845_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};
+
+static const struct lmh_soc_data sm8150_lmh_data = {
+	.enable_algos = false,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};
+
 static const struct of_device_id lmh_table[] = {
-	{ .compatible = "qcom,sc8180x-lmh", },
-	{ .compatible = "qcom,sdm845-lmh", .data = (void *)LMH_ENABLE_ALGOS},
-	{ .compatible = "qcom,sm8150-lmh", },
+	{ .compatible = "qcom,sc8180x-lmh", .data = &sm8150_lmh_data },
+	{ .compatible = "qcom,sdm670-lmh", .data = &sdm670_lmh_data },
+	{ .compatible = "qcom,sdm845-lmh", .data = &sdm845_lmh_data },
+	{ .compatible = "qcom,sm8150-lmh", .data = &sm8150_lmh_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, lmh_table);
Signature · 1 line
2.53.0
#6 lore raw

Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters

Quoted 31 lines · Richard Acayan

The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but some SoCs divide the CPUs into different sizes of clusters. In SDM670, the first 6 CPUs are in the little cluster and the next 2 are in the big cluster. Define the clusters in the match data and define the different cluster configuration for SDM670.

Currently, this only supports 8 CPUs and tolerates linking to any CPU in the cluster.

---
 drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
 1 file changed, 56 insertions(+), 13 deletions(-)
drivers/thermal/qcom/lmh.c +17 -0
+static const struct lmh_soc_data sdm670_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};
+
+static const struct lmh_soc_data sdm845_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 260

Quoted 10 lines
drivers/thermal/qcom/lmh.c +10 -0
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

These tables made me wonder, can we determine this information from the DT? For example, by reading the qcom,freq-domain property. But...

Quoted 4 lines
drivers/thermal/qcom/lmh.c +4 -0
+
+static const struct lmh_soc_data sm8150_lmh_data = {
+	.enable_algos = false,
+	.node_ids = {

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 274

Quoted 10 lines
drivers/thermal/qcom/lmh.c +10 -0
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

... this might be problematic, unless this entry is broken. On SM8150 we have three freq domains, but up to now we were programming two clustern nodes. Of course it is possible to define that node_id is 0 for freq domain 0 and 1 for domains 1 and 2.

Quoted 15 lines
drivers/thermal/qcom/lmh.c +5 -3
+
 static const struct of_device_id lmh_table[] = {
-	{ .compatible = "qcom,sc8180x-lmh", },
-	{ .compatible = "qcom,sdm845-lmh", .data = (void *)LMH_ENABLE_ALGOS},
-	{ .compatible = "qcom,sm8150-lmh", },
+	{ .compatible = "qcom,sc8180x-lmh", .data = &sm8150_lmh_data },
+	{ .compatible = "qcom,sdm670-lmh", .data = &sdm670_lmh_data },
+	{ .compatible = "qcom,sdm845-lmh", .data = &sdm845_lmh_data },
+	{ .compatible = "qcom,sm8150-lmh", .data = &sm8150_lmh_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, lmh_table);
Signature · 1 line
2.53.0
Signature · 2 lines
With best wishes
Dmitry
#7 lore raw

Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters

Quoted 57 lines · Dmitry Baryshkov
Quoted 31 lines · Richard Acayan

The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but some SoCs divide the CPUs into different sizes of clusters. In SDM670, the first 6 CPUs are in the little cluster and the next 2 are in the big cluster. Define the clusters in the match data and define the different cluster configuration for SDM670.

Currently, this only supports 8 CPUs and tolerates linking to any CPU in the cluster.

---
 drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
 1 file changed, 56 insertions(+), 13 deletions(-)
drivers/thermal/qcom/lmh.c +17 -0
+static const struct lmh_soc_data sdm670_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};
+
+static const struct lmh_soc_data sdm845_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 260

Quoted 10 lines
drivers/thermal/qcom/lmh.c +10 -0
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

These tables made me wonder, can we determine this information from the DT? For example, by reading the qcom,freq-domain property. But...

Quoted 11 lines
drivers/thermal/qcom/lmh.c +11 -0
+
+static const struct lmh_soc_data sm8150_lmh_data = {
+	.enable_algos = false,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
Quoted 8 lines

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 246

Quoted 3 lines
drivers/thermal/qcom/lmh.c +3 -0
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

... this might be problematic, unless this entry is broken. On SM8150 we have three freq domains, but up to now we were programming two clustern nodes. Of course it is possible to define that node_id is 0 for freq domain 0 and 1 for domains 1 and 2.

The third cluster situation on 8150 is not super good - we e.g. only have a single LMH irq that's shared between the big and prime cores. That was fixed with later SoCs (which is why it's not wired up in the DT today)

Funnily enough the bigger 8180 didn't have that problem because it only had 2 freq domains

Konrad

#8 lore raw

Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters

Quoted 67 lines · Konrad Dybcio
Quoted 57 lines · Dmitry Baryshkov
Quoted 31 lines · Richard Acayan

The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but some SoCs divide the CPUs into different sizes of clusters. In SDM670, the first 6 CPUs are in the little cluster and the next 2 are in the big cluster. Define the clusters in the match data and define the different cluster configuration for SDM670.

Currently, this only supports 8 CPUs and tolerates linking to any CPU in the cluster.

---
 drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
 1 file changed, 56 insertions(+), 13 deletions(-)
drivers/thermal/qcom/lmh.c +17 -0
+static const struct lmh_soc_data sdm670_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};
+
+static const struct lmh_soc_data sdm845_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 260

Quoted 10 lines
drivers/thermal/qcom/lmh.c +10 -0
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

These tables made me wonder, can we determine this information from the DT? For example, by reading the qcom,freq-domain property. But...

Quoted 11 lines
drivers/thermal/qcom/lmh.c +11 -0
+
+static const struct lmh_soc_data sm8150_lmh_data = {
+	.enable_algos = false,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
Quoted 8 lines

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 246

Quoted 3 lines
drivers/thermal/qcom/lmh.c +3 -0
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

... this might be problematic, unless this entry is broken. On SM8150 we have three freq domains, but up to now we were programming two clustern nodes. Of course it is possible to define that node_id is 0 for freq domain 0 and 1 for domains 1 and 2.

Quoted 3 lines

The third cluster situation on 8150 is not super good - we e.g. only have a single LMH irq that's shared between the big and prime cores. That was fixed with later SoCs (which is why it's not wired up in the DT today)

Thanks!

Anyway, from your point of view, would it be better to define mappings in the driver (like it's done with this patch) or parse the DT?

Quoted 2 lines

Funnily enough the bigger 8180 didn't have that problem because it only had 2 freq domains

Yep.

Signature · 2 lines
With best wishes
Dmitry
#9 lore raw

Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters

Quoted 68 lines · Dmitry Baryshkov
Quoted 67 lines · Konrad Dybcio
Quoted 65 lines · Dmitry Baryshkov
Quoted 31 lines · Richard Acayan

The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but some SoCs divide the CPUs into different sizes of clusters. In SDM670, the first 6 CPUs are in the little cluster and the next 2 are in the big cluster. Define the clusters in the match data and define the different cluster configuration for SDM670.

Currently, this only supports 8 CPUs and tolerates linking to any CPU in the cluster.

---
 drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
 1 file changed, 56 insertions(+), 13 deletions(-)
drivers/thermal/qcom/lmh.c +17 -0
+static const struct lmh_soc_data sdm670_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};
+
+static const struct lmh_soc_data sdm845_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 260

Quoted 10 lines
drivers/thermal/qcom/lmh.c +10 -0
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

These tables made me wonder, can we determine this information from the DT? For example, by reading the qcom,freq-domain property. But...

Quoted 4 lines
drivers/thermal/qcom/lmh.c +4 -0
+
+static const struct lmh_soc_data sm8150_lmh_data = {
+	.enable_algos = false,
+	.node_ids = {

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 274

Quoted 10 lines
drivers/thermal/qcom/lmh.c +10 -0
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

... this might be problematic, unless this entry is broken. On SM8150 we have three freq domains, but up to now we were programming two clustern nodes. Of course it is possible to define that node_id is 0 for freq domain 0 and 1 for domains 1 and 2.

Quoted 8 lines
Quoted 3 lines

The third cluster situation on 8150 is not super good - we e.g. only have a single LMH irq that's shared between the big and prime cores. That was fixed with later SoCs (which is why it's not wired up in the DT today)

Thanks!

Anyway, from your point of view, would it be better to define mappings in the driver (like it's done with this patch) or parse the DT?

Well, we can spend a lot of time trying to be smart about it and handle the odd edge case, or add a simple comparison!

Konrad

#10 lore raw

Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters

Quoted 73 lines · Konrad Dybcio
Quoted 72 lines · Dmitry Baryshkov
Quoted 70 lines · Konrad Dybcio
Quoted 57 lines · Dmitry Baryshkov
Quoted 31 lines · Richard Acayan

The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but some SoCs divide the CPUs into different sizes of clusters. In SDM670, the first 6 CPUs are in the little cluster and the next 2 are in the big cluster. Define the clusters in the match data and define the different cluster configuration for SDM670.

Currently, this only supports 8 CPUs and tolerates linking to any CPU in the cluster.

---
 drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
 1 file changed, 56 insertions(+), 13 deletions(-)
drivers/thermal/qcom/lmh.c +17 -0
+static const struct lmh_soc_data sdm670_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};
+
+static const struct lmh_soc_data sdm845_lmh_data = {
+	.enable_algos = true,
+	.node_ids = {

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 260

Quoted 10 lines
drivers/thermal/qcom/lmh.c +10 -0
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

These tables made me wonder, can we determine this information from the DT? For example, by reading the qcom,freq-domain property. But...

Quoted 11 lines
drivers/thermal/qcom/lmh.c +11 -0
+
+static const struct lmh_soc_data sm8150_lmh_data = {
+	.enable_algos = false,
+	.node_ids = {
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER0_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
+		LMH_CLUSTER1_NODE_ID,
Quoted 8 lines

drivers/thermal/qcom/lmh.c static int lmh_probe(struct platform_device *pdev) · line 246

Quoted 3 lines
drivers/thermal/qcom/lmh.c +3 -0
+		LMH_CLUSTER1_NODE_ID,
+	},
+};

... this might be problematic, unless this entry is broken. On SM8150 we have three freq domains, but up to now we were programming two clustern nodes. Of course it is possible to define that node_id is 0 for freq domain 0 and 1 for domains 1 and 2.

The third cluster situation on 8150 is not super good - we e.g. only have a single LMH irq that's shared between the big and prime cores. That was fixed with later SoCs (which is why it's not wired up in the DT today)

Quoted 7 lines
Quoted 4 lines

Thanks!

Anyway, from your point of view, would it be better to define mappings in the driver (like it's done with this patch) or parse the DT?

Well, we can spend a lot of time trying to be smart about it and handle the odd edge case, or add a simple comparison!

:-)

Then let's go with your suggestion of 'first core from second cluster'.

Signature · 2 lines
With best wishes
Dmitry
#11 lore raw

Re: [PATCH v4 3/4] thermal/qcom/lmh: support SDM670 and its CPU clusters

In reply to Richard Acayan
Quoted 23 lines · Richard Acayan

The LMh driver was made for Qualcomm SoCs with clusters of 4 CPUs, but some SoCs divide the CPUs into different sizes of clusters. In SDM670, the first 6 CPUs are in the little cluster and the next 2 are in the big cluster. Define the clusters in the match data and define the different cluster configuration for SDM670.

Currently, this only supports 8 CPUs and tolerates linking to any CPU in the cluster.

---
 drivers/thermal/qcom/lmh.c | 69 +++++++++++++++++++++++++++++++-------
 1 file changed, 56 insertions(+), 13 deletions(-)
drivers/thermal/qcom/lmh.c +0 -1
index 3d072b7a4a6d..46c1e301f6c8 100644
@@ -30,14 +30,17 @@
 
 #define LMH_REG_DCVS_INTR_CLR		0x8
 
-#define LMH_ENABLE_ALGOS		1

drivers/thermal/qcom/lmh.c line 41

Quoted 10 lines
drivers/thermal/qcom/lmh.c +3 -1
-
 struct lmh_hw_data {
 	void __iomem *base;
 	struct irq_domain *domain;
 	int irq;
 };
 
+struct lmh_soc_data {
+	bool enable_algos;
+	u32 node_ids[8];

u32 clus1_start_idx or something similar denoting the first CPU index in the second cluster?

Konrad

#12 lore raw

PATCH v4 4/4 arm64: dts: qcom: sdm670: add thermal zones and thermal devices

In reply to Richard Acayan

Add thermal zones to safeguard from overheating to high temperatures, along with the thermal sensors (TSENS) and CPU frequency limits (LMh). The temperatures are very high, but should still be safeguard for devices that do not specify their own thermal zones.

---
 arch/arm64/boot/dts/qcom/sdm670.dtsi | 400 +++++++++++++++++++++++++++
 1 file changed, 400 insertions(+)
arch/arm64/boot/dts/qcom/sdm670.dtsi +400 -0
index f115bc6e64f3..c5f7655421a3 100644
@@ -20,6 +20,7 @@
 #include <dt-bindings/phy/phy-qcom-qusb2.h>
 #include <dt-bindings/power/qcom-rpmpd.h>
 #include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	interrupt-parent = <&intc>;
@@ -62,6 +63,7 @@ cpu0: cpu@0 {
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			power-domains = <&cpu_pd0>;
 			power-domain-names = "psci";
+			#cooling-cells = <2>;
 			next-level-cache = <&l2_0>;
 			l2_0: l2-cache {
 				compatible = "cache";
@@ -89,6 +91,7 @@ cpu1: cpu@100 {
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			power-domains = <&cpu_pd1>;
 			power-domain-names = "psci";
+			#cooling-cells = <2>;
 			next-level-cache = <&l2_100>;
 			l2_100: l2-cache {
 				compatible = "cache";
@@ -111,6 +114,7 @@ cpu2: cpu@200 {
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			power-domains = <&cpu_pd2>;
 			power-domain-names = "psci";
+			#cooling-cells = <2>;
 			next-level-cache = <&l2_200>;
 			l2_200: l2-cache {
 				compatible = "cache";
@@ -133,6 +137,7 @@ cpu3: cpu@300 {
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			power-domains = <&cpu_pd3>;
 			power-domain-names = "psci";
+			#cooling-cells = <2>;
 			next-level-cache = <&l2_300>;
 			l2_300: l2-cache {
 				compatible = "cache";
@@ -155,6 +160,7 @@ cpu4: cpu@400 {
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			power-domains = <&cpu_pd4>;
 			power-domain-names = "psci";
+			#cooling-cells = <2>;
 			next-level-cache = <&l2_400>;
 			l2_400: l2-cache {
 				compatible = "cache";
@@ -177,6 +183,7 @@ cpu5: cpu@500 {
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			power-domains = <&cpu_pd5>;
 			power-domain-names = "psci";
+			#cooling-cells = <2>;
 			next-level-cache = <&l2_500>;
 			l2_500: l2-cache {
 				compatible = "cache";
@@ -199,6 +206,7 @@ cpu6: cpu@600 {
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			power-domains = <&cpu_pd6>;
 			power-domain-names = "psci";
+			#cooling-cells = <2>;
 			next-level-cache = <&l2_600>;
 			l2_600: l2-cache {
 				compatible = "cache";
@@ -221,6 +229,7 @@ cpu7: cpu@700 {
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			power-domains = <&cpu_pd7>;
 			power-domain-names = "psci";
+			#cooling-cells = <2>;
 			next-level-cache = <&l2_700>;
 			l2_700: l2-cache {
 				compatible = "cache";
@@ -1408,6 +1417,8 @@ gpu: gpu@5000000 {
 			nvmem-cells = <&gpu_speed_bin>;
 			nvmem-cell-names = "speed_bin";
 
+			#cooling-cells = <2>;
+
 			status = "disabled";
 
 			gpu_zap_shader: zap-shader {
@@ -2100,6 +2111,28 @@ dispcc: clock-controller@af00000 {
 			#power-domain-cells = <1>;
 		};
 
+		tsens0: thermal-sensor@c263000 {
+			compatible = "qcom,sdm670-tsens", "qcom,tsens-v2";
+			reg = <0 0x0c263000 0 0x1000>,
+			      <0 0x0c222000 0 0x1000>;
+			interrupts-extended = <&pdc 26 IRQ_TYPE_EDGE_RISING>,
+					      <&pdc 28 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+			#qcom,sensors = <13>;
+		};
+
+		tsens1: thermal-sensor@c265000 {
+			compatible = "qcom,sdm670-tsens", "qcom,tsens-v2";
+			reg = <0 0x0c265000 0 0x1000>,
+			      <0 0x0c223000 0 0x1000>;
+			interrupts-extended = <&pdc 27 IRQ_TYPE_EDGE_RISING>,
+					      <&pdc 29 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+			#qcom,sensors = <8>;
+		};
+
 		apps_smmu: iommu@15000000 {
 			compatible = "qcom,sdm670-smmu-500", "qcom,smmu-500", "arm,mmu-500";
 			reg = <0 0x15000000 0 0x80000>;
@@ -2289,5 +2322,372 @@ cpufreq_hw: cpufreq@17d43000 {
 
 			#freq-domain-cells = <1>;
 		};
+
+		lmh_cluster1: lmh@17d70800 {
+			compatible = "qcom,sdm670-lmh", "qcom,sdm845-lmh";
+			reg = <0 0x17d70800 0 0x400>;
+			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+			cpus = <&cpu6>;
+			qcom,lmh-temp-arm-millicelsius = <65000>;
+			qcom,lmh-temp-low-millicelsius = <94500>;
+			qcom,lmh-temp-high-millicelsius = <95000>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		lmh_cluster0: lmh@17d78800 {
+			compatible = "qcom,sdm670-lmh", "qcom,sdm845-lmh";
+			reg = <0 0x17d78800 0 0x400>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			cpus = <&cpu0>;
+			qcom,lmh-temp-arm-millicelsius = <65000>;
+			qcom,lmh-temp-low-millicelsius = <94500>;
+			qcom,lmh-temp-high-millicelsius = <95000>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+	};
+
+	thermal-zones {
+		aoss0-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 0>;
+
+			trips {
+				aoss0_crit: trip-point0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu0-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 1>;
+
+			trips {
+				cpu0_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu1-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 2>;
+
+			trips {
+				cpu1_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu2-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 3>;
+
+			trips {
+				cpu2_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu3-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 4>;
+
+			trips {
+				cpu3_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cluster0-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 5>;
+
+			trips {
+				cluster0_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cluster1-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 6>;
+
+			trips {
+				cluster1_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu4-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 7>;
+
+			trips {
+				cpu4_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu5-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 8>;
+
+			trips {
+				cpu5_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu6-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 9>;
+
+			trips {
+				cpu6_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu7-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 10>;
+
+			trips {
+				cpu7_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		gpu0-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 11>;
+
+			cooling-maps {
+				map0 {
+					trip = <&gpu0_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
+			trips {
+				gpu0_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				gpu0_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		gpu1-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens0 12>;
+
+			cooling-maps {
+				map0 {
+					trip = <&gpu1_alert0>;
+					cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+
+			trips {
+				gpu1_alert0: trip-point0 {
+					temperature = <95000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				gpu1_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		aoss1-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens1 0>;
+
+			trips {
+				aoss1_crit: trip-point0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		q6-modem-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens1 1>;
+
+			trips {
+				q6_modem_crit: trip-point0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		mem-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens1 2>;
+
+			trips {
+				mem_crit: trip-point1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		wlan-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens1 3>;
+
+			trips {
+				wlan_crit: trip-point0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		q6-hvx-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens1 4>;
+
+			trips {
+				q6_hvx_crit: trip-point0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		camera-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens1 5>;
+
+			trips {
+				camera_crit: trip-point0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		video-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens1 6>;
+
+			trips {
+				video_crit: trip-point0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		modem-thermal {
+			polling-delay-passive = <250>;
+			polling-delay = <1000>;
+
+			thermal-sensors = <&tsens1 7>;
+
+			trips {
+				modem_crit: trip-point0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
 	};
 };
Signature · 1 line
2.53.0