xref: /linux/Documentation/hwmon/prom21-xhci.rst (revision 3d5e48944e824bddc20d7b874e784f7b279636fe)
1.. SPDX-License-Identifier: GPL-2.0
2
3Kernel driver prom21-xhci
4=========================
5
6Supported chips:
7
8  * AMD Promontory 21 (PROM21) xHCI USB host controller
9
10    Prefix: 'prom21_xhci'
11
12    PCI IDs: 1022:43fc, 1022:43fd
13
14Author:
15
16  - Jihong Min <hurryman2212@gmail.com>
17
18Description
19-----------
20
21This driver exposes the temperature sensor in AMD PROM21 xHCI controllers.
22
23The driver binds to an auxiliary device created by the xHCI PCI driver for
24supported controllers. The sensor value is accessed through a vendor-specific
25index/data register pair in the controller's PCI MMIO BAR.
26The auxiliary device is created by the ``xhci-pci-prom21`` PCI glue driver.
27USB host operation is otherwise delegated to the common ``xhci-pci`` code.
28
29PROM21 is an AMD chipset IP used in single-chip or daisy-chained configurations
30to build AMD 6xx/8xx series chipsets. Since the xHCI controllers are
31integrated in PROM21, this temperature can also be used as a monitor for a
32temperature close to the AMD chipset temperature.
33
34Register access
35---------------
36
37The temperature value is read through a vendor-specific index/data register
38pair in the xHCI PCI MMIO BAR. The driver uses the following byte offsets from
39the MMIO BAR base:
40
41======================= =====================================================
420x3000			Vendor index register
430x3008			Vendor data register
44======================= =====================================================
45
46The driver saves the current vendor index register value, writes the
47temperature selector ``0x0001e520`` to the vendor index register, reads the
48vendor data register, and restores the previous vendor index value before
49returning. The raw temperature value is the low 8 bits of the vendor data
50register value.
51
52The hwmon core serializes this driver's callbacks, and the driver restores the
53previous index value after each read. This does not provide synchronization
54with firmware, SMM, ACPI AML, or any other user outside this driver.
55
56No public AMD reference is available for the register pair or the raw value.
57The register pair was identified on an X870E system with two PROM21 xHCI
58controllers. One controller was passed through to a Windows VM, and the same
59controller's PCI MMIO BAR was observed from the Linux host while HWiNFO64 was
60reporting the PROM21 xHCI temperature. In the test environment, the reported
61temperature was very stable at idle and the displayed sensor resolution was
62low, which made it possible to look for a consistently repeating MMIO response
63for the same reported temperature. During observation, offset 0x3000 repeatedly
64contained selector ``0x0001e520``. Writing the same selector to offset 0x3000
65from Linux and then reading offset 0x3008 reproduced the same raw value, so the
66offsets are treated as a vendor index/data register pair.
67
68The conversion formula was empirically inferred by matching observed raw
698-bit values against HWiNFO64's reported PROM21 xHCI temperature for the same
70controller. The observed mapping is:
71
72  temp[C] = raw * 0.9066 - 78.624
73
74Runtime PM
75----------
76
77The driver does not wake the xHCI PCI device for hwmon reads. It reads the
78temperature only when the parent device is already active. A read from a
79suspended device returns ``-ENODATA``. After a successful read, the driver
80drops its active-only runtime PM reference and lets the PM core re-evaluate the
81idle state.
82
83Sysfs entries
84-------------
85
86======================= =====================================================
87temp1_input		Temperature in millidegrees Celsius
88======================= =====================================================
89
90The hwmon device name is ``prom21_xhci``. The sysfs path depends on the hwmon
91device number assigned by the kernel. Userspace can locate the device by
92matching the ``name`` attribute:
93
94.. code-block:: sh
95
96   for hwmon in /sys/class/hwmon/hwmon*; do
97           [ "$(cat "$hwmon/name")" = "prom21_xhci" ] || continue
98           cat "$hwmon/temp1_input"
99   done
100
101If the raw register value is invalid, ``temp1_input`` returns ``-ENODATA``.
102