* [PATCH v4 0/5] Allwinner: A523: add support for A523 THS0/1 controllers
@ 2026-05-04 5:02 Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 1/5] dt-bindings: thermal: sun8i: Add " Mikhail Kalashnikov
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-05-04 5:02 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,
Philipp Zabel
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel
This patch series adds temperature sensor support for the Allwinner A523
family of processors (same die with H728/A527/T527)
Based on 7.1-rc1.
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
Allwinner: A523: add support for A523 THS0/1 controllers
.../thermal/allwinner,sun8i-a83t-ths.yaml | 54 ++++-
.../arm64/boot/dts/allwinner/sun55i-a523.dtsi | 154 ++++++++++++
drivers/thermal/sun8i_thermal.c | 226 ++++++++++++++----
3 files changed, 391 insertions(+), 43 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v4 1/5] dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers
2026-05-04 5:02 [PATCH v4 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
@ 2026-05-04 5:02 ` Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 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-05-04 5:02 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,
Philipp Zabel
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel
Add dt-bindings description of the thermal sensors in the A523 processor.
The controllers require activation of the additional frequency of the
associated gpadc controller, so a mod clock property required.
The calibration data is split into two cells that are in different areas
of nvmem. Both controllers require access to both memory cell, so a new
property nvmem-cells has been added. To maintain backward compatibility,
the name of the old cell remains the same and the new nvmem-cell-names is
called calibration-second-part
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
---
.../thermal/allwinner,sun8i-a83t-ths.yaml | 54 +++++++++++++++++--
1 file changed, 51 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..6020413c3 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,29 @@ allOf:
- clock-names
- resets
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - allwinner,sun55i-a523-ths0
+ - allwinner,sun55i-a523-ths1
+ then:
+ properties:
+ clocks:
+ minItems: 2
+ nvmem-cells:
+ minItems: 2
+ nvmem-cell-names:
+ minItems: 2
+ else:
+ properties:
+ nvmem-cells:
+ maxItems: 1
+ nvmem-cell-names:
+ items:
+ - const: calibration
+
required:
- compatible
- reg
@@ -176,4 +207,21 @@ examples:
#thermal-sensor-cells = <1>;
};
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/sun55i-a523-ccu.h>
+ #include <dt-bindings/reset/sun55i-a523-ccu.h>
+
+ 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>;
+ };
...
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/5] thermal/drivers/sun8i: replace devm_reset_control_get to devm_reset_control_get_shared_deasserted
2026-05-04 5:02 [PATCH v4 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 1/5] dt-bindings: thermal: sun8i: Add " Mikhail Kalashnikov
@ 2026-05-04 5:02 ` Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 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-05-04 5:02 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,
Philipp Zabel
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel
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@csie.org>
---
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 226747906..df0c26970 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -342,11 +342,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;
@@ -389,19 +384,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.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 3/5] thermal/drivers/sun8i: get calibration data from two nvmem cells
2026-05-04 5:02 [PATCH v4 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 1/5] dt-bindings: thermal: sun8i: Add " Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 2/5] thermal/drivers/sun8i: replace devm_reset_control_get to devm_reset_control_get_shared_deasserted Mikhail Kalashnikov
@ 2026-05-04 5:02 ` Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 4/5] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 5/5] Allwinner: A523: add " Mikhail Kalashnikov
4 siblings, 0 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-05-04 5:02 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,
Philipp Zabel
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel
The A523 processor has calibration data in two nvmem cell. 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 | 77 ++++++++++++++++++++++-----------
1 file changed, 52 insertions(+), 25 deletions(-)
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index df0c26970..c4aaff8f7 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -301,43 +301,70 @@ 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);
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 (calcell && !IS_ERR(calcell))
nvmem_cell_put(calcell);
return ret;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 4/5] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
2026-05-04 5:02 [PATCH v4 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
` (2 preceding siblings ...)
2026-05-04 5:02 ` [PATCH v4 3/5] thermal/drivers/sun8i: get calibration data from two nvmem cells Mikhail Kalashnikov
@ 2026-05-04 5:02 ` Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 5/5] Allwinner: A523: add " Mikhail Kalashnikov
4 siblings, 0 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-05-04 5:02 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,
Philipp Zabel
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel
The A523 processor has two temperature controllers, THS0 and THS1.
THS0 has only one temperature sensor, which is located in the DRAM.
THS1 does have 3 sensors:
ths1_0 - "big" cores
ths1_1 - "little" cores
ths1_2 - gpu
The datasheet mentions a fourth sensor in the NPU, but lacks any registers
for operation other than calibration registers. The vendor code reads the
value from ths1_2, but uses separate calibration data, so we get two
different values from real one.
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
---
drivers/thermal/sun8i_thermal.c | 133 ++++++++++++++++++++++++++++++++
1 file changed, 133 insertions(+)
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index c4aaff8f7..3b73aafab 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_ABOVE 2736
+#define SUN55I_A523_OFFSET_BELOW 2825
+#define SUN55I_A523_SCALE_ABOVE 74
+#define SUN55I_A523_SCALE_BELOW 65
+
struct tsensor {
struct ths_device *tmdev;
struct thermal_zone_device *tzd;
@@ -114,6 +120,15 @@ static int sun50i_h5_calc_temp(struct ths_device *tmdev,
return -1590 * reg / 10 + 276000;
}
+static int sun55i_a523_calc_temp(struct ths_device *tmdev,
+ int id, int reg)
+{
+ if (reg >= SUN55I_A523_DELIMITER)
+ return SUN55I_A523_SCALE_ABOVE * (SUN55I_A523_OFFSET_ABOVE - reg);
+ else
+ return SUN55I_A523_SCALE_BELOW * (SUN55I_A523_OFFSET_BELOW - reg);
+}
+
static int sun8i_ths_get_temp(struct thermal_zone_device *tz, int *temp)
{
struct tsensor *s = thermal_zone_device_priv(tz);
@@ -299,6 +314,97 @@ static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
return 0;
}
+/*
+ * The A523 nvmem calibration values. The ths1_3 is not used as it
+ * doesn't have its own sensor and doesn't have any internal switch.
+ * Instead, the value from the ths1_2 sensor is used, which gives the
+ * illusion of an independent sensor for NPU and GPU when using
+ * different calibration values.
+ *
+ * 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[0])
+ 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;
+ 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)
+ */
+ cdata = CALIBRATE_DEFAULT -
+ ((sensor_temp - ft_temp) / SUN55I_A523_SCALE_ABOVE);
+
+ 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;
@@ -722,6 +828,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 = 3,
+ .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 },
@@ -732,6 +863,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.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 5/5] Allwinner: A523: add support for A523 THS0/1 controllers
2026-05-04 5:02 [PATCH v4 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
` (3 preceding siblings ...)
2026-05-04 5:02 ` [PATCH v4 4/5] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers Mikhail Kalashnikov
@ 2026-05-04 5:02 ` Mikhail Kalashnikov
4 siblings, 0 replies; 6+ messages in thread
From: Mikhail Kalashnikov @ 2026-05-04 5:02 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,
Philipp Zabel
Cc: linux-pm, devicetree, linux-arm-kernel, linux-sunxi, linux-kernel
The A523 processor has two temperature controllers, THS0 and THS1.
THS0 has only one temperature sensor, which is located in the DRAM.
THS1 does have 3 sensors:
ths1_0 - "big" cores
ths1_1 - "little" cores
ths1_2 - gpu
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 | 154 ++++++++++++++++++
1 file changed, 154 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
index 5afa8d92a..288a4710b 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>;
};
};
@@ -565,12 +574,46 @@ dma: dma-controller@3002000 {
#dma-cells = <1>;
};
+ 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>;
+ };
+
sid: efuse@3006000 {
compatible = "allwinner,sun55i-a523-sid",
"allwinner,sun50i-a64-sid";
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 {
@@ -1087,4 +1130,115 @@ npu: npu@7122000 {
power-domains = <&ppu PD_NPU>;
};
};
+
+ thermal-zones {
+ cpu0_thermal: cpu0-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths1 1>;
+ sustainable-power = <1200>;
+
+ trips {
+ cpu0_threshold: cpu-trip-0 {
+ temperature = <70000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+ cpu0_target: cpu-trip-1 {
+ temperature = <90000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+ cpu0_critical: 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: cpu4-thermal {
+ polling-delay-passive = <100>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths1 0>;
+ sustainable-power = <1600>;
+
+ trips {
+ cpu4_threshold: cpu-trip-0 {
+ temperature = <70000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+ cpu4_target: cpu-trip-1 {
+ temperature = <90000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+ cpu4_critical: 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>;
+
+ gpu-trips {
+ gpu_temp_threshold: gpu-trip-0 {
+ temperature = <60000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+ gpu_temp_target: gpu-trip-1 {
+ temperature = <90000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+ gpu_temp_critical: gpu-trip-2 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+
+ ddr-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&ths0>;
+
+ trips {
+ ddr_temp_critical: ddr-trip-0 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+ };
};
--
2.54.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-05-04 5:04 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-04 5:02 [PATCH v4 0/5] Allwinner: A523: add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 1/5] dt-bindings: thermal: sun8i: Add " Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 2/5] thermal/drivers/sun8i: replace devm_reset_control_get to devm_reset_control_get_shared_deasserted Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 3/5] thermal/drivers/sun8i: get calibration data from two nvmem cells Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 4/5] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers Mikhail Kalashnikov
2026-05-04 5:02 ` [PATCH v4 5/5] Allwinner: A523: add " Mikhail Kalashnikov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox