diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hwmon/hwmon-vid.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/hwmon-vid.c')
-rw-r--r-- | drivers/hwmon/hwmon-vid.c | 169 |
1 files changed, 81 insertions, 88 deletions
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 89cfd64b337..932da8a5aaf 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
@@ -40,7 +40,7 @@ | |||
40 | * available at http://developer.intel.com/. | 40 | * available at http://developer.intel.com/. |
41 | * | 41 | * |
42 | * AMD Athlon 64 and AMD Opteron Processors, AMD Publication 26094, | 42 | * AMD Athlon 64 and AMD Opteron Processors, AMD Publication 26094, |
43 | * http://support.amd.com/us/Processor_TechDocs/26094.PDF | 43 | * http://support.amd.com/us/Processor_TechDocs/26094.PDF |
44 | * Table 74. VID Code Voltages | 44 | * Table 74. VID Code Voltages |
45 | * This corresponds to an arbitrary VRM code of 24 in the functions below. | 45 | * This corresponds to an arbitrary VRM code of 24 in the functions below. |
46 | * These CPU models (K8 revision <= E) have 5 VID pins. See also: | 46 | * These CPU models (K8 revision <= E) have 5 VID pins. See also: |
@@ -83,27 +83,27 @@ int vid_from_reg(int val, u8 vrm) | |||
83 | { | 83 | { |
84 | int vid; | 84 | int vid; |
85 | 85 | ||
86 | switch (vrm) { | 86 | switch(vrm) { |
87 | 87 | ||
88 | case 100: /* VRD 10.0 */ | 88 | case 100: /* VRD 10.0 */ |
89 | /* compute in uV, round to mV */ | 89 | /* compute in uV, round to mV */ |
90 | val &= 0x3f; | 90 | val &= 0x3f; |
91 | if ((val & 0x1f) == 0x1f) | 91 | if((val & 0x1f) == 0x1f) |
92 | return 0; | 92 | return 0; |
93 | if ((val & 0x1f) <= 0x09 || val == 0x0a) | 93 | if((val & 0x1f) <= 0x09 || val == 0x0a) |
94 | vid = 1087500 - (val & 0x1f) * 25000; | 94 | vid = 1087500 - (val & 0x1f) * 25000; |
95 | else | 95 | else |
96 | vid = 1862500 - (val & 0x1f) * 25000; | 96 | vid = 1862500 - (val & 0x1f) * 25000; |
97 | if (val & 0x20) | 97 | if(val & 0x20) |
98 | vid -= 12500; | 98 | vid -= 12500; |
99 | return (vid + 500) / 1000; | 99 | return((vid + 500) / 1000); |
100 | 100 | ||
101 | case 110: /* Intel Conroe */ | 101 | case 110: /* Intel Conroe */ |
102 | /* compute in uV, round to mV */ | 102 | /* compute in uV, round to mV */ |
103 | val &= 0xff; | 103 | val &= 0xff; |
104 | if (val < 0x02 || val > 0xb2) | 104 | if (val < 0x02 || val > 0xb2) |
105 | return 0; | 105 | return 0; |
106 | return (1600000 - (val - 2) * 6250 + 500) / 1000; | 106 | return((1600000 - (val - 2) * 6250 + 500) / 1000); |
107 | 107 | ||
108 | case 24: /* Athlon64 & Opteron */ | 108 | case 24: /* Athlon64 & Opteron */ |
109 | val &= 0x1f; | 109 | val &= 0x1f; |
@@ -115,47 +115,41 @@ int vid_from_reg(int val, u8 vrm) | |||
115 | return (val < 32) ? 1550 - 25 * val | 115 | return (val < 32) ? 1550 - 25 * val |
116 | : 775 - (25 * (val - 31)) / 2; | 116 | : 775 - (25 * (val - 31)) / 2; |
117 | 117 | ||
118 | case 26: /* AMD family 10h to 15h, serial VID */ | ||
119 | val &= 0x7f; | ||
120 | if (val >= 0x7c) | ||
121 | return 0; | ||
122 | return DIV_ROUND_CLOSEST(15500 - 125 * val, 10); | ||
123 | |||
124 | case 91: /* VRM 9.1 */ | 118 | case 91: /* VRM 9.1 */ |
125 | case 90: /* VRM 9.0 */ | 119 | case 90: /* VRM 9.0 */ |
126 | val &= 0x1f; | 120 | val &= 0x1f; |
127 | return val == 0x1f ? 0 : | 121 | return(val == 0x1f ? 0 : |
128 | 1850 - val * 25; | 122 | 1850 - val * 25); |
129 | 123 | ||
130 | case 85: /* VRM 8.5 */ | 124 | case 85: /* VRM 8.5 */ |
131 | val &= 0x1f; | 125 | val &= 0x1f; |
132 | return (val & 0x10 ? 25 : 0) + | 126 | return((val & 0x10 ? 25 : 0) + |
133 | ((val & 0x0f) > 0x04 ? 2050 : 1250) - | 127 | ((val & 0x0f) > 0x04 ? 2050 : 1250) - |
134 | ((val & 0x0f) * 50); | 128 | ((val & 0x0f) * 50)); |
135 | 129 | ||
136 | case 84: /* VRM 8.4 */ | 130 | case 84: /* VRM 8.4 */ |
137 | val &= 0x0f; | 131 | val &= 0x0f; |
138 | /* fall through */ | 132 | /* fall through */ |
139 | case 82: /* VRM 8.2 */ | 133 | case 82: /* VRM 8.2 */ |
140 | val &= 0x1f; | 134 | val &= 0x1f; |
141 | return val == 0x1f ? 0 : | 135 | return(val == 0x1f ? 0 : |
142 | val & 0x10 ? 5100 - (val) * 100 : | 136 | val & 0x10 ? 5100 - (val) * 100 : |
143 | 2050 - (val) * 50; | 137 | 2050 - (val) * 50); |
144 | case 17: /* Intel IMVP-II */ | 138 | case 17: /* Intel IMVP-II */ |
145 | val &= 0x1f; | 139 | val &= 0x1f; |
146 | return val & 0x10 ? 975 - (val & 0xF) * 25 : | 140 | return(val & 0x10 ? 975 - (val & 0xF) * 25 : |
147 | 1750 - val * 50; | 141 | 1750 - val * 50); |
148 | case 13: | 142 | case 13: |
149 | case 131: | 143 | case 131: |
150 | val &= 0x3f; | 144 | val &= 0x3f; |
151 | /* Exception for Eden ULV 500 MHz */ | 145 | /* Exception for Eden ULV 500 MHz */ |
152 | if (vrm == 131 && val == 0x3f) | 146 | if (vrm == 131 && val == 0x3f) |
153 | val++; | 147 | val++; |
154 | return 1708 - val * 16; | 148 | return(1708 - val * 16); |
155 | case 14: /* Intel Core */ | 149 | case 14: /* Intel Core */ |
156 | /* compute in uV, round to mV */ | 150 | /* compute in uV, round to mV */ |
157 | val &= 0x7f; | 151 | val &= 0x7f; |
158 | return val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000; | 152 | return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000); |
159 | default: /* report 0 for unknown */ | 153 | default: /* report 0 for unknown */ |
160 | if (vrm) | 154 | if (vrm) |
161 | pr_warn("Requested unsupported VRM version (%u)\n", | 155 | pr_warn("Requested unsupported VRM version (%u)\n", |
@@ -163,7 +157,7 @@ int vid_from_reg(int val, u8 vrm) | |||
163 | return 0; | 157 | return 0; |
164 | } | 158 | } |
165 | } | 159 | } |
166 | EXPORT_SYMBOL(vid_from_reg); | 160 | |
167 | 161 | ||
168 | /* | 162 | /* |
169 | * After this point is the code to automatically determine which | 163 | * After this point is the code to automatically determine which |
@@ -172,10 +166,9 @@ EXPORT_SYMBOL(vid_from_reg); | |||
172 | 166 | ||
173 | struct vrm_model { | 167 | struct vrm_model { |
174 | u8 vendor; | 168 | u8 vendor; |
175 | u8 family; | 169 | u8 eff_family; |
176 | u8 model_from; | 170 | u8 eff_model; |
177 | u8 model_to; | 171 | u8 eff_stepping; |
178 | u8 stepping_to; | ||
179 | u8 vrm_type; | 172 | u8 vrm_type; |
180 | }; | 173 | }; |
181 | 174 | ||
@@ -184,56 +177,42 @@ struct vrm_model { | |||
184 | #ifdef CONFIG_X86 | 177 | #ifdef CONFIG_X86 |
185 | 178 | ||
186 | /* | 179 | /* |
187 | * The stepping_to parameter is highest acceptable stepping for current line. | 180 | * The stepping parameter is highest acceptable stepping for current line. |
188 | * The model match must be exact for 4-bit values. For model values 0x10 | 181 | * The model match must be exact for 4-bit values. For model values 0x10 |
189 | * and above (extended model), all models below the parameter will match. | 182 | * and above (extended model), all models below the parameter will match. |
190 | */ | 183 | */ |
191 | 184 | ||
192 | static struct vrm_model vrm_models[] = { | 185 | static struct vrm_model vrm_models[] = { |
193 | {X86_VENDOR_AMD, 0x6, 0x0, ANY, ANY, 90}, /* Athlon Duron etc */ | 186 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ |
194 | {X86_VENDOR_AMD, 0xF, 0x0, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ | 187 | {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ |
195 | /* | 188 | /* In theory, all NPT family 0Fh processors have 6 VID pins and should |
196 | * In theory, all NPT family 0Fh processors have 6 VID pins and should | 189 | thus use vrm 25, however in practice not all mainboards route the |
197 | * thus use vrm 25, however in practice not all mainboards route the | 190 | 6th VID pin because it is never needed. So we use the 5 VID pin |
198 | * 6th VID pin because it is never needed. So we use the 5 VID pin | 191 | variant (vrm 24) for the models which exist today. */ |
199 | * variant (vrm 24) for the models which exist today. | 192 | {X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24}, /* NPT family 0Fh */ |
200 | */ | 193 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* future fam. 0Fh */ |
201 | {X86_VENDOR_AMD, 0xF, 0x40, 0x7F, ANY, 24}, /* NPT family 0Fh */ | 194 | {X86_VENDOR_AMD, 0x10, ANY, ANY, 25}, /* NPT family 10h */ |
202 | {X86_VENDOR_AMD, 0xF, 0x80, ANY, ANY, 25}, /* future fam. 0Fh */ | 195 | |
203 | {X86_VENDOR_AMD, 0x10, 0x0, ANY, ANY, 25}, /* NPT family 10h */ | 196 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ |
204 | {X86_VENDOR_AMD, 0x11, 0x0, ANY, ANY, 26}, /* family 11h */ | 197 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ |
205 | {X86_VENDOR_AMD, 0x12, 0x0, ANY, ANY, 26}, /* family 12h */ | 198 | {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ |
206 | {X86_VENDOR_AMD, 0x14, 0x0, ANY, ANY, 26}, /* family 14h */ | 199 | {X86_VENDOR_INTEL, 0x6, 0xE, ANY, 14}, /* Intel Core (65 nm) */ |
207 | {X86_VENDOR_AMD, 0x15, 0x0, ANY, ANY, 26}, /* family 15h */ | 200 | {X86_VENDOR_INTEL, 0x6, 0xF, ANY, 110}, /* Intel Conroe */ |
208 | 201 | {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */ | |
209 | {X86_VENDOR_INTEL, 0x6, 0x0, 0x6, ANY, 82}, /* Pentium Pro, | 202 | {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ |
210 | * Pentium II, Xeon, | 203 | {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */ |
211 | * Mobile Pentium, | 204 | {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */ |
212 | * Celeron */ | 205 | {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */ |
213 | {X86_VENDOR_INTEL, 0x6, 0x7, 0x7, ANY, 84}, /* Pentium III, Xeon */ | 206 | |
214 | {X86_VENDOR_INTEL, 0x6, 0x8, 0x8, ANY, 82}, /* Pentium III, Xeon */ | 207 | {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */ |
215 | {X86_VENDOR_INTEL, 0x6, 0x9, 0x9, ANY, 13}, /* Pentium M (130 nm) */ | 208 | {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */ |
216 | {X86_VENDOR_INTEL, 0x6, 0xA, 0xA, ANY, 82}, /* Pentium III Xeon */ | 209 | {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nehemiah */ |
217 | {X86_VENDOR_INTEL, 0x6, 0xB, 0xB, ANY, 85}, /* Tualatin */ | 210 | {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */ |
218 | {X86_VENDOR_INTEL, 0x6, 0xD, 0xD, ANY, 13}, /* Pentium M (90 nm) */ | 211 | {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */ |
219 | {X86_VENDOR_INTEL, 0x6, 0xE, 0xE, ANY, 14}, /* Intel Core (65 nm) */ | 212 | {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7-M, C7, Eden (Esther) */ |
220 | {X86_VENDOR_INTEL, 0x6, 0xF, ANY, ANY, 110}, /* Intel Conroe and | 213 | {X86_VENDOR_CENTAUR, 0x6, 0xD, ANY, 134}, /* C7-D, C7-M, C7, Eden (Esther) */ |
221 | * later */ | 214 | |
222 | {X86_VENDOR_INTEL, 0xF, 0x0, 0x0, ANY, 90}, /* P4 */ | 215 | {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ |
223 | {X86_VENDOR_INTEL, 0xF, 0x1, 0x1, ANY, 90}, /* P4 Willamette */ | ||
224 | {X86_VENDOR_INTEL, 0xF, 0x2, 0x2, ANY, 90}, /* P4 Northwood */ | ||
225 | {X86_VENDOR_INTEL, 0xF, 0x3, ANY, ANY, 100}, /* Prescott and above | ||
226 | * assume VRD 10 */ | ||
227 | |||
228 | {X86_VENDOR_CENTAUR, 0x6, 0x7, 0x7, ANY, 85}, /* Eden ESP/Ezra */ | ||
229 | {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x8, 0x7, 85}, /* Ezra T */ | ||
230 | {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, 0x7, 85}, /* Nehemiah */ | ||
231 | {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, ANY, 17}, /* C3-M, Eden-N */ | ||
232 | {X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, 0x7, 0}, /* No information */ | ||
233 | {X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, ANY, 13}, /* C7-M, C7, | ||
234 | * Eden (Esther) */ | ||
235 | {X86_VENDOR_CENTAUR, 0x6, 0xD, 0xD, ANY, 134}, /* C7-D, C7-M, C7, | ||
236 | * Eden (Esther) */ | ||
237 | }; | 216 | }; |
238 | 217 | ||
239 | /* | 218 | /* |
@@ -269,17 +248,20 @@ static u8 get_via_model_d_vrm(void) | |||
269 | } | 248 | } |
270 | } | 249 | } |
271 | 250 | ||
272 | static u8 find_vrm(u8 family, u8 model, u8 stepping, u8 vendor) | 251 | static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) |
273 | { | 252 | { |
274 | int i; | 253 | int i = 0; |
275 | 254 | ||
276 | for (i = 0; i < ARRAY_SIZE(vrm_models); i++) { | 255 | while (vrm_models[i].vendor!=X86_VENDOR_UNKNOWN) { |
277 | if (vendor == vrm_models[i].vendor && | 256 | if (vrm_models[i].vendor==vendor) |
278 | family == vrm_models[i].family && | 257 | if ((vrm_models[i].eff_family==eff_family) |
279 | model >= vrm_models[i].model_from && | 258 | && ((vrm_models[i].eff_model==eff_model) || |
280 | model <= vrm_models[i].model_to && | 259 | (vrm_models[i].eff_model >= 0x10 && |
281 | stepping <= vrm_models[i].stepping_to) | 260 | eff_model <= vrm_models[i].eff_model) || |
282 | return vrm_models[i].vrm_type; | 261 | (vrm_models[i].eff_model==ANY)) && |
262 | (eff_stepping <= vrm_models[i].eff_stepping)) | ||
263 | return vrm_models[i].vrm_type; | ||
264 | i++; | ||
283 | } | 265 | } |
284 | 266 | ||
285 | return 0; | 267 | return 0; |
@@ -288,12 +270,21 @@ static u8 find_vrm(u8 family, u8 model, u8 stepping, u8 vendor) | |||
288 | u8 vid_which_vrm(void) | 270 | u8 vid_which_vrm(void) |
289 | { | 271 | { |
290 | struct cpuinfo_x86 *c = &cpu_data(0); | 272 | struct cpuinfo_x86 *c = &cpu_data(0); |
291 | u8 vrm_ret; | 273 | u32 eax; |
274 | u8 eff_family, eff_model, eff_stepping, vrm_ret; | ||
292 | 275 | ||
293 | if (c->x86 < 6) /* Any CPU with family lower than 6 */ | 276 | if (c->x86 < 6) /* Any CPU with family lower than 6 */ |
294 | return 0; /* doesn't have VID */ | 277 | return 0; /* doesn't have VID and/or CPUID */ |
295 | 278 | ||
296 | vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_mask, c->x86_vendor); | 279 | eax = cpuid_eax(1); |
280 | eff_family = ((eax & 0x00000F00)>>8); | ||
281 | eff_model = ((eax & 0x000000F0)>>4); | ||
282 | eff_stepping = eax & 0xF; | ||
283 | if (eff_family == 0xF) { /* use extended model & family */ | ||
284 | eff_family += ((eax & 0x00F00000)>>20); | ||
285 | eff_model += ((eax & 0x000F0000)>>16)<<4; | ||
286 | } | ||
287 | vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor); | ||
297 | if (vrm_ret == 134) | 288 | if (vrm_ret == 134) |
298 | vrm_ret = get_via_model_d_vrm(); | 289 | vrm_ret = get_via_model_d_vrm(); |
299 | if (vrm_ret == 0) | 290 | if (vrm_ret == 0) |
@@ -309,6 +300,8 @@ u8 vid_which_vrm(void) | |||
309 | return 0; | 300 | return 0; |
310 | } | 301 | } |
311 | #endif | 302 | #endif |
303 | |||
304 | EXPORT_SYMBOL(vid_from_reg); | ||
312 | EXPORT_SYMBOL(vid_which_vrm); | 305 | EXPORT_SYMBOL(vid_which_vrm); |
313 | 306 | ||
314 | MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); | 307 | MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); |