diff options
Diffstat (limited to 'sys-kernel/linux-image-redcore/files/5.5-02-hwmon-add-zenpower-module.patch')
-rw-r--r-- | sys-kernel/linux-image-redcore/files/5.5-02-hwmon-add-zenpower-module.patch | 693 |
1 files changed, 0 insertions, 693 deletions
diff --git a/sys-kernel/linux-image-redcore/files/5.5-02-hwmon-add-zenpower-module.patch b/sys-kernel/linux-image-redcore/files/5.5-02-hwmon-add-zenpower-module.patch deleted file mode 100644 index d155d386..00000000 --- a/sys-kernel/linux-image-redcore/files/5.5-02-hwmon-add-zenpower-module.patch +++ /dev/null @@ -1,693 +0,0 @@ -diff -Naur linux-5.5.5/drivers/hwmon/Kconfig linux-5.5.5-p/drivers/hwmon/Kconfig ---- linux-5.5.5/drivers/hwmon/Kconfig 2020-02-23 19:55:09.002053939 +0100 -+++ linux-5.5.5-p/drivers/hwmon/Kconfig 2020-02-23 19:52:32.184058339 +0100 -@@ -295,6 +295,17 @@ - This driver can also be built as a module. If so, the module - will be called k10temp. - -+config SENSORS_ZENPOWER -+ tristate "AMD Family 17h+ temperature and power sensor" -+ depends on X86 && PCI && AMD_NB -+ help -+ If you say yes here you get support for the temperature and power -+ sensor(s) inside your CPU. Supported are later revisions of -+ the AMD Family 17h microarchitectures. -+ -+ This driver can also be built as a module. If so, the module -+ will be called zenpower. -+ - config SENSORS_FAM15H_POWER - tristate "AMD Family 15h processor power" - depends on X86 && PCI && CPU_SUP_AMD -diff -Naur linux-5.5.5/drivers/hwmon/Makefile linux-5.5.5-p/drivers/hwmon/Makefile ---- linux-5.5.5/drivers/hwmon/Makefile 2020-02-19 19:54:14.000000000 +0100 -+++ linux-5.5.5-p/drivers/hwmon/Makefile 2020-02-23 19:49:35.639936556 +0100 -@@ -87,6 +87,7 @@ - obj-$(CONFIG_SENSORS_JC42) += jc42.o - obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o - obj-$(CONFIG_SENSORS_K10TEMP) += k10temp.o -+obj-$(CONFIG_SENSORS_ZENPOWER) += zenpower.o - obj-$(CONFIG_SENSORS_LINEAGE) += lineage-pem.o - obj-$(CONFIG_SENSORS_LOCHNAGAR) += lochnagar-hwmon.o - obj-$(CONFIG_SENSORS_LM63) += lm63.o -diff -Naur linux-5.5.5/drivers/hwmon/zenpower.c linux-5.5.5-p/drivers/hwmon/zenpower.c ---- linux-5.5.5/drivers/hwmon/zenpower.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.5.5-p/drivers/hwmon/zenpower.c 2020-02-23 19:48:10.473395027 +0100 -@@ -0,0 +1,657 @@ -+/* -+ * Zenpower - Driver for reading temperature, voltage, current and power for AMD 17h CPUs -+ * -+ * Copyright (c) 2018-2020 Ondrej Čerman -+ * -+ * This driver is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This driver is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this driver; if not, see <http://www.gnu.org/licenses/>. -+ * -+ */ -+ -+/* -+ * based on k10temp by Clemens Ladisch -+ * -+ * Docs: -+ * - https://www.kernel.org/doc/Documentation/hwmon/hwmon-kernel-api.txt -+ * - https://developer.amd.com/wp-content/resources/56255_3_03.PDF -+ * -+ * Sources: -+ * - Temp monitoring is from k10temp -+ * - SVI address and voltage formula is from LibreHardwareMonitor -+ * - Current formulas and CCD temp addresses were discovered experimentally -+ */ -+ -+#include <linux/hwmon.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <asm/amd_nb.h> -+ -+MODULE_DESCRIPTION("AMD ZEN family CPU Sensors Driver"); -+MODULE_AUTHOR("Ondrej Čerman"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION("0.1.9"); -+ -+ -+#ifndef PCI_DEVICE_ID_AMD_17H_DF_F3 -+#define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 -+#endif -+ -+#ifndef PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 -+#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb -+#endif -+ -+#ifndef PCI_DEVICE_ID_AMD_17H_M30H_DF_F3 -+#define PCI_DEVICE_ID_AMD_17H_M30H_DF_F3 0x1493 -+#endif -+ -+#ifndef PCI_DEVICE_ID_AMD_17H_M70H_DF_F3 -+#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F3 0x1443 -+#endif -+ -+#define F17H_M01H_REPORTED_TEMP_CTRL 0x00059800 -+#define F17H_M01H_SVI 0x0005A000 -+#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_M70H_SVI_TEL_PLANE0 (F17H_M01H_SVI + 0x10) -+#define F17H_M70H_SVI_TEL_PLANE1 (F17H_M01H_SVI + 0xC) -+#define F17H_M70H_CCD_TEMP(x) (0x00059954 + ((x) * 4)) -+ -+#define F17H_TEMP_ADJUST_MASK 0x80000 -+ -+#ifndef HWMON_CHANNEL_INFO -+#define HWMON_CHANNEL_INFO(stype, ...) \ -+ (&(struct hwmon_channel_info) { \ -+ .type = hwmon_##stype, \ -+ .config = (u32 []) { \ -+ __VA_ARGS__, 0 \ -+ } \ -+ }) -+#endif -+ -+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; -+ bool amps_visible; -+ bool ccd_visible[8]; -+}; -+ -+struct tctl_offset { -+ u8 model; -+ char const *id; -+ int offset; -+}; -+ -+static const struct tctl_offset tctl_offset_table[] = { -+ { 0x17, "AMD Ryzen 5 1600X", 20000 }, -+ { 0x17, "AMD Ryzen 7 1700X", 20000 }, -+ { 0x17, "AMD Ryzen 7 1800X", 20000 }, -+ { 0x17, "AMD Ryzen 7 2700X", 10000 }, -+ { 0x17, "AMD Ryzen Threadripper 19", 27000 }, /* 19{00,20,50}X */ -+ { 0x17, "AMD Ryzen Threadripper 29", 27000 }, /* 29{20,50,70,90}[W]X */ -+}; -+ -+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, -+ u32 attr, int channel) -+{ -+ const struct zenpower_data *data = rdata; -+ -+ switch (type) { -+ case hwmon_temp: -+ if (channel >= 2 && data->ccd_visible[channel-2] == false) // Tccd1-8 -+ return 0; -+ break; -+ -+ case hwmon_curr: -+ case hwmon_power: -+ if (data->amps_visible == false) -+ return 0; -+ if (channel == 0 && data->svi_core_addr == 0) -+ return 0; -+ if (channel == 1 && data->svi_soc_addr == 0) -+ return 0; -+ break; -+ -+ case hwmon_in: -+ if (channel == 0) // fake item to align different indexing, -+ return 0; // see note at zenpower_info -+ if (channel == 1 && data->svi_core_addr == 0) -+ return 0; -+ if (channel == 2 && data->svi_soc_addr == 0) -+ return 0; -+ break; -+ -+ default: -+ break; -+ } -+ -+ return 0444; -+} -+ -+static u32 plane_to_vcc(u32 p) -+{ -+ u32 vdd_cor; -+ vdd_cor = (p >> 16) & 0xff; -+ // U = 1550 - 6.25 * vddcor -+ -+ return 1550 - ((625 * vdd_cor) / 100); -+} -+ -+static u32 get_core_current(u32 plane, bool zen2) -+{ -+ u32 idd_cor, fc; -+ idd_cor = plane & 0xff; -+ -+ // I = 1039.211 * iddcor -+ // I = 658.823 * iddcor -+ fc = zen2 ? 658823 : 1039211; -+ -+ return (fc * idd_cor) / 1000; -+} -+ -+static u32 get_soc_current(u32 plane, bool zen2) -+{ -+ u32 idd_cor, fc; -+ idd_cor = plane & 0xff; -+ -+ // I = 360.772 * iddcor -+ // I = 294.3 * iddcor -+ fc = zen2 ? 294300 : 360772; -+ -+ return (fc * idd_cor) / 1000; -+} -+ -+static unsigned int get_ctl_temp(struct zenpower_data *data) -+{ -+ unsigned int temp; -+ u32 regval; -+ -+ data->read_amdsmn_addr(data->pdev, data->node_id, -+ F17H_M01H_REPORTED_TEMP_CTRL, ®val); -+ temp = (regval >> 21) * 125; -+ if (regval & F17H_TEMP_ADJUST_MASK) -+ temp -= 49000; -+ return temp; -+} -+ -+static unsigned int get_ccd_temp(struct zenpower_data *data, u32 ccd_addr) -+{ -+ u32 regval; -+ data->read_amdsmn_addr(data->pdev, data->node_id, ccd_addr, ®val); -+ -+ return (regval & 0xfff) * 125 - 305000; -+} -+ -+int static debug_addrs_arr[] = { -+ F17H_M01H_SVI + 0x8, F17H_M01H_SVI + 0xC, F17H_M01H_SVI + 0x10, -+ 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) -+}; -+ -+static ssize_t debug_data_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ int i, len = 0; -+ struct zenpower_data *data = dev_get_drvdata(dev); -+ u32 smndata; -+ -+ 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); -+ } -+ -+ return len; -+} -+ -+static int zenpower_read(struct device *dev, enum hwmon_sensor_types type, -+ u32 attr, int channel, long *val) -+{ -+ struct zenpower_data *data = dev_get_drvdata(dev); -+ u32 plane; -+ -+ switch (type) { -+ -+ // Temperatures -+ case hwmon_temp: -+ switch (attr) { -+ case hwmon_temp_input: -+ switch (channel) { -+ case 0: // Tdie -+ *val = get_ctl_temp(data) - data->temp_offset; -+ break; -+ case 1: // Tctl -+ *val = get_ctl_temp(data); -+ break; -+ case 2 ... 9: // Tccd1-8 -+ *val = get_ccd_temp(data, F17H_M70H_CCD_TEMP(channel-2)); -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ break; -+ -+ case hwmon_temp_max: // Tdie max -+ // source: https://www.amd.com/en/products/cpu/amd-ryzen-7-3700x -+ // other cpus have also same* Tmax on AMD website -+ // * = when taking into consideration a tctl offset -+ *val = 95 * 1000; -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ break; -+ -+ // Voltage -+ case hwmon_in: -+ if (channel == 0) -+ return -EOPNOTSUPP; -+ channel -= 1; // hwmon_in have different indexing, see note at zenpower_info -+ // fall through -+ // Power / Current -+ case hwmon_curr: -+ case hwmon_power: -+ if (attr != hwmon_in_input && attr != hwmon_curr_input && -+ attr != hwmon_power_input) { -+ return -EOPNOTSUPP; -+ } -+ -+ switch (channel) { -+ case 0: // Core SVI2 -+ data->read_amdsmn_addr(data->pdev, data->node_id, -+ data->svi_core_addr, &plane); -+ break; -+ case 1: // SoC SVI2 -+ data->read_amdsmn_addr(data->pdev, data->node_id, -+ data->svi_soc_addr, &plane); -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ switch (type) { -+ case hwmon_in: -+ *val = plane_to_vcc(plane); -+ break; -+ case hwmon_curr: -+ *val = (channel == 0) ? -+ get_core_current(plane, data->zen2): -+ get_soc_current(plane, data->zen2); -+ break; -+ case hwmon_power: -+ *val = (channel == 0) ? -+ get_core_current(plane, data->zen2) * plane_to_vcc(plane): -+ get_soc_current(plane, data->zen2) * plane_to_vcc(plane); -+ break; -+ default: -+ break; -+ } -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+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[][3] = { -+ { -+ "", -+ "SVI2_Core", -+ "SVI2_SoC", -+ }, -+ { -+ "", -+ "cpu0 SVI2_Core", -+ "cpu0 SVI2_SoC", -+ }, -+ { -+ "", -+ "cpu1 SVI2_Core", -+ "cpu1 SVI2_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[][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[i][channel]; -+ break; -+ case hwmon_in: -+ *str = zenpower_in_label[i][channel]; -+ break; -+ case hwmon_curr: -+ *str = zenpower_curr_label[i][channel]; -+ break; -+ case hwmon_power: -+ *str = zenpower_power_label[i][channel]; -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static void kernel_smn_read(struct pci_dev *pdev, u16 node_id, u32 address, u32 *regval) -+{ -+ amd_smn_read(node_id, address, regval); -+} -+ -+// fallback method from k10temp -+// may return inaccurate results on multi-die chips -+static void nb_index_read(struct pci_dev *pdev, u16 node_id, 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 const struct hwmon_channel_info *zenpower_info[] = { -+ HWMON_CHANNEL_INFO(temp, -+ HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_LABEL, // Tdie -+ HWMON_T_INPUT | HWMON_T_LABEL, // Tctl -+ HWMON_T_INPUT | HWMON_T_LABEL, // Tccd1 -+ HWMON_T_INPUT | HWMON_T_LABEL, // Tccd2 -+ HWMON_T_INPUT | HWMON_T_LABEL, // Tccd3 -+ HWMON_T_INPUT | HWMON_T_LABEL, // Tccd4 -+ HWMON_T_INPUT | HWMON_T_LABEL, // Tccd5 -+ HWMON_T_INPUT | HWMON_T_LABEL, // Tccd6 -+ HWMON_T_INPUT | HWMON_T_LABEL, // Tccd7 -+ HWMON_T_INPUT | HWMON_T_LABEL), // Tccd8 -+ -+ HWMON_CHANNEL_INFO(in, -+ HWMON_I_LABEL, // everything is using 1 based indexing except -+ // hwmon_in - that is using 0 based indexing -+ // let's make fake item so corresponding SVI2 data is -+ // associated with same index -+ HWMON_I_INPUT | HWMON_I_LABEL, // Core Voltage (SVI2) -+ HWMON_I_INPUT | HWMON_I_LABEL), // SoC Voltage (SVI2) -+ -+ HWMON_CHANNEL_INFO(curr, -+ HWMON_C_INPUT | HWMON_C_LABEL, // Core Current (SVI2) -+ HWMON_C_INPUT | HWMON_C_LABEL), // SoC Current (SVI2) -+ -+ HWMON_CHANNEL_INFO(power, -+ HWMON_P_INPUT | HWMON_P_LABEL, // Core Power (SVI2) -+ HWMON_P_INPUT | HWMON_P_LABEL), // SoC Power (SVI2) -+ -+ NULL -+}; -+ -+static const struct hwmon_ops zenpower_hwmon_ops = { -+ .is_visible = zenpower_is_visible, -+ .read = zenpower_read, -+ .read_string = zenpower_read_labels, -+}; -+ -+static const struct hwmon_chip_info zenpower_chip_info = { -+ .ops = &zenpower_hwmon_ops, -+ .info = zenpower_info, -+}; -+ -+static DEVICE_ATTR_RO(debug_data); -+ -+static struct attribute *zenpower_attrs[] = { -+ &dev_attr_debug_data.attr, -+ NULL -+}; -+ -+static const struct attribute_group zenpower_group = { -+ .attrs = zenpower_attrs -+}; -+__ATTRIBUTE_GROUPS(zenpower); -+ -+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; -+ int i, ccd_check = 0; -+ bool multinode; -+ u8 node_of_cpu; -+ u32 val; -+ -+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ data->zen2 = false; -+ data->pdev = pdev; -+ data->temp_offset = 0; -+ data->read_amdsmn_addr = nb_index_read; -+ data->kernel_smn_support = false; -+ data->svi_core_addr = false; -+ data->svi_soc_addr = false; -+ data->amps_visible = false; -+ data->node_id = 0; -+ for (i = 0; i < 8; i++) { -+ data->ccd_visible[i] = 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 (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) { -+ case 0x1: // Zen -+ case 0x8: // Zen+ -+ data->amps_visible = true; -+ -+ if (multinode) { // Threadripper / EPYC -+ if (node_of_cpu == 0) { -+ data->svi_soc_addr = F17H_M01H_SVI_TEL_PLANE0; -+ } -+ if (node_of_cpu == 1) { -+ data->svi_core_addr = F17H_M01H_SVI_TEL_PLANE0; -+ } -+ } -+ else { // Ryzen -+ data->svi_core_addr = F17H_M01H_SVI_TEL_PLANE0; -+ data->svi_soc_addr = F17H_M01H_SVI_TEL_PLANE1; -+ } -+ ccd_check = 4; -+ break; -+ -+ case 0x11: // Zen APU -+ case 0x18: // Zen+ APU -+ data->amps_visible = true; -+ data->svi_core_addr = F17H_M01H_SVI_TEL_PLANE0; -+ data->svi_soc_addr = F17H_M01H_SVI_TEL_PLANE1; -+ break; -+ -+ case 0x31: // Zen2 Threadripper/EPYC -+ data->zen2 = true; -+ 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 0x71: // Zen2 Ryzen -+ data->zen2 = true; -+ 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: -+ 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++) { -+ data->read_amdsmn_addr(pdev, data->node_id, -+ F17H_M70H_CCD_TEMP(i), &val); -+ if ((val & 0xfff) > 0) { -+ data->ccd_visible[i] = true; -+ } -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) { -+ const struct tctl_offset *entry = &tctl_offset_table[i]; -+ -+ if (boot_cpu_data.x86 == entry->model && -+ strstr(boot_cpu_data.x86_model_id, entry->id)) { -+ data->temp_offset = entry->offset; -+ break; -+ } -+ } -+ -+ hwmon_dev = devm_hwmon_device_register_with_info( -+ dev, "zenpower", data, &zenpower_chip_info, zenpower_groups -+ ); -+ -+ return PTR_ERR_OR_ZERO(hwmon_dev); -+} -+ -+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_M70H_DF_F3) }, -+ {} -+}; -+MODULE_DEVICE_TABLE(pci, zenpower_id_table); -+ -+static struct pci_driver zenpower_driver = { -+ .name = "zenpower", -+ .id_table = zenpower_id_table, -+ .probe = zenpower_probe, -+}; -+ -+module_pci_driver(zenpower_driver); |