1303760b4SJean Delvare /* 215872212SFrank Myhr * hwmon-vid.c - VID/VRM/VRD voltage conversions 315872212SFrank Myhr * 415872212SFrank Myhr * Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz> 515872212SFrank Myhr * 615872212SFrank Myhr * Partly imported from i2c-vid.h of the lm_sensors project 715872212SFrank Myhr * Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> 815872212SFrank Myhr * With assistance from Trent Piepho <xyzzy@speakeasy.org> 915872212SFrank Myhr * 1015872212SFrank Myhr * This program is free software; you can redistribute it and/or modify 1115872212SFrank Myhr * it under the terms of the GNU General Public License as published by 1215872212SFrank Myhr * the Free Software Foundation; either version 2 of the License, or 1315872212SFrank Myhr * (at your option) any later version. 1415872212SFrank Myhr * 1515872212SFrank Myhr * This program is distributed in the hope that it will be useful, 1615872212SFrank Myhr * but WITHOUT ANY WARRANTY; without even the implied warranty of 1715872212SFrank Myhr * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1815872212SFrank Myhr * GNU General Public License for more details. 1915872212SFrank Myhr * 2015872212SFrank Myhr * You should have received a copy of the GNU General Public License 2115872212SFrank Myhr * along with this program; if not, write to the Free Software 2215872212SFrank Myhr * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23303760b4SJean Delvare */ 24303760b4SJean Delvare 251f923c7aSJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 261f923c7aSJoe Perches 27303760b4SJean Delvare #include <linux/module.h> 28303760b4SJean Delvare #include <linux/kernel.h> 29303760b4SJean Delvare #include <linux/hwmon-vid.h> 30303760b4SJean Delvare 31d0f28270SJean Delvare /* 3215872212SFrank Myhr * Common code for decoding VID pins. 3315872212SFrank Myhr * 3415872212SFrank Myhr * References: 3515872212SFrank Myhr * 3615872212SFrank Myhr * For VRM 8.4 to 9.1, "VRM x.y DC-DC Converter Design Guidelines", 3715872212SFrank Myhr * available at http://developer.intel.com/. 3815872212SFrank Myhr * 3915872212SFrank Myhr * For VRD 10.0 and up, "VRD x.y Design Guide", 4015872212SFrank Myhr * available at http://developer.intel.com/. 4115872212SFrank Myhr * 42cebd7709SJean Delvare * AMD Athlon 64 and AMD Opteron Processors, AMD Publication 26094, 43631dd1a8SJustin P. Mattock * http://support.amd.com/us/Processor_TechDocs/26094.PDF 44cebd7709SJean Delvare * Table 74. VID Code Voltages 45cebd7709SJean Delvare * This corresponds to an arbitrary VRM code of 24 in the functions below. 46cebd7709SJean Delvare * These CPU models (K8 revision <= E) have 5 VID pins. See also: 47cebd7709SJean Delvare * Revision Guide for AMD Athlon 64 and AMD Opteron Processors, AMD Publication 25759, 48cebd7709SJean Delvare * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf 49cebd7709SJean Delvare * 50cebd7709SJean Delvare * AMD NPT Family 0Fh Processors, AMD Publication 32559, 51116d0486SFrank Myhr * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf 52116d0486SFrank Myhr * Table 71. VID Code Voltages 53cebd7709SJean Delvare * This corresponds to an arbitrary VRM code of 25 in the functions below. 54cebd7709SJean Delvare * These CPU models (K8 revision >= F) have 6 VID pins. See also: 55cebd7709SJean Delvare * Revision Guide for AMD NPT Family 0Fh Processors, AMD Publication 33610, 56cebd7709SJean Delvare * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf 5715872212SFrank Myhr * 5815872212SFrank Myhr * The 17 specification is in fact Intel Mobile Voltage Positioning - 5915872212SFrank Myhr * (IMVP-II). You can find more information in the datasheet of Max1718 6015872212SFrank Myhr * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 6115872212SFrank Myhr * 6215872212SFrank Myhr * The 13 specification corresponds to the Intel Pentium M series. There 6315872212SFrank Myhr * doesn't seem to be any named specification for these. The conversion 6415872212SFrank Myhr * tables are detailed directly in the various Pentium M datasheets: 6515872212SFrank Myhr * http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm 6615872212SFrank Myhr * 6715872212SFrank Myhr * The 14 specification corresponds to Intel Core series. There 6815872212SFrank Myhr * doesn't seem to be any named specification for these. The conversion 6915872212SFrank Myhr * tables are detailed directly in the various Pentium Core datasheets: 7015872212SFrank Myhr * http://www.intel.com/design/mobile/datashts/309221.htm 7115872212SFrank Myhr * 7215872212SFrank Myhr * The 110 (VRM 11) specification corresponds to Intel Conroe based series. 7315872212SFrank Myhr * http://www.intel.com/design/processor/applnots/313214.htm 74d0f28270SJean Delvare */ 75d0f28270SJean Delvare 7615872212SFrank Myhr /* 7715872212SFrank Myhr * vrm is the VRM/VRD document version multiplied by 10. 7815872212SFrank Myhr * val is the 4-bit or more VID code. 7915872212SFrank Myhr * Returned value is in mV to avoid floating point in the kernel. 8015872212SFrank Myhr * Some VID have some bits in uV scale, this is rounded to mV. 8115872212SFrank Myhr */ 82734a12a3SRudolf Marek int vid_from_reg(int val, u8 vrm) 83d0f28270SJean Delvare { 84d0f28270SJean Delvare int vid; 85d0f28270SJean Delvare 86d0f28270SJean Delvare switch(vrm) { 87d0f28270SJean Delvare 88d0f28270SJean Delvare case 100: /* VRD 10.0 */ 896af586dcSRudolf Marek /* compute in uV, round to mV */ 90177d165dSRudolf Marek val &= 0x3f; 91d0f28270SJean Delvare if((val & 0x1f) == 0x1f) 92d0f28270SJean Delvare return 0; 93d0f28270SJean Delvare if((val & 0x1f) <= 0x09 || val == 0x0a) 946af586dcSRudolf Marek vid = 1087500 - (val & 0x1f) * 25000; 95d0f28270SJean Delvare else 966af586dcSRudolf Marek vid = 1862500 - (val & 0x1f) * 25000; 97d0f28270SJean Delvare if(val & 0x20) 986af586dcSRudolf Marek vid -= 12500; 997fe83ad8SFrans Meulenbroeks return (vid + 500) / 1000; 100d0f28270SJean Delvare 1016af586dcSRudolf Marek case 110: /* Intel Conroe */ 1026af586dcSRudolf Marek /* compute in uV, round to mV */ 1036af586dcSRudolf Marek val &= 0xff; 1049fab2d8bSJean Delvare if (val < 0x02 || val > 0xb2) 1056af586dcSRudolf Marek return 0; 1067fe83ad8SFrans Meulenbroeks return (1600000 - (val - 2) * 6250 + 500) / 1000; 107116d0486SFrank Myhr 108cebd7709SJean Delvare case 24: /* Athlon64 & Opteron */ 109cebd7709SJean Delvare val &= 0x1f; 110cebd7709SJean Delvare if (val == 0x1f) 111cebd7709SJean Delvare return 0; 112cebd7709SJean Delvare /* fall through */ 113cebd7709SJean Delvare case 25: /* AMD NPT 0Fh */ 114116d0486SFrank Myhr val &= 0x3f; 115116d0486SFrank Myhr return (val < 32) ? 1550 - 25 * val 116116d0486SFrank Myhr : 775 - (25 * (val - 31)) / 2; 117d0f28270SJean Delvare 118d0f28270SJean Delvare case 91: /* VRM 9.1 */ 119d0f28270SJean Delvare case 90: /* VRM 9.0 */ 120177d165dSRudolf Marek val &= 0x1f; 1217fe83ad8SFrans Meulenbroeks return val == 0x1f ? 0 : 1227fe83ad8SFrans Meulenbroeks 1850 - val * 25; 123d0f28270SJean Delvare 124d0f28270SJean Delvare case 85: /* VRM 8.5 */ 125177d165dSRudolf Marek val &= 0x1f; 1267fe83ad8SFrans Meulenbroeks return (val & 0x10 ? 25 : 0) + 127d0f28270SJean Delvare ((val & 0x0f) > 0x04 ? 2050 : 1250) - 1287fe83ad8SFrans Meulenbroeks ((val & 0x0f) * 50); 129d0f28270SJean Delvare 130d0f28270SJean Delvare case 84: /* VRM 8.4 */ 131d0f28270SJean Delvare val &= 0x0f; 132d0f28270SJean Delvare /* fall through */ 133734a12a3SRudolf Marek case 82: /* VRM 8.2 */ 134177d165dSRudolf Marek val &= 0x1f; 1357fe83ad8SFrans Meulenbroeks return val == 0x1f ? 0 : 136d0f28270SJean Delvare val & 0x10 ? 5100 - (val) * 100 : 1377fe83ad8SFrans Meulenbroeks 2050 - (val) * 50; 138734a12a3SRudolf Marek case 17: /* Intel IMVP-II */ 139177d165dSRudolf Marek val &= 0x1f; 1407fe83ad8SFrans Meulenbroeks return val & 0x10 ? 975 - (val & 0xF) * 25 : 1417fe83ad8SFrans Meulenbroeks 1750 - val * 50; 1424c537fb2SJean Delvare case 13: 1430a88f4b5SJean Delvare case 131: 144177d165dSRudolf Marek val &= 0x3f; 1450a88f4b5SJean Delvare /* Exception for Eden ULV 500 MHz */ 1460a88f4b5SJean Delvare if (vrm == 131 && val == 0x3f) 1470a88f4b5SJean Delvare val++; 1487fe83ad8SFrans Meulenbroeks return 1708 - val * 16; 1496af586dcSRudolf Marek case 14: /* Intel Core */ 1506af586dcSRudolf Marek /* compute in uV, round to mV */ 1516af586dcSRudolf Marek val &= 0x7f; 1527fe83ad8SFrans Meulenbroeks return val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000; 153734a12a3SRudolf Marek default: /* report 0 for unknown */ 15445f2acc4SJean Delvare if (vrm) 1551f923c7aSJoe Perches pr_warn("Requested unsupported VRM version (%u)\n", 1561f923c7aSJoe Perches (unsigned int)vrm); 157734a12a3SRudolf Marek return 0; 158d0f28270SJean Delvare } 159d0f28270SJean Delvare } 160d0f28270SJean Delvare 161d0f28270SJean Delvare 162d0f28270SJean Delvare /* 16315872212SFrank Myhr * After this point is the code to automatically determine which 16415872212SFrank Myhr * VRM/VRD specification should be used depending on the CPU. 165d0f28270SJean Delvare */ 166d0f28270SJean Delvare 167303760b4SJean Delvare struct vrm_model { 168303760b4SJean Delvare u8 vendor; 169*3230f704SGuenter Roeck u8 family; 170*3230f704SGuenter Roeck u8 model_from; 171*3230f704SGuenter Roeck u8 model_to; 172*3230f704SGuenter Roeck u8 stepping_to; 173734a12a3SRudolf Marek u8 vrm_type; 174303760b4SJean Delvare }; 175303760b4SJean Delvare 176303760b4SJean Delvare #define ANY 0xFF 177303760b4SJean Delvare 178303760b4SJean Delvare #ifdef CONFIG_X86 179303760b4SJean Delvare 180cebd7709SJean Delvare /* 181*3230f704SGuenter Roeck * The stepping_to parameter is highest acceptable stepping for current line. 182cebd7709SJean Delvare * The model match must be exact for 4-bit values. For model values 0x10 183cebd7709SJean Delvare * and above (extended model), all models below the parameter will match. 184cebd7709SJean Delvare */ 185734a12a3SRudolf Marek 186303760b4SJean Delvare static struct vrm_model vrm_models[] = { 187*3230f704SGuenter Roeck {X86_VENDOR_AMD, 0x6, 0x0, ANY, ANY, 90}, /* Athlon Duron etc */ 188*3230f704SGuenter Roeck {X86_VENDOR_AMD, 0xF, 0x0, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ 18986d566e5SGuenter Roeck /* 19086d566e5SGuenter Roeck * In theory, all NPT family 0Fh processors have 6 VID pins and should 19186d566e5SGuenter Roeck * thus use vrm 25, however in practice not all mainboards route the 19286d566e5SGuenter Roeck * 6th VID pin because it is never needed. So we use the 5 VID pin 19386d566e5SGuenter Roeck * variant (vrm 24) for the models which exist today. 19486d566e5SGuenter Roeck */ 195*3230f704SGuenter Roeck {X86_VENDOR_AMD, 0xF, 0x40, 0x7F, ANY, 24}, /* NPT family 0Fh */ 196*3230f704SGuenter Roeck {X86_VENDOR_AMD, 0xF, 0x80, ANY, ANY, 25}, /* future fam. 0Fh */ 197*3230f704SGuenter Roeck {X86_VENDOR_AMD, 0x10, 0x0, ANY, ANY, 25}, /* NPT family 10h */ 1985bed13f5SJean Delvare 199*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0x0, 0x6, ANY, 82}, /* Pentium Pro, 200*3230f704SGuenter Roeck * Pentium II, Xeon, 201*3230f704SGuenter Roeck * Mobile Pentium, 202*3230f704SGuenter Roeck * Celeron */ 203*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0x7, 0x7, ANY, 84}, /* Pentium III, Xeon */ 204*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0x8, 0x8, ANY, 82}, /* Pentium III, Xeon */ 205*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0x9, 0x9, ANY, 13}, /* Pentium M (130 nm) */ 206*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0xA, 0xA, ANY, 82}, /* Pentium III Xeon */ 207*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0xB, 0xB, ANY, 85}, /* Tualatin */ 208*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0xD, 0xD, ANY, 13}, /* Pentium M (90 nm) */ 209*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0xE, 0xE, ANY, 14}, /* Intel Core (65 nm) */ 210*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0x6, 0xF, ANY, ANY, 110}, /* Intel Conroe and 211*3230f704SGuenter Roeck * later */ 212*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0xF, 0x0, 0x0, ANY, 90}, /* P4 */ 213*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0xF, 0x1, 0x1, ANY, 90}, /* P4 Willamette */ 214*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0xF, 0x2, 0x2, ANY, 90}, /* P4 Northwood */ 215*3230f704SGuenter Roeck {X86_VENDOR_INTEL, 0xF, 0x3, ANY, ANY, 100}, /* Prescott and above 216*3230f704SGuenter Roeck * assume VRD 10 */ 2175bed13f5SJean Delvare 218*3230f704SGuenter Roeck {X86_VENDOR_CENTAUR, 0x6, 0x7, 0x7, ANY, 85}, /* Eden ESP/Ezra */ 219*3230f704SGuenter Roeck {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x8, 0x7, 85}, /* Ezra T */ 220*3230f704SGuenter Roeck {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, 0x7, 85}, /* Nehemiah */ 221*3230f704SGuenter Roeck {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, ANY, 17}, /* C3-M, Eden-N */ 222*3230f704SGuenter Roeck {X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, 0x7, 0}, /* No information */ 223*3230f704SGuenter Roeck {X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, ANY, 13}, /* C7-M, C7, 224*3230f704SGuenter Roeck * Eden (Esther) */ 225*3230f704SGuenter Roeck {X86_VENDOR_CENTAUR, 0x6, 0xD, 0xD, ANY, 134}, /* C7-D, C7-M, C7, 226*3230f704SGuenter Roeck * Eden (Esther) */ 227303760b4SJean Delvare }; 228303760b4SJean Delvare 2290a88f4b5SJean Delvare /* 2300a88f4b5SJean Delvare * Special case for VIA model D: there are two different possible 2310a88f4b5SJean Delvare * VID tables, so we have to figure out first, which one must be 2320a88f4b5SJean Delvare * used. This resolves temporary drm value 134 to 14 (Intel Core 2330a88f4b5SJean Delvare * 7-bit VID), 13 (Pentium M 6-bit VID) or 131 (Pentium M 6-bit VID 2340a88f4b5SJean Delvare * + quirk for Eden ULV 500 MHz). 2350a88f4b5SJean Delvare * Note: something similar might be needed for model A, I'm not sure. 2360a88f4b5SJean Delvare */ 2370a88f4b5SJean Delvare static u8 get_via_model_d_vrm(void) 2380a88f4b5SJean Delvare { 2390a88f4b5SJean Delvare unsigned int vid, brand, dummy; 2400a88f4b5SJean Delvare static const char *brands[4] = { 2410a88f4b5SJean Delvare "C7-M", "C7", "Eden", "C7-D" 2420a88f4b5SJean Delvare }; 2430a88f4b5SJean Delvare 2440a88f4b5SJean Delvare rdmsr(0x198, dummy, vid); 2450a88f4b5SJean Delvare vid &= 0xff; 2460a88f4b5SJean Delvare 2470a88f4b5SJean Delvare rdmsr(0x1154, brand, dummy); 2480a88f4b5SJean Delvare brand = ((brand >> 4) ^ (brand >> 2)) & 0x03; 2490a88f4b5SJean Delvare 2500a88f4b5SJean Delvare if (vid > 0x3f) { 2510a88f4b5SJean Delvare pr_info("Using %d-bit VID table for VIA %s CPU\n", 2520a88f4b5SJean Delvare 7, brands[brand]); 2530a88f4b5SJean Delvare return 14; 2540a88f4b5SJean Delvare } else { 2550a88f4b5SJean Delvare pr_info("Using %d-bit VID table for VIA %s CPU\n", 2560a88f4b5SJean Delvare 6, brands[brand]); 2570a88f4b5SJean Delvare /* Enable quirk for Eden */ 2580a88f4b5SJean Delvare return brand == 2 ? 131 : 13; 2590a88f4b5SJean Delvare } 2600a88f4b5SJean Delvare } 2610a88f4b5SJean Delvare 262*3230f704SGuenter Roeck static u8 find_vrm(u8 family, u8 model, u8 stepping, u8 vendor) 263303760b4SJean Delvare { 264*3230f704SGuenter Roeck int i; 265303760b4SJean Delvare 266*3230f704SGuenter Roeck for (i = 0; i < ARRAY_SIZE(vrm_models); i++) { 267*3230f704SGuenter Roeck if (vendor == vrm_models[i].vendor && 268*3230f704SGuenter Roeck family == vrm_models[i].family && 269*3230f704SGuenter Roeck model >= vrm_models[i].model_from && 270*3230f704SGuenter Roeck model <= vrm_models[i].model_to && 271*3230f704SGuenter Roeck stepping <= vrm_models[i].stepping_to) 272303760b4SJean Delvare return vrm_models[i].vrm_type; 273303760b4SJean Delvare } 274303760b4SJean Delvare 275303760b4SJean Delvare return 0; 276303760b4SJean Delvare } 277303760b4SJean Delvare 278734a12a3SRudolf Marek u8 vid_which_vrm(void) 279303760b4SJean Delvare { 28092cb7612SMike Travis struct cpuinfo_x86 *c = &cpu_data(0); 281*3230f704SGuenter Roeck u8 vrm_ret; 282303760b4SJean Delvare 283da97a5a3SJean Delvare if (c->x86 < 6) /* Any CPU with family lower than 6 */ 284*3230f704SGuenter Roeck return 0; /* doesn't have VID */ 285da97a5a3SJean Delvare 286*3230f704SGuenter Roeck vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_mask, c->x86_vendor); 2870a88f4b5SJean Delvare if (vrm_ret == 134) 2880a88f4b5SJean Delvare vrm_ret = get_via_model_d_vrm(); 289303760b4SJean Delvare if (vrm_ret == 0) 2901f923c7aSJoe Perches pr_info("Unknown VRM version of your x86 CPU\n"); 291303760b4SJean Delvare return vrm_ret; 292303760b4SJean Delvare } 293303760b4SJean Delvare 294734a12a3SRudolf Marek /* and now for something completely different for the non-x86 world */ 295303760b4SJean Delvare #else 296734a12a3SRudolf Marek u8 vid_which_vrm(void) 297303760b4SJean Delvare { 2981f923c7aSJoe Perches pr_info("Unknown VRM version of your CPU\n"); 299303760b4SJean Delvare return 0; 300303760b4SJean Delvare } 301303760b4SJean Delvare #endif 302303760b4SJean Delvare 303d0f28270SJean Delvare EXPORT_SYMBOL(vid_from_reg); 304303760b4SJean Delvare EXPORT_SYMBOL(vid_which_vrm); 305303760b4SJean Delvare 3067188cc66SJean Delvare MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); 307303760b4SJean Delvare 308303760b4SJean Delvare MODULE_DESCRIPTION("hwmon-vid driver"); 309303760b4SJean Delvare MODULE_LICENSE("GPL"); 310