Thread (17 messages) 17 messages, 5 authors, 2026-01-21

RE: [PATCH v5 5/5] thermal: renesas: rzg3e: add support for RZ/T2H and RZ/N2H

From: Cosmin-Gabriel Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Date: 2026-01-09 08:51:31
Also in: linux-pm, linux-renesas-soc, lkml

From: Biju Das <biju.das.jz@bp.renesas.com>
Sent: Friday, January 9, 2026 8:12 AM

Hi Geert/Cosmin/John,
quoted
-----Original Message-----
From: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Sent: 08 January 2026 19:52
Subject: [PATCH v5 5/5] thermal: renesas: rzg3e: add support for RZ/T2H and RZ/N2H

The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs expose the temperature calibration via
SMC
quoted
SIP and do not have a reset for the TSU peripheral, and use different minimum and maximum
temperature
quoted
values compared to the already supported RZ/G3E.

Although the calibration data is stored in an OTP memory, the OTP itself is not memory-mapped,
access
quoted
to it is done through an OTP controller.

The OTP controller is only accessible from the secure world, but the temperature calibration data
stored in the OTP is exposed via SMC.

Add support for retrieving the calibration data using arm_smcc_smc().

Add a compatible for RZ/T2H, RZ/N2H can use it as a fallback.

Reviewed-by: John Madieu <john.madieu.xa@bp.renesas.com>
Tested-by: John Madieu <john.madieu.xa@bp.renesas.com>
Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
---

V5:
 * add arm-smccc.h include

V4:
 * pick up John's Reviewed-by and Tested-by
 * replace new macro TSU_TEMP_MASK usage with existing macro
   TSU_CODE_MAX

V3:
 * no changes

V2:
 * no changes

 drivers/thermal/renesas/rzg3e_thermal.c | 27 +++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
diff --git a/drivers/thermal/renesas/rzg3e_thermal.c b/drivers/thermal/renesas/rzg3e_thermal.c
index 97c4053303e0..dde021e283b7 100644
--- a/drivers/thermal/renesas/rzg3e_thermal.c
+++ b/drivers/thermal/renesas/rzg3e_thermal.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2025 Renesas Electronics Corporation
  */
+#include <linux/arm-smccc.h>
 #include <linux/clk.h>
 #include <linux/cleanup.h>
 #include <linux/delay.h>
@@ -70,6 +71,10 @@
 #define TSU_POLL_DELAY_US	10	/* Polling interval */
 #define TSU_MIN_CLOCK_RATE	24000000  /* TSU_PCLK minimum 24MHz */

+#define RZ_SIP_SVC_GET_SYSTSU	0x82000022
Maybe add a comment mentioning firmware should
support this index and the otp value is stored in
arm_smccc_res.a0
The fact that the calibration value is stored in .a0 is clear from
the retrieval code, let's not add comments where the code is
straightforward.

Regarding the firmware support, it's obvious that the firmware needs
to support this and that the values don't just magically appear, no?

Let's see what Geert thinks.
quoted
+#define OTP_TSU_REG_ADR_TEMPHI	0x01DC
+#define OTP_TSU_REG_ADR_TEMPLO	0x01DD
+
 struct rzg3e_thermal_priv;

 struct rzg3e_thermal_info {
@@ -362,6 +367,21 @@ static int rzg3e_thermal_get_syscon_trim(struct rzg3e_thermal_priv *priv)
 	return 0;
 }

+static int rzg3e_thermal_get_smc_trim(struct rzg3e_thermal_priv *priv)
+{
+	struct arm_smccc_res local_res;
+
+	arm_smccc_smc(RZ_SIP_SVC_GET_SYSTSU, OTP_TSU_REG_ADR_TEMPLO,
+		      0, 0, 0, 0, 0, 0, &local_res);
+	priv->trmval0 = local_res.a0 & TSU_CODE_MAX;
Do you think it is worth to ask firmware team to return error values in a0
and actual OTP value in a1.

So that driver can check the error code and propagate to the caller.
If we do that, we will have one more variant to handle here, as we cannot
make sure that the TF-A running on the board is always the latest.

Right now things are simple as it's either supported or not supported.

If a0 is some error value, how would you distinguish between an error in
the new variant and a proper value in the old variant? Both cases would
only populate a0.

Also, I'm not sure how much use we can get out of a TF-A error value.

The error that TF-A already returns in SMC_UNK = -1, or 0xFFFFFFFF in u32,
it is pretty standard for SMC calls and the probe() function already checks
against it.
Cheers,
Biju

quoted
+
+	arm_smccc_smc(RZ_SIP_SVC_GET_SYSTSU, OTP_TSU_REG_ADR_TEMPHI,
+		      0, 0, 0, 0, 0, 0, &local_res);
+	priv->trmval1 = local_res.a0 & TSU_CODE_MAX;
+
+	return 0;
+}
+
 static int rzg3e_thermal_probe(struct platform_device *pdev)  {
 	struct device *dev = &pdev->dev;
@@ -524,8 +544,15 @@ static const struct rzg3e_thermal_info rzg3e_thermal_info = {
 	.temp_e_mc = 126000,
 };

+static const struct rzg3e_thermal_info rzt2h_thermal_info = {
+	.get_trim = rzg3e_thermal_get_smc_trim,
+	.temp_d_mc = -40000,
+	.temp_e_mc = 125000,
+};
+
 static const struct of_device_id rzg3e_thermal_dt_ids[] = {
 	{ .compatible = "renesas,r9a09g047-tsu", .data = &rzg3e_thermal_info },
+	{ .compatible = "renesas,r9a09g077-tsu", .data = &rzt2h_thermal_info
+},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, rzg3e_thermal_dt_ids);
--
2.52.0
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help