Compare commits
28 commits
Author | SHA1 | Date | |
---|---|---|---|
c176fdb0d5 | |||
c36a86c64b | |||
ccc7d9e2d1 | |||
|
184c4c7797 | ||
27eb87fb05 | |||
|
d2582d9194 | ||
2ab1693f4b | |||
318d591b12 | |||
3773f2a7b2 | |||
16e81693e5 | |||
a0cdb44fc5 | |||
90637b5561 | |||
aba5677583 | |||
5ed3765eff | |||
625e56d034 | |||
938c36c3dc | |||
7cc5f1fefb | |||
cd677b2677 | |||
25a3bb8ff1 | |||
1acdb47889 | |||
52ce0be504 | |||
|
2d0e5fad2d | ||
|
caf80fef03 | ||
|
5e2f56fabe | ||
|
86f79621b0 | ||
|
ee05fcfcf0 | ||
|
5f50ac2dbd | ||
|
2fc24934a0 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
*.ko
|
||||
*.o
|
||||
*.mod
|
||||
*.mod.c
|
||||
.tmp_versions/
|
||||
*.order
|
||||
|
|
7
Makefile
7
Makefile
|
@ -1,7 +1,9 @@
|
|||
VERSION := 0.1.9
|
||||
VERSION := 0.2.0
|
||||
TARGET := $(shell uname -r)
|
||||
DKMS_ROOT_PATH := /usr/src/zenpower-$(VERSION)
|
||||
|
||||
KBUILD_CFLAGS += -Wno-implicit-fallthrough
|
||||
|
||||
KERNEL_MODULES := /lib/modules/$(TARGET)
|
||||
|
||||
ifneq ("","$(wildcard /usr/src/linux-headers-$(TARGET)/*)")
|
||||
|
@ -30,7 +32,8 @@ clean:
|
|||
@$(MAKE) -C $(KERNEL_BUILD) M=$(CURDIR) clean
|
||||
|
||||
dkms-install:
|
||||
mkdir $(DKMS_ROOT_PATH)
|
||||
dkms --version >> /dev/null
|
||||
mkdir -p $(DKMS_ROOT_PATH)
|
||||
cp $(CURDIR)/dkms.conf $(DKMS_ROOT_PATH)
|
||||
cp $(CURDIR)/Makefile $(DKMS_ROOT_PATH)
|
||||
cp $(CURDIR)/zenpower.c $(DKMS_ROOT_PATH)
|
||||
|
|
24
README.md
24
README.md
|
@ -1,23 +1,29 @@
|
|||
# Zenpower
|
||||
Zenpower is Linux kernel driver for reading temperature, voltage(SVI2), current(SVI2) and power(SVI2) for AMD Zen family CPUs.
|
||||
# Zenpower3
|
||||
Zenpower3 is a Linux kernel driver for reading temperature, voltage(SVI2), current(SVI2) and power(SVI2) for AMD Zen family CPUs, now with Zen 3 support!
|
||||
|
||||
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
|
||||
You can install this module via dkms.
|
||||
You can install this module via DKMS.
|
||||
|
||||
### Installation commands for Ubuntu
|
||||
```
|
||||
### Installation for Ubuntu
|
||||
```sh
|
||||
sudo apt install dkms git build-essential linux-headers-$(uname -r)
|
||||
cd ~
|
||||
git clone https://github.com/ocerman/zenpower.git
|
||||
cd zenpower
|
||||
git clone https://github.com/Ta180m/zenpower3.git
|
||||
cd zenpower3
|
||||
sudo make dkms-install
|
||||
```
|
||||
|
||||
### Installation for Arch
|
||||
You can install the [AUR package](https://aur.archlinux.org/packages/zenpower3-dkms/).
|
||||
|
||||
### Installation for Fedora 35+
|
||||
You can install it from the [copr package repo](https://copr.fedorainfracloud.org/coprs/birkch/zenpower3/)
|
||||
|
||||
## Module activation
|
||||
Because zenpower is using same PCI device as k10temp, you have to disable k10temp first.
|
||||
Because zenpower is using same PCI device as k10temp, you have to disable k10temp first. This is automatically done by the AUR package.
|
||||
|
||||
1. Check if k10temp is active. `lsmod | grep k10temp`
|
||||
2. Unload k10temp `sudo modprobe -r k10temp`
|
||||
|
@ -27,7 +33,7 @@ Because zenpower is using same PCI device as k10temp, you have to disable k10tem
|
|||
*If k10temp is not blacklisted, you may have to manually unload k10temp after each restart.
|
||||
|
||||
## Sensors monitoring
|
||||
You can use this app: [zenmonitor](https://github.com/ocerman/zenmonitor), or your favourie sensors monitoring software
|
||||
You can use the `sensors` command, [zenmonitor3](https://github.com/Ta180m/zenmonitor3), or your favorite sensors monitoring software.
|
||||
|
||||
## Update instructions
|
||||
1. Unload zenpower `sudo modprobe -r zenpower`
|
||||
|
|
291
zenpower.c
291
zenpower.c
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Zenpower - Driver for reading temperature, voltage, current and power for AMD 17h CPUs
|
||||
*
|
||||
* Copyright (c) 2018-2020 Ondrej Čerman
|
||||
* Copyright (c) 2018-2021 Anthony Wang
|
||||
*
|
||||
* This driver is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License; either
|
||||
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* forked from the original zenpower by Ondrej Čerman
|
||||
*
|
||||
* based on k10temp by Clemens Ladisch
|
||||
*
|
||||
* Docs:
|
||||
|
@ -36,9 +38,13 @@
|
|||
#include <asm/amd_nb.h>
|
||||
|
||||
MODULE_DESCRIPTION("AMD ZEN family CPU Sensors Driver");
|
||||
MODULE_AUTHOR("Ondrej Čerman");
|
||||
MODULE_AUTHOR("Anthony Wang");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.1.9");
|
||||
MODULE_VERSION("0.2.0");
|
||||
|
||||
static bool zen1_calc;
|
||||
module_param(zen1_calc, bool, 0);
|
||||
MODULE_PARM_DESC(zen1_calc, "Set to 1 to use ZEN1 calculation");
|
||||
|
||||
|
||||
#ifndef PCI_DEVICE_ID_AMD_17H_DF_F3
|
||||
|
@ -53,18 +59,50 @@ MODULE_VERSION("0.1.9");
|
|||
#define PCI_DEVICE_ID_AMD_17H_M30H_DF_F3 0x1493
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_AMD_17H_M60H_DF_F3
|
||||
#define PCI_DEVICE_ID_AMD_17H_M60H_DF_F3 0x144b
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_AMD_17H_M70H_DF_F3
|
||||
#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F3 0x1443
|
||||
#endif
|
||||
|
||||
/* ZEN3 */
|
||||
#ifndef PCI_DEVICE_ID_AMD_19H_DF_F3
|
||||
#define PCI_DEVICE_ID_AMD_19H_DF_F3 0x1653
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_AMD_19H_M40H_DF_F3
|
||||
#define PCI_DEVICE_ID_AMD_19H_M40H_DF_F3 0x167c
|
||||
#endif
|
||||
|
||||
#ifndef PCI_DEVICE_ID_AMD_19H_M50H_DF_F3
|
||||
#define PCI_DEVICE_ID_AMD_19H_M50H_DF_F3 0x166d
|
||||
#endif
|
||||
|
||||
/* F17H_M01H_SVI, should be renamed to something generic I think... */
|
||||
|
||||
#define F17H_M01H_REPORTED_TEMP_CTRL 0x00059800
|
||||
#define F17H_M01H_SVI 0x0005A000
|
||||
#define F17H_M02H_SVI 0x0006F000
|
||||
#define F17H_M01H_SVI_TEL_PLANE0 (F17H_M01H_SVI + 0xC)
|
||||
#define F17H_M01H_SVI_TEL_PLANE1 (F17H_M01H_SVI + 0x10)
|
||||
#define F17H_M30H_SVI_TEL_PLANE0 (F17H_M01H_SVI + 0x14)
|
||||
#define F17H_M30H_SVI_TEL_PLANE1 (F17H_M01H_SVI + 0x10)
|
||||
#define F17H_M60H_SVI_TEL_PLANE0 (F17H_M02H_SVI + 0x38)
|
||||
#define F17H_M60H_SVI_TEL_PLANE1 (F17H_M02H_SVI + 0x3C)
|
||||
#define F17H_M70H_SVI_TEL_PLANE0 (F17H_M01H_SVI + 0x10)
|
||||
#define F17H_M70H_SVI_TEL_PLANE1 (F17H_M01H_SVI + 0xC)
|
||||
/* ZEN3 SP3/TR */
|
||||
#define F19H_M01H_SVI_TEL_PLANE0 (F17H_M01H_SVI + 0x14)
|
||||
#define F19H_M01H_SVI_TEL_PLANE1 (F17H_M01H_SVI + 0x10)
|
||||
/* ZEN3 Ryzen desktop */
|
||||
#define F19H_M21H_SVI_TEL_PLANE0 (F17H_M01H_SVI + 0x10)
|
||||
#define F19H_M21H_SVI_TEL_PLANE1 (F17H_M01H_SVI + 0xC)
|
||||
/* ZEN3 APU */
|
||||
#define F19H_M50H_SVI_TEL_PLANE0 (F17H_M02H_SVI + 0x38)
|
||||
#define F19H_M50H_SVI_TEL_PLANE1 (F17H_M02H_SVI + 0x3C)
|
||||
|
||||
#define F17H_M70H_CCD_TEMP(x) (0x00059954 + ((x) * 4))
|
||||
|
||||
#define F17H_TEMP_ADJUST_MASK 0x80000
|
||||
|
@ -79,17 +117,14 @@ MODULE_VERSION("0.1.9");
|
|||
})
|
||||
#endif
|
||||
|
||||
/* CPUID function 0x80000001, ebx */
|
||||
#define CPUID_PKGTYPE_MASK 0xf0000000
|
||||
#define CPUID_PKGTYPE_SP3 0x40000000 // https://www.sandpile.org/x86/cpuid.htm
|
||||
#define CPUID_PKGTYPE_SP3r2 0x70000000
|
||||
|
||||
struct zenpower_data {
|
||||
struct pci_dev *pdev;
|
||||
void (*read_amdsmn_addr)(struct pci_dev *pdev, u16 node_id, u32 address, u32 *regval);
|
||||
u32 svi_core_addr;
|
||||
u32 svi_soc_addr;
|
||||
u16 node_id;
|
||||
u8 cpu_id;
|
||||
u8 nodes_per_cpu;
|
||||
int temp_offset;
|
||||
bool zen2;
|
||||
bool kernel_smn_support;
|
||||
|
@ -113,6 +148,7 @@ static const struct tctl_offset tctl_offset_table[] = {
|
|||
};
|
||||
|
||||
static DEFINE_MUTEX(nb_smu_ind_mutex);
|
||||
static bool multicpu = false;
|
||||
|
||||
static umode_t zenpower_is_visible(const void *rdata,
|
||||
enum hwmon_sensor_types type,
|
||||
|
@ -211,7 +247,7 @@ int static debug_addrs_arr[] = {
|
|||
F17H_M01H_SVI + 0x14, 0x000598BC, 0x0005994C, F17H_M70H_CCD_TEMP(0),
|
||||
F17H_M70H_CCD_TEMP(1), F17H_M70H_CCD_TEMP(2), F17H_M70H_CCD_TEMP(3),
|
||||
F17H_M70H_CCD_TEMP(4), F17H_M70H_CCD_TEMP(5), F17H_M70H_CCD_TEMP(6),
|
||||
F17H_M70H_CCD_TEMP(7)
|
||||
F17H_M70H_CCD_TEMP(7), F17H_M02H_SVI + 0x38, F17H_M02H_SVI + 0x3C
|
||||
};
|
||||
|
||||
static ssize_t debug_data_show(struct device *dev,
|
||||
|
@ -221,8 +257,10 @@ 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);
|
||||
len += sprintf(buf + len, "node_id = %d\n", data->node_id);
|
||||
len += sprintf(buf + len, "KERN_SUP: %d\n", data->kernel_smn_support);
|
||||
len += sprintf(buf + len, "NODE%d; CPU%d; ", data->node_id, data->cpu_id);
|
||||
len += sprintf(buf + len, "N/CPU: %d\n", data->nodes_per_cpu);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(debug_addrs_arr); i++){
|
||||
data->read_amdsmn_addr(data->pdev, data->node_id, debug_addrs_arr[i], &smndata);
|
||||
len += sprintf(buf + len, "%08x = %08x\n", debug_addrs_arr[i], smndata);
|
||||
|
@ -323,51 +361,118 @@ static int zenpower_read(struct device *dev, enum hwmon_sensor_types type,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const char *zenpower_temp_label[] = {
|
||||
"Tdie",
|
||||
"Tctl",
|
||||
"Tccd1",
|
||||
"Tccd2",
|
||||
"Tccd3",
|
||||
"Tccd4",
|
||||
"Tccd5",
|
||||
"Tccd6",
|
||||
"Tccd7",
|
||||
"Tccd8",
|
||||
static const char *zenpower_temp_label[][10] = {
|
||||
{
|
||||
"Tdie",
|
||||
"Tctl",
|
||||
"Tccd1",
|
||||
"Tccd2",
|
||||
"Tccd3",
|
||||
"Tccd4",
|
||||
"Tccd5",
|
||||
"Tccd6",
|
||||
"Tccd7",
|
||||
"Tccd8",
|
||||
},
|
||||
{
|
||||
"cpu0 Tdie",
|
||||
"cpu0 Tctl",
|
||||
"cpu0 Tccd1",
|
||||
"cpu0 Tccd2",
|
||||
"cpu0 Tccd3",
|
||||
"cpu0 Tccd4",
|
||||
"cpu0 Tccd5",
|
||||
"cpu0 Tccd6",
|
||||
"cpu0 Tccd7",
|
||||
"cpu0 Tccd8",
|
||||
},
|
||||
{
|
||||
"cpu1 Tdie",
|
||||
"cpu1 Tctl",
|
||||
"cpu1 Tccd1",
|
||||
"cpu1 Tccd2",
|
||||
"cpu1 Tccd3",
|
||||
"cpu1 Tccd4",
|
||||
"cpu1 Tccd5",
|
||||
"cpu1 Tccd6",
|
||||
"cpu1 Tccd7",
|
||||
"cpu1 Tccd8",
|
||||
}
|
||||
};
|
||||
|
||||
static const char *zenpower_in_label[] = {
|
||||
"",
|
||||
"SVI2_Core",
|
||||
"SVI2_SoC",
|
||||
static const char *zenpower_in_label[][3] = {
|
||||
{
|
||||
"",
|
||||
"SVI2_Core",
|
||||
"SVI2_SoC",
|
||||
},
|
||||
{
|
||||
"",
|
||||
"cpu0 SVI2_Core",
|
||||
"cpu0 SVI2_SoC",
|
||||
},
|
||||
{
|
||||
"",
|
||||
"cpu1 SVI2_Core",
|
||||
"cpu1 SVI2_SoC",
|
||||
}
|
||||
};
|
||||
|
||||
static const char *zenpower_curr_label[] = {
|
||||
"SVI2_C_Core",
|
||||
"SVI2_C_SoC",
|
||||
static const char *zenpower_curr_label[][2] = {
|
||||
{
|
||||
"SVI2_C_Core",
|
||||
"SVI2_C_SoC",
|
||||
},
|
||||
{
|
||||
"cpu0 SVI2_C_Core",
|
||||
"cpu0 SVI2_C_SoC",
|
||||
},
|
||||
{
|
||||
"cpu1 SVI2_C_Core",
|
||||
"cpu1 SVI2_C_SoC",
|
||||
}
|
||||
};
|
||||
|
||||
static const char *zenpower_power_label[] = {
|
||||
"SVI2_P_Core",
|
||||
"SVI2_P_SoC",
|
||||
static const char *zenpower_power_label[][2] = {
|
||||
{
|
||||
"SVI2_P_Core",
|
||||
"SVI2_P_SoC",
|
||||
},
|
||||
{
|
||||
"cpu0 SVI2_P_Core",
|
||||
"cpu0 SVI2_P_SoC",
|
||||
},
|
||||
{
|
||||
"cpu1 SVI2_P_Core",
|
||||
"cpu1 SVI2_P_SoC",
|
||||
}
|
||||
};
|
||||
|
||||
static int zenpower_read_labels(struct device *dev,
|
||||
enum hwmon_sensor_types type, u32 attr,
|
||||
int channel, const char **str)
|
||||
{
|
||||
struct zenpower_data *data;
|
||||
u8 i = 0;
|
||||
|
||||
if (multicpu) {
|
||||
data = dev_get_drvdata(dev);
|
||||
if (data->cpu_id <= 1)
|
||||
i = data->cpu_id + 1;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case hwmon_temp:
|
||||
*str = zenpower_temp_label[channel];
|
||||
*str = zenpower_temp_label[i][channel];
|
||||
break;
|
||||
case hwmon_in:
|
||||
*str = zenpower_in_label[channel];
|
||||
*str = zenpower_in_label[i][channel];
|
||||
break;
|
||||
case hwmon_curr:
|
||||
*str = zenpower_curr_label[channel];
|
||||
*str = zenpower_curr_label[i][channel];
|
||||
break;
|
||||
case hwmon_power:
|
||||
*str = zenpower_power_label[channel];
|
||||
*str = zenpower_power_label[i][channel];
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -451,7 +556,10 @@ static int zenpower_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct zenpower_data *data;
|
||||
struct device *hwmon_dev;
|
||||
struct pci_dev *misc;
|
||||
int i, ccd_check = 0;
|
||||
bool multinode;
|
||||
u8 node_of_cpu;
|
||||
u32 val;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
|
@ -471,17 +579,26 @@ static int zenpower_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
data->ccd_visible[i] = false;
|
||||
}
|
||||
|
||||
for (id = amd_nb_misc_ids; id->vendor; id++) {
|
||||
if (pdev->vendor == id->vendor && pdev->device == id->device) {
|
||||
for (i = 0; i < amd_nb_num(); i++) {
|
||||
misc = node_to_amd_nb(i)->misc;
|
||||
if (pdev->vendor == misc->vendor && pdev->device == misc->device) {
|
||||
data->kernel_smn_support = true;
|
||||
data->read_amdsmn_addr = kernel_smn_read;
|
||||
data->node_id = amd_pci_dev_to_node_id(pdev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->kernel_smn_support) {
|
||||
data->node_id = amd_pci_dev_to_node_id(pdev);
|
||||
}
|
||||
// CPUID_Fn8000001E_ECX [Node Identifiers] (Core::X86::Cpuid::NodeId)
|
||||
// 10:8 NodesPerProcessor
|
||||
data->nodes_per_cpu = 1 + ((cpuid_ecx(0x8000001E) >> 8) & 0b111);
|
||||
multinode = (data->nodes_per_cpu > 1);
|
||||
|
||||
node_of_cpu = data->node_id % data->nodes_per_cpu;
|
||||
data->cpu_id = data->node_id / data->nodes_per_cpu;
|
||||
|
||||
if (data->cpu_id > 0)
|
||||
multicpu = true;
|
||||
|
||||
if (boot_cpu_data.x86 == 0x17) {
|
||||
switch (boot_cpu_data.x86_model) {
|
||||
|
@ -489,18 +606,15 @@ static int zenpower_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
case 0x8: // Zen+
|
||||
data->amps_visible = true;
|
||||
|
||||
val = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK; // package type
|
||||
if (val == CPUID_PKGTYPE_SP3 || val == CPUID_PKGTYPE_SP3r2) {
|
||||
// Threadripper / EPYC
|
||||
if (data->node_id == 0) {
|
||||
if (multinode) { // Threadripper / EPYC
|
||||
if (node_of_cpu == 0) {
|
||||
data->svi_soc_addr = F17H_M01H_SVI_TEL_PLANE0;
|
||||
}
|
||||
if (data->node_id == 1) {
|
||||
if (node_of_cpu == 1) {
|
||||
data->svi_core_addr = F17H_M01H_SVI_TEL_PLANE0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
// Ryzen
|
||||
else { // Ryzen
|
||||
data->svi_core_addr = F17H_M01H_SVI_TEL_PLANE0;
|
||||
data->svi_soc_addr = F17H_M01H_SVI_TEL_PLANE1;
|
||||
}
|
||||
|
@ -515,26 +629,91 @@ static int zenpower_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
break;
|
||||
|
||||
case 0x31: // Zen2 Threadripper/EPYC
|
||||
data->zen2 = true;
|
||||
/* fixme: add helper for that */
|
||||
if (!zen1_calc) {
|
||||
data->zen2 = true;
|
||||
dev_info(dev, "Using ZEN2 calculation formula.\n");
|
||||
} else {
|
||||
dev_info(dev, "Using ZEN1 calculation formula.\n");
|
||||
}
|
||||
data->amps_visible = true;
|
||||
data->svi_core_addr = F17H_M30H_SVI_TEL_PLANE0;
|
||||
data->svi_soc_addr = F17H_M30H_SVI_TEL_PLANE1;
|
||||
ccd_check = 8;
|
||||
break;
|
||||
|
||||
case 0x60: // Zen2 APU
|
||||
case 0x68: // Zen2 Lucienne
|
||||
if (!zen1_calc) {
|
||||
data->zen2 = true;
|
||||
dev_info(dev, "Using ZEN2 calculation formula.\n");
|
||||
} else {
|
||||
dev_info(dev, "Using ZEN1 calculation formula.\n");
|
||||
}
|
||||
data->amps_visible = true;
|
||||
data->svi_core_addr = F17H_M60H_SVI_TEL_PLANE0;
|
||||
data->svi_soc_addr = F17H_M60H_SVI_TEL_PLANE1;
|
||||
ccd_check = 8;
|
||||
break;
|
||||
|
||||
case 0x71: // Zen2 Ryzen
|
||||
data->zen2 = true;
|
||||
if (!zen1_calc) {
|
||||
data->zen2 = true;
|
||||
dev_info(dev, "Using ZEN2 calculation formula.\n");
|
||||
} else {
|
||||
dev_info(dev, "Using ZEN1 calculation formula.\n");
|
||||
}
|
||||
data->amps_visible = true;
|
||||
data->svi_core_addr = F17H_M70H_SVI_TEL_PLANE0;
|
||||
data->svi_soc_addr = F17H_M70H_SVI_TEL_PLANE1;
|
||||
ccd_check = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
}
|
||||
} else if (boot_cpu_data.x86 == 0x19) {
|
||||
switch (boot_cpu_data.x86_model) {
|
||||
case 0x0 ... 0x1: /* Zen3 SP3/TR */
|
||||
if (!zen1_calc) {
|
||||
/* The code need refactoring but calculation is the same
|
||||
* Is this per Server/Desktop/APU?. EG: each one has his own set of formula(s)?
|
||||
*/
|
||||
data->zen2 = true;
|
||||
dev_info(dev, "Using ZEN2 calculation formula.\n");
|
||||
} else {
|
||||
dev_info(dev, "Using ZEN1 calculation formula.\n");
|
||||
}
|
||||
data->amps_visible = true;
|
||||
data->svi_core_addr = F19H_M01H_SVI_TEL_PLANE0;
|
||||
data->svi_soc_addr = F19H_M01H_SVI_TEL_PLANE1;
|
||||
ccd_check = 8; /* max 64C, 8C per CCD = max 8 CCDs */
|
||||
break;
|
||||
case 0x21: /* Zen3 Ryzen */
|
||||
if (!zen1_calc) {
|
||||
data->zen2 = true;
|
||||
dev_info(dev, "using ZEN2 calculation formula.\n");
|
||||
} else {
|
||||
dev_info(dev, "using ZEN1 calculation formula.\n");
|
||||
}
|
||||
data->amps_visible = true;
|
||||
data->svi_core_addr = F19H_M21H_SVI_TEL_PLANE0;
|
||||
data->svi_soc_addr = F19H_M21H_SVI_TEL_PLANE1;
|
||||
ccd_check = 2; /* max 16C, 8C per CCD = max 2 CCD's */
|
||||
break;
|
||||
case 0x50: /* Zen3 APU */
|
||||
if (!zen1_calc) {
|
||||
data->zen2 = true;
|
||||
dev_info(dev, "using ZEN2 calculation formula.\n");
|
||||
} else {
|
||||
dev_info(dev, "using ZEN1 calculation formula.\n");
|
||||
}
|
||||
data->amps_visible = true;
|
||||
data->svi_core_addr = F19H_M50H_SVI_TEL_PLANE0;
|
||||
data->svi_soc_addr = F19H_M50H_SVI_TEL_PLANE1;
|
||||
ccd_check = 2;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
data->svi_core_addr = F17H_M01H_SVI_TEL_PLANE0;
|
||||
data->svi_soc_addr = F17H_M01H_SVI_TEL_PLANE1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ccd_check; i++) {
|
||||
|
@ -566,7 +745,11 @@ static const struct pci_device_id zenpower_id_table[] = {
|
|||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) },
|
||||
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, zenpower_id_table);
|
||||
|
|
20
zp_read_debug.sh
Executable file
20
zp_read_debug.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
hwmon="/sys/class/hwmon"
|
||||
mdevs=`ls $hwmon`
|
||||
zenmon=""
|
||||
ok=0
|
||||
|
||||
for dev in $mdevs; do
|
||||
path="$hwmon/$dev"
|
||||
devname=`cat $path/name`
|
||||
if [ "$devname" == "zenpower" ]; then
|
||||
cat $path/debug_data
|
||||
ok=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $ok -ne 1 ]; then
|
||||
echo "Zenpower not found"
|
||||
exit
|
||||
fi
|
Loading…
Reference in a new issue