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