From: Daniel Lezcano <daniel.lezcano@linaro.org>
To: iuncuim <iuncuim@gmail.com>
Cc: Vasily Khoruzhick <anarsoul@gmail.com>,
Yangtao Li <tiny.windzz@gmail.com>, Chen-Yu Tsai <wens@csie.org>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Samuel Holland <samuel@sholland.org>,
Andre Przywara <andre.przywara@arm.com>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Zhang Rui <rui.zhang@intel.com>,
Lukasz Luba <lukasz.luba@arm.com>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Philipp Zabel <p.zabel@pengutronix.de>,
linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org,
Piotr Oniszczuk <piotr.oniszczuk@gmail.com>
Subject: Re: [PATCH 3/6] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers
Date: Fri, 18 Apr 2025 10:41:34 +0200 [thread overview]
Message-ID: <aAIQPtxCDuT2e7vE@mai.linaro.org> (raw)
In-Reply-To: <20250411003827.782544-4-iuncuim@gmail.com>
On Fri, Apr 11, 2025 at 08:38:23AM +0800, Mikhail Kalashnikov wrote:
> 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.
>
> 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 | 134 ++++++++++++++++++++++++++++++++
> 1 file changed, 134 insertions(+)
>
> diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
> index dc4055c9c..919b05a96 100644
> --- a/drivers/thermal/sun8i_thermal.c
> +++ b/drivers/thermal/sun8i_thermal.c
> @@ -116,6 +116,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 >= 0x7c8)
> + return tmdev->chip->scale * (tmdev->chip->offset - reg);
> + else
> + return 65 * (2825 - reg);
> +}
Please use macro instead of litterals
> +
> static int sun8i_ths_get_temp(struct thermal_zone_device *tz, int *temp)
> {
> struct tsensor *s = thermal_zone_device_priv(tz);
> @@ -208,6 +217,100 @@ static irqreturn_t sun8i_irq_thread(int irq, void *data)
> return IRQ_HANDLED;
> }
>
> +
> +/*
> + * 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 0x40-0x43 (caldata[4..5]) - not in use
> + *
> + * efuse layout 0x44-0x4B (caldata[6..9]):
> + * caldata[6] caldata[7] caldata[8] caldata[9]
> + * 0 12 16 24 32 36 48 64
> + * +---------------+---------------+---------------+---------------+
> + * | ths1_2 | ths1_3 | ths0_0 | | +
> + * +---------------+---------------+---------------+---------------+
> + */
> +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[7] >> 8) | (caldata[8] << 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[6] & 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) / tmdev->chip->scale);
> +
> + 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_h3_ths_calibrate(struct ths_device *tmdev,
> u16 *caldata, int callen)
> {
> @@ -721,6 +824,35 @@ 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,
> + .offset = 2736,
> + .scale = 74,
> + .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,
> + .offset = 2736,
> + .scale = 74,
> + .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 },
> @@ -731,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.49.0
>
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
next prev parent reply other threads:[~2025-04-18 8:52 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-11 0:38 [PATCH 0/6] Add support for A523 Thermal system iuncuim
2025-04-11 0:38 ` [PATCH 1/6] thermal/drivers/sun8i: add gpadc clock iuncuim
2025-04-18 8:37 ` Daniel Lezcano
2025-04-11 0:38 ` [PATCH 2/6] thermal/drivers/sun8i: replace devm_reset_control_get to shared iuncuim
2025-06-30 4:53 ` Chen-Yu Tsai
2025-04-11 0:38 ` [PATCH 3/6] thermal/drivers/sun8i: Add support for A523 THS0/1 controllers iuncuim
2025-04-18 8:41 ` Daniel Lezcano [this message]
2025-04-11 0:38 ` [PATCH 4/6] arm64: dts: allwinner: A523: Add SID controller node iuncuim
2025-06-30 4:32 ` Chen-Yu Tsai
2025-04-11 0:38 ` [PATCH 5/6] arm64: dts: allwinner: A523: Add thermal sensors and zones iuncuim
2025-06-30 4:45 ` Chen-Yu Tsai
2025-04-11 0:38 ` [PATCH 6/6] dt-bindings: thermal: sun8i: Add A523 THS0/1 controllers iuncuim
2025-04-11 1:21 ` Rob Herring (Arm)
2025-04-12 0:50 ` Mikhail Kalashnikov
2025-04-11 13:43 ` Rob Herring
2025-04-11 13:11 ` [PATCH 0/6] Add support for A523 Thermal system Rob Herring (Arm)
2025-04-12 0:53 ` Mikhail Kalashnikov
2025-04-13 22:11 ` Andre Przywara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aAIQPtxCDuT2e7vE@mai.linaro.org \
--to=daniel.lezcano@linaro.org \
--cc=anarsoul@gmail.com \
--cc=andre.przywara@arm.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=iuncuim@gmail.com \
--cc=jernej.skrabec@gmail.com \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=lukasz.luba@arm.com \
--cc=p.zabel@pengutronix.de \
--cc=piotr.oniszczuk@gmail.com \
--cc=rafael@kernel.org \
--cc=robh@kernel.org \
--cc=rui.zhang@intel.com \
--cc=samuel@sholland.org \
--cc=tiny.windzz@gmail.com \
--cc=wens@csie.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.