* Re: [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-14 10:28 ` [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support Haoning CHENG via B4 Relay
@ 2026-07-14 14:35 ` Frank Li
2026-07-15 7:30 ` Lukasz Luba
2026-07-15 9:06 ` Frieder Schrempf
2 siblings, 0 replies; 14+ messages in thread
From: Frank Li @ 2026-07-14 14:35 UTC (permalink / raw)
To: Haoning.CHENG
Cc: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-pm,
devicetree, imx, linux-arm-kernel, linux-kernel
On Tue, Jul 14, 2026 at 06:28:43PM +0800, Haoning CHENG via B4 Relay wrote:
> From: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
>
> Some boards need a small per-design correction to align the reported CPU
> temperature with board-level measurements. Read the optional
> fsl,temp-calibration-offset-millicelsius property from DT and apply it
> uniformly to the i.MX6/6SX/7D calibration formulas.
>
> The offset is applied symmetrically at two points to ensure the thermal
> framework sees calibrated temperatures while hardware thresholds remain
> correctly positioned:
>
> 1. In imx_set_alarm_temp() and imx_set_panic_temp(): the temperature
> threshold is *subtracted* by the offset before being converted to a
> hardware register value. This shifts the hardware IRQ trigger to the
> physical temperature that corresponds to the intended threshold.
>
> 2. In imx_get_temp(): after computing physical temperature from the
> hardware register, the offset is *added* back. The thermal framework
> always sees the calibrated temperature.
>
> For example, if DT sets offset = +3000 m°C (board reads 3°C too low)
> and the passive trip is 95°C:
>
> imx_set_alarm_temp(95000):
> alarm_temp = 95000 - 3000 = 92000
> → hardware register programmed for 92°C physical
>
> Hardware IRQ fires at 92°C physical
>
> imx_get_temp():
> reads hardware, computes 92°C physical
> *temp = 92000 + 3000 = 95000
> → thermal framework sees 95°C → correct trip
>
> When the property is not present, the offset defaults to 0, preserving
> the current behavior.
>
> Signed-off-by: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/thermal/imx_thermal.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
> index 7f7d1116b9d6..d471acc16bce 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
> @@ -85,6 +85,10 @@ enum imx_thermal_trip {
> #define TEMPMON_IMX6SX 2
> #define TEMPMON_IMX7D 3
>
> +/* Calibration offset limits (±20 °C in millicelsius) */
> +#define IMX_TEMP_CALIB_OFFSET_MIN (-20000)
> +#define IMX_TEMP_CALIB_OFFSET_MAX 20000
> +
> struct thermal_soc_data {
> u32 version;
>
> @@ -207,6 +211,7 @@ struct imx_thermal_data {
> struct regmap *tempmon;
> u32 c1, c2; /* See formula in imx_init_calib() */
> int temp_max;
> + s32 calibration_offset;
> int alarm_temp;
> int last_temp;
> bool irq_enabled;
> @@ -223,6 +228,7 @@ static void imx_set_panic_temp(struct imx_thermal_data *data,
> struct regmap *map = data->tempmon;
> int critical_value;
>
> + panic_temp -= data->calibration_offset;
> critical_value = (data->c2 - panic_temp) / data->c1;
>
> regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
> @@ -239,6 +245,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data,
> int alarm_value;
>
> data->alarm_temp = alarm_temp;
> + alarm_temp -= data->calibration_offset;
>
> if (data->socdata->version == TEMPMON_IMX7D) {
> if (alarm_temp >= 0)
> @@ -283,6 +290,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
> *temp = (n_meas - data->c1 + 25) * 1000;
> else
> *temp = data->c2 - n_meas * data->c1;
> + *temp += data->calibration_offset;
>
> /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
> if (data->socdata->version == TEMPMON_IMX6Q) {
> @@ -635,6 +643,25 @@ static int imx_thermal_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, data);
>
> + if (of_property_present(dev->of_node,
> + "fsl,temp-calibration-offset-millicelsius")) {
> + ret = of_property_read_s32(dev->of_node,
> + "fsl,temp-calibration-offset-millicelsius",
> + &data->calibration_offset);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to read calibration offset\n");
> +
> + if (data->calibration_offset < IMX_TEMP_CALIB_OFFSET_MIN ||
> + data->calibration_offset > IMX_TEMP_CALIB_OFFSET_MAX)
> + return dev_err_probe(dev, -EINVAL,
> + "calibration offset %d millicelsius out of range\n",
> + data->calibration_offset);
> +
> + dev_dbg(dev, "calibration offset: %d millicelsius\n",
> + data->calibration_offset);
> + }
> +
> if (of_property_present(dev->of_node, "nvmem-cells")) {
> ret = imx_init_from_nvmem_cells(pdev);
> if (ret)
>
> --
> 2.43.0
>
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-14 10:28 ` [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support Haoning CHENG via B4 Relay
2026-07-14 14:35 ` Frank Li
@ 2026-07-15 7:30 ` Lukasz Luba
2026-07-15 9:06 ` Frieder Schrempf
2 siblings, 0 replies; 14+ messages in thread
From: Lukasz Luba @ 2026-07-15 7:30 UTC (permalink / raw)
To: Haoning.CHENG
Cc: linux-pm, Pengutronix Kernel Team, Shawn Guo, Krzysztof Kozlowski,
Zhang Rui, devicetree, imx, Fabio Estevam, linux-arm-kernel,
linux-kernel, Rafael J. Wysocki, Conor Dooley, Daniel Lezcano,
Rob Herring, Sascha Hauer
On 7/14/26 11:28, Haoning CHENG via B4 Relay wrote:
> From: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
>
> Some boards need a small per-design correction to align the reported CPU
> temperature with board-level measurements. Read the optional
> fsl,temp-calibration-offset-millicelsius property from DT and apply it
> uniformly to the i.MX6/6SX/7D calibration formulas.
>
> The offset is applied symmetrically at two points to ensure the thermal
> framework sees calibrated temperatures while hardware thresholds remain
> correctly positioned:
>
> 1. In imx_set_alarm_temp() and imx_set_panic_temp(): the temperature
> threshold is *subtracted* by the offset before being converted to a
> hardware register value. This shifts the hardware IRQ trigger to the
> physical temperature that corresponds to the intended threshold.
>
> 2. In imx_get_temp(): after computing physical temperature from the
> hardware register, the offset is *added* back. The thermal framework
> always sees the calibrated temperature.
>
> For example, if DT sets offset = +3000 m°C (board reads 3°C too low)
> and the passive trip is 95°C:
>
> imx_set_alarm_temp(95000):
> alarm_temp = 95000 - 3000 = 92000
> → hardware register programmed for 92°C physical
>
> Hardware IRQ fires at 92°C physical
>
> imx_get_temp():
> reads hardware, computes 92°C physical
> *temp = 92000 + 3000 = 95000
> → thermal framework sees 95°C → correct trip
>
> When the property is not present, the offset defaults to 0, preserving
> the current behavior.
>
> Signed-off-by: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
> ---
> drivers/thermal/imx_thermal.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
> index 7f7d1116b9d6..d471acc16bce 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
> @@ -85,6 +85,10 @@ enum imx_thermal_trip {
> #define TEMPMON_IMX6SX 2
> #define TEMPMON_IMX7D 3
>
> +/* Calibration offset limits (±20 °C in millicelsius) */
> +#define IMX_TEMP_CALIB_OFFSET_MIN (-20000)
> +#define IMX_TEMP_CALIB_OFFSET_MAX 20000
> +
> struct thermal_soc_data {
> u32 version;
>
> @@ -207,6 +211,7 @@ struct imx_thermal_data {
> struct regmap *tempmon;
> u32 c1, c2; /* See formula in imx_init_calib() */
> int temp_max;
> + s32 calibration_offset;
> int alarm_temp;
> int last_temp;
> bool irq_enabled;
> @@ -223,6 +228,7 @@ static void imx_set_panic_temp(struct imx_thermal_data *data,
> struct regmap *map = data->tempmon;
> int critical_value;
>
> + panic_temp -= data->calibration_offset;
> critical_value = (data->c2 - panic_temp) / data->c1;
>
> regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
> @@ -239,6 +245,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data,
> int alarm_value;
>
> data->alarm_temp = alarm_temp;
> + alarm_temp -= data->calibration_offset;
>
> if (data->socdata->version == TEMPMON_IMX7D) {
> if (alarm_temp >= 0)
> @@ -283,6 +290,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
> *temp = (n_meas - data->c1 + 25) * 1000;
> else
> *temp = data->c2 - n_meas * data->c1;
> + *temp += data->calibration_offset;
>
> /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
> if (data->socdata->version == TEMPMON_IMX6Q) {
> @@ -635,6 +643,25 @@ static int imx_thermal_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, data);
>
> + if (of_property_present(dev->of_node,
> + "fsl,temp-calibration-offset-millicelsius")) {
> + ret = of_property_read_s32(dev->of_node,
> + "fsl,temp-calibration-offset-millicelsius",
> + &data->calibration_offset);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to read calibration offset\n");
> +
> + if (data->calibration_offset < IMX_TEMP_CALIB_OFFSET_MIN ||
> + data->calibration_offset > IMX_TEMP_CALIB_OFFSET_MAX)
> + return dev_err_probe(dev, -EINVAL,
> + "calibration offset %d millicelsius out of range\n",
> + data->calibration_offset);
> +
> + dev_dbg(dev, "calibration offset: %d millicelsius\n",
> + data->calibration_offset);
> + }
> +
> if (of_property_present(dev->of_node, "nvmem-cells")) {
> ret = imx_init_from_nvmem_cells(pdev);
> if (ret)
>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-14 10:28 ` [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support Haoning CHENG via B4 Relay
2026-07-14 14:35 ` Frank Li
2026-07-15 7:30 ` Lukasz Luba
@ 2026-07-15 9:06 ` Frieder Schrempf
2026-07-17 6:23 ` CHENG Haoning (BCSC/ENG1)
2 siblings, 1 reply; 14+ messages in thread
From: Frieder Schrempf @ 2026-07-15 9:06 UTC (permalink / raw)
To: Haoning.CHENG, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: linux-pm, devicetree, imx, linux-arm-kernel, linux-kernel
On 14.07.26 12:28, Haoning CHENG via B4 Relay wrote:
> From: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
>
> Some boards need a small per-design correction to align the reported CPU
> temperature with board-level measurements. Read the optional
> fsl,temp-calibration-offset-millicelsius property from DT and apply it
> uniformly to the i.MX6/6SX/7D calibration formulas.
>
Sorry to chime in so late. I just want to understand what this
calibration offset is about. Why would there be a need of a
board-specific offset? The sensor is in the SoC and if you add a
board-specific offset, you no longer measure the SoC core temperature,
right?
How would you determine the offset in the first place? How would I know
what fsl,temp-calibration-offset-millicelsius should be set to? I could
put a sensor on the SoC case and use the delta as offset, but then I
would just account for the thermal resistance of the casing and not
measure the SoC core temperature anymore, right?
Maybe I'm just missing something obvious here, so if anyone could
enlighten me that would be appreciated.
Thanks!
> The offset is applied symmetrically at two points to ensure the thermal
> framework sees calibrated temperatures while hardware thresholds remain
> correctly positioned:
>
> 1. In imx_set_alarm_temp() and imx_set_panic_temp(): the temperature
> threshold is *subtracted* by the offset before being converted to a
> hardware register value. This shifts the hardware IRQ trigger to the
> physical temperature that corresponds to the intended threshold.
>
> 2. In imx_get_temp(): after computing physical temperature from the
> hardware register, the offset is *added* back. The thermal framework
> always sees the calibrated temperature.
>
> For example, if DT sets offset = +3000 m°C (board reads 3°C too low)
> and the passive trip is 95°C:
>
> imx_set_alarm_temp(95000):
> alarm_temp = 95000 - 3000 = 92000
> → hardware register programmed for 92°C physical
>
> Hardware IRQ fires at 92°C physical
>
> imx_get_temp():
> reads hardware, computes 92°C physical
> *temp = 92000 + 3000 = 95000
> → thermal framework sees 95°C → correct trip
>
> When the property is not present, the offset defaults to 0, preserving
> the current behavior.
>
> Signed-off-by: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
> ---
> drivers/thermal/imx_thermal.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
> index 7f7d1116b9d6..d471acc16bce 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
> @@ -85,6 +85,10 @@ enum imx_thermal_trip {
> #define TEMPMON_IMX6SX 2
> #define TEMPMON_IMX7D 3
>
> +/* Calibration offset limits (±20 °C in millicelsius) */
> +#define IMX_TEMP_CALIB_OFFSET_MIN (-20000)
> +#define IMX_TEMP_CALIB_OFFSET_MAX 20000
> +
> struct thermal_soc_data {
> u32 version;
>
> @@ -207,6 +211,7 @@ struct imx_thermal_data {
> struct regmap *tempmon;
> u32 c1, c2; /* See formula in imx_init_calib() */
> int temp_max;
> + s32 calibration_offset;
> int alarm_temp;
> int last_temp;
> bool irq_enabled;
> @@ -223,6 +228,7 @@ static void imx_set_panic_temp(struct imx_thermal_data *data,
> struct regmap *map = data->tempmon;
> int critical_value;
>
> + panic_temp -= data->calibration_offset;
> critical_value = (data->c2 - panic_temp) / data->c1;
>
> regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
> @@ -239,6 +245,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data,
> int alarm_value;
>
> data->alarm_temp = alarm_temp;
> + alarm_temp -= data->calibration_offset;
>
> if (data->socdata->version == TEMPMON_IMX7D) {
> if (alarm_temp >= 0)
> @@ -283,6 +290,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
> *temp = (n_meas - data->c1 + 25) * 1000;
> else
> *temp = data->c2 - n_meas * data->c1;
> + *temp += data->calibration_offset;
>
> /* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
> if (data->socdata->version == TEMPMON_IMX6Q) {
> @@ -635,6 +643,25 @@ static int imx_thermal_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, data);
>
> + if (of_property_present(dev->of_node,
> + "fsl,temp-calibration-offset-millicelsius")) {
> + ret = of_property_read_s32(dev->of_node,
> + "fsl,temp-calibration-offset-millicelsius",
> + &data->calibration_offset);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to read calibration offset\n");
> +
> + if (data->calibration_offset < IMX_TEMP_CALIB_OFFSET_MIN ||
> + data->calibration_offset > IMX_TEMP_CALIB_OFFSET_MAX)
> + return dev_err_probe(dev, -EINVAL,
> + "calibration offset %d millicelsius out of range\n",
> + data->calibration_offset);
> +
> + dev_dbg(dev, "calibration offset: %d millicelsius\n",
> + data->calibration_offset);
> + }
> +
> if (of_property_present(dev->of_node, "nvmem-cells")) {
> ret = imx_init_from_nvmem_cells(pdev);
> if (ret)
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-15 9:06 ` Frieder Schrempf
@ 2026-07-17 6:23 ` CHENG Haoning (BCSC/ENG1)
2026-07-20 2:10 ` CHENG Haoning (BCSC/ENG1)
0 siblings, 1 reply; 14+ messages in thread
From: CHENG Haoning (BCSC/ENG1) @ 2026-07-17 6:23 UTC (permalink / raw)
To: Frieder Schrempf
Cc: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
On Wed, Jul 15, 2026 at 11:06:07AM +0200, Frieder Schrempf wrote:
> On 14.07.26 12:28, Haoning CHENG via B4 Relay wrote:
> > Some boards need a small per-design correction to align the reported CPU
> > temperature with board-level measurements. Read the optional
> > fsl,temp-calibration-offset-millicelsius property from DT and apply it
> > uniformly to the i.MX6/6SX/7D calibration formulas.
>
> Sorry to chime in so late. I just want to understand what this
> calibration offset is about. Why would there be a need of a
> board-specific offset? The sensor is in the SoC and if you add a
> board-specific offset, you no longer measure the SoC core temperature,
> right?
>
> How would you determine the offset in the first place? How would I know
> what fsl,temp-calibration-offset-millicelsius should be set to? I could
> put a sensor on the SoC case and use the delta as offset, but then I
> would just account for the thermal resistance of the casing and not
> measure the SoC core temperature anymore, right?
Hi Frieder,
Thanks for pointing this out. Your understanding is correct: after
applying the offset, the reported value no longer represents the raw
SoC die or junction temperature.
For this board, the required "SoC temperature" is the package-surface
temperature. The offset was derived by comparing the TEMPMON reading
against a calibrated external sensor placed near the SoC package
surface under steady-state thermal conditions, and is used to
approximate the package-surface temperature from the internal TEMPMON
reading.
The Linux thermal framework does not require a thermal zone to use a
specific temperature reference. It only requires the reported
temperature and trip points to use the same temperature domain.
In this driver, the offset is added in get_temp() and subtracted in
set_alarm() and set_panic() when programming the hardware thresholds.
This keeps the reported temperature and trip points in the same
package-surface temperature domain. Doing this in the driver is
necessary because the hardware alarm thresholds must also be offset-
corrected; applying the offset only in userspace would cause the
TEMPMON IRQ to fire at the wrong die temperature.
I agree that "calibration offset" is misleading, since this does not
calibrate TEMPMON to a more accurate junction temperature. In the next
revision, the commit messages and DT binding have been updated to
describe this as a board-specific conversion offset from the internal
sensor reading to an estimated package-surface temperature.
Thanks,
Haoning
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-17 6:23 ` CHENG Haoning (BCSC/ENG1)
@ 2026-07-20 2:10 ` CHENG Haoning (BCSC/ENG1)
2026-07-20 8:27 ` Frieder Schrempf
0 siblings, 1 reply; 14+ messages in thread
From: CHENG Haoning (BCSC/ENG1) @ 2026-07-20 2:10 UTC (permalink / raw)
To: Frieder Schrempf
Cc: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
On 2026-07-17 06:23:44+00:00, CHENG Haoning (BCSC/ENG1) wrote:
> On Wed, Jul 15, 2026 at 11:06:07AM +0200, Frieder Schrempf wrote:
>
> > On 14.07.26 12:28, Haoning CHENG via B4 Relay wrote:
> >
> > Sorry to chime in so late. I just want to understand what this
> > calibration offset is about. Why would there be a need of a
> > board-specific offset? The sensor is in the SoC and if you add a
> > board-specific offset, you no longer measure the SoC core temperature,
> > right?
> >
> > How would you determine the offset in the first place? How would I know
> > what fsl,temp-calibration-offset-millicelsius should be set to? I could
> > put a sensor on the SoC case and use the delta as offset, but then I
> > would just account for the thermal resistance of the casing and not
> > measure the SoC core temperature anymore, right?
>
> Hi Frieder,
>
> Thanks for pointing this out. Your understanding is correct: after
> applying the offset, the reported value no longer represents the raw
> SoC die or junction temperature.
>
> For this board, the required "SoC temperature" is the package-surface
> temperature. The offset was derived by comparing the TEMPMON reading
> against a calibrated external sensor placed near the SoC package
> surface under steady-state thermal conditions, and is used to
> approximate the package-surface temperature from the internal TEMPMON
> reading.
>
> The Linux thermal framework does not require a thermal zone to use a
> specific temperature reference. It only requires the reported
> temperature and trip points to use the same temperature domain.
>
> In this driver, the offset is added in get_temp() and subtracted in
> set_alarm() and set_panic() when programming the hardware thresholds.
> This keeps the reported temperature and trip points in the same
> package-surface temperature domain. Doing this in the driver is
> necessary because the hardware alarm thresholds must also be offset-
> corrected; applying the offset only in userspace would cause the
> TEMPMON IRQ to fire at the wrong die temperature.
>
> I agree that "calibration offset" is misleading, since this does not
> calibrate TEMPMON to a more accurate junction temperature. In the next
> revision, the commit messages and DT binding have been updated to
> describe this as a board-specific conversion offset from the internal
> sensor reading to an estimated package-surface temperature.
>
> Thanks,
> Haoning
Hi Frieder,
I need to correct my previous reply. After further discussion with our hardware team, the offset does NOT convert die temperature to package-surface temperature.
Their thermal characterization shows that the raw TEMPMON sensor reading itself deviates from the theoretical junction temperature - this deviation exists even at the die level, before any board or package influence. The offset corrects the sensor reading toward the actual junction temperature, so it is a genuine sensor calibration.
Board-level effects may contribute additionally, but they are not the primary reason for this feature. I apologize for the confusion - my earlier description was inaccurate. The v10 series reflects this corrected understanding.
Thanks,
Haoning
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-20 2:10 ` CHENG Haoning (BCSC/ENG1)
@ 2026-07-20 8:27 ` Frieder Schrempf
2026-07-22 1:42 ` CHENG Haoning (BCSC/ENG1)
0 siblings, 1 reply; 14+ messages in thread
From: Frieder Schrempf @ 2026-07-20 8:27 UTC (permalink / raw)
To: CHENG Haoning (BCSC/ENG1)
Cc: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
On 20.07.26 04:10, CHENG Haoning (BCSC/ENG1) wrote:
> [Sie erhalten nicht h?ufig E-Mails von haoning.cheng@cn.bosch.com. Weitere Informationen, warum dies wichtig ist, finden Sie unter https://aka.ms/LearnAboutSenderIdentification ]
>
> On 2026-07-17 06:23:44+00:00, CHENG Haoning (BCSC/ENG1) wrote:
>> On Wed, Jul 15, 2026 at 11:06:07AM +0200, Frieder Schrempf wrote:
>>
>>> On 14.07.26 12:28, Haoning CHENG via B4 Relay wrote:
>>>
>>> Sorry to chime in so late. I just want to understand what this
>>> calibration offset is about. Why would there be a need of a
>>> board-specific offset? The sensor is in the SoC and if you add a
>>> board-specific offset, you no longer measure the SoC core temperature,
>>> right?
>>>
>>> How would you determine the offset in the first place? How would I know
>>> what fsl,temp-calibration-offset-millicelsius should be set to? I could
>>> put a sensor on the SoC case and use the delta as offset, but then I
>>> would just account for the thermal resistance of the casing and not
>>> measure the SoC core temperature anymore, right?
>>
>> Hi Frieder,
>>
>> Thanks for pointing this out. Your understanding is correct: after
>> applying the offset, the reported value no longer represents the raw
>> SoC die or junction temperature.
>>
>> For this board, the required "SoC temperature" is the package-surface
>> temperature. The offset was derived by comparing the TEMPMON reading
>> against a calibrated external sensor placed near the SoC package
>> surface under steady-state thermal conditions, and is used to
>> approximate the package-surface temperature from the internal TEMPMON
>> reading.
>>
>> The Linux thermal framework does not require a thermal zone to use a
>> specific temperature reference. It only requires the reported
>> temperature and trip points to use the same temperature domain.
>>
>> In this driver, the offset is added in get_temp() and subtracted in
>> set_alarm() and set_panic() when programming the hardware thresholds.
>> This keeps the reported temperature and trip points in the same
>> package-surface temperature domain. Doing this in the driver is
>> necessary because the hardware alarm thresholds must also be offset-
>> corrected; applying the offset only in userspace would cause the
>> TEMPMON IRQ to fire at the wrong die temperature.
>>
>> I agree that "calibration offset" is misleading, since this does not
>> calibrate TEMPMON to a more accurate junction temperature. In the next
>> revision, the commit messages and DT binding have been updated to
>> describe this as a board-specific conversion offset from the internal
>> sensor reading to an estimated package-surface temperature.
>>
>> Thanks,
>> Haoning
> Hi Frieder,
>
> I need to correct my previous reply. After further discussion with our hardware team, the offset does NOT convert die temperature to package-surface temperature.
>
> Their thermal characterization shows that the raw TEMPMON sensor reading itself deviates from the theoretical junction temperature - this deviation exists even at the die level, before any board or package influence. The offset corrects the sensor reading toward the actual junction temperature, so it is a genuine sensor calibration.
>
> Board-level effects may contribute additionally, but they are not the primary reason for this feature. I apologize for the confusion - my earlier description was inaccurate. The v10 series reflects this corrected understanding.
Thanks for the update. If that is the case, then I would still be
interested to know:
1. How is the value for fsl,temp-calibration-offset-millicelsius
determined, if it is not provided by the SoC vendor.
2. Why do we need an additional offset, if there is already a
calibration using the value that NXP stores in the OTPs.
3. Who is supposed to set this property and where does it belong? The
SoC dtsi, the board dts?
Thanks
Frieder
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v8 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-20 8:27 ` Frieder Schrempf
@ 2026-07-22 1:42 ` CHENG Haoning (BCSC/ENG1)
0 siblings, 0 replies; 14+ messages in thread
From: CHENG Haoning (BCSC/ENG1) @ 2026-07-22 1:42 UTC (permalink / raw)
To: Frieder Schrempf
Cc: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
linux-pm@vger.kernel.org, devicetree@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
On 2026-07-20 10:27:33+02:00, Frieder Schrempf wrote:
> On 20.07.26 04:10, CHENG Haoning (BCSC/ENG1) wrote:
>
> > [Sie erhalten nicht h?ufig E-Mails von haoning.cheng@cn.bosch.com. Weitere Informationen, warum dies wichtig ist, finden Sie unter https://aka.ms/LearnAboutSenderIdentification ]
> >
> > On 2026-07-17 06:23:44+00:00, CHENG Haoning (BCSC/ENG1) wrote:
> > Hi Frieder,
> >
> > I need to correct my previous reply. After further discussion with our hardware team, the offset does NOT convert die temperature to package-surface temperature.
> >
> > Their thermal characterization shows that the raw TEMPMON sensor reading itself deviates from the theoretical junction temperature - this deviation exists even at the die level, before any board or package influence. The offset corrects the sensor reading toward the actual junction temperature, so it is a genuine sensor calibration.
> >
> > Board-level effects may contribute additionally, but they are not the primary reason for this feature. I apologize for the confusion - my earlier description was inaccurate. The v10 series reflects this corrected understanding.
>
> Thanks for the update. If that is the case, then I would still be
> interested to know:
>
> 1. How is the value for fsl,temp-calibration-offset-millicelsius
> determined, if it is not provided by the SoC vendor.
>
> 2. Why do we need an additional offset, if there is already a
> calibration using the value that NXP stores in the OTPs.
>
> 3. Who is supposed to set this property and where does it belong? The
> SoC dtsi, the board dts?
>
> Thanks
> Frieder
Hi Frieder,
On 1: The offset was determined during product-level thermal characterization by comparing TEMPMON readings against the junction temperature, as estimated from calibrated external measurements and a validated thermal model. A repeatable residual bias was observed. This offset compensates for that bias and does not replace the NXP factory OTP calibration.
On 2: After applying the NXP factory calibration data and vendor-provided conversion formula, a repeatable residual error remains. The offset compensates for this residual error. This correction is particularly important in the high-temperature range, where accurate trip points are most critical.
The correction must be applied consistently in the kernel to both temperature reporting and hardware alarm programming. imx_set_alarm_temp() converts a thermal trip temperature into the raw threshold value programmed into the TEMPMON hardware comparator. If the correction were applied only in userspace, the hardware IRQ threshold would not correspond to the corrected temperature scale used by the thermal framework.
On 3: The offset was determined and validated by the product integrator's hardware team during development, based on thermal characterization of representative devices. The resulting value is specified in the board DTS because it was derived and validated for this specific board/product configuration. It should not be treated as a generic correction for all i.MX6UL devices.
Thanks,
Haoning
^ permalink raw reply [flat|nested] 14+ messages in thread