1 | /* |
2 | * Copyright 2019 Advanced Micro Devices, Inc. |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
11 | * The above copyright notice and this permission notice shall be included in |
12 | * all copies or substantial portions of the Software. |
13 | * |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * |
22 | */ |
23 | |
24 | #include "amdgpu_ras_eeprom.h" |
25 | #include "amdgpu.h" |
26 | #include "amdgpu_ras.h" |
27 | #include <linux/bits.h> |
28 | #include "atom.h" |
29 | #include "amdgpu_eeprom.h" |
30 | #include "amdgpu_atomfirmware.h" |
31 | #include <linux/debugfs.h> |
32 | #include <linux/uaccess.h> |
33 | |
34 | #include "amdgpu_reset.h" |
35 | |
36 | /* These are memory addresses as would be seen by one or more EEPROM |
37 | * chips strung on the I2C bus, usually by manipulating pins 1-3 of a |
38 | * set of EEPROM devices. They form a continuous memory space. |
39 | * |
40 | * The I2C device address includes the device type identifier, 1010b, |
41 | * which is a reserved value and indicates that this is an I2C EEPROM |
42 | * device. It also includes the top 3 bits of the 19 bit EEPROM memory |
43 | * address, namely bits 18, 17, and 16. This makes up the 7 bit |
44 | * address sent on the I2C bus with bit 0 being the direction bit, |
45 | * which is not represented here, and sent by the hardware directly. |
46 | * |
47 | * For instance, |
48 | * 50h = 1010000b => device type identifier 1010b, bits 18:16 = 000b, address 0. |
49 | * 54h = 1010100b => --"--, bits 18:16 = 100b, address 40000h. |
50 | * 56h = 1010110b => --"--, bits 18:16 = 110b, address 60000h. |
51 | * Depending on the size of the I2C EEPROM device(s), bits 18:16 may |
52 | * address memory in a device or a device on the I2C bus, depending on |
53 | * the status of pins 1-3. See top of amdgpu_eeprom.c. |
54 | * |
55 | * The RAS table lives either at address 0 or address 40000h of EEPROM. |
56 | */ |
57 | #define EEPROM_I2C_MADDR_0 0x0 |
58 | #define EEPROM_I2C_MADDR_4 0x40000 |
59 | |
60 | /* |
61 | * The 2 macros bellow represent the actual size in bytes that |
62 | * those entities occupy in the EEPROM memory. |
63 | * RAS_TABLE_RECORD_SIZE is different than sizeof(eeprom_table_record) which |
64 | * uses uint64 to store 6b fields such as retired_page. |
65 | */ |
66 | #define 20 |
67 | #define RAS_TABLE_RECORD_SIZE 24 |
68 | |
69 | /* Table hdr is 'AMDR' */ |
70 | #define RAS_TABLE_HDR_VAL 0x414d4452 |
71 | |
72 | /* Bad GPU tag ‘BADG’ */ |
73 | #define RAS_TABLE_HDR_BAD 0x42414447 |
74 | |
75 | /* |
76 | * EEPROM Table structure v1 |
77 | * --------------------------------- |
78 | * | | |
79 | * | EEPROM TABLE HEADER | |
80 | * | ( size 20 Bytes ) | |
81 | * | | |
82 | * --------------------------------- |
83 | * | | |
84 | * | BAD PAGE RECORD AREA | |
85 | * | | |
86 | * --------------------------------- |
87 | */ |
88 | |
89 | /* Assume 2-Mbit size EEPROM and take up the whole space. */ |
90 | #define RAS_TBL_SIZE_BYTES (256 * 1024) |
91 | #define RAS_TABLE_START 0 |
92 | #define RAS_HDR_START RAS_TABLE_START |
93 | #define RAS_RECORD_START (RAS_HDR_START + RAS_TABLE_HEADER_SIZE) |
94 | #define RAS_MAX_RECORD_COUNT ((RAS_TBL_SIZE_BYTES - RAS_TABLE_HEADER_SIZE) \ |
95 | / RAS_TABLE_RECORD_SIZE) |
96 | |
97 | /* |
98 | * EEPROM Table structrue v2.1 |
99 | * --------------------------------- |
100 | * | | |
101 | * | EEPROM TABLE HEADER | |
102 | * | ( size 20 Bytes ) | |
103 | * | | |
104 | * --------------------------------- |
105 | * | | |
106 | * | EEPROM TABLE RAS INFO | |
107 | * | (available info size 4 Bytes) | |
108 | * | ( reserved size 252 Bytes ) | |
109 | * | | |
110 | * --------------------------------- |
111 | * | | |
112 | * | BAD PAGE RECORD AREA | |
113 | * | | |
114 | * --------------------------------- |
115 | */ |
116 | |
117 | /* EEPROM Table V2_1 */ |
118 | #define RAS_TABLE_V2_1_INFO_SIZE 256 |
119 | #define RAS_TABLE_V2_1_INFO_START RAS_TABLE_HEADER_SIZE |
120 | #define RAS_RECORD_START_V2_1 (RAS_HDR_START + RAS_TABLE_HEADER_SIZE + \ |
121 | RAS_TABLE_V2_1_INFO_SIZE) |
122 | #define RAS_MAX_RECORD_COUNT_V2_1 ((RAS_TBL_SIZE_BYTES - RAS_TABLE_HEADER_SIZE - \ |
123 | RAS_TABLE_V2_1_INFO_SIZE) \ |
124 | / RAS_TABLE_RECORD_SIZE) |
125 | |
126 | /* Given a zero-based index of an EEPROM RAS record, yields the EEPROM |
127 | * offset off of RAS_TABLE_START. That is, this is something you can |
128 | * add to control->i2c_address, and then tell I2C layer to read |
129 | * from/write to there. _N is the so called absolute index, |
130 | * because it starts right after the table header. |
131 | */ |
132 | #define RAS_INDEX_TO_OFFSET(_C, _N) ((_C)->ras_record_offset + \ |
133 | (_N) * RAS_TABLE_RECORD_SIZE) |
134 | |
135 | #define RAS_OFFSET_TO_INDEX(_C, _O) (((_O) - \ |
136 | (_C)->ras_record_offset) / RAS_TABLE_RECORD_SIZE) |
137 | |
138 | /* Given a 0-based relative record index, 0, 1, 2, ..., etc., off |
139 | * of "fri", return the absolute record index off of the end of |
140 | * the table header. |
141 | */ |
142 | #define RAS_RI_TO_AI(_C, _I) (((_I) + (_C)->ras_fri) % \ |
143 | (_C)->ras_max_record_count) |
144 | |
145 | #define RAS_NUM_RECS(_tbl_hdr) (((_tbl_hdr)->tbl_size - \ |
146 | RAS_TABLE_HEADER_SIZE) / RAS_TABLE_RECORD_SIZE) |
147 | |
148 | #define RAS_NUM_RECS_V2_1(_tbl_hdr) (((_tbl_hdr)->tbl_size - \ |
149 | RAS_TABLE_HEADER_SIZE - \ |
150 | RAS_TABLE_V2_1_INFO_SIZE) / RAS_TABLE_RECORD_SIZE) |
151 | |
152 | #define to_amdgpu_device(x) ((container_of(x, struct amdgpu_ras, eeprom_control))->adev) |
153 | |
154 | static bool __is_ras_eeprom_supported(struct amdgpu_device *adev) |
155 | { |
156 | switch (amdgpu_ip_version(adev, ip: MP1_HWIP, inst: 0)) { |
157 | case IP_VERSION(11, 0, 2): /* VEGA20 and ARCTURUS */ |
158 | case IP_VERSION(11, 0, 7): /* Sienna cichlid */ |
159 | case IP_VERSION(13, 0, 0): |
160 | case IP_VERSION(13, 0, 2): /* Aldebaran */ |
161 | case IP_VERSION(13, 0, 10): |
162 | return true; |
163 | case IP_VERSION(13, 0, 6): |
164 | return (adev->gmc.is_app_apu) ? false : true; |
165 | default: |
166 | return false; |
167 | } |
168 | } |
169 | |
170 | static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, |
171 | struct amdgpu_ras_eeprom_control *control) |
172 | { |
173 | struct atom_context *atom_ctx = adev->mode_info.atom_context; |
174 | u8 i2c_addr; |
175 | |
176 | if (!control) |
177 | return false; |
178 | |
179 | if (amdgpu_atomfirmware_ras_rom_addr(adev, i2c_address: &i2c_addr)) { |
180 | /* The address given by VBIOS is an 8-bit, wire-format |
181 | * address, i.e. the most significant byte. |
182 | * |
183 | * Normalize it to a 19-bit EEPROM address. Remove the |
184 | * device type identifier and make it a 7-bit address; |
185 | * then make it a 19-bit EEPROM address. See top of |
186 | * amdgpu_eeprom.c. |
187 | */ |
188 | i2c_addr = (i2c_addr & 0x0F) >> 1; |
189 | control->i2c_address = ((u32) i2c_addr) << 16; |
190 | |
191 | return true; |
192 | } |
193 | |
194 | switch (amdgpu_ip_version(adev, ip: MP1_HWIP, inst: 0)) { |
195 | case IP_VERSION(11, 0, 2): |
196 | /* VEGA20 and ARCTURUS */ |
197 | if (adev->asic_type == CHIP_VEGA20) |
198 | control->i2c_address = EEPROM_I2C_MADDR_0; |
199 | else if (strnstr(atom_ctx->vbios_pn, |
200 | "D342" , |
201 | sizeof(atom_ctx->vbios_pn))) |
202 | control->i2c_address = EEPROM_I2C_MADDR_0; |
203 | else |
204 | control->i2c_address = EEPROM_I2C_MADDR_4; |
205 | return true; |
206 | case IP_VERSION(11, 0, 7): |
207 | control->i2c_address = EEPROM_I2C_MADDR_0; |
208 | return true; |
209 | case IP_VERSION(13, 0, 2): |
210 | if (strnstr(atom_ctx->vbios_pn, "D673" , |
211 | sizeof(atom_ctx->vbios_pn))) |
212 | control->i2c_address = EEPROM_I2C_MADDR_4; |
213 | else |
214 | control->i2c_address = EEPROM_I2C_MADDR_0; |
215 | return true; |
216 | case IP_VERSION(13, 0, 0): |
217 | if (strnstr(atom_ctx->vbios_pn, "D707" , |
218 | sizeof(atom_ctx->vbios_pn))) |
219 | control->i2c_address = EEPROM_I2C_MADDR_0; |
220 | else |
221 | control->i2c_address = EEPROM_I2C_MADDR_4; |
222 | return true; |
223 | case IP_VERSION(13, 0, 6): |
224 | case IP_VERSION(13, 0, 10): |
225 | control->i2c_address = EEPROM_I2C_MADDR_4; |
226 | return true; |
227 | default: |
228 | return false; |
229 | } |
230 | } |
231 | |
232 | static void |
233 | (struct amdgpu_ras_eeprom_table_header *hdr, |
234 | unsigned char *buf) |
235 | { |
236 | u32 *pp = (uint32_t *)buf; |
237 | |
238 | pp[0] = cpu_to_le32(hdr->header); |
239 | pp[1] = cpu_to_le32(hdr->version); |
240 | pp[2] = cpu_to_le32(hdr->first_rec_offset); |
241 | pp[3] = cpu_to_le32(hdr->tbl_size); |
242 | pp[4] = cpu_to_le32(hdr->checksum); |
243 | } |
244 | |
245 | static void |
246 | (struct amdgpu_ras_eeprom_table_header *hdr, |
247 | unsigned char *buf) |
248 | { |
249 | u32 *pp = (uint32_t *)buf; |
250 | |
251 | hdr->header = le32_to_cpu(pp[0]); |
252 | hdr->version = le32_to_cpu(pp[1]); |
253 | hdr->first_rec_offset = le32_to_cpu(pp[2]); |
254 | hdr->tbl_size = le32_to_cpu(pp[3]); |
255 | hdr->checksum = le32_to_cpu(pp[4]); |
256 | } |
257 | |
258 | static int (struct amdgpu_ras_eeprom_control *control) |
259 | { |
260 | u8 buf[RAS_TABLE_HEADER_SIZE]; |
261 | struct amdgpu_device *adev = to_amdgpu_device(control); |
262 | int res; |
263 | |
264 | memset(buf, 0, sizeof(buf)); |
265 | __encode_table_header_to_buf(hdr: &control->tbl_hdr, buf); |
266 | |
267 | /* i2c may be unstable in gpu reset */ |
268 | down_read(sem: &adev->reset_domain->sem); |
269 | res = amdgpu_eeprom_write(i2c_adap: adev->pm.ras_eeprom_i2c_bus, |
270 | eeprom_addr: control->i2c_address + |
271 | control->ras_header_offset, |
272 | eeprom_buf: buf, RAS_TABLE_HEADER_SIZE); |
273 | up_read(sem: &adev->reset_domain->sem); |
274 | |
275 | if (res < 0) { |
276 | DRM_ERROR("Failed to write EEPROM table header:%d" , res); |
277 | } else if (res < RAS_TABLE_HEADER_SIZE) { |
278 | DRM_ERROR("Short write:%d out of %d\n" , |
279 | res, RAS_TABLE_HEADER_SIZE); |
280 | res = -EIO; |
281 | } else { |
282 | res = 0; |
283 | } |
284 | |
285 | return res; |
286 | } |
287 | |
288 | static void |
289 | __encode_table_ras_info_to_buf(struct amdgpu_ras_eeprom_table_ras_info *rai, |
290 | unsigned char *buf) |
291 | { |
292 | u32 *pp = (uint32_t *)buf; |
293 | u32 tmp; |
294 | |
295 | tmp = ((uint32_t)(rai->rma_status) & 0xFF) | |
296 | (((uint32_t)(rai->health_percent) << 8) & 0xFF00) | |
297 | (((uint32_t)(rai->ecc_page_threshold) << 16) & 0xFFFF0000); |
298 | pp[0] = cpu_to_le32(tmp); |
299 | } |
300 | |
301 | static void |
302 | __decode_table_ras_info_from_buf(struct amdgpu_ras_eeprom_table_ras_info *rai, |
303 | unsigned char *buf) |
304 | { |
305 | u32 *pp = (uint32_t *)buf; |
306 | u32 tmp; |
307 | |
308 | tmp = le32_to_cpu(pp[0]); |
309 | rai->rma_status = tmp & 0xFF; |
310 | rai->health_percent = (tmp >> 8) & 0xFF; |
311 | rai->ecc_page_threshold = (tmp >> 16) & 0xFFFF; |
312 | } |
313 | |
314 | static int __write_table_ras_info(struct amdgpu_ras_eeprom_control *control) |
315 | { |
316 | struct amdgpu_device *adev = to_amdgpu_device(control); |
317 | u8 *buf; |
318 | int res; |
319 | |
320 | buf = kzalloc(RAS_TABLE_V2_1_INFO_SIZE, GFP_KERNEL); |
321 | if (!buf) { |
322 | DRM_ERROR("Failed to alloc buf to write table ras info\n" ); |
323 | return -ENOMEM; |
324 | } |
325 | |
326 | __encode_table_ras_info_to_buf(rai: &control->tbl_rai, buf); |
327 | |
328 | /* i2c may be unstable in gpu reset */ |
329 | down_read(sem: &adev->reset_domain->sem); |
330 | res = amdgpu_eeprom_write(i2c_adap: adev->pm.ras_eeprom_i2c_bus, |
331 | eeprom_addr: control->i2c_address + |
332 | control->ras_info_offset, |
333 | eeprom_buf: buf, RAS_TABLE_V2_1_INFO_SIZE); |
334 | up_read(sem: &adev->reset_domain->sem); |
335 | |
336 | if (res < 0) { |
337 | DRM_ERROR("Failed to write EEPROM table ras info:%d" , res); |
338 | } else if (res < RAS_TABLE_V2_1_INFO_SIZE) { |
339 | DRM_ERROR("Short write:%d out of %d\n" , |
340 | res, RAS_TABLE_V2_1_INFO_SIZE); |
341 | res = -EIO; |
342 | } else { |
343 | res = 0; |
344 | } |
345 | |
346 | kfree(objp: buf); |
347 | |
348 | return res; |
349 | } |
350 | |
351 | static u8 __calc_hdr_byte_sum(const struct amdgpu_ras_eeprom_control *control) |
352 | { |
353 | int ii; |
354 | u8 *pp, csum; |
355 | size_t sz; |
356 | |
357 | /* Header checksum, skip checksum field in the calculation */ |
358 | sz = sizeof(control->tbl_hdr) - sizeof(control->tbl_hdr.checksum); |
359 | pp = (u8 *) &control->tbl_hdr; |
360 | csum = 0; |
361 | for (ii = 0; ii < sz; ii++, pp++) |
362 | csum += *pp; |
363 | |
364 | return csum; |
365 | } |
366 | |
367 | static u8 __calc_ras_info_byte_sum(const struct amdgpu_ras_eeprom_control *control) |
368 | { |
369 | int ii; |
370 | u8 *pp, csum; |
371 | size_t sz; |
372 | |
373 | sz = sizeof(control->tbl_rai); |
374 | pp = (u8 *) &control->tbl_rai; |
375 | csum = 0; |
376 | for (ii = 0; ii < sz; ii++, pp++) |
377 | csum += *pp; |
378 | |
379 | return csum; |
380 | } |
381 | |
382 | static int ( |
383 | struct amdgpu_ras_eeprom_control *control, |
384 | uint32_t ) |
385 | { |
386 | struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr; |
387 | u8 *hh; |
388 | int res; |
389 | u8 csum; |
390 | |
391 | csum = -hdr->checksum; |
392 | |
393 | hh = (void *) &hdr->header; |
394 | csum -= (hh[0] + hh[1] + hh[2] + hh[3]); |
395 | hh = (void *) &header; |
396 | csum += hh[0] + hh[1] + hh[2] + hh[3]; |
397 | csum = -csum; |
398 | mutex_lock(&control->ras_tbl_mutex); |
399 | hdr->header = header; |
400 | hdr->checksum = csum; |
401 | res = __write_table_header(control); |
402 | mutex_unlock(lock: &control->ras_tbl_mutex); |
403 | |
404 | return res; |
405 | } |
406 | |
407 | /** |
408 | * amdgpu_ras_eeprom_reset_table -- Reset the RAS EEPROM table |
409 | * @control: pointer to control structure |
410 | * |
411 | * Reset the contents of the header of the RAS EEPROM table. |
412 | * Return 0 on success, -errno on error. |
413 | */ |
414 | int amdgpu_ras_eeprom_reset_table(struct amdgpu_ras_eeprom_control *control) |
415 | { |
416 | struct amdgpu_device *adev = to_amdgpu_device(control); |
417 | struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr; |
418 | struct amdgpu_ras_eeprom_table_ras_info *rai = &control->tbl_rai; |
419 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
420 | u8 csum; |
421 | int res; |
422 | |
423 | mutex_lock(&control->ras_tbl_mutex); |
424 | |
425 | hdr->header = RAS_TABLE_HDR_VAL; |
426 | if (adev->umc.ras && |
427 | adev->umc.ras->set_eeprom_table_version) |
428 | adev->umc.ras->set_eeprom_table_version(hdr); |
429 | else |
430 | hdr->version = RAS_TABLE_VER_V1; |
431 | |
432 | if (hdr->version == RAS_TABLE_VER_V2_1) { |
433 | hdr->first_rec_offset = RAS_RECORD_START_V2_1; |
434 | hdr->tbl_size = RAS_TABLE_HEADER_SIZE + |
435 | RAS_TABLE_V2_1_INFO_SIZE; |
436 | rai->rma_status = GPU_HEALTH_USABLE; |
437 | /** |
438 | * GPU health represented as a percentage. |
439 | * 0 means worst health, 100 means fully health. |
440 | */ |
441 | rai->health_percent = 100; |
442 | /* ecc_page_threshold = 0 means disable bad page retirement */ |
443 | rai->ecc_page_threshold = con->bad_page_cnt_threshold; |
444 | } else { |
445 | hdr->first_rec_offset = RAS_RECORD_START; |
446 | hdr->tbl_size = RAS_TABLE_HEADER_SIZE; |
447 | } |
448 | |
449 | csum = __calc_hdr_byte_sum(control); |
450 | if (hdr->version == RAS_TABLE_VER_V2_1) |
451 | csum += __calc_ras_info_byte_sum(control); |
452 | csum = -csum; |
453 | hdr->checksum = csum; |
454 | res = __write_table_header(control); |
455 | if (!res && hdr->version > RAS_TABLE_VER_V1) |
456 | res = __write_table_ras_info(control); |
457 | |
458 | control->ras_num_recs = 0; |
459 | control->ras_fri = 0; |
460 | |
461 | amdgpu_dpm_send_hbm_bad_pages_num(adev, size: control->ras_num_recs); |
462 | |
463 | control->bad_channel_bitmap = 0; |
464 | amdgpu_dpm_send_hbm_bad_channel_flag(adev, size: control->bad_channel_bitmap); |
465 | con->update_channel_flag = false; |
466 | |
467 | amdgpu_ras_debugfs_set_ret_size(control); |
468 | |
469 | mutex_unlock(lock: &control->ras_tbl_mutex); |
470 | |
471 | return res; |
472 | } |
473 | |
474 | static void |
475 | __encode_table_record_to_buf(struct amdgpu_ras_eeprom_control *control, |
476 | struct eeprom_table_record *record, |
477 | unsigned char *buf) |
478 | { |
479 | __le64 tmp = 0; |
480 | int i = 0; |
481 | |
482 | /* Next are all record fields according to EEPROM page spec in LE foramt */ |
483 | buf[i++] = record->err_type; |
484 | |
485 | buf[i++] = record->bank; |
486 | |
487 | tmp = cpu_to_le64(record->ts); |
488 | memcpy(buf + i, &tmp, 8); |
489 | i += 8; |
490 | |
491 | tmp = cpu_to_le64((record->offset & 0xffffffffffff)); |
492 | memcpy(buf + i, &tmp, 6); |
493 | i += 6; |
494 | |
495 | buf[i++] = record->mem_channel; |
496 | buf[i++] = record->mcumc_id; |
497 | |
498 | tmp = cpu_to_le64((record->retired_page & 0xffffffffffff)); |
499 | memcpy(buf + i, &tmp, 6); |
500 | } |
501 | |
502 | static void |
503 | __decode_table_record_from_buf(struct amdgpu_ras_eeprom_control *control, |
504 | struct eeprom_table_record *record, |
505 | unsigned char *buf) |
506 | { |
507 | __le64 tmp = 0; |
508 | int i = 0; |
509 | |
510 | /* Next are all record fields according to EEPROM page spec in LE foramt */ |
511 | record->err_type = buf[i++]; |
512 | |
513 | record->bank = buf[i++]; |
514 | |
515 | memcpy(&tmp, buf + i, 8); |
516 | record->ts = le64_to_cpu(tmp); |
517 | i += 8; |
518 | |
519 | memcpy(&tmp, buf + i, 6); |
520 | record->offset = (le64_to_cpu(tmp) & 0xffffffffffff); |
521 | i += 6; |
522 | |
523 | record->mem_channel = buf[i++]; |
524 | record->mcumc_id = buf[i++]; |
525 | |
526 | memcpy(&tmp, buf + i, 6); |
527 | record->retired_page = (le64_to_cpu(tmp) & 0xffffffffffff); |
528 | } |
529 | |
530 | bool amdgpu_ras_eeprom_check_err_threshold(struct amdgpu_device *adev) |
531 | { |
532 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
533 | |
534 | if (!__is_ras_eeprom_supported(adev) || |
535 | !amdgpu_bad_page_threshold) |
536 | return false; |
537 | |
538 | /* skip check eeprom table for VEGA20 Gaming */ |
539 | if (!con) |
540 | return false; |
541 | else |
542 | if (!(con->features & BIT(AMDGPU_RAS_BLOCK__UMC))) |
543 | return false; |
544 | |
545 | if (con->eeprom_control.tbl_hdr.header == RAS_TABLE_HDR_BAD) { |
546 | if (amdgpu_bad_page_threshold == -1) { |
547 | dev_warn(adev->dev, "RAS records:%d exceed threshold:%d" , |
548 | con->eeprom_control.ras_num_recs, con->bad_page_cnt_threshold); |
549 | dev_warn(adev->dev, |
550 | "But GPU can be operated due to bad_page_threshold = -1.\n" ); |
551 | return false; |
552 | } else { |
553 | dev_warn(adev->dev, "This GPU is in BAD status." ); |
554 | dev_warn(adev->dev, "Please retire it or set a larger " |
555 | "threshold value when reloading driver.\n" ); |
556 | return true; |
557 | } |
558 | } |
559 | |
560 | return false; |
561 | } |
562 | |
563 | /** |
564 | * __amdgpu_ras_eeprom_write -- write indexed from buffer to EEPROM |
565 | * @control: pointer to control structure |
566 | * @buf: pointer to buffer containing data to write |
567 | * @fri: start writing at this index |
568 | * @num: number of records to write |
569 | * |
570 | * The caller must hold the table mutex in @control. |
571 | * Return 0 on success, -errno otherwise. |
572 | */ |
573 | static int __amdgpu_ras_eeprom_write(struct amdgpu_ras_eeprom_control *control, |
574 | u8 *buf, const u32 fri, const u32 num) |
575 | { |
576 | struct amdgpu_device *adev = to_amdgpu_device(control); |
577 | u32 buf_size; |
578 | int res; |
579 | |
580 | /* i2c may be unstable in gpu reset */ |
581 | down_read(sem: &adev->reset_domain->sem); |
582 | buf_size = num * RAS_TABLE_RECORD_SIZE; |
583 | res = amdgpu_eeprom_write(i2c_adap: adev->pm.ras_eeprom_i2c_bus, |
584 | eeprom_addr: control->i2c_address + |
585 | RAS_INDEX_TO_OFFSET(control, fri), |
586 | eeprom_buf: buf, bytes: buf_size); |
587 | up_read(sem: &adev->reset_domain->sem); |
588 | if (res < 0) { |
589 | DRM_ERROR("Writing %d EEPROM table records error:%d" , |
590 | num, res); |
591 | } else if (res < buf_size) { |
592 | /* Short write, return error. |
593 | */ |
594 | DRM_ERROR("Wrote %d records out of %d" , |
595 | res / RAS_TABLE_RECORD_SIZE, num); |
596 | res = -EIO; |
597 | } else { |
598 | res = 0; |
599 | } |
600 | |
601 | return res; |
602 | } |
603 | |
604 | static int |
605 | amdgpu_ras_eeprom_append_table(struct amdgpu_ras_eeprom_control *control, |
606 | struct eeprom_table_record *record, |
607 | const u32 num) |
608 | { |
609 | struct amdgpu_ras *con = amdgpu_ras_get_context(to_amdgpu_device(control)); |
610 | u32 a, b, i; |
611 | u8 *buf, *pp; |
612 | int res; |
613 | |
614 | buf = kcalloc(n: num, RAS_TABLE_RECORD_SIZE, GFP_KERNEL); |
615 | if (!buf) |
616 | return -ENOMEM; |
617 | |
618 | /* Encode all of them in one go. |
619 | */ |
620 | pp = buf; |
621 | for (i = 0; i < num; i++, pp += RAS_TABLE_RECORD_SIZE) { |
622 | __encode_table_record_to_buf(control, record: &record[i], buf: pp); |
623 | |
624 | /* update bad channel bitmap */ |
625 | if ((record[i].mem_channel < BITS_PER_TYPE(control->bad_channel_bitmap)) && |
626 | !(control->bad_channel_bitmap & (1 << record[i].mem_channel))) { |
627 | control->bad_channel_bitmap |= 1 << record[i].mem_channel; |
628 | con->update_channel_flag = true; |
629 | } |
630 | } |
631 | |
632 | /* a, first record index to write into. |
633 | * b, last record index to write into. |
634 | * a = first index to read (fri) + number of records in the table, |
635 | * b = a + @num - 1. |
636 | * Let N = control->ras_max_num_record_count, then we have, |
637 | * case 0: 0 <= a <= b < N, |
638 | * just append @num records starting at a; |
639 | * case 1: 0 <= a < N <= b, |
640 | * append (N - a) records starting at a, and |
641 | * append the remainder, b % N + 1, starting at 0. |
642 | * case 2: 0 <= fri < N <= a <= b, then modulo N we get two subcases, |
643 | * case 2a: 0 <= a <= b < N |
644 | * append num records starting at a; and fix fri if b overwrote it, |
645 | * and since a <= b, if b overwrote it then a must've also, |
646 | * and if b didn't overwrite it, then a didn't also. |
647 | * case 2b: 0 <= b < a < N |
648 | * write num records starting at a, which wraps around 0=N |
649 | * and overwrite fri unconditionally. Now from case 2a, |
650 | * this means that b eclipsed fri to overwrite it and wrap |
651 | * around 0 again, i.e. b = 2N+r pre modulo N, so we unconditionally |
652 | * set fri = b + 1 (mod N). |
653 | * Now, since fri is updated in every case, except the trivial case 0, |
654 | * the number of records present in the table after writing, is, |
655 | * num_recs - 1 = b - fri (mod N), and we take the positive value, |
656 | * by adding an arbitrary multiple of N before taking the modulo N |
657 | * as shown below. |
658 | */ |
659 | a = control->ras_fri + control->ras_num_recs; |
660 | b = a + num - 1; |
661 | if (b < control->ras_max_record_count) { |
662 | res = __amdgpu_ras_eeprom_write(control, buf, fri: a, num); |
663 | } else if (a < control->ras_max_record_count) { |
664 | u32 g0, g1; |
665 | |
666 | g0 = control->ras_max_record_count - a; |
667 | g1 = b % control->ras_max_record_count + 1; |
668 | res = __amdgpu_ras_eeprom_write(control, buf, fri: a, num: g0); |
669 | if (res) |
670 | goto Out; |
671 | res = __amdgpu_ras_eeprom_write(control, |
672 | buf: buf + g0 * RAS_TABLE_RECORD_SIZE, |
673 | fri: 0, num: g1); |
674 | if (res) |
675 | goto Out; |
676 | if (g1 > control->ras_fri) |
677 | control->ras_fri = g1 % control->ras_max_record_count; |
678 | } else { |
679 | a %= control->ras_max_record_count; |
680 | b %= control->ras_max_record_count; |
681 | |
682 | if (a <= b) { |
683 | /* Note that, b - a + 1 = num. */ |
684 | res = __amdgpu_ras_eeprom_write(control, buf, fri: a, num); |
685 | if (res) |
686 | goto Out; |
687 | if (b >= control->ras_fri) |
688 | control->ras_fri = (b + 1) % control->ras_max_record_count; |
689 | } else { |
690 | u32 g0, g1; |
691 | |
692 | /* b < a, which means, we write from |
693 | * a to the end of the table, and from |
694 | * the start of the table to b. |
695 | */ |
696 | g0 = control->ras_max_record_count - a; |
697 | g1 = b + 1; |
698 | res = __amdgpu_ras_eeprom_write(control, buf, fri: a, num: g0); |
699 | if (res) |
700 | goto Out; |
701 | res = __amdgpu_ras_eeprom_write(control, |
702 | buf: buf + g0 * RAS_TABLE_RECORD_SIZE, |
703 | fri: 0, num: g1); |
704 | if (res) |
705 | goto Out; |
706 | control->ras_fri = g1 % control->ras_max_record_count; |
707 | } |
708 | } |
709 | control->ras_num_recs = 1 + (control->ras_max_record_count + b |
710 | - control->ras_fri) |
711 | % control->ras_max_record_count; |
712 | Out: |
713 | kfree(objp: buf); |
714 | return res; |
715 | } |
716 | |
717 | static int |
718 | (struct amdgpu_ras_eeprom_control *control) |
719 | { |
720 | struct amdgpu_device *adev = to_amdgpu_device(control); |
721 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
722 | u8 *buf, *pp, csum; |
723 | u32 buf_size; |
724 | int res; |
725 | |
726 | /* Modify the header if it exceeds. |
727 | */ |
728 | if (amdgpu_bad_page_threshold != 0 && |
729 | control->ras_num_recs >= ras->bad_page_cnt_threshold) { |
730 | dev_warn(adev->dev, |
731 | "Saved bad pages %d reaches threshold value %d\n" , |
732 | control->ras_num_recs, ras->bad_page_cnt_threshold); |
733 | control->tbl_hdr.header = RAS_TABLE_HDR_BAD; |
734 | if (control->tbl_hdr.version == RAS_TABLE_VER_V2_1) { |
735 | control->tbl_rai.rma_status = GPU_RETIRED__ECC_REACH_THRESHOLD; |
736 | control->tbl_rai.health_percent = 0; |
737 | } |
738 | |
739 | /* ignore the -ENOTSUPP return value */ |
740 | amdgpu_dpm_send_rma_reason(adev); |
741 | } |
742 | |
743 | if (control->tbl_hdr.version == RAS_TABLE_VER_V2_1) |
744 | control->tbl_hdr.tbl_size = RAS_TABLE_HEADER_SIZE + |
745 | RAS_TABLE_V2_1_INFO_SIZE + |
746 | control->ras_num_recs * RAS_TABLE_RECORD_SIZE; |
747 | else |
748 | control->tbl_hdr.tbl_size = RAS_TABLE_HEADER_SIZE + |
749 | control->ras_num_recs * RAS_TABLE_RECORD_SIZE; |
750 | control->tbl_hdr.checksum = 0; |
751 | |
752 | buf_size = control->ras_num_recs * RAS_TABLE_RECORD_SIZE; |
753 | buf = kcalloc(n: control->ras_num_recs, RAS_TABLE_RECORD_SIZE, GFP_KERNEL); |
754 | if (!buf) { |
755 | DRM_ERROR("allocating memory for table of size %d bytes failed\n" , |
756 | control->tbl_hdr.tbl_size); |
757 | res = -ENOMEM; |
758 | goto Out; |
759 | } |
760 | |
761 | down_read(sem: &adev->reset_domain->sem); |
762 | res = amdgpu_eeprom_read(i2c_adap: adev->pm.ras_eeprom_i2c_bus, |
763 | eeprom_addr: control->i2c_address + |
764 | control->ras_record_offset, |
765 | eeprom_buf: buf, bytes: buf_size); |
766 | up_read(sem: &adev->reset_domain->sem); |
767 | if (res < 0) { |
768 | DRM_ERROR("EEPROM failed reading records:%d\n" , |
769 | res); |
770 | goto Out; |
771 | } else if (res < buf_size) { |
772 | DRM_ERROR("EEPROM read %d out of %d bytes\n" , |
773 | res, buf_size); |
774 | res = -EIO; |
775 | goto Out; |
776 | } |
777 | |
778 | /** |
779 | * bad page records have been stored in eeprom, |
780 | * now calculate gpu health percent |
781 | */ |
782 | if (amdgpu_bad_page_threshold != 0 && |
783 | control->tbl_hdr.version == RAS_TABLE_VER_V2_1 && |
784 | control->ras_num_recs < ras->bad_page_cnt_threshold) |
785 | control->tbl_rai.health_percent = ((ras->bad_page_cnt_threshold - |
786 | control->ras_num_recs) * 100) / |
787 | ras->bad_page_cnt_threshold; |
788 | |
789 | /* Recalc the checksum. |
790 | */ |
791 | csum = 0; |
792 | for (pp = buf; pp < buf + buf_size; pp++) |
793 | csum += *pp; |
794 | |
795 | csum += __calc_hdr_byte_sum(control); |
796 | if (control->tbl_hdr.version == RAS_TABLE_VER_V2_1) |
797 | csum += __calc_ras_info_byte_sum(control); |
798 | /* avoid sign extension when assigning to "checksum" */ |
799 | csum = -csum; |
800 | control->tbl_hdr.checksum = csum; |
801 | res = __write_table_header(control); |
802 | if (!res && control->tbl_hdr.version > RAS_TABLE_VER_V1) |
803 | res = __write_table_ras_info(control); |
804 | Out: |
805 | kfree(objp: buf); |
806 | return res; |
807 | } |
808 | |
809 | /** |
810 | * amdgpu_ras_eeprom_append -- append records to the EEPROM RAS table |
811 | * @control: pointer to control structure |
812 | * @record: array of records to append |
813 | * @num: number of records in @record array |
814 | * |
815 | * Append @num records to the table, calculate the checksum and write |
816 | * the table back to EEPROM. The maximum number of records that |
817 | * can be appended is between 1 and control->ras_max_record_count, |
818 | * regardless of how many records are already stored in the table. |
819 | * |
820 | * Return 0 on success or if EEPROM is not supported, -errno on error. |
821 | */ |
822 | int amdgpu_ras_eeprom_append(struct amdgpu_ras_eeprom_control *control, |
823 | struct eeprom_table_record *record, |
824 | const u32 num) |
825 | { |
826 | struct amdgpu_device *adev = to_amdgpu_device(control); |
827 | int res; |
828 | |
829 | if (!__is_ras_eeprom_supported(adev)) |
830 | return 0; |
831 | |
832 | if (num == 0) { |
833 | DRM_ERROR("will not append 0 records\n" ); |
834 | return -EINVAL; |
835 | } else if (num > control->ras_max_record_count) { |
836 | DRM_ERROR("cannot append %d records than the size of table %d\n" , |
837 | num, control->ras_max_record_count); |
838 | return -EINVAL; |
839 | } |
840 | |
841 | mutex_lock(&control->ras_tbl_mutex); |
842 | |
843 | res = amdgpu_ras_eeprom_append_table(control, record, num); |
844 | if (!res) |
845 | res = amdgpu_ras_eeprom_update_header(control); |
846 | if (!res) |
847 | amdgpu_ras_debugfs_set_ret_size(control); |
848 | |
849 | mutex_unlock(lock: &control->ras_tbl_mutex); |
850 | return res; |
851 | } |
852 | |
853 | /** |
854 | * __amdgpu_ras_eeprom_read -- read indexed from EEPROM into buffer |
855 | * @control: pointer to control structure |
856 | * @buf: pointer to buffer to read into |
857 | * @fri: first record index, start reading at this index, absolute index |
858 | * @num: number of records to read |
859 | * |
860 | * The caller must hold the table mutex in @control. |
861 | * Return 0 on success, -errno otherwise. |
862 | */ |
863 | static int __amdgpu_ras_eeprom_read(struct amdgpu_ras_eeprom_control *control, |
864 | u8 *buf, const u32 fri, const u32 num) |
865 | { |
866 | struct amdgpu_device *adev = to_amdgpu_device(control); |
867 | u32 buf_size; |
868 | int res; |
869 | |
870 | /* i2c may be unstable in gpu reset */ |
871 | down_read(sem: &adev->reset_domain->sem); |
872 | buf_size = num * RAS_TABLE_RECORD_SIZE; |
873 | res = amdgpu_eeprom_read(i2c_adap: adev->pm.ras_eeprom_i2c_bus, |
874 | eeprom_addr: control->i2c_address + |
875 | RAS_INDEX_TO_OFFSET(control, fri), |
876 | eeprom_buf: buf, bytes: buf_size); |
877 | up_read(sem: &adev->reset_domain->sem); |
878 | if (res < 0) { |
879 | DRM_ERROR("Reading %d EEPROM table records error:%d" , |
880 | num, res); |
881 | } else if (res < buf_size) { |
882 | /* Short read, return error. |
883 | */ |
884 | DRM_ERROR("Read %d records out of %d" , |
885 | res / RAS_TABLE_RECORD_SIZE, num); |
886 | res = -EIO; |
887 | } else { |
888 | res = 0; |
889 | } |
890 | |
891 | return res; |
892 | } |
893 | |
894 | /** |
895 | * amdgpu_ras_eeprom_read -- read EEPROM |
896 | * @control: pointer to control structure |
897 | * @record: array of records to read into |
898 | * @num: number of records in @record |
899 | * |
900 | * Reads num records from the RAS table in EEPROM and |
901 | * writes the data into @record array. |
902 | * |
903 | * Returns 0 on success, -errno on error. |
904 | */ |
905 | int amdgpu_ras_eeprom_read(struct amdgpu_ras_eeprom_control *control, |
906 | struct eeprom_table_record *record, |
907 | const u32 num) |
908 | { |
909 | struct amdgpu_device *adev = to_amdgpu_device(control); |
910 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
911 | int i, res; |
912 | u8 *buf, *pp; |
913 | u32 g0, g1; |
914 | |
915 | if (!__is_ras_eeprom_supported(adev)) |
916 | return 0; |
917 | |
918 | if (num == 0) { |
919 | DRM_ERROR("will not read 0 records\n" ); |
920 | return -EINVAL; |
921 | } else if (num > control->ras_num_recs) { |
922 | DRM_ERROR("too many records to read:%d available:%d\n" , |
923 | num, control->ras_num_recs); |
924 | return -EINVAL; |
925 | } |
926 | |
927 | buf = kcalloc(n: num, RAS_TABLE_RECORD_SIZE, GFP_KERNEL); |
928 | if (!buf) |
929 | return -ENOMEM; |
930 | |
931 | /* Determine how many records to read, from the first record |
932 | * index, fri, to the end of the table, and from the beginning |
933 | * of the table, such that the total number of records is |
934 | * @num, and we handle wrap around when fri > 0 and |
935 | * fri + num > RAS_MAX_RECORD_COUNT. |
936 | * |
937 | * First we compute the index of the last element |
938 | * which would be fetched from each region, |
939 | * g0 is in [fri, fri + num - 1], and |
940 | * g1 is in [0, RAS_MAX_RECORD_COUNT - 1]. |
941 | * Then, if g0 < RAS_MAX_RECORD_COUNT, the index of |
942 | * the last element to fetch, we set g0 to _the number_ |
943 | * of elements to fetch, @num, since we know that the last |
944 | * indexed to be fetched does not exceed the table. |
945 | * |
946 | * If, however, g0 >= RAS_MAX_RECORD_COUNT, then |
947 | * we set g0 to the number of elements to read |
948 | * until the end of the table, and g1 to the number of |
949 | * elements to read from the beginning of the table. |
950 | */ |
951 | g0 = control->ras_fri + num - 1; |
952 | g1 = g0 % control->ras_max_record_count; |
953 | if (g0 < control->ras_max_record_count) { |
954 | g0 = num; |
955 | g1 = 0; |
956 | } else { |
957 | g0 = control->ras_max_record_count - control->ras_fri; |
958 | g1 += 1; |
959 | } |
960 | |
961 | mutex_lock(&control->ras_tbl_mutex); |
962 | res = __amdgpu_ras_eeprom_read(control, buf, fri: control->ras_fri, num: g0); |
963 | if (res) |
964 | goto Out; |
965 | if (g1) { |
966 | res = __amdgpu_ras_eeprom_read(control, |
967 | buf: buf + g0 * RAS_TABLE_RECORD_SIZE, |
968 | fri: 0, num: g1); |
969 | if (res) |
970 | goto Out; |
971 | } |
972 | |
973 | res = 0; |
974 | |
975 | /* Read up everything? Then transform. |
976 | */ |
977 | pp = buf; |
978 | for (i = 0; i < num; i++, pp += RAS_TABLE_RECORD_SIZE) { |
979 | __decode_table_record_from_buf(control, record: &record[i], buf: pp); |
980 | |
981 | /* update bad channel bitmap */ |
982 | if ((record[i].mem_channel < BITS_PER_TYPE(control->bad_channel_bitmap)) && |
983 | !(control->bad_channel_bitmap & (1 << record[i].mem_channel))) { |
984 | control->bad_channel_bitmap |= 1 << record[i].mem_channel; |
985 | con->update_channel_flag = true; |
986 | } |
987 | } |
988 | Out: |
989 | kfree(objp: buf); |
990 | mutex_unlock(lock: &control->ras_tbl_mutex); |
991 | |
992 | return res; |
993 | } |
994 | |
995 | uint32_t amdgpu_ras_eeprom_max_record_count(struct amdgpu_ras_eeprom_control *control) |
996 | { |
997 | if (control->tbl_hdr.version == RAS_TABLE_VER_V2_1) |
998 | return RAS_MAX_RECORD_COUNT_V2_1; |
999 | else |
1000 | return RAS_MAX_RECORD_COUNT; |
1001 | } |
1002 | |
1003 | static ssize_t |
1004 | amdgpu_ras_debugfs_eeprom_size_read(struct file *f, char __user *buf, |
1005 | size_t size, loff_t *pos) |
1006 | { |
1007 | struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private; |
1008 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
1009 | struct amdgpu_ras_eeprom_control *control = ras ? &ras->eeprom_control : NULL; |
1010 | u8 data[50]; |
1011 | int res; |
1012 | |
1013 | if (!size) |
1014 | return size; |
1015 | |
1016 | if (!ras || !control) { |
1017 | res = snprintf(buf: data, size: sizeof(data), fmt: "Not supported\n" ); |
1018 | } else { |
1019 | res = snprintf(buf: data, size: sizeof(data), fmt: "%d bytes or %d records\n" , |
1020 | RAS_TBL_SIZE_BYTES, control->ras_max_record_count); |
1021 | } |
1022 | |
1023 | if (*pos >= res) |
1024 | return 0; |
1025 | |
1026 | res -= *pos; |
1027 | res = min_t(size_t, res, size); |
1028 | |
1029 | if (copy_to_user(to: buf, from: &data[*pos], n: res)) |
1030 | return -EFAULT; |
1031 | |
1032 | *pos += res; |
1033 | |
1034 | return res; |
1035 | } |
1036 | |
1037 | const struct file_operations amdgpu_ras_debugfs_eeprom_size_ops = { |
1038 | .owner = THIS_MODULE, |
1039 | .read = amdgpu_ras_debugfs_eeprom_size_read, |
1040 | .write = NULL, |
1041 | .llseek = default_llseek, |
1042 | }; |
1043 | |
1044 | static const char *tbl_hdr_str = " Signature Version FirstOffs Size Checksum\n" ; |
1045 | static const char *tbl_hdr_fmt = "0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n" ; |
1046 | #define tbl_hdr_fmt_size (5 * (2+8) + 4 + 1) |
1047 | static const char *rec_hdr_str = "Index Offset ErrType Bank/CU TimeStamp Offs/Addr MemChl MCUMCID RetiredPage\n" ; |
1048 | static const char *rec_hdr_fmt = "%5d 0x%05X %7s 0x%02X 0x%016llX 0x%012llX 0x%02X 0x%02X 0x%012llX\n" ; |
1049 | #define rec_hdr_fmt_size (5 + 1 + 7 + 1 + 7 + 1 + 7 + 1 + 18 + 1 + 14 + 1 + 6 + 1 + 7 + 1 + 14 + 1) |
1050 | |
1051 | static const char *record_err_type_str[AMDGPU_RAS_EEPROM_ERR_COUNT] = { |
1052 | "ignore" , |
1053 | "re" , |
1054 | "ue" , |
1055 | }; |
1056 | |
1057 | static loff_t amdgpu_ras_debugfs_table_size(struct amdgpu_ras_eeprom_control *control) |
1058 | { |
1059 | return strlen(tbl_hdr_str) + tbl_hdr_fmt_size + |
1060 | strlen(rec_hdr_str) + rec_hdr_fmt_size * control->ras_num_recs; |
1061 | } |
1062 | |
1063 | void amdgpu_ras_debugfs_set_ret_size(struct amdgpu_ras_eeprom_control *control) |
1064 | { |
1065 | struct amdgpu_ras *ras = container_of(control, struct amdgpu_ras, |
1066 | eeprom_control); |
1067 | struct dentry *de = ras->de_ras_eeprom_table; |
1068 | |
1069 | if (de) |
1070 | d_inode(dentry: de)->i_size = amdgpu_ras_debugfs_table_size(control); |
1071 | } |
1072 | |
1073 | static ssize_t amdgpu_ras_debugfs_table_read(struct file *f, char __user *buf, |
1074 | size_t size, loff_t *pos) |
1075 | { |
1076 | struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private; |
1077 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
1078 | struct amdgpu_ras_eeprom_control *control = &ras->eeprom_control; |
1079 | const size_t orig_size = size; |
1080 | int res = -EFAULT; |
1081 | size_t data_len; |
1082 | |
1083 | mutex_lock(&control->ras_tbl_mutex); |
1084 | |
1085 | /* We want *pos - data_len > 0, which means there's |
1086 | * bytes to be printed from data. |
1087 | */ |
1088 | data_len = strlen(tbl_hdr_str); |
1089 | if (*pos < data_len) { |
1090 | data_len -= *pos; |
1091 | data_len = min_t(size_t, data_len, size); |
1092 | if (copy_to_user(to: buf, from: &tbl_hdr_str[*pos], n: data_len)) |
1093 | goto Out; |
1094 | buf += data_len; |
1095 | size -= data_len; |
1096 | *pos += data_len; |
1097 | } |
1098 | |
1099 | data_len = strlen(tbl_hdr_str) + tbl_hdr_fmt_size; |
1100 | if (*pos < data_len && size > 0) { |
1101 | u8 data[tbl_hdr_fmt_size + 1]; |
1102 | loff_t lpos; |
1103 | |
1104 | snprintf(buf: data, size: sizeof(data), fmt: tbl_hdr_fmt, |
1105 | control->tbl_hdr.header, |
1106 | control->tbl_hdr.version, |
1107 | control->tbl_hdr.first_rec_offset, |
1108 | control->tbl_hdr.tbl_size, |
1109 | control->tbl_hdr.checksum); |
1110 | |
1111 | data_len -= *pos; |
1112 | data_len = min_t(size_t, data_len, size); |
1113 | lpos = *pos - strlen(tbl_hdr_str); |
1114 | if (copy_to_user(to: buf, from: &data[lpos], n: data_len)) |
1115 | goto Out; |
1116 | buf += data_len; |
1117 | size -= data_len; |
1118 | *pos += data_len; |
1119 | } |
1120 | |
1121 | data_len = strlen(tbl_hdr_str) + tbl_hdr_fmt_size + strlen(rec_hdr_str); |
1122 | if (*pos < data_len && size > 0) { |
1123 | loff_t lpos; |
1124 | |
1125 | data_len -= *pos; |
1126 | data_len = min_t(size_t, data_len, size); |
1127 | lpos = *pos - strlen(tbl_hdr_str) - tbl_hdr_fmt_size; |
1128 | if (copy_to_user(to: buf, from: &rec_hdr_str[lpos], n: data_len)) |
1129 | goto Out; |
1130 | buf += data_len; |
1131 | size -= data_len; |
1132 | *pos += data_len; |
1133 | } |
1134 | |
1135 | data_len = amdgpu_ras_debugfs_table_size(control); |
1136 | if (*pos < data_len && size > 0) { |
1137 | u8 dare[RAS_TABLE_RECORD_SIZE]; |
1138 | u8 data[rec_hdr_fmt_size + 1]; |
1139 | struct eeprom_table_record record; |
1140 | int s, r; |
1141 | |
1142 | /* Find the starting record index |
1143 | */ |
1144 | s = *pos - strlen(tbl_hdr_str) - tbl_hdr_fmt_size - |
1145 | strlen(rec_hdr_str); |
1146 | s = s / rec_hdr_fmt_size; |
1147 | r = *pos - strlen(tbl_hdr_str) - tbl_hdr_fmt_size - |
1148 | strlen(rec_hdr_str); |
1149 | r = r % rec_hdr_fmt_size; |
1150 | |
1151 | for ( ; size > 0 && s < control->ras_num_recs; s++) { |
1152 | u32 ai = RAS_RI_TO_AI(control, s); |
1153 | /* Read a single record |
1154 | */ |
1155 | res = __amdgpu_ras_eeprom_read(control, buf: dare, fri: ai, num: 1); |
1156 | if (res) |
1157 | goto Out; |
1158 | __decode_table_record_from_buf(control, record: &record, buf: dare); |
1159 | snprintf(buf: data, size: sizeof(data), fmt: rec_hdr_fmt, |
1160 | s, |
1161 | RAS_INDEX_TO_OFFSET(control, ai), |
1162 | record_err_type_str[record.err_type], |
1163 | record.bank, |
1164 | record.ts, |
1165 | record.offset, |
1166 | record.mem_channel, |
1167 | record.mcumc_id, |
1168 | record.retired_page); |
1169 | |
1170 | data_len = min_t(size_t, rec_hdr_fmt_size - r, size); |
1171 | if (copy_to_user(to: buf, from: &data[r], n: data_len)) { |
1172 | res = -EFAULT; |
1173 | goto Out; |
1174 | } |
1175 | buf += data_len; |
1176 | size -= data_len; |
1177 | *pos += data_len; |
1178 | r = 0; |
1179 | } |
1180 | } |
1181 | res = 0; |
1182 | Out: |
1183 | mutex_unlock(lock: &control->ras_tbl_mutex); |
1184 | return res < 0 ? res : orig_size - size; |
1185 | } |
1186 | |
1187 | static ssize_t |
1188 | amdgpu_ras_debugfs_eeprom_table_read(struct file *f, char __user *buf, |
1189 | size_t size, loff_t *pos) |
1190 | { |
1191 | struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private; |
1192 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
1193 | struct amdgpu_ras_eeprom_control *control = ras ? &ras->eeprom_control : NULL; |
1194 | u8 data[81]; |
1195 | int res; |
1196 | |
1197 | if (!size) |
1198 | return size; |
1199 | |
1200 | if (!ras || !control) { |
1201 | res = snprintf(buf: data, size: sizeof(data), fmt: "Not supported\n" ); |
1202 | if (*pos >= res) |
1203 | return 0; |
1204 | |
1205 | res -= *pos; |
1206 | res = min_t(size_t, res, size); |
1207 | |
1208 | if (copy_to_user(to: buf, from: &data[*pos], n: res)) |
1209 | return -EFAULT; |
1210 | |
1211 | *pos += res; |
1212 | |
1213 | return res; |
1214 | } else { |
1215 | return amdgpu_ras_debugfs_table_read(f, buf, size, pos); |
1216 | } |
1217 | } |
1218 | |
1219 | const struct file_operations amdgpu_ras_debugfs_eeprom_table_ops = { |
1220 | .owner = THIS_MODULE, |
1221 | .read = amdgpu_ras_debugfs_eeprom_table_read, |
1222 | .write = NULL, |
1223 | .llseek = default_llseek, |
1224 | }; |
1225 | |
1226 | /** |
1227 | * __verify_ras_table_checksum -- verify the RAS EEPROM table checksum |
1228 | * @control: pointer to control structure |
1229 | * |
1230 | * Check the checksum of the stored in EEPROM RAS table. |
1231 | * |
1232 | * Return 0 if the checksum is correct, |
1233 | * positive if it is not correct, and |
1234 | * -errno on I/O error. |
1235 | */ |
1236 | static int __verify_ras_table_checksum(struct amdgpu_ras_eeprom_control *control) |
1237 | { |
1238 | struct amdgpu_device *adev = to_amdgpu_device(control); |
1239 | int buf_size, res; |
1240 | u8 csum, *buf, *pp; |
1241 | |
1242 | if (control->tbl_hdr.version == RAS_TABLE_VER_V2_1) |
1243 | buf_size = RAS_TABLE_HEADER_SIZE + |
1244 | RAS_TABLE_V2_1_INFO_SIZE + |
1245 | control->ras_num_recs * RAS_TABLE_RECORD_SIZE; |
1246 | else |
1247 | buf_size = RAS_TABLE_HEADER_SIZE + |
1248 | control->ras_num_recs * RAS_TABLE_RECORD_SIZE; |
1249 | |
1250 | buf = kzalloc(size: buf_size, GFP_KERNEL); |
1251 | if (!buf) { |
1252 | DRM_ERROR("Out of memory checking RAS table checksum.\n" ); |
1253 | return -ENOMEM; |
1254 | } |
1255 | |
1256 | res = amdgpu_eeprom_read(i2c_adap: adev->pm.ras_eeprom_i2c_bus, |
1257 | eeprom_addr: control->i2c_address + |
1258 | control->ras_header_offset, |
1259 | eeprom_buf: buf, bytes: buf_size); |
1260 | if (res < buf_size) { |
1261 | DRM_ERROR("Partial read for checksum, res:%d\n" , res); |
1262 | /* On partial reads, return -EIO. |
1263 | */ |
1264 | if (res >= 0) |
1265 | res = -EIO; |
1266 | goto Out; |
1267 | } |
1268 | |
1269 | csum = 0; |
1270 | for (pp = buf; pp < buf + buf_size; pp++) |
1271 | csum += *pp; |
1272 | Out: |
1273 | kfree(objp: buf); |
1274 | return res < 0 ? res : csum; |
1275 | } |
1276 | |
1277 | static int __read_table_ras_info(struct amdgpu_ras_eeprom_control *control) |
1278 | { |
1279 | struct amdgpu_ras_eeprom_table_ras_info *rai = &control->tbl_rai; |
1280 | struct amdgpu_device *adev = to_amdgpu_device(control); |
1281 | unsigned char *buf; |
1282 | int res; |
1283 | |
1284 | buf = kzalloc(RAS_TABLE_V2_1_INFO_SIZE, GFP_KERNEL); |
1285 | if (!buf) { |
1286 | DRM_ERROR("Failed to alloc buf to read EEPROM table ras info\n" ); |
1287 | return -ENOMEM; |
1288 | } |
1289 | |
1290 | /** |
1291 | * EEPROM table V2_1 supports ras info, |
1292 | * read EEPROM table ras info |
1293 | */ |
1294 | res = amdgpu_eeprom_read(i2c_adap: adev->pm.ras_eeprom_i2c_bus, |
1295 | eeprom_addr: control->i2c_address + control->ras_info_offset, |
1296 | eeprom_buf: buf, RAS_TABLE_V2_1_INFO_SIZE); |
1297 | if (res < RAS_TABLE_V2_1_INFO_SIZE) { |
1298 | DRM_ERROR("Failed to read EEPROM table ras info, res:%d" , res); |
1299 | res = res >= 0 ? -EIO : res; |
1300 | goto Out; |
1301 | } |
1302 | |
1303 | __decode_table_ras_info_from_buf(rai, buf); |
1304 | |
1305 | Out: |
1306 | kfree(objp: buf); |
1307 | return res == RAS_TABLE_V2_1_INFO_SIZE ? 0 : res; |
1308 | } |
1309 | |
1310 | int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control, |
1311 | bool *exceed_err_limit) |
1312 | { |
1313 | struct amdgpu_device *adev = to_amdgpu_device(control); |
1314 | unsigned char buf[RAS_TABLE_HEADER_SIZE] = { 0 }; |
1315 | struct amdgpu_ras_eeprom_table_header *hdr = &control->tbl_hdr; |
1316 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); |
1317 | int res; |
1318 | |
1319 | *exceed_err_limit = false; |
1320 | |
1321 | if (!__is_ras_eeprom_supported(adev)) |
1322 | return 0; |
1323 | |
1324 | /* Verify i2c adapter is initialized */ |
1325 | if (!adev->pm.ras_eeprom_i2c_bus || !adev->pm.ras_eeprom_i2c_bus->algo) |
1326 | return -ENOENT; |
1327 | |
1328 | if (!__get_eeprom_i2c_addr(adev, control)) |
1329 | return -EINVAL; |
1330 | |
1331 | control->ras_header_offset = RAS_HDR_START; |
1332 | control->ras_info_offset = RAS_TABLE_V2_1_INFO_START; |
1333 | mutex_init(&control->ras_tbl_mutex); |
1334 | |
1335 | /* Read the table header from EEPROM address */ |
1336 | res = amdgpu_eeprom_read(i2c_adap: adev->pm.ras_eeprom_i2c_bus, |
1337 | eeprom_addr: control->i2c_address + control->ras_header_offset, |
1338 | eeprom_buf: buf, RAS_TABLE_HEADER_SIZE); |
1339 | if (res < RAS_TABLE_HEADER_SIZE) { |
1340 | DRM_ERROR("Failed to read EEPROM table header, res:%d" , res); |
1341 | return res >= 0 ? -EIO : res; |
1342 | } |
1343 | |
1344 | __decode_table_header_from_buf(hdr, buf); |
1345 | |
1346 | if (hdr->version == RAS_TABLE_VER_V2_1) { |
1347 | control->ras_num_recs = RAS_NUM_RECS_V2_1(hdr); |
1348 | control->ras_record_offset = RAS_RECORD_START_V2_1; |
1349 | control->ras_max_record_count = RAS_MAX_RECORD_COUNT_V2_1; |
1350 | } else { |
1351 | control->ras_num_recs = RAS_NUM_RECS(hdr); |
1352 | control->ras_record_offset = RAS_RECORD_START; |
1353 | control->ras_max_record_count = RAS_MAX_RECORD_COUNT; |
1354 | } |
1355 | control->ras_fri = RAS_OFFSET_TO_INDEX(control, hdr->first_rec_offset); |
1356 | |
1357 | if (hdr->header == RAS_TABLE_HDR_VAL) { |
1358 | DRM_DEBUG_DRIVER("Found existing EEPROM table with %d records" , |
1359 | control->ras_num_recs); |
1360 | |
1361 | if (hdr->version == RAS_TABLE_VER_V2_1) { |
1362 | res = __read_table_ras_info(control); |
1363 | if (res) |
1364 | return res; |
1365 | } |
1366 | |
1367 | res = __verify_ras_table_checksum(control); |
1368 | if (res) |
1369 | DRM_ERROR("RAS table incorrect checksum or error:%d\n" , |
1370 | res); |
1371 | |
1372 | /* Warn if we are at 90% of the threshold or above |
1373 | */ |
1374 | if (10 * control->ras_num_recs >= 9 * ras->bad_page_cnt_threshold) |
1375 | dev_warn(adev->dev, "RAS records:%u exceeds 90%% of threshold:%d" , |
1376 | control->ras_num_recs, |
1377 | ras->bad_page_cnt_threshold); |
1378 | } else if (hdr->header == RAS_TABLE_HDR_BAD && |
1379 | amdgpu_bad_page_threshold != 0) { |
1380 | if (hdr->version == RAS_TABLE_VER_V2_1) { |
1381 | res = __read_table_ras_info(control); |
1382 | if (res) |
1383 | return res; |
1384 | } |
1385 | |
1386 | res = __verify_ras_table_checksum(control); |
1387 | if (res) |
1388 | DRM_ERROR("RAS Table incorrect checksum or error:%d\n" , |
1389 | res); |
1390 | if (ras->bad_page_cnt_threshold > control->ras_num_recs) { |
1391 | /* This means that, the threshold was increased since |
1392 | * the last time the system was booted, and now, |
1393 | * ras->bad_page_cnt_threshold - control->num_recs > 0, |
1394 | * so that at least one more record can be saved, |
1395 | * before the page count threshold is reached. |
1396 | */ |
1397 | dev_info(adev->dev, |
1398 | "records:%d threshold:%d, resetting " |
1399 | "RAS table header signature" , |
1400 | control->ras_num_recs, |
1401 | ras->bad_page_cnt_threshold); |
1402 | res = amdgpu_ras_eeprom_correct_header_tag(control, |
1403 | RAS_TABLE_HDR_VAL); |
1404 | } else { |
1405 | dev_err(adev->dev, "RAS records:%d exceed threshold:%d" , |
1406 | control->ras_num_recs, ras->bad_page_cnt_threshold); |
1407 | if (amdgpu_bad_page_threshold == -1) { |
1408 | dev_warn(adev->dev, "GPU will be initialized due to bad_page_threshold = -1." ); |
1409 | res = 0; |
1410 | } else { |
1411 | *exceed_err_limit = true; |
1412 | dev_err(adev->dev, |
1413 | "RAS records:%d exceed threshold:%d, " |
1414 | "GPU will not be initialized. Replace this GPU or increase the threshold" , |
1415 | control->ras_num_recs, ras->bad_page_cnt_threshold); |
1416 | } |
1417 | } |
1418 | } else { |
1419 | DRM_INFO("Creating a new EEPROM table" ); |
1420 | |
1421 | res = amdgpu_ras_eeprom_reset_table(control); |
1422 | } |
1423 | |
1424 | return res < 0 ? res : 0; |
1425 | } |
1426 | |