Added fallback method (from k10temp) for reading data from SMN
parent
71f658f6c3
commit
d22dd2a438
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION := 0.1.4
|
||||
VERSION := 0.1.5
|
||||
TARGET := $(shell uname -r)
|
||||
DKMS_ROOT_PATH := /usr/src/zenpower-$(VERSION)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Zenpower
|
||||
Zenpower is Linux kernel driver for reading temperature, voltage(SVI2), current(SVI2) and power(SVI2) for AMD Zen family CPUs.
|
||||
|
||||
Make sure that your Linux kernel have support for your CPUs as Zenpower is using kernel calls to read values from SMN.
|
||||
Make sure that your Linux kernel have support for your CPUs as Zenpower is using kernel function `amd_smn_read` to read values from SMN. A fallback method (which may or may not work!) will be used when it is detected that kernel function `amd_smn_read` lacks support for your CPU.
|
||||
For AMD family 17h Model 70h (Ryzen 3000) CPUs you need kernel version 5.3.4 or newer or kernel with this patch: https://patchwork.kernel.org/patch/11043277/
|
||||
|
||||
## Installation
|
||||
|
|
29
zenpower.c
29
zenpower.c
|
@ -7,7 +7,7 @@
|
|||
MODULE_DESCRIPTION("AMD ZEN family CPU Sensors Driver");
|
||||
MODULE_AUTHOR("Ondrej Čerman");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.1.4");
|
||||
MODULE_VERSION("0.1.5");
|
||||
|
||||
// based on k10temp - GPL - (c) 2009 Clemens Ladisch <clemens@ladisch.de>
|
||||
//
|
||||
|
@ -51,6 +51,7 @@ struct zenpower_data {
|
|||
u32 svi_soc_addr;
|
||||
int temp_offset;
|
||||
bool zen2;
|
||||
bool kernel_smn_support;
|
||||
};
|
||||
|
||||
struct tctl_offset {
|
||||
|
@ -68,6 +69,8 @@ static const struct tctl_offset tctl_offset_table[] = {
|
|||
{ 0x17, "AMD Ryzen Threadripper 29", 27000 }, /* 29{20,50,70,90}[W]X */
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(nb_smu_ind_mutex);
|
||||
|
||||
static umode_t zenpower_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int index)
|
||||
{
|
||||
|
@ -226,6 +229,7 @@ static ssize_t debug_data_show(struct device *dev,
|
|||
struct zenpower_data *data = dev_get_drvdata(dev);
|
||||
u32 smndata;
|
||||
|
||||
len += sprintf(buf, "kernel_smn_support = %d\n", data->kernel_smn_support);
|
||||
for (i = 0; i < ARRAY_SIZE(debug_addrs_arr); i++){
|
||||
data->read_amdsmn_addr(data->pdev, debug_addrs_arr[i], &smndata);
|
||||
len += sprintf(buf + len, "%08x = %08x\n", debug_addrs_arr[i], smndata);
|
||||
|
@ -310,11 +314,21 @@ static const struct attribute_group zenpower_group = {
|
|||
__ATTRIBUTE_GROUPS(zenpower);
|
||||
|
||||
|
||||
static void read_amdsmn_addr(struct pci_dev *pdev, u32 address, u32 *regval)
|
||||
static void kernel_smn_read(struct pci_dev *pdev, u32 address, u32 *regval)
|
||||
{
|
||||
amd_smn_read(amd_pci_dev_to_node_id(pdev), address, regval);
|
||||
}
|
||||
|
||||
// fallback method from k10temp
|
||||
// may return inaccurate results on multi-die chips
|
||||
static void nb_index_read(struct pci_dev *pdev, u32 address, u32 *regval)
|
||||
{
|
||||
mutex_lock(&nb_smu_ind_mutex);
|
||||
pci_bus_write_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0x60, address);
|
||||
pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0x64, regval);
|
||||
mutex_unlock(&nb_smu_ind_mutex);
|
||||
}
|
||||
|
||||
static int zenpower_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
@ -329,7 +343,16 @@ static int zenpower_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
|
||||
data->zen2 = false;
|
||||
data->pdev = pdev;
|
||||
data->read_amdsmn_addr = read_amdsmn_addr;
|
||||
data->read_amdsmn_addr = nb_index_read;
|
||||
data->kernel_smn_support = false;
|
||||
|
||||
for (id = amd_nb_misc_ids; id->vendor; id++) {
|
||||
if (pdev->vendor == id->vendor && pdev->device == id->device) {
|
||||
data->kernel_smn_support = true;
|
||||
data->read_amdsmn_addr = kernel_smn_read;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (boot_cpu_data.x86 == 0x17 && boot_cpu_data.x86_model == 0x71) {
|
||||
data->zen2 = true;
|
||||
|
|
Loading…
Reference in New Issue