Signed-off-by: Huaxu Wan <huax...@linux.intel.com>
---
drivers/hwmon/coretemp.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 44 insertions(+), 1 deletions(-)
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 237c68d..7a01032 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -241,6 +241,49 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
return tjmax;
}
+static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
+{
+ /* The 100C is default for both mobile and non mobile CPUs */
+ int err;
+ u32 eax, edx;
+ u32 val;
+
+ /* A new feature of current Intel(R) processors, the
+ IA32_TEMPERATURE_TARGET(0x1a2) contains the TjMax value */
+ err = rdmsr_safe_on_cpu(id, 0x1a2, &eax, &edx);
+ if (err){
+ printk_once(KERN_WARNING DRVNAME " : Unable to read TjMax from CPU.\n");
+ } else {
+ val = (eax >> 16 ) & 0xff;
+ /* If the TjMax is not reasonable, an assumption value
+ will be used */
+ if (( val > 80) && (val < 120)){
+ printk_once(KERN_INFO DRVNAME " : The TjMax is %d C. \n", val);
+ return val * 1000;
+ }
+ }
+
+ /* For the early CPUs, an approximation is given.
+ NOTE: the given value may not be correct. */
+ switch(c->x86_model){
+ case 0xe :
+ case 0xf :
+ case 0x16 :
+ case 0x1a :
+ printk_once(KERN_WARNING DRVNAME " : TjMax is assumed as 100 C! \n");
+ return 100000;
+ break;
+ case 0x17 :
+ case 0x1c : /* Atom CPUs */
+ return adjust_tjmax(c, id, dev);
+ break;
+ default :
+ printk_once(KERN_WARNING DRVNAME " : Your CPU is not support yet,"
+ "using the default TjMax: 100 C.\n");
+ return 100000;
+ }
+}
+
static int __devinit coretemp_probe(struct platform_device *pdev)
{
struct coretemp_data *data;
@@ -283,7 +326,7 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
}
}
- data->tjmax = adjust_tjmax(c, data->id, &pdev->dev);
+ data->tjmax = get_tjmax(c, data->id, &pdev->dev);
platform_set_drvdata(pdev, data);
/* read the still undocumented IA32_TEMPERATURE_TARGET it exists
--
1.6.3.3.363.g725cf7
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
> The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer
> processers.
I took the liberty to make some very minor changes to your patch:
- Unified and adapted messages and comments
- Added a definition of MSR_IA32_TEMPERATURE_TARGET to the arch header
- Replaced 0x1a2 by MSR_IA32_TEMPERATURE_TARGET
- Applied changes suggested by checkpatch
Hope you like it.
Signed-off-by: Carsten Emde <C.E...@osadl.org>
> + err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
> + if (err)
> + dev_warn(dev, "Unable to read TjMax from CPU.\n");
> + else {
> + val = (eax >> 16) & 0xff;
> + if (val > 80 && val < 120) {
> + dev_info(dev, "TjMax is %dC.\n", val);
> + return val * 1000;
> + } else {
> + dev_warn(dev, "TjMax of %dC not plausible,"
> + " using 100C instead." , val);
> + return 100000;
> + }
> + }
The CPU, in the following case switch, may return no err at the above rdmsr. The
val is 0 with CPU model 0x0f in my test. The function should not return when
(val > 80 && val < 120) is false.
> +
> + /*
> + * An assumption is made for early CPUs and unreadable MSR.
> + * NOTE: the given value may not be correct.
> + */
> + switch (c->x86_model) {
> + case 0x0e:
> + case 0x0f:
> + case 0x16:
> + case 0x1a:
> + dev_warn(dev, "TjMax is assumed as 100C!\n");
> + return 100000;
> + break;
> + case 0x17:
> + case 0x1c: /* Atom CPUs */
> + return adjust_tjmax(c, id, dev);
> + break;
> + default:
> + dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
> + " using default TjMax of 100C.\n", c->x86_model);
> + return 100000;
> + }
> +}
--
Thanks
Huaxu
Signed-off-by: Huaxu Wan <huax...@linux.intel.com>
Signed-off-by: Carsten Emde <C.E...@osadl.org>
---
arch/x86/include/asm/msr-index.h | 2 +
drivers/hwmon/coretemp.c | 52 ++++++++++++++++++++++++++++++++++++-
2 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 4604e6a..9bc0cf8 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -232,6 +232,8 @@
#define MSR_IA32_MISC_ENABLE 0x000001a0
+#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
+
/* MISC_ENABLE bits: architectural */
#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0)
#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1)
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index d194207..9959390 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -241,6 +241,54 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *
return tjmax;
}
+static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
+{
+ /* The 100C is default for both mobile and non mobile CPUs */
+ int err;
+ u32 eax, edx;
+ u32 val;
+
+ /* A new feature of current Intel(R) processors, the
+ IA32_TEMPERATURE_TARGET contains the TjMax value */
+ err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
+ if (err){
+ dev_warn(dev, "Unable to read TjMax from CPU.\n");
+ } else {
+ val = (eax >> 16 ) & 0xff;
+ /*
+ * If the TjMax is not plausible, an assumption
+ * will be used
+ */
+ if (( val > 80) && (val < 120)){
+ dev_info(dev, "TjMax is %d C. \n", val);
+ return val * 1000;
+ }
+ }
+
+ /*
+ * An assumption is made for early CPUs and unreadable MSR.
+ * NOTE: the given value may not be correct.
+ */
+
+ switch(c->x86_model){
+ case 0xe :
+ case 0xf :
+ case 0x16 :
+ case 0x1a :
+ dev_warn(dev, "TjMax is assumed as 100 C! \n");
+ return 100000;
+ break;
+ case 0x17 :
+ case 0x1c : /* Atom CPUs */
+ return adjust_tjmax(c, id, dev);
+ break;
+ default :
+ dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
+ " using default TjMax of 100C.\n", c->x86_model);
+ return 100000;
+ }
+}
+
static int __devinit coretemp_probe(struct platform_device *pdev)
{
struct coretemp_data *data;
@@ -283,14 +331,14 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
}
}
- data->tjmax = adjust_tjmax(c, data->id, &pdev->dev);
+ data->tjmax = get_tjmax(c, data->id, &pdev->dev);
platform_set_drvdata(pdev, data);
/* read the still undocumented IA32_TEMPERATURE_TARGET it exists
on older CPUs but not in this register, Atoms don't have it either */
if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) {
- err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx);
+ err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
if (err) {
dev_warn(&pdev->dev, "Unable to read"
" IA32_TEMPERATURE_TARGET MSR\n");
I know that TjMax on my system is 85, and now coretemp reports wrong
temperatures.
First of all BIOS using stupid tricks actualy reports CPU temperature
through ACPI, and assuming it was correct TjMax is 85.
It also shuts down the system if I 'lie' to it that cpu temperature is
85C.
Coretemp was working correctly in 2.6.34
cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 15
model name : Intel(R) Core(TM)2 Duo CPU T5450 @ 1.66GHz
stepping : 13
cpu MHz : 1667.000
cache size : 2048 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm
bogomips : 3324.70
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 15
model name : Intel(R) Core(TM)2 Duo CPU T5450 @ 1.66GHz
stepping : 13
cpu MHz : 1667.000
cache size : 2048 KB
physical id : 0
siblings : 2
core id : 1
cpu cores : 2
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm
bogomips : 3324.99
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
Best regards,
Maxim Levitsky
The following patch unbreaks the driver:
commit 8ff4f666908dd208a10f1b6b38286303fdb774fc
Author: Maxim Levitsky <maximl...@gmail.com>
Date: Sat May 29 08:57:09 2010 +0300
coretemp: unbreak tjmax reports on Core2 CPUs
Core2 CPUS don't report TjMax, but its not always 100C
Signed-off-by: Maxim Levitsky <maximl...@gmail.com>
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 2988da1..fb100a4 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -276,11 +276,8 @@ static int __devinit get_tjmax(struct cpuinfo_x86
*c, u32 id,
case 0xf:
case 0x16:
case 0x1a:
- dev_warn(dev, "TjMax is assumed as 100 C!\n");
- return 100000;
- break;
case 0x17:
- case 0x1c: /* Atom CPUs */
+ case 0x1c:
return adjust_tjmax(c, id, dev);
break;
default:
From the list at [1], the TjMax(Tjunction) of T5450 is 100C. Does anyone
here can make a double check?
[1] http://ark.intel.com/Product.aspx?id=30787&processor=T5450&spec-codes=SLA4F
Thanks
Huaxu
This is very interesting.
With TjMax 85C, the CPUs idle temperature is reported at around 45~50C
GPU temperature that is around 60C
BIOS also reports 45~50C.
BIOS hooks an SMI to CPU thermal report, and stores the temperature it
read in ram, then ACPI code reads it, reports and passes to the EC
(embedded controller).
If I write myself 85 to embedded controller, systems shuts down.
(values less that 85, eg 84 don't shut system).
Thats all I know.
Another clue is that right after resume from ram, after long delay
(~hour) the displayed temperature with TjMax 85 is 33C. Since room
temperature here is around 27C, this seems more plausible that
33 + 15 = 48C
Any update?
I'm occupied by other things, sorry for slow response. But, as said in a
spec, I can't remember which one now, there are too many, the relative
value read from DTS is accurate approaching to TjMax. The accuracy
deteriorates to +-10C at 50C. Any DTS reading below 50C should be
considered to indicate only a temperature below 50C and not a specific
temperature.
So, the value around 50C can't be taken as real chip temperature. I
would like this issue could be confirmed by more users to avoid it as a
particular case. At the meantime, I still looking for a laptop with T5450,
this may take some time.
Thanks
Huaxu --
Any update?
Best regards,
Maxim Levitsky
--
Could you found a Laptop with T5450 at hand? I can't found anywhere.
-Huaxu
Hi, Maxim,
Could you send out thermal zone info under /proc/acpi/thermal_zone/TZ*?
Thanks.
-Fenghua