* [PATCH v6 0/5] Allwinner: A523: add support for A523 THS0/1 controllers
@ 2026-09-13 14:55 Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 1/5] dt-bindings: thermal: sun8i: Add " Mikhail Kalashnikov
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-09-13 14:55 UTC (permalink / raw)
To: Vasily Khoruzhick, Yangtao Li, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
Philipp Zabel, Juan Manuel López Carrillo, Andre Przywara
This patch series adds temperature sensor support for the Allwinner A523
family of processors (same die with H728/A527/T527)
Based on 7.3-rc2.
Changes v6~v5:
1) dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers
- removed the redundant clocks constraint for the A523 controllers
- simplified the else branch to maxItems: 1
- dropped the extra example node
2) thermal/drivers/sun8i: replace devm_reset_control_get to...
- no changes
3) thermal/drivers/sun8i: get calibration data from two nvmem cells
- skip calibration instead of passing a NULL pointer to the calibration
callback when no calibration cell is found
4) thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
- THS1 has four sensors; added the ths1_3 (NPU) calibration data
- renamed the scale/offset constants to match the BSP naming
- check caldata[1] instead of caldata[0] for the factory temperature
- use SCALE_BELOW as the calibration divisor, as in the BSP
- documented that the BSP CAL_COM(5000) is applied through ft_deviation
- updated the commit description
5) arm64: dts: allwinner: sun55i: add thermal sensors
- put nvmem-cell-names on a single line
- dropped unused trip labels, kept the ones referenced by the cooling maps
- renamed the "gpu-trips" container to "trips"
- added the npu-thermal zone for the fourth THS1 sensor
Changes v5~v4:
1) dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers
- added empty line between what and context
- clarified description
- added missing period
2) thermal/drivers/sun8i: replace devm_reset_control_get to...
- updated Reviewed-by tag
3) thermal/drivers/sun8i: get calibration data from two nvmem cells
- removed dead IS_ERR(caldata) check
- replaced NULL/IS_ERR check with IS_ERR_OR_NULL()
4) thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
- clarified description
- added Reviewed-by tag
5) arm64: dts: allwinner: sun55i: add thermal sensors
- fixed patch subject prefix
- clarified description
- sorted thermal-sensor nodes by base address
- added empty lines between trip nodes (DT coding style)
v4 https://lore.kernel.org/linux-sunxi/20260504050245.646078-1-iuncuim@gmail.com/
Changes v4~v3:
1) dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers
- gpadc replaced to mod clock
x) thermal/drivers/sun8i: add gpadc clock
- removed
2) thermal/drivers/sun8i: replace devm_reset_control_get to
- no functional changes
3) thermal/drivers/sun8i: get calibration data from two nvmem cells
- no functional changes
4) thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
- gpadc replaced to mod clock
5) arm64: dts: allwinner: A523: Add thermal sensors and zones
- gpadc replaced to mod clock
v3 https://lore.kernel.org/linux-sunxi/20251025043129.160454-1-iuncuim@gmail.com
Changes v3~v2:
x) dt-bindings: nvmem: SID: Add binding for A523 SID controller
- previously accepted, therefore removed from this version
1) dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers
- added changes as requested by Rob
2) thermal/drivers/sun8i: add gpadc clock
- removed undescribed changes spaces to tabs
3) thermal/drivers/sun8i: replace devm_reset_control_get to
- changed the commit description to the version suggested by wens
- added reviewed-by tag
4) thermal/drivers/sun8i: get calibration data from two nvmem cells
- added spaces in the description block before "*"
5) thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
- added alignment of functions in compliance with open parenthesis
x) arm64: dts: allwinner: A523: Add SID controller node
- previously accepted, therefore removed from this version
6) arm64: dts: allwinner: A523: Add thermal sensors and zones
- no functional changes
Changes v2~v1:
1) dt-bindings: nvmem: SID: Add binding for A523 SID controller
- added new patch
2) dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers
- changed clock order
- added additional nvmem cell with calibration data
- added requirements for new controllers
- added description
3) thermal/drivers/sun8i: add gpadc clock
- removed unnecessary call to clk_prepare_enable() since
devm_clk_get_enabled()includes this
4) thermal/drivers/sun8i: replace devm_reset_control_get to
- original function replaced with devm_reset_control_get_shared_deasserted()
- removed some of the repetitive code executed by
devm_reset_control_get_shared_deasserted()
5) thermal/drivers/sun8i: get calibration data from two nvmem cells
- added possibility to get calibration data from two independent cells
6) thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
- removed magic digits
- changed description of calibration data procedure for A523
- changed numbers of array elements with calibration data
7) arm64: dts: allwinner: A523: Add SID controller node
- fix typo (sun50i->sun55i)
8) arm64: dts: allwinner: A523: Add thermal sensors and zones
- cell with calibration data divided into two
- added passive trips for gpu
- added information that information obtained from BSP
v1: https://lore.kernel.org/linux-sunxi/20250411003827.782544-1-iuncuim@gmail.com
Mikhail Kalashnikov (5):
dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers
thermal/drivers/sun8i: replace devm_reset_control_get to
devm_reset_control_get_shared_deasserted
thermal/drivers/sun8i: get calibration data from two nvmem cells
thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
arm64: dts: allwinner: sun55i: add thermal sensors
.../thermal/allwinner,sun8i-a83t-ths.yaml | 34 ++-
.../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 172 +++++++++++++
drivers/thermal/sun8i_thermal.c | 242 +++++++++++++++---
3 files changed, 403 insertions(+), 45 deletions(-)
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v6 1/5] dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers
2026-09-13 14:55 [PATCH v6 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
@ 2026-09-13 14:55 ` Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 2/5] thermal/drivers/sun8i: replace devm_reset_control_get to devm_reset_control_get_shared_deasserted Mikhail Kalashnikov
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-09-13 14:55 UTC (permalink / raw)
To: Vasily Khoruzhick, Yangtao Li, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
Philipp Zabel, Juan Manuel López Carrillo, Andre Przywara
From: Mikhail Kalashnikov <iuncuim@gmail.com>
Add dt-bindings description of the thermal sensors in the A523 processor.
The calibration data for both thermal controllers (THS0, THS1) is split
across two nvmem cells at different offsets, requiring the two cells
to be read and merged. To maintain backward compatibility, the name of
the old cell remains "calibration" and the new cell is named
"calibration-second-part".
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
---
.../thermal/allwinner,sun8i-a83t-ths.yaml | 34 +++++++++++++++++--
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
index 3e61689f6..792081af5 100644
--- a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
+++ b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
@@ -24,6 +24,8 @@ properties:
- allwinner,sun50i-h5-ths
- allwinner,sun50i-h6-ths
- allwinner,sun50i-h616-ths
+ - allwinner,sun55i-a523-ths0
+ - allwinner,sun55i-a523-ths1
clocks:
minItems: 1
@@ -47,11 +49,16 @@ properties:
maxItems: 1
nvmem-cells:
- maxItems: 1
- description: Calibration data for thermal sensors
+ minItems: 1
+ items:
+ - description: Calibration data for thermal sensors
+ - description: Additional cell in case of separate calibration data
nvmem-cell-names:
- const: calibration
+ minItems: 1
+ items:
+ - const: calibration
+ - const: calibration-second-part
allwinner,sram:
maxItems: 1
@@ -107,6 +114,7 @@ allOf:
enum:
- allwinner,sun8i-h3-ths
- allwinner,sun20i-d1-ths
+ - allwinner,sun55i-a523-ths0
then:
properties:
@@ -132,6 +140,26 @@ allOf:
- clock-names
- resets
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - allwinner,sun55i-a523-ths0
+ - allwinner,sun55i-a523-ths1
+ then:
+ properties:
+ nvmem-cells:
+ minItems: 2
+ nvmem-cell-names:
+ minItems: 2
+ else:
+ properties:
+ nvmem-cells:
+ maxItems: 1
+ nvmem-cell-names:
+ maxItems: 1
+
required:
- compatible
- reg
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v6 2/5] thermal/drivers/sun8i: replace devm_reset_control_get to devm_reset_control_get_shared_deasserted
2026-09-13 14:55 [PATCH v6 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 1/5] dt-bindings: thermal: sun8i: Add " Mikhail Kalashnikov
@ 2026-09-13 14:55 ` Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 3/5] thermal/drivers/sun8i: get calibration data from two nvmem cells Mikhail Kalashnikov
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-09-13 14:55 UTC (permalink / raw)
To: Vasily Khoruzhick, Yangtao Li, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
Philipp Zabel, Juan Manuel López Carrillo, Andre Przywara
From: Mikhail Kalashnikov <iuncuim@gmail.com>
The A523 processor has two temperature controllers, but they share a
common reset line. Make it shared with the shared variant of
devm_reset_control_get(), and also simplify the driver by switching to
devm_reset_control_get_shared_deasserted().
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
---
drivers/thermal/sun8i_thermal.c | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 284684137..1412bce63 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -341,11 +341,6 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev)
return ret;
}
-static void sun8i_ths_reset_control_assert(void *data)
-{
- reset_control_assert(data);
-}
-
static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node)
{
struct platform_device *sram_pdev;
@@ -388,19 +383,10 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
return PTR_ERR(tmdev->regmap);
if (tmdev->chip->has_bus_clk_reset) {
- tmdev->reset = devm_reset_control_get(dev, NULL);
+ tmdev->reset = devm_reset_control_get_shared_deasserted(dev, NULL);
if (IS_ERR(tmdev->reset))
return PTR_ERR(tmdev->reset);
- ret = reset_control_deassert(tmdev->reset);
- if (ret)
- return ret;
-
- ret = devm_add_action_or_reset(dev, sun8i_ths_reset_control_assert,
- tmdev->reset);
- if (ret)
- return ret;
-
tmdev->bus_clk = devm_clk_get_enabled(&pdev->dev, "bus");
if (IS_ERR(tmdev->bus_clk))
return PTR_ERR(tmdev->bus_clk);
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v6 3/5] thermal/drivers/sun8i: get calibration data from two nvmem cells
2026-09-13 14:55 [PATCH v6 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 1/5] dt-bindings: thermal: sun8i: Add " Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 2/5] thermal/drivers/sun8i: replace devm_reset_control_get to devm_reset_control_get_shared_deasserted Mikhail Kalashnikov
@ 2026-09-13 14:55 ` Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 4/5] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 5/5] arm64: dts: allwinner: sun55i: add thermal sensors Mikhail Kalashnikov
4 siblings, 0 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-09-13 14:55 UTC (permalink / raw)
To: Vasily Khoruzhick, Yangtao Li, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
Philipp Zabel, Juan Manuel López Carrillo, Andre Przywara
From: Mikhail Kalashnikov <iuncuim@gmail.com>
The A523 processor has calibration data in two nvmem cells. To be able to
add support, the ability to add data from two cells into one array must be
added.
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
---
drivers/thermal/sun8i_thermal.c | 81 +++++++++++++++++++++------------
1 file changed, 53 insertions(+), 28 deletions(-)
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 1412bce63..360654880 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -300,43 +300,68 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
static int sun8i_ths_calibrate(struct ths_device *tmdev)
{
- struct nvmem_cell *calcell;
+ struct nvmem_cell *calcell = NULL;
struct device *dev = tmdev->dev;
- u16 *caldata;
- size_t callen;
+ struct device_node *np = dev_of_node(dev);
+ struct property *prop;
+ const char *cellname;
+ u8 *caldata = NULL;
+ size_t callen = 0;
int ret = 0;
- calcell = nvmem_cell_get(dev, "calibration");
- if (IS_ERR(calcell)) {
- if (PTR_ERR(calcell) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- /*
- * Even if the external calibration data stored in sid is
- * not accessible, the THS hardware can still work, although
- * the data won't be so accurate.
- *
- * The default value of calibration register is 0x800 for
- * every sensor, and the calibration value is usually 0x7xx
- * or 0x8xx, so they won't be away from the default value
- * for a lot.
- *
- * So here we do not return error if the calibration data is
- * not available, except the probe needs deferring.
- */
- goto out;
+ of_property_for_each_string(np, "nvmem-cell-names", prop, cellname) {
+ size_t len;
+ u8 *caldatapart;
+
+ calcell = of_nvmem_cell_get(np, cellname);
+ if (IS_ERR(calcell)) {
+ if (PTR_ERR(calcell) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ /*
+ * Even if the external calibration data stored in sid is
+ * not accessible, the THS hardware can still work, although
+ * the data won't be so accurate.
+ *
+ * The default value of calibration register is 0x800 for
+ * every sensor, and the calibration value is usually 0x7xx
+ * or 0x8xx, so they won't be away from the default value
+ * for a lot.
+ *
+ * So here we do not return error if the calibration data is
+ * not available, except the probe needs deferring.
+ */
+ goto out;
+ }
+
+ caldatapart = nvmem_cell_read(calcell, &len);
+ nvmem_cell_put(calcell);
+ calcell = NULL;
+ if (IS_ERR(caldatapart)) {
+ ret = PTR_ERR(caldatapart);
+ goto out;
+ }
+
+ caldata = devm_krealloc(dev, caldata, callen + len, GFP_KERNEL);
+ if (!caldata) {
+ kfree(caldatapart);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(caldata + callen, caldatapart, len);
+ callen += len;
+ kfree(caldatapart);
}
- caldata = nvmem_cell_read(calcell, &callen);
- if (IS_ERR(caldata)) {
- ret = PTR_ERR(caldata);
+ if (!caldata)
goto out;
- }
- tmdev->chip->calibrate(tmdev, caldata, callen);
+ tmdev->chip->calibrate(tmdev, (u16 *)caldata, callen);
- kfree(caldata);
+ devm_kfree(dev, caldata);
+ caldata = NULL;
out:
- if (!IS_ERR(calcell))
+ if (!IS_ERR_OR_NULL(calcell))
nvmem_cell_put(calcell);
return ret;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v6 4/5] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
2026-09-13 14:55 [PATCH v6 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
` (2 preceding siblings ...)
2026-09-13 14:55 ` [PATCH v6 3/5] thermal/drivers/sun8i: get calibration data from two nvmem cells Mikhail Kalashnikov
@ 2026-09-13 14:55 ` Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 5/5] arm64: dts: allwinner: sun55i: add thermal sensors Mikhail Kalashnikov
4 siblings, 0 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-09-13 14:55 UTC (permalink / raw)
To: Vasily Khoruzhick, Yangtao Li, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
Philipp Zabel, Juan Manuel López Carrillo, Andre Przywara
From: Mikhail Kalashnikov <iuncuim@gmail.com>
The A523 processor has two temperature controllers, THS0 and THS1.
THS0 has only one temperature sensor, which is located in the DRAM
controller. THS1 does have 4 sensors:
ths1_0 - "big" cores
ths1_1 - "little" cores
ths1_2 - gpu
ths1_3 - npu
The user manual for the T527 processor describes 4 sensors, whereas
the one for the A523 describes only 3. As additional information, the BSP
driver was used, in which the value SUN55IW3_CAL_COM(5000) is used as
the calibration value in the formula; in the mainline driver it is
treated as the ft_deviation value. Also, in the BSP driver the NPU sensor
is used for both the GPU and the NPU — its actual purpose is unclear;
both sensors are functional and show temperature changes depending on
load.
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
---
drivers/thermal/sun8i_thermal.c | 147 ++++++++++++++++++++++++++++++++
1 file changed, 147 insertions(+)
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 360654880..4a81486f8 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -59,6 +59,12 @@
#define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12)
#define SUN50I_H6_THS_DATA_IRQ_STS(x) BIT(x)
+#define SUN55I_A523_DELIMITER 0x7c8
+#define SUN55I_A523_OFFSET_BELOW 2736
+#define SUN55I_A523_OFFSET_ABOVE 2825
+#define SUN55I_A523_SCALE_BELOW 74
+#define SUN55I_A523_SCALE_ABOVE 65
+
struct tsensor {
struct ths_device *tmdev;
struct thermal_zone_device *tzd;
@@ -114,6 +120,21 @@ static int sun50i_h5_calc_temp(struct ths_device *tmdev,
return -1590 * reg / 10 + 276000;
}
+/*
+ * The constant names were chosen in accordance with the BSP driver;
+ * they indicate whether the value corresponds to a high or low
+ * temperature (relative to a value of ~55 °C), rather than the reg value
+ * that was read.
+ */
+static int sun55i_a523_calc_temp(struct ths_device *tmdev,
+ int id, int reg)
+{
+ if (reg >= SUN55I_A523_DELIMITER)
+ return SUN55I_A523_SCALE_BELOW * (SUN55I_A523_OFFSET_BELOW - reg);
+ else
+ return SUN55I_A523_SCALE_ABOVE * (SUN55I_A523_OFFSET_ABOVE - reg);
+}
+
static int sun8i_ths_get_temp(struct thermal_zone_device *tz, int *temp)
{
struct tsensor *s = thermal_zone_device_priv(tz);
@@ -298,6 +319,105 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
return 0;
}
+/*
+ * The A523 calibration data is stored in the eFuse, split across two
+ * nvmem cells. THS1 has four sensors, including ths1_3 which is used
+ * for the NPU, each with its own calibration value. The fields are
+ * packed as shown in the layouts below.
+ *
+ * efuse layout 0x38-0x3F (caldata[0..3]):
+ * caldata[0] caldata[1] caldata[2] caldata[3]
+ * 0 16 24 32 36 48 60 64
+ * +---------------+---------------+---------------+---------------+
+ * | | | temp | ths1_0 | ths1_1 | +
+ * +---------------+---------------+---------------+---------------+
+ *
+ * efuse layout 0x44-0x4B (caldata[4..7]):
+ * caldata[4] caldata[5] caldata[6] caldata[7]
+ * 0 12 16 24 32 36 48 64
+ * +---------------+---------------+---------------+---------------+
+ * | ths1_2 | ths1_3 | ths0 | | +
+ * +---------------+---------------+---------------+---------------+
+ */
+static int sun55i_a523_ths_calibrate(struct ths_device *tmdev,
+ u16 *caldata, int callen)
+{
+ struct device *dev = tmdev->dev;
+ int i, ft_temp;
+
+ if (!caldata[1])
+ return -EINVAL;
+
+ ft_temp = (((caldata[2] << 8) | (caldata[1] >> 8)) & FT_TEMP_MASK) * 100;
+
+ for (i = 0; i < tmdev->chip->sensor_num; i++) {
+ int sensor_reg, sensor_temp, cdata, offset;
+ /*
+ * Chips ths0 and ths1 have common parameters for value
+ * calibration. To separate them we can use the number of
+ * temperature sensors on each chip.
+ * For ths0 this value is 1.
+ */
+ if (tmdev->chip->sensor_num == 1) {
+ sensor_reg = ((caldata[5] >> 8) |
+ (caldata[6] << 8)) & TEMP_CALIB_MASK;
+ } else {
+ switch (i) {
+ case 0:
+ sensor_reg = (caldata[2] >> 4) & TEMP_CALIB_MASK;
+ break;
+ case 1:
+ sensor_reg = caldata[3] & TEMP_CALIB_MASK;
+ break;
+ case 2:
+ sensor_reg = caldata[4] & TEMP_CALIB_MASK;
+ break;
+ case 3:
+ sensor_reg = ((caldata[4] >> 12) |
+ (caldata[5] << 4)) & TEMP_CALIB_MASK;
+ break;
+ default:
+ sensor_reg = 0;
+ break;
+ }
+ }
+
+ sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg);
+
+ /*
+ * Calibration data is CALIBRATE_DEFAULT - (calculated
+ * temperature from sensor reading at factory temperature
+ * minus actual factory temperature) * X (scale from
+ * temperature to register values).
+ *
+ * The BSP's SUN55IW3_CAL_COM(5000) is applied as ft_deviation
+ * in sun8i_ths_get_temp(), after calc_temp(), and therefore
+ * intentionally not repeated here.
+ */
+ cdata = CALIBRATE_DEFAULT -
+ ((sensor_temp - ft_temp) / SUN55I_A523_SCALE_BELOW);
+
+ if (cdata & ~TEMP_CALIB_MASK) {
+ /*
+ * Calibration value more than 12-bit, but calibration
+ * register is 12-bit. In this case, ths hardware can
+ * still work without calibration, although the data
+ * won't be so accurate.
+ */
+ dev_warn(dev, "sensor%d is not calibrated.\n", i);
+ continue;
+ }
+
+ offset = (i % 2) * 16;
+ regmap_update_bits(tmdev->regmap,
+ SUN50I_H6_THS_TEMP_CALIB + (i / 2 * 4),
+ TEMP_CALIB_MASK << offset,
+ cdata << offset);
+ }
+
+ return 0;
+}
+
static int sun8i_ths_calibrate(struct ths_device *tmdev)
{
struct nvmem_cell *calcell = NULL;
@@ -719,6 +839,31 @@ static const struct ths_thermal_chip sun50i_h616_ths = {
.calc_temp = sun8i_ths_calc_temp,
};
+/* The A523 has a shared reset line for both chips */
+static const struct ths_thermal_chip sun55i_a523_ths0 = {
+ .sensor_num = 1,
+ .has_bus_clk_reset = true,
+ .has_mod_clk = true,
+ .ft_deviation = 5000,
+ .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
+ .calibrate = sun55i_a523_ths_calibrate,
+ .init = sun50i_h6_thermal_init,
+ .irq_ack = sun50i_h6_irq_ack,
+ .calc_temp = sun55i_a523_calc_temp,
+};
+
+static const struct ths_thermal_chip sun55i_a523_ths1 = {
+ .sensor_num = 4,
+ .has_bus_clk_reset = true,
+ .has_mod_clk = true,
+ .ft_deviation = 5000,
+ .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
+ .calibrate = sun55i_a523_ths_calibrate,
+ .init = sun50i_h6_thermal_init,
+ .irq_ack = sun50i_h6_irq_ack,
+ .calc_temp = sun55i_a523_calc_temp,
+};
+
static const struct of_device_id of_ths_match[] = {
{ .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
{ .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
@@ -729,6 +874,8 @@ static const struct of_device_id of_ths_match[] = {
{ .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths },
{ .compatible = "allwinner,sun20i-d1-ths", .data = &sun20i_d1_ths },
{ .compatible = "allwinner,sun50i-h616-ths", .data = &sun50i_h616_ths },
+ { .compatible = "allwinner,sun55i-a523-ths0", .data = &sun55i_a523_ths0 },
+ { .compatible = "allwinner,sun55i-a523-ths1", .data = &sun55i_a523_ths1 },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, of_ths_match);
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v6 5/5] arm64: dts: allwinner: sun55i: add thermal sensors
2026-09-13 14:55 [PATCH v6 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
` (3 preceding siblings ...)
2026-09-13 14:55 ` [PATCH v6 4/5] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers Mikhail Kalashnikov
@ 2026-09-13 14:55 ` Mikhail Kalashnikov
4 siblings, 0 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-09-13 14:55 UTC (permalink / raw)
To: Vasily Khoruzhick, Yangtao Li, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel,
Philipp Zabel, Juan Manuel López Carrillo, Andre Przywara
From: Mikhail Kalashnikov <iuncuim@gmail.com>
The A523 processor has two temperature controllers, THS0 and THS1.
THS0 has only one temperature sensor, which is located in the DRAM
controller.
THS1 does have 4 sensors:
ths1_0 - "big" cores
ths1_1 - "little" cores
ths1_2 - gpu
ths1_3 - npu
Add the thermal sensor configuration and the thermal zones.
Trips temperature, polling-delay and sustainable-power parameters are
derived from the manufacturer's BSP.
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
---
.../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 172 ++++++++++++++++++
1 file changed, 172 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
index 85ef492ff..ced544154 100644
--- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
@@ -11,6 +11,7 @@
#include <dt-bindings/reset/sun55i-a523-r-ccu.h>
#include <dt-bindings/power/allwinner,sun55i-a523-ppu.h>
#include <dt-bindings/power/allwinner,sun55i-a523-pck-600.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
interrupt-parent = <&gic>;
@@ -26,6 +27,7 @@ cpu0: cpu@0 {
device_type = "cpu";
reg = <0x000>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
cpu1: cpu@100 {
@@ -33,6 +35,7 @@ cpu1: cpu@100 {
device_type = "cpu";
reg = <0x100>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
cpu2: cpu@200 {
@@ -40,6 +43,7 @@ cpu2: cpu@200 {
device_type = "cpu";
reg = <0x200>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
cpu3: cpu@300 {
@@ -47,6 +51,7 @@ cpu3: cpu@300 {
device_type = "cpu";
reg = <0x300>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
cpu4: cpu@400 {
@@ -54,6 +59,7 @@ cpu4: cpu@400 {
device_type = "cpu";
reg = <0x400>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
cpu5: cpu@500 {
@@ -61,6 +67,7 @@ cpu5: cpu@500 {
device_type = "cpu";
reg = <0x500>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
cpu6: cpu@600 {
@@ -68,6 +75,7 @@ cpu6: cpu@600 {
device_type = "cpu";
reg = <0x600>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
cpu7: cpu@700 {
@@ -75,6 +83,7 @@ cpu7: cpu@700 {
device_type = "cpu";
reg = <0x700>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
};
@@ -380,6 +389,30 @@ gpadc: adc@2009000 {
status = "disabled";
};
+ ths1: thermal-sensor@2009400 {
+ compatible = "allwinner,sun55i-a523-ths1";
+ reg = <0x02009400 0x400>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_GPADC1>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_THS>;
+ nvmem-cells = <&ths_calibration0>, <&ths_calibration1>;
+ nvmem-cell-names = "calibration", "calibration-second-part";
+ #thermal-sensor-cells = <1>;
+ };
+
+ ths0: thermal-sensor@200a000 {
+ compatible = "allwinner,sun55i-a523-ths0";
+ reg = <0x0200a000 0x400>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_GPADC0>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_THS>;
+ nvmem-cells = <&ths_calibration0>, <&ths_calibration1>;
+ nvmem-cell-names = "calibration", "calibration-second-part";
+ #thermal-sensor-cells = <0>;
+ };
+
wdt: watchdog@2050000 {
compatible = "allwinner,sun55i-a523-wdt";
reg = <0x2050000 0x20>;
@@ -611,6 +644,14 @@ sid: efuse@3006000 {
reg = <0x03006000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
+
+ ths_calibration0: ths-calibration0@38 {
+ reg = <0x38 0x8>;
+ };
+
+ ths_calibration1: ths-calibration1@44 {
+ reg = <0x44 0x8>;
+ };
};
gic: interrupt-controller@3400000 {
@@ -1145,4 +1186,135 @@ npu: npu@7122000 {
power-domains = <&ppu PD_NPU>;
};
};
+
+ thermal-zones {
+ cpu0-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths1 1>;
+ sustainable-power = <1200>;
+
+ trips {
+ cpu-trip-0 {
+ temperature = <70000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+
+ cpu0_target: cpu-trip-1 {
+ temperature = <90000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+
+ cpu-trip-2 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu0_target>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu4-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths1 0>;
+ sustainable-power = <1600>;
+
+ trips {
+ cpu-trip-0 {
+ temperature = <70000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+
+ cpu4_target: cpu-trip-1 {
+ temperature = <90000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+
+ cpu-trip-2 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu4_target>;
+ cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ gpu-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths1 2>;
+ sustainable-power = <2400>;
+
+ trips {
+ gpu-trip-0 {
+ temperature = <60000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+
+ gpu-trip-1 {
+ temperature = <90000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+
+ gpu-trip-2 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+
+ npu-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths1 3>;
+
+ trips {
+ npu-trip-0 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+
+ ddr-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&ths0>;
+
+ trips {
+ ddr-trip-0 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+ };
};
--
2.55.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-13 14:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-13 14:55 [PATCH v6 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 1/5] dt-bindings: thermal: sun8i: Add " Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 2/5] thermal/drivers/sun8i: replace devm_reset_control_get to devm_reset_control_get_shared_deasserted Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 3/5] thermal/drivers/sun8i: get calibration data from two nvmem cells Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 4/5] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-09-13 14:55 ` [PATCH v6 5/5] arm64: dts: allwinner: sun55i: add thermal sensors Mikhail Kalashnikov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox