Feature request: Thermal zone for package

I would like to request the inclusion of a thermal zone for measuring the package temperature.

I am wondering if one could wire in the TVS (if it exists) on the MPFS025T
and somehow expose it to Linux in /sys/class/thermal.

This link is what got me going:
https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/UserGuides/microsemi_polarfire_fpga_temperature_and_voltage_sensor_demo_guide_dg0852_v3.pdf

Having a little experience with Verilog, I could probably pull off getting it wired into Gateware
somehow, should it exist, but I would be completely lost trying to do the Linux exposure part.

I would very much welcome any input you might have about the feasibility and implementation.

Right now I’m contemplating either an AXI-Lite slave device or maybe emulating a LM75 on an I2C bus.
Choices, choices… :thinking:

Interesting. That IP block is available on PolarFire SoC.

Thats very promising. Once we figure out whats going on with our build-runners,
I think I’ll start tinkering around with the information from here:
kernel.org/doc/Documentation/devicetree/bindings/thermal/thermal.txt

In the meantime, I’m still all ears for suggestions on implementation!

Given what it says in the thermal.txt file, it looks like you could expose the thermal (and voltage if you wish) to Linux as a simple set of registers. You could for example, add an APB slave port to the FIC3_INITIATOR in the BVF_RISCV_SUBSYSTEM. An APB slave is quite easy to write, so if you know some Verilog, it should be fairly straight forward.
When I tried to get the User Guide for the Temperature and Voltage Sensor Interface from Libero, it didn’t take me anywhere useful, but if you web search on UG0753 you can find it.

A sound suggestion, but perhaps we’re comming at this from the wrong angle,
being hardware people and all. :smiling_face:

This article seem to suggest that all the hard work has already been done for us
and the registers we want, are mapped in memory, just waiting for a driver to expose them.

But enough conjecture; I’ll spend some hours looking at the mpfs trm to see if
this holds true in our universe… :smiling_face:

Interesting. If you look at the PolarFireSoC_Register_Map html bundle (the official reference for IO register mapping) there is nothing listed at 0x37020000. I guess one quick way of checking is to simply read the addresses they specify and see if anything shows up. You don’t need a driver, just the devmem2 program, which may be available in your Linux distro or a version of which can be found here radii/devmem2: devmem2 - simple program to read/write from/to any location in memory. (github.com)

Been fuzzing with devmem2, but so far I’ve gotten little except segmentation faults.

A bing-search on “PFSoC_Regmap-> MPFS Instance Map->PFSoC_Control_SCB” yielded
a hit on a file called PolarFireSoC_Register_Map.zip, inside which, I found this intriguing information:
( thanks @keck9939 )

PFSOC_CONTROL_SCB:

Lo and behold, there be our TVS registers; tantalizingly close, but yet so far away…

As I said, devmem2 is playing coy with me, so if anyone is able to demonstrate
how to get it to work, I’d be most interested!
@Vauban, perhaps we can solicit you to spend 10 minutes on poking this beast?

Especially the registers at offsets 0x24 and 0x28 are of particular interest, I think.

A somewhat educated wild guess: Try this to read the first register in that block which happens to have non-zero read-only bits (0x0710) :

sudo devmem2 0x37020000 w

This is returning 0x7100000 for me. Which looks promising.

This looks like this gets things started:

sudo devmem2 0x37020008 w 0xF

Read the result:

sudo devmem2 0x37020028 w

Now the next thing to figure out is what the value read actually means.

@lranders :

So, I am reading 0x14264E5E from address 0x37020028.
The upper 16 bits are the temperature in the format above. That would be 322 Kelvin → 48.8 Celsius. That’s looks like a plausible die temperature.

1 Like

You’re the man @Vauban!

I was missing the little w at the end…

My board is returning 0x145D4E9C, which means 325K → 51°C, without the fan.
If I turn the fan back on, the temperature drops down to 311K → 38°C.

I’d still like to stick a thermocouple onto the PF, just to see how accurate the sensor is.

All in all, I think I have the required pieces to solve the puzzle.

@lranders could you post the link to the Register Map zip file you found? The one I’ve got doesn’t seem to have any of the sensor registers listed. The Microchip link I used to get my copy must be stale. Thanks and good work.

Actually, never mind. The information is in the zip I’ve got, but it is just buried where I didn’t find it.
For the benefit of others, when you open the home page of the file set, there will be a link to the MPFS Instance Map. The PFSOC_CONTROL_SCB registers are buried in that list about half way down, and when you click on that you will find the temperature sensors.

:smiling_face: :+1:

Progress update!

Standalone LKM is practically done, but unfortunately, it’s clashing with the mpfs-mailbox driver
who claims the same iomem space.

I am currently speaking with Conor Dooley (author), nice guy by the way, and he has suggested I
turn my driver into an auxiliary device and connect it to mpfs-mailbox that way.

This rabbit hole is way deeper than I imagined, but also a lot of fun to figure out.

Quick question @Vauban, can you link me the document you pulled that register description from?

The “PolarFire Family FPGA Security User Guide”. Isn’t that obvious from the title of the document? :rofl:

Strangely there is a logic to it… but definitively last place a normal person would look.

That is indeed the very last place anyone would venture, I must concede.

I really don’t want to ask @RobertCNelson, but search as I might, I can’t seem to
find the procedure to update the kernel and modules with the latest nightly build.

I’d rather not spend 30 minutes writing the whole image via usbdmsc…

How is it done again?

I tried the method that @Vauban suggested to measure the temperature and it works fine. My question is, is it possible to measure the Channel 0—1V voltage supply, Channel 1—1.8V voltage supply, Channel 2—2.5V voltage supply using the same method? Which registers I need to access to do that?
Can I measure the currents also on those channels?
I am a newbie in this field and any help on this is really appreciated.
Thank you.

They’re all available as sensors in Linux already.