From bb9a35f293a3c8b5d57253cdfe2f29fa2627e1b9 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 15 Jan 2009 22:27:46 +0100 Subject: hwmon: (k8temp) Warn about fam F rev F errata Add warning about wrong CPU temperature readouts on all fam F rev F. The allowed combinations of processors ensure that all processors in a multisocket system have similar characteristics, e.g. (1) provide temperature sensor interface (>=RevC && =RevF) Thus it is sufficient to check the revision of the boot CPU. For "mixed silicon support" refer to "Revision Guide for AMD Athlon 64 and AMD Opteron Processors" (RevA-E) and "Revision Guide for AMD NPT Family 0Fh Processors" (RefF-G). Cc: Rudolf Marek Signed-off-by: Andreas Herrmann Signed-off-by: Jean Delvare --- drivers/hwmon/k8temp.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers/hwmon/k8temp.c') diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index bd2bde0..ca56f2e 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -31,6 +31,7 @@ #include #include #include +#include #define TEMP_FROM_REG(val) (((((val) >> 16) & 0xff) - 49) * 1000) #define REG_TEMP 0xe4 @@ -141,20 +142,34 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, int err; u8 scfg; u32 temp; + u8 model, stepping; struct k8temp_data *data; - u32 cpuid = cpuid_eax(1); - - /* this feature should be available since SH-C0 core */ - if ((cpuid == 0xf40) || (cpuid == 0xf50) || (cpuid == 0xf51)) { - err = -ENODEV; - goto exit; - } if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; } + model = boot_cpu_data.x86_model; + stepping = boot_cpu_data.x86_mask; + + switch (boot_cpu_data.x86) { + case 0xf: + /* feature available since SH-C0, exclude older revisions */ + if (((model == 4) && (stepping == 0)) || + ((model == 5) && (stepping <= 1))) { + err = -ENODEV; + goto exit_free; + } + + if (model >= 0x40) { + dev_warn(&pdev->dev, "Temperature readouts might be " + "wrong - check erratum #141\n"); + } + + break; + } + pci_read_config_byte(pdev, REG_TEMP, &scfg); scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ pci_write_config_byte(pdev, REG_TEMP, scfg); -- cgit v1.1 From a2e066bba2aad6583e3ff648bf28339d6c9f0898 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 15 Jan 2009 22:27:47 +0100 Subject: hwmon: (k8temp) Fix wrong sensor selection for AMD K8 RevF/RevG CPUs Meaning of ThermSenseCoreSel bit was inverted beginning with K8 RevF. That means with current driver temp1/temp2 belong to core 1 and temp3/temp4 belong to core 0 on a K8 RevF/RevG CPU. This patch ensures that temp1/temp2 always belong to core 0 and temp3/temp4 to core 1 for all K8 revisions. Cc: Rudolf Marek Signed-off-by: Andreas Herrmann Signed-off-by: Jean Delvare --- drivers/hwmon/k8temp.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/hwmon/k8temp.c') diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index ca56f2e..a6381bc 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -48,6 +48,7 @@ struct k8temp_data { /* registers values */ u8 sensorsp; /* sensor presence bits - SEL_CORE & SEL_PLACE */ u32 temp[2][2]; /* core, place */ + u8 swap_core_select; /* meaning of SEL_CORE is inverted */ }; static struct k8temp_data *k8temp_update_device(struct device *dev) @@ -117,6 +118,9 @@ static ssize_t show_temp(struct device *dev, int place = attr->index; struct k8temp_data *data = k8temp_update_device(dev); + if (data->swap_core_select) + core = core ? 0 : 1; + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[core][place])); } @@ -162,7 +166,12 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, goto exit_free; } + /* + * AMD NPT family 0fh, i.e. RevF and RevG: + * meaning of SEL_CORE bit is inverted + */ if (model >= 0x40) { + data->swap_core_select = 1; dev_warn(&pdev->dev, "Temperature readouts might be " "wrong - check erratum #141\n"); } -- cgit v1.1 From 76ff08da34196cfa308fcd3552bb9ea20888e745 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 15 Jan 2009 22:27:47 +0100 Subject: hwmon: (k8temp) Fix temperature reporting for (most) K8 RevG CPUs Current Temperature for K8 RevG desktop CPUs is a "normalized value" which can be below ambient temperature. As a consequence lots of RevG systems report temperatures like: $ sensors k8temp-pci-00c3 Adapter: PCI adapter Core0 Temp: +17 C Core0 Temp: +3 C Core1 Temp: +21 C Core1 Temp: +5 C being quite below ambient temperature. There are even reports of negative temperature values. This patch corrects the temperature reporting of k8temp for RevG desktop CPUs. Cc: Rudolf Marek Signed-off-by: Andreas Herrmann Signed-off-by: Jean Delvare --- drivers/hwmon/k8temp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/hwmon/k8temp.c') diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index a6381bc..1fe9951 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -49,6 +49,7 @@ struct k8temp_data { u8 sensorsp; /* sensor presence bits - SEL_CORE & SEL_PLACE */ u32 temp[2][2]; /* core, place */ u8 swap_core_select; /* meaning of SEL_CORE is inverted */ + u32 temp_offset; }; static struct k8temp_data *k8temp_update_device(struct device *dev) @@ -116,13 +117,15 @@ static ssize_t show_temp(struct device *dev, to_sensor_dev_attr_2(devattr); int core = attr->nr; int place = attr->index; + int temp; struct k8temp_data *data = k8temp_update_device(dev); if (data->swap_core_select) core = core ? 0 : 1; - return sprintf(buf, "%d\n", - TEMP_FROM_REG(data->temp[core][place])); + temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset; + + return sprintf(buf, "%d\n", temp); } /* core, place */ @@ -176,6 +179,16 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, "wrong - check erratum #141\n"); } + if ((model >= 0x69) && + !(model == 0xc1 || model == 0x6c || model == 0x7c)) { + /* + * RevG desktop CPUs (i.e. no socket S1G1 parts) + * need additional offset, otherwise reported + * temperature is below ambient temperature + */ + data->temp_offset = 21000; + } + break; } -- cgit v1.1