xref: /linux/drivers/gpu/drm/amd/ras/core/eeprom_fw.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2026 Advanced Micro Devices, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
25 #include "ras.h"
26 
27 #define RAS_SMU_MESSAGE_TIMEOUT_MS 1000 /* 1s */
28 
29 void ras_fw_init_feature_flags(struct ras_core_context *ras_core)
30 {
31 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
32 	const struct ras_mp1_sys_func *sys_func = mp1->sys_func;
33 	uint64_t flags = 0ULL;
34 
35 	if (!sys_func || !sys_func->mp1_get_ras_enabled_mask)
36 		return;
37 
38 	if (!sys_func->mp1_get_ras_enabled_mask(ras_core, &flags))
39 		ras_core->ras_fw_features = flags;
40 }
41 
42 bool ras_fw_eeprom_supported(struct ras_core_context *ras_core)
43 {
44 	return !!(ras_core->ras_fw_features & RAS_CORE_FW_FEATURE_BIT__RAS_EEPROM);
45 }
46 
47 int ras_fw_get_table_version(struct ras_core_context *ras_core,
48 				     uint32_t *table_version)
49 {
50 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
51 	const struct ras_mp1_sys_func *sys_func = mp1->sys_func;
52 
53 	return sys_func->mp1_send_eeprom_msg(ras_core,
54 				RAS_SMU_GetRASTableVersion, 0, table_version);
55 }
56 
57 int ras_fw_get_badpage_count(struct ras_core_context *ras_core,
58 				     uint32_t *count, uint32_t timeout)
59 {
60 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
61 	const struct ras_mp1_sys_func *sys_func = mp1->sys_func;
62 	uint64_t end, now;
63 	int ret = 0;
64 
65 	now = (uint64_t)ktime_to_ms(ktime_get());
66 	end = now + timeout;
67 
68 	do {
69 		ret = sys_func->mp1_send_eeprom_msg(ras_core,
70 			RAS_SMU_GetBadPageCount, 0, count);
71 		/* eeprom is not ready */
72 		if (ret != -EBUSY)
73 			return ret;
74 
75 		usleep_range(10000, 15000);
76 		now = (uint64_t)ktime_to_ms(ktime_get());
77 	} while (now < end);
78 
79 	RAS_DEV_ERR(ras_core->dev,
80 			"smu get bad page count timeout!\n");
81 	return ret;
82 }
83 
84 int ras_fw_get_badpage_mca_addr(struct ras_core_context *ras_core,
85 					uint16_t index, uint64_t *mca_addr)
86 {
87 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
88 	const struct ras_mp1_sys_func *sys_func = mp1->sys_func;
89 	uint32_t temp_arg, temp_addr_lo, temp_addr_high;
90 	int ret;
91 
92 	temp_arg = index | (1 << 16);
93 	ret = sys_func->mp1_send_eeprom_msg(ras_core,
94 			RAS_SMU_GetBadPageMcaAddr, temp_arg, &temp_addr_lo);
95 	if (ret)
96 		return ret;
97 
98 	temp_arg = index | (2 << 16);
99 	ret = sys_func->mp1_send_eeprom_msg(ras_core,
100 			RAS_SMU_GetBadPageMcaAddr, temp_arg, &temp_addr_high);
101 
102 	if (!ret)
103 		*mca_addr = (uint64_t)temp_addr_high << 32 | temp_addr_lo;
104 
105 	return ret;
106 }
107 
108 int ras_fw_set_timestamp(struct ras_core_context *ras_core,
109 				 uint64_t timestamp)
110 {
111 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
112 	const struct ras_mp1_sys_func *sys_func = mp1->sys_func;
113 
114 	return sys_func->mp1_send_eeprom_msg(ras_core,
115 			RAS_SMU_SetTimestamp, (uint32_t)timestamp, 0);
116 }
117 
118 int ras_fw_get_timestamp(struct ras_core_context *ras_core,
119 				 uint16_t index, uint64_t *timestamp)
120 {
121 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
122 	const struct ras_mp1_sys_func *sys_func = mp1->sys_func;
123 	uint32_t temp = 0;
124 	int ret;
125 
126 	ret = sys_func->mp1_send_eeprom_msg(ras_core,
127 			RAS_SMU_GetTimestamp, index, &temp);
128 	if (!ret)
129 		*timestamp = temp;
130 
131 	return ret;
132 }
133 
134 int ras_fw_get_badpage_ipid(struct ras_core_context *ras_core,
135 				    uint16_t index, uint64_t *ipid)
136 {
137 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
138 	const struct ras_mp1_sys_func *sys_func = mp1->sys_func;
139 	uint32_t temp_arg, temp_ipid_lo, temp_ipid_high;
140 	int ret;
141 
142 	temp_arg = index | (1 << 16);
143 	ret = sys_func->mp1_send_eeprom_msg(ras_core,
144 			RAS_SMU_GetBadPageIpid, temp_arg, &temp_ipid_lo);
145 	if (ret)
146 		return ret;
147 
148 	temp_arg = index | (2 << 16);
149 	ret = sys_func->mp1_send_eeprom_msg(ras_core,
150 			RAS_SMU_GetBadPageIpid, temp_arg, &temp_ipid_high);
151 	if (!ret)
152 		*ipid = (uint64_t)temp_ipid_high << 32 | temp_ipid_lo;
153 
154 	return ret;
155 }
156 
157 int ras_fw_erase_ras_table(struct ras_core_context *ras_core,
158 				   uint32_t *result)
159 {
160 	struct ras_mp1 *mp1 = &ras_core->ras_mp1;
161 	const struct ras_mp1_sys_func *sys_func = mp1->sys_func;
162 
163 	return sys_func->mp1_send_eeprom_msg(ras_core,
164 			RAS_SMU_EraseRasTable, 0, result);
165 }
166 
167 int ras_fw_eeprom_reset_table(struct ras_core_context *ras_core)
168 {
169 	struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
170 	u32 erase_res = 0;
171 	int res;
172 
173 	mutex_lock(&control->ras_tbl_mutex);
174 
175 	res = ras_fw_erase_ras_table(ras_core, &erase_res);
176 	if (res || erase_res) {
177 		RAS_DEV_WARN(ras_core->dev, "RAS EEPROM reset failed, res:%d result:%d",
178 									res, erase_res);
179 		if (!res)
180 			res = -EIO;
181 	}
182 
183 	control->ras_num_recs = 0;
184 	control->bad_channel_bitmap = 0;
185 	ras_core_event_notify(ras_core, RAS_EVENT_ID__UPDATE_BAD_PAGE_NUM,
186 		&control->ras_num_recs);
187 	ras_core_event_notify(ras_core, RAS_EVENT_ID__UPDATE_BAD_CHANNEL_BITMAP,
188 		&control->bad_channel_bitmap);
189 	control->update_channel_flag = false;
190 
191 	mutex_unlock(&control->ras_tbl_mutex);
192 
193 	return res;
194 }
195 
196 bool ras_fw_eeprom_check_safety_watermark(struct ras_core_context *ras_core)
197 {
198 	struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
199 	bool ret = false;
200 	int bad_page_count;
201 
202 	if (!control->record_threshold_config)
203 		return false;
204 
205 	bad_page_count = ras_umc_get_badpage_count(ras_core);
206 
207 	if (bad_page_count > control->record_threshold_count)
208 		RAS_DEV_WARN(ras_core->dev, "RAS records:%d exceed threshold:%d",
209 			bad_page_count, control->record_threshold_count);
210 
211 	if ((control->record_threshold_config == WARN_NONSTOP_OVER_THRESHOLD) ||
212 		(control->record_threshold_config == NONSTOP_OVER_THRESHOLD)) {
213 		RAS_DEV_WARN(ras_core->dev,
214 			"Please consult AMD Service Action Guide (SAG) for appropriate service procedures.\n");
215 		ret = false;
216 	} else {
217 		ras_core->is_rma = true;
218 		RAS_DEV_WARN(ras_core->dev,
219 			"Please consider adjusting the customized threshold.\n");
220 		ret = true;
221 	}
222 
223 	return ret;
224 }
225 
226 int ras_fw_eeprom_append(struct ras_core_context *ras_core,
227 			   struct eeprom_umc_record *record, const u32 num)
228 {
229 	struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
230 	int threshold_config = control->record_threshold_config;
231 	int i, bad_page_count;
232 
233 	mutex_lock(&control->ras_tbl_mutex);
234 
235 	for (i = 0; i < num; i++) {
236 		/* update bad channel bitmap */
237 		if ((record[i].mem_channel < BITS_PER_TYPE(control->bad_channel_bitmap)) &&
238 			!(control->bad_channel_bitmap & (1 << record[i].mem_channel))) {
239 			control->bad_channel_bitmap |= 1 << record[i].mem_channel;
240 			control->update_channel_flag = true;
241 		}
242 	}
243 	control->ras_num_recs += num;
244 
245 	bad_page_count = ras_umc_get_badpage_count(ras_core);
246 
247 	if (threshold_config != 0 &&
248 		bad_page_count > control->record_threshold_count) {
249 		RAS_DEV_WARN(ras_core->dev,
250 			"Saved bad pages %d reaches threshold value %d\n",
251 			bad_page_count, control->record_threshold_count);
252 
253 		if ((threshold_config != WARN_NONSTOP_OVER_THRESHOLD) &&
254 			(threshold_config != NONSTOP_OVER_THRESHOLD))
255 			ras_core->is_rma = true;
256 
257 		/* ignore the -ENOTSUPP return value */
258 		ras_core_event_notify(ras_core, RAS_EVENT_ID__DEVICE_RMA, NULL);
259 	}
260 
261 	mutex_unlock(&control->ras_tbl_mutex);
262 	return 0;
263 }
264 
265 int ras_fw_eeprom_read_idx(struct ras_core_context *ras_core,
266 			 struct eeprom_umc_record *record_umc,
267 			 struct ras_bank_ecc *ras_ecc,
268 			 u32 rec_idx, const u32 num)
269 {
270 	struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
271 	int i, ret, end_idx;
272 	u64 mca, ipid, ts;
273 	u32 cu, mem_channel, mcumc_id;
274 
275 	if (!ras_core->ras_umc.ip_func ||
276 	    !ras_core->ras_umc.ip_func->mca_ipid_parse)
277 		return -EOPNOTSUPP;
278 
279 	mutex_lock(&control->ras_tbl_mutex);
280 
281 	end_idx = rec_idx + num;
282 	for (i = rec_idx; i < end_idx; i++) {
283 		ret = ras_fw_get_badpage_mca_addr(ras_core, i, &mca);
284 		if (ret)
285 			goto out;
286 
287 		ret = ras_fw_get_badpage_ipid(ras_core, i, &ipid);
288 		if (ret)
289 			goto out;
290 
291 		ret = ras_fw_get_timestamp(ras_core, i, &ts);
292 		if (ret)
293 			goto out;
294 
295 		if (record_umc) {
296 			record_umc[i - rec_idx].address = mca;
297 			/* retired_page (pa) is unused now */
298 			record_umc[i - rec_idx].retired_row_pfn = 0x1ULL;
299 			record_umc[i - rec_idx].ts = ts;
300 			record_umc[i - rec_idx].err_type = RAS_EEPROM_ERR_NON_RECOVERABLE;
301 
302 			ras_core->ras_umc.ip_func->mca_ipid_parse(ras_core, ipid,
303 				&cu, &mem_channel, &mcumc_id, NULL);
304 			record_umc[i - rec_idx].cu = (u8)cu;
305 			record_umc[i - rec_idx].mem_channel = (u8)mem_channel;
306 			record_umc[i - rec_idx].mcumc_id = (u8)mcumc_id;
307 
308 			/* update bad channel bitmap */
309 			if ((record_umc[i - rec_idx].mem_channel < BITS_PER_TYPE(control->bad_channel_bitmap)) &&
310 				!(control->bad_channel_bitmap & (1 << record_umc[i - rec_idx].mem_channel))) {
311 				control->bad_channel_bitmap |= 1 << record_umc[i - rec_idx].mem_channel;
312 				control->update_channel_flag = true;
313 			}
314 		}
315 
316 		if (ras_ecc) {
317 			ras_ecc[i - rec_idx].addr = mca;
318 			ras_ecc[i - rec_idx].ipid = ipid;
319 			ras_ecc[i - rec_idx].ts = ts;
320 		}
321 
322 	}
323 
324 out:
325 	mutex_unlock(&control->ras_tbl_mutex);
326 	return ret;
327 }
328 
329 uint32_t ras_fw_eeprom_get_record_count(struct ras_core_context *ras_core)
330 {
331 	if (!ras_core)
332 		return 0;
333 
334 	return ras_core->ras_fw_eeprom.ras_num_recs;
335 }
336 
337 int ras_fw_eeprom_update_record(struct ras_core_context *ras_core,
338 				struct ras_bank_ecc *ras_ecc)
339 {
340 	struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
341 	int ret, retry = 20;
342 	u32 recs_num_new = control->ras_num_recs;
343 
344 	do {
345 		/* 1000ms timeout is long enough, smu_get_badpage_count won't
346 		 * return -EBUSY before timeout.
347 		 */
348 		ret = ras_fw_get_badpage_count(ras_core,
349 			&recs_num_new, RAS_SMU_MESSAGE_TIMEOUT_MS);
350 		if (!ret &&
351 		    (recs_num_new == control->ras_num_recs)) {
352 			/* record number update in PMFW needs some time,
353 			 * smu_get_badpage_count may return immediately without
354 			 * count update, sleep for a while and retry again.
355 			 */
356 			msleep(50);
357 			retry--;
358 		} else {
359 			break;
360 		}
361 	} while (retry);
362 
363 	if (ret)
364 		return ret;
365 
366 	if (recs_num_new > control->ras_num_recs)
367 		ret = ras_fw_eeprom_read_idx(ras_core, 0,
368 					ras_ecc, control->ras_num_recs, 1);
369 	else
370 		ret = -EINVAL;
371 
372 	return ret;
373 }
374 
375 static int __check_ras_fw_table_status(struct ras_core_context *ras_core)
376 {
377 	struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
378 	uint64_t local_time;
379 	int res;
380 
381 	mutex_init(&control->ras_tbl_mutex);
382 
383 	res = ras_fw_get_table_version(ras_core, &(control->version));
384 	if (res)
385 		return res;
386 
387 	res = ras_fw_get_badpage_count(ras_core, &(control->ras_num_recs), 100);
388 	if (res)
389 		return res;
390 
391 	local_time = (uint64_t)ktime_get_real_seconds();
392 	res = ras_fw_set_timestamp(ras_core, local_time);
393 	if (res)
394 		return res;
395 
396 	control->ras_max_record_count = 4000;
397 
398 
399 	if (control->ras_num_recs > control->ras_max_record_count) {
400 		RAS_DEV_ERR(ras_core->dev,
401 			"RAS header invalid, records in header: %u max allowed :%u",
402 			control->ras_num_recs, control->ras_max_record_count);
403 		return -EINVAL;
404 	}
405 
406 	return 0;
407 }
408 
409 int ras_fw_eeprom_hw_init(struct ras_core_context *ras_core)
410 {
411 	struct ras_fw_eeprom_control *control;
412 	struct ras_eeprom_config *eeprom_cfg;
413 	struct ras_mp1 *mp1;
414 	const struct ras_mp1_sys_func *sys_func;
415 
416 	if (!ras_core)
417 		return -EINVAL;
418 
419 	mp1 = &ras_core->ras_mp1;
420 	sys_func = mp1->sys_func;
421 
422 	if (!sys_func || !sys_func->mp1_send_eeprom_msg)
423 		return -EINVAL;
424 
425 	ras_core->is_rma = false;
426 
427 	control = &ras_core->ras_fw_eeprom;
428 
429 	memset(control, 0, sizeof(*control));
430 
431 	eeprom_cfg = &ras_core->config->eeprom_cfg;
432 	control->record_threshold_config =
433 		eeprom_cfg->eeprom_record_threshold_config;
434 
435 	control->record_threshold_count = 4000;
436 	if (eeprom_cfg->eeprom_record_threshold_count <
437 		control->record_threshold_count)
438 		control->record_threshold_count =
439 			eeprom_cfg->eeprom_record_threshold_count;
440 
441 	control->update_channel_flag = false;
442 
443 	return __check_ras_fw_table_status(ras_core);
444 }
445 
446 int ras_fw_eeprom_hw_fini(struct ras_core_context *ras_core)
447 {
448 	struct ras_fw_eeprom_control *control;
449 
450 	if (!ras_core)
451 		return -EINVAL;
452 
453 	control = &ras_core->ras_fw_eeprom;
454 	mutex_destroy(&control->ras_tbl_mutex);
455 
456 	return 0;
457 }
458 
459 int ras_fw_eeprom_check_storage_status(struct ras_core_context *ras_core)
460 {
461 	struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
462 	int bad_page_count;
463 
464 	bad_page_count = ras_umc_get_badpage_count(ras_core);
465 
466 	if ((control->record_threshold_count < bad_page_count) &&
467 	    (control->record_threshold_config != 0)) {
468 		RAS_DEV_ERR(ras_core->dev, "RAS records:%d exceed threshold:%d",
469 				bad_page_count, control->record_threshold_count);
470 		if ((control->record_threshold_config == WARN_NONSTOP_OVER_THRESHOLD) ||
471 			(control->record_threshold_config == NONSTOP_OVER_THRESHOLD)) {
472 			RAS_DEV_WARN(ras_core->dev,
473 			"Please consult AMD Service Action Guide (SAG) for appropriate service procedures\n");
474 		} else {
475 			ras_core->is_rma = true;
476 			RAS_DEV_ERR(ras_core->dev,
477 			"User defined threshold is set, runtime service will be halt when threshold is reached\n");
478 		}
479 		return 0;
480 	}
481 
482 	RAS_DEV_INFO(ras_core->dev,
483 			"Found existing EEPROM table with %d records\n",
484 			bad_page_count);
485 	/* Warn if we are at 90% of the threshold or above
486 	 */
487 	if (10 * bad_page_count >= 9 * control->record_threshold_count)
488 		RAS_DEV_WARN(ras_core->dev,
489 			"RAS records:%u exceeds 90%% of threshold:%d\n",
490 			bad_page_count,
491 			control->record_threshold_count);
492 
493 	return 0;
494 }
495 
496 enum ras_gpu_health_status
497 	ras_fw_eeprom_check_gpu_status(struct ras_core_context *ras_core)
498 {
499 	struct ras_fw_eeprom_control *control = &ras_core->ras_fw_eeprom;
500 
501 	if (!control->record_threshold_config)
502 		return RAS_GPU_HEALTH_NONE;
503 
504 	if (ras_core->is_rma)
505 		return RAS_GPU_RETIRED__ECC_REACH_THRESHOLD;
506 
507 	return RAS_GPU_HEALTH_USABLE;
508 }
509 
510 void ras_fw_eeprom_sync_info(struct ras_core_context *ras_core)
511 {
512 	struct ras_fw_eeprom_control *control;
513 
514 	if (!ras_core)
515 		return;
516 
517 	control = &ras_core->ras_fw_eeprom;
518 	ras_core_event_notify(ras_core, RAS_EVENT_ID__UPDATE_BAD_PAGE_NUM,
519 		&control->ras_num_recs);
520 	ras_core_event_notify(ras_core, RAS_EVENT_ID__UPDATE_BAD_CHANNEL_BITMAP,
521 		&control->bad_channel_bitmap);
522 }
523