This source file includes following definitions.
- vid_from_reg
- get_via_model_d_vrm
- find_vrm
- vid_which_vrm
- vid_which_vrm
1
2
3
4
5
6
7
8
9
10
11
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/hwmon-vid.h>
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 int vid_from_reg(int val, u8 vrm)
70 {
71 int vid;
72
73 switch (vrm) {
74
75 case 100:
76
77 val &= 0x3f;
78 if ((val & 0x1f) == 0x1f)
79 return 0;
80 if ((val & 0x1f) <= 0x09 || val == 0x0a)
81 vid = 1087500 - (val & 0x1f) * 25000;
82 else
83 vid = 1862500 - (val & 0x1f) * 25000;
84 if (val & 0x20)
85 vid -= 12500;
86 return (vid + 500) / 1000;
87
88 case 110:
89
90 val &= 0xff;
91 if (val < 0x02 || val > 0xb2)
92 return 0;
93 return (1600000 - (val - 2) * 6250 + 500) / 1000;
94
95 case 24:
96 val &= 0x1f;
97 if (val == 0x1f)
98 return 0;
99
100 case 25:
101 val &= 0x3f;
102 return (val < 32) ? 1550 - 25 * val
103 : 775 - (25 * (val - 31)) / 2;
104
105 case 26:
106 val &= 0x7f;
107 if (val >= 0x7c)
108 return 0;
109 return DIV_ROUND_CLOSEST(15500 - 125 * val, 10);
110
111 case 91:
112 case 90:
113 val &= 0x1f;
114 return val == 0x1f ? 0 :
115 1850 - val * 25;
116
117 case 85:
118 val &= 0x1f;
119 return (val & 0x10 ? 25 : 0) +
120 ((val & 0x0f) > 0x04 ? 2050 : 1250) -
121 ((val & 0x0f) * 50);
122
123 case 84:
124 val &= 0x0f;
125
126 case 82:
127 val &= 0x1f;
128 return val == 0x1f ? 0 :
129 val & 0x10 ? 5100 - (val) * 100 :
130 2050 - (val) * 50;
131 case 17:
132 val &= 0x1f;
133 return val & 0x10 ? 975 - (val & 0xF) * 25 :
134 1750 - val * 50;
135 case 13:
136 case 131:
137 val &= 0x3f;
138
139 if (vrm == 131 && val == 0x3f)
140 val++;
141 return 1708 - val * 16;
142 case 14:
143
144 val &= 0x7f;
145 return val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000;
146 default:
147 if (vrm)
148 pr_warn("Requested unsupported VRM version (%u)\n",
149 (unsigned int)vrm);
150 return 0;
151 }
152 }
153 EXPORT_SYMBOL(vid_from_reg);
154
155
156
157
158
159
160 struct vrm_model {
161 u8 vendor;
162 u8 family;
163 u8 model_from;
164 u8 model_to;
165 u8 stepping_to;
166 u8 vrm_type;
167 };
168
169 #define ANY 0xFF
170
171 #ifdef CONFIG_X86
172
173
174
175
176
177
178
179 static struct vrm_model vrm_models[] = {
180 {X86_VENDOR_AMD, 0x6, 0x0, ANY, ANY, 90},
181 {X86_VENDOR_AMD, 0xF, 0x0, 0x3F, ANY, 24},
182
183
184
185
186
187
188 {X86_VENDOR_AMD, 0xF, 0x40, 0x7F, ANY, 24},
189 {X86_VENDOR_AMD, 0xF, 0x80, ANY, ANY, 25},
190 {X86_VENDOR_AMD, 0x10, 0x0, ANY, ANY, 25},
191 {X86_VENDOR_AMD, 0x11, 0x0, ANY, ANY, 26},
192 {X86_VENDOR_AMD, 0x12, 0x0, ANY, ANY, 26},
193 {X86_VENDOR_AMD, 0x14, 0x0, ANY, ANY, 26},
194 {X86_VENDOR_AMD, 0x15, 0x0, ANY, ANY, 26},
195
196 {X86_VENDOR_INTEL, 0x6, 0x0, 0x6, ANY, 82},
197
198
199
200 {X86_VENDOR_INTEL, 0x6, 0x7, 0x7, ANY, 84},
201 {X86_VENDOR_INTEL, 0x6, 0x8, 0x8, ANY, 82},
202 {X86_VENDOR_INTEL, 0x6, 0x9, 0x9, ANY, 13},
203 {X86_VENDOR_INTEL, 0x6, 0xA, 0xA, ANY, 82},
204 {X86_VENDOR_INTEL, 0x6, 0xB, 0xB, ANY, 85},
205 {X86_VENDOR_INTEL, 0x6, 0xD, 0xD, ANY, 13},
206 {X86_VENDOR_INTEL, 0x6, 0xE, 0xE, ANY, 14},
207 {X86_VENDOR_INTEL, 0x6, 0xF, ANY, ANY, 110},
208
209 {X86_VENDOR_INTEL, 0xF, 0x0, 0x0, ANY, 90},
210 {X86_VENDOR_INTEL, 0xF, 0x1, 0x1, ANY, 90},
211 {X86_VENDOR_INTEL, 0xF, 0x2, 0x2, ANY, 90},
212 {X86_VENDOR_INTEL, 0xF, 0x3, ANY, ANY, 100},
213
214
215 {X86_VENDOR_CENTAUR, 0x6, 0x7, 0x7, ANY, 85},
216 {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x8, 0x7, 85},
217 {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, 0x7, 85},
218 {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, ANY, 17},
219 {X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, 0x7, 0},
220 {X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, ANY, 13},
221
222 {X86_VENDOR_CENTAUR, 0x6, 0xD, 0xD, ANY, 134},
223
224 };
225
226
227
228
229
230
231
232
233
234 static u8 get_via_model_d_vrm(void)
235 {
236 unsigned int vid, brand, __maybe_unused dummy;
237 static const char *brands[4] = {
238 "C7-M", "C7", "Eden", "C7-D"
239 };
240
241 rdmsr(0x198, dummy, vid);
242 vid &= 0xff;
243
244 rdmsr(0x1154, brand, dummy);
245 brand = ((brand >> 4) ^ (brand >> 2)) & 0x03;
246
247 if (vid > 0x3f) {
248 pr_info("Using %d-bit VID table for VIA %s CPU\n",
249 7, brands[brand]);
250 return 14;
251 } else {
252 pr_info("Using %d-bit VID table for VIA %s CPU\n",
253 6, brands[brand]);
254
255 return brand == 2 ? 131 : 13;
256 }
257 }
258
259 static u8 find_vrm(u8 family, u8 model, u8 stepping, u8 vendor)
260 {
261 int i;
262
263 for (i = 0; i < ARRAY_SIZE(vrm_models); i++) {
264 if (vendor == vrm_models[i].vendor &&
265 family == vrm_models[i].family &&
266 model >= vrm_models[i].model_from &&
267 model <= vrm_models[i].model_to &&
268 stepping <= vrm_models[i].stepping_to)
269 return vrm_models[i].vrm_type;
270 }
271
272 return 0;
273 }
274
275 u8 vid_which_vrm(void)
276 {
277 struct cpuinfo_x86 *c = &cpu_data(0);
278 u8 vrm_ret;
279
280 if (c->x86 < 6)
281 return 0;
282
283 vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_stepping, c->x86_vendor);
284 if (vrm_ret == 134)
285 vrm_ret = get_via_model_d_vrm();
286 if (vrm_ret == 0)
287 pr_info("Unknown VRM version of your x86 CPU\n");
288 return vrm_ret;
289 }
290
291
292 #else
293 u8 vid_which_vrm(void)
294 {
295 pr_info("Unknown VRM version of your CPU\n");
296 return 0;
297 }
298 #endif
299 EXPORT_SYMBOL(vid_which_vrm);
300
301 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
302
303 MODULE_DESCRIPTION("hwmon-vid driver");
304 MODULE_LICENSE("GPL");