[2/2] ARM: dts: sun8i-r40: Add SID node and THS calibration

Message ID 20261003012534.418820-5-otavio@ossystems.com.br (mailing list archive)
State New
Headers
Series Add SID and THS calibration for Allwinner R40 |

Commit Message

Otavio Salvador Oct. 3, 2026, 1:25 a.m. UTC
Without the calibration cell, the THS driver leaves the sensor
calibration registers at their reset value (0x800) and the reported
temperatures drift from the real die temperature by a chip-dependent
offset.

Add the SID node at 0x01c1b000 and wire the thermal sensor to its
factory calibration at eFuse offset 0x40, one 16-bit word for each of
the two sensors.

The R40 user manual gives the size of the thermal sensor key (32 bits)
but not its offset. The vendor SDK key map names 0x48 "thermal_sensor",
but that word is zero on all the boards checked. On an A40i running the
Boardcon vendor kernel, the THS_0_1_CDATA register holds exactly the
eFuse word at 0x40 (0x08780875), which confirms the location.

Tested on two Boardcon EMA40i (A40i) boards: THS_0_1_CDATA now holds
the eFuse word at 0x40 of each chip (0x082d0822 and 0x083d0838) instead
of the reset value 0x08000800.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 arch/arm/boot/dts/allwinner/sun8i-r40.dtsi | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
  

Comments

Andre Przywara Oct. 5, 2026, 9:02 a.m. UTC | #1
Hi Otavio,

thanks for sending the patch!

On 10/3/26 03:25, Otavio Salvador wrote:
> Without the calibration cell, the THS driver leaves the sensor
> calibration registers at their reset value (0x800) and the reported
> temperatures drift from the real die temperature by a chip-dependent
> offset.
> 
> Add the SID node at 0x01c1b000 and wire the thermal sensor to its
> factory calibration at eFuse offset 0x40, one 16-bit word for each of
> the two sensors.
> 
> The R40 user manual gives the size of the thermal sensor key (32 bits)
> but not its offset. The vendor SDK key map names 0x48 "thermal_sensor",
> but that word is zero on all the boards checked. On an A40i running the
> Boardcon vendor kernel, the THS_0_1_CDATA register holds exactly the
> eFuse word at 0x40 (0x08780875), which confirms the location.

So in some U-Boot BSP sources on github I see 
arch/arm/include/asm/arch-sun8iw11p1/sid.h putting the sensor at 0x34 
(like the H3 or A64).
Can you check the values there? I see that Tina-Linux puts them at 0x40, 
as you reported, and it's probably more reliable there than in the 
U-Boot sources, but it's worth double checking.

The rest looks alright (checked the manual and how the compatible string 
is handled in the driver), so if you can confirm that it's 0x40:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Thanks,
Andre

> 
> Tested on two Boardcon EMA40i (A40i) boards: THS_0_1_CDATA now holds
> the eFuse word at 0x40 of each chip (0x082d0822 and 0x083d0838) instead
> of the reset value 0x08000800.
> 
> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
> ---
>   arch/arm/boot/dts/allwinner/sun8i-r40.dtsi | 15 ++++++++++++++-
>   1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi b/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
> index f0ed802a9d08e..c7c9cad695ca4 100644
> --- a/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
> +++ b/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
> @@ -485,6 +485,18 @@ ohci1: usb@1c19400 {
>   			status = "disabled";
>   		};
>   
> +		sid: efuse@1c1b000 {
> +			compatible = "allwinner,sun8i-r40-sid",
> +				     "allwinner,sun50i-a64-sid";
> +			reg = <0x01c1b000 0x400>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			ths_calibration: thermal-sensor-calibration@40 {
> +				reg = <0x40 0x4>;
> +			};
> +		};
> +
>   		ehci2: usb@1c1c000 {
>   			compatible = "allwinner,sun8i-r40-ehci", "generic-ehci";
>   			reg = <0x01c1c000 0x100>;
> @@ -832,7 +844,8 @@ ths: thermal-sensor@1c24c00 {
>   			clock-names = "bus", "mod";
>   			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
>   			resets = <&ccu RST_BUS_THS>;
> -			/* TODO: add nvmem-cells for calibration */
> +			nvmem-cells = <&ths_calibration>;
> +			nvmem-cell-names = "calibration";
>   			#thermal-sensor-cells = <1>;
>   		};
>
  
Otavio Salvador Oct. 5, 2026, 3:49 p.m. UTC | #2
Hi Andre,

Thanks for the review.

Em seg., 5 de out. de 2026 às 06:02, Andre Przywara
<andre.przywara@arm.com> escreveu:
>
> Hi Otavio,
>
> thanks for sending the patch!
>
> On 10/3/26 03:25, Otavio Salvador wrote:
> > Without the calibration cell, the THS driver leaves the sensor
> > calibration registers at their reset value (0x800) and the reported
> > temperatures drift from the real die temperature by a chip-dependent
> > offset.
> >
> > Add the SID node at 0x01c1b000 and wire the thermal sensor to its
> > factory calibration at eFuse offset 0x40, one 16-bit word for each of
> > the two sensors.
> >
> > The R40 user manual gives the size of the thermal sensor key (32 bits)
> > but not its offset. The vendor SDK key map names 0x48 "thermal_sensor",
> > but that word is zero on all the boards checked. On an A40i running the
> > Boardcon vendor kernel, the THS_0_1_CDATA register holds exactly the
> > eFuse word at 0x40 (0x08780875), which confirms the location.
>
> So in some U-Boot BSP sources on github I see
> arch/arm/include/asm/arch-sun8iw11p1/sid.h putting the sensor at 0x34
> (like the H3 or A64).
> Can you check the values there? I see that Tina-Linux puts them at 0x40,
> as you reported, and it's probably more reliable there than in the
> U-Boot sources, but it's worth double checking.
>
> The rest looks alright (checked the manual and how the compatible string
> is handled in the driver), so if you can confirm that it's 0x40:
>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Yes, I checked 0x34. The BPI U-Boot sid.h for sun8iw11p1 puts the
thermal key there, but that word is zero on every A40i I dumped: three
boards on mainline with this patch, and the Boardcon board on its
vendor kernel. 0x48 is zero too. Only 0x40 holds two plausible 12-bit
values:

  board 1: 0x08780875 (vendor kernel, THS_0_1_CDATA = 0x08780875)
  board 2: 0x082d0822
  board 3: 0x083d0838

The value differs per board, and on the vendor kernel THS_0_1_CDATA
holds exactly the word at 0x40. With this patch, CDATA on boards 2 and
3 also matches their word at 0x40. So 0x40 it is, matching Tina Linux.

I also compared the MMIO window at SID + 0x200 with the register-based
readout (the H3 method) across several boots. All 64 words matched, so
the R40 doesn't seem to have the H3 readout problem.

Best regards,
Otavio
  
Andre Przywara Oct. 5, 2026, 5:54 p.m. UTC | #3
On Mon, 5 Oct 2026 12:49:57 -0300
Otavio Salvador <otavio.salvador@ossystems.com.br> wrote:

Hi Otavio,

> Thanks for the review.
> 
> Em seg., 5 de out. de 2026 às 06:02, Andre Przywara
> <andre.przywara@arm.com> escreveu:
> >
> > Hi Otavio,
> >
> > thanks for sending the patch!
> >
> > On 10/3/26 03:25, Otavio Salvador wrote:
> > > Without the calibration cell, the THS driver leaves the sensor
> > > calibration registers at their reset value (0x800) and the reported
> > > temperatures drift from the real die temperature by a chip-dependent
> > > offset.
> > >
> > > Add the SID node at 0x01c1b000 and wire the thermal sensor to its
> > > factory calibration at eFuse offset 0x40, one 16-bit word for each of
> > > the two sensors.
> > >
> > > The R40 user manual gives the size of the thermal sensor key (32 bits)
> > > but not its offset. The vendor SDK key map names 0x48 "thermal_sensor",
> > > but that word is zero on all the boards checked. On an A40i running the
> > > Boardcon vendor kernel, the THS_0_1_CDATA register holds exactly the
> > > eFuse word at 0x40 (0x08780875), which confirms the location.
> >
> > So in some U-Boot BSP sources on github I see
> > arch/arm/include/asm/arch-sun8iw11p1/sid.h putting the sensor at 0x34
> > (like the H3 or A64).
> > Can you check the values there? I see that Tina-Linux puts them at 0x40,
> > as you reported, and it's probably more reliable there than in the
> > U-Boot sources, but it's worth double checking.
> >
> > The rest looks alright (checked the manual and how the compatible string
> > is handled in the driver), so if you can confirm that it's 0x40:
> >
> > Reviewed-by: Andre Przywara <andre.przywara@arm.com>
> 
> Yes, I checked 0x34. The BPI U-Boot sid.h for sun8iw11p1 puts the
> thermal key there, but that word is zero on every A40i I dumped: three
> boards on mainline with this patch, and the Boardcon board on its
> vendor kernel. 0x48 is zero too. Only 0x40 holds two plausible 12-bit
> values:

Yes, I found my BananaPi-M2 Berry, and can confirm that 0x34 holds 0,
and 0x40 reads 0x085a0857.

So all fine, 0x40 it is.

Thanks for checking, and my tag of course stands.

> 
>   board 1: 0x08780875 (vendor kernel, THS_0_1_CDATA = 0x08780875)
>   board 2: 0x082d0822
>   board 3: 0x083d0838
> 
> The value differs per board, and on the vendor kernel THS_0_1_CDATA
> holds exactly the word at 0x40. With this patch, CDATA on boards 2 and
> 3 also matches their word at 0x40. So 0x40 it is, matching Tina Linux.
> 
> I also compared the MMIO window at SID + 0x200 with the register-based
> readout (the H3 method) across several boots. All 64 words matched, so
> the R40 doesn't seem to have the H3 readout problem.

Yes, we have never seen this issue again, it seems to have been a
one-off bug.

Cheers,
Andre
  

Patch

diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi b/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
index f0ed802a9d08e..c7c9cad695ca4 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-r40.dtsi
@@ -485,6 +485,18 @@  ohci1: usb@1c19400 {
 			status = "disabled";
 		};
 
+		sid: efuse@1c1b000 {
+			compatible = "allwinner,sun8i-r40-sid",
+				     "allwinner,sun50i-a64-sid";
+			reg = <0x01c1b000 0x400>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			ths_calibration: thermal-sensor-calibration@40 {
+				reg = <0x40 0x4>;
+			};
+		};
+
 		ehci2: usb@1c1c000 {
 			compatible = "allwinner,sun8i-r40-ehci", "generic-ehci";
 			reg = <0x01c1c000 0x100>;
@@ -832,7 +844,8 @@  ths: thermal-sensor@1c24c00 {
 			clock-names = "bus", "mod";
 			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 			resets = <&ccu RST_BUS_THS>;
-			/* TODO: add nvmem-cells for calibration */
+			nvmem-cells = <&ths_calibration>;
+			nvmem-cell-names = "calibration";
 			#thermal-sensor-cells = <1>;
 		};