804 lines
23 KiB
Diff
804 lines
23 KiB
Diff
From 8476f1b10b6acc327455c840d3f89a56ec6dedea Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
|
Date: Fri, 07 Nov 2025 12:46:30 +0000
|
|
Subject: [PATCH] [PATCH v3 1/6] dt-bindings: thermal: sun8i: Add A523 THS0/1
|
|
|
|
Add a binding for D1/T113s thermal sensor controller. 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 new clock property has been added.
|
|
|
|
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 | 56 ++++++++++++++++++-
|
|
1 file changed, 53 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..b2f750ef2 100644
|
|
--- a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
|
|
+++ b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
|
|
@@ -24,18 +24,23 @@ properties:
|
|
- allwinner,sun50i-h5-ths
|
|
- allwinner,sun50i-h6-ths
|
|
- allwinner,sun50i-h616-ths
|
|
+ - allwinner,sun55i-a523-ths0
|
|
+ - allwinner,sun55i-a523-ths1
|
|
|
|
clocks:
|
|
minItems: 1
|
|
items:
|
|
- description: Bus Clock
|
|
- description: Module Clock
|
|
+ - description: GPADC Clock
|
|
|
|
clock-names:
|
|
minItems: 1
|
|
+ maxItems: 2
|
|
items:
|
|
- const: bus
|
|
- const: mod
|
|
+ - const: gpadc
|
|
|
|
reg:
|
|
maxItems: 1
|
|
@@ -47,11 +52,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 +117,7 @@ allOf:
|
|
enum:
|
|
- allwinner,sun8i-h3-ths
|
|
- allwinner,sun20i-d1-ths
|
|
+ - allwinner,sun55i-a523-ths0
|
|
|
|
then:
|
|
properties:
|
|
@@ -132,6 +143,32 @@ allOf:
|
|
- clock-names
|
|
- resets
|
|
|
|
+ - if:
|
|
+ properties:
|
|
+ compatible:
|
|
+ contains:
|
|
+ enum:
|
|
+ - allwinner,sun55i-a523-ths0
|
|
+ - allwinner,sun55i-a523-ths1
|
|
+ then:
|
|
+ properties:
|
|
+ clocks:
|
|
+ minItems: 2
|
|
+ clock-names:
|
|
+ enum: [ bus, gpadc ]
|
|
+ nvmem-cells:
|
|
+ minItems: 2
|
|
+ nvmem-cell-names:
|
|
+ minItems: 2
|
|
+ else:
|
|
+ properties:
|
|
+ nvmem-cells:
|
|
+ maxItems: 1
|
|
+ nvmem-cell-names:
|
|
+ maxItems: 1
|
|
+ items:
|
|
+ - const: calibration
|
|
+
|
|
required:
|
|
- compatible
|
|
- reg
|
|
@@ -176,4 +213,17 @@ examples:
|
|
#thermal-sensor-cells = <1>;
|
|
};
|
|
|
|
+ - |
|
|
+ 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", "gpadc";
|
|
+ resets = <&ccu RST_BUS_THS>;
|
|
+ nvmem-cells = <&ths_calibration0>, <&ths_calibration1>;
|
|
+ nvmem-cell-names = "calibration",
|
|
+ "calibration-second-part";
|
|
+ #thermal-sensor-cells = <1>;
|
|
+ };
|
|
...
|
|
|
|
From 955935d64eeca888d0cde1dd3475b5b82ad37331 Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
|
Date: Fri, 07 Nov 2025 12:46:30 +0000
|
|
Subject: [PATCH 2/X] auto-split from bundle
|
|
|
|
Some processors (e.g. Allwinner A523) require GPADC clocking activation for
|
|
temperature sensors to work. So let's add support for enabling it.
|
|
|
|
Signed-off-by: Mikhail Kalashnikov <iuncuim@gmail.com>
|
|
Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
|
|
---
|
|
drivers/thermal/sun8i_thermal.c | 8 ++++++++
|
|
1 file changed, 8 insertions(+)
|
|
|
|
diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
|
|
index 226747906..c02c398b0 100644
|
|
--- a/drivers/thermal/sun8i_thermal.c
|
|
+++ b/drivers/thermal/sun8i_thermal.c
|
|
@@ -66,6 +66,7 @@ struct tsensor {
|
|
};
|
|
|
|
struct ths_thermal_chip {
|
|
+ bool has_gpadc_clk;
|
|
bool has_mod_clk;
|
|
bool has_bus_clk_reset;
|
|
bool needs_sram;
|
|
@@ -89,6 +90,7 @@ struct ths_device {
|
|
struct regmap_field *sram_regmap_field;
|
|
struct reset_control *reset;
|
|
struct clk *bus_clk;
|
|
+ struct clk *gpadc_clk;
|
|
struct clk *mod_clk;
|
|
struct tsensor sensor[MAX_SENSOR_NUM];
|
|
};
|
|
@@ -417,6 +419,12 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ if (tmdev->chip->has_gpadc_clk) {
|
|
+ tmdev->gpadc_clk = devm_clk_get_enabled(&pdev->dev, "gpadc");
|
|
+ if (IS_ERR(tmdev->gpadc_clk))
|
|
+ return PTR_ERR(tmdev->gpadc_clk);
|
|
+ }
|
|
+
|
|
if (tmdev->chip->needs_sram) {
|
|
struct regmap *regmap;
|
|
|
|
From d047c1633c69dca78a06517d595cbbd694a621c7 Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
|
Date: Fri, 07 Nov 2025 12:46:30 +0000
|
|
Subject: [PATCH 3/X] auto-split from bundle
|
|
|
|
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 c02c398b0..aa496e1ba 100644
|
|
--- a/drivers/thermal/sun8i_thermal.c
|
|
+++ b/drivers/thermal/sun8i_thermal.c
|
|
@@ -344,11 +344,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;
|
|
@@ -391,19 +386,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);
|
|
|
|
From c71a090a859ac701105f82166d6ffd03204bfcd0 Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
|
Date: Fri, 07 Nov 2025 12:46:30 +0000
|
|
Subject: [PATCH 4/X] auto-split from bundle
|
|
|
|
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 aa496e1ba..d6d8e13e5 100644
|
|
--- a/drivers/thermal/sun8i_thermal.c
|
|
+++ b/drivers/thermal/sun8i_thermal.c
|
|
@@ -303,43 +303,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;
|
|
}
|
|
|
|
From 6157843778fda7cd704d2c553e7ee9593b831fcb Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
|
Date: Fri, 07 Nov 2025 12:46:30 +0000
|
|
Subject: [PATCH 5/X] auto-split from bundle
|
|
|
|
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 d6d8e13e5..7d35ea3c4 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;
|
|
@@ -116,6 +122,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);
|
|
@@ -301,6 +316,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;
|
|
@@ -730,6 +836,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_gpadc_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_gpadc_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 },
|
|
@@ -740,6 +871,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);
|
|
|
|
From 74804cbc70cbd2aa933b3b9144bc9ed7115a14c5 Mon Sep 17 00:00:00 2001
|
|
From: Mikhail Kalashnikov <iuncuim@gmail.com>
|
|
Date: Fri, 07 Nov 2025 12:46:30 +0000
|
|
Subject: [PATCH 6/X] auto-split from bundle
|
|
|
|
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 7b36c47a3..0cbe73601 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>;
|
|
};
|
|
};
|
|
|
|
@@ -398,12 +407,46 @@ syscon: syscon@3000000 {
|
|
ranges;
|
|
};
|
|
|
|
+ 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", "gpadc";
|
|
+ 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", "gpadc";
|
|
+ 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 {
|
|
@@ -732,4 +775,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>;
|
|
+ };
|
|
+ };
|
|
+ };
|
|
+ };
|
|
};
|