From 18a6121cb189f0033614411daa94c78991d6fae8 Mon Sep 17 00:00:00 2001 From: YiPeng Chai Date: Wed, 22 Apr 2026 10:45:54 +0800 Subject: [PATCH] drm/amd/ras: add interface to report bad page info Add interface to report bad page info. Signed-off-by: YiPeng Chai Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/ras/core/ras_umc.c | 42 +++++++++++++++++++++++++- drivers/gpu/drm/amd/ras/core/ras_umc.h | 5 +++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/ras/core/ras_umc.c b/drivers/gpu/drm/amd/ras/core/ras_umc.c index cf024dd94f95..9156b0f7ffa4 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_umc.c +++ b/drivers/gpu/drm/amd/ras/core/ras_umc.c @@ -535,6 +535,11 @@ static int ras_umc_update_eeprom_rom_data(struct ras_core_context *ras_core, memcpy(&data->bps[data->count], bps, sizeof(*data->bps)); data->count++; data->space_left--; + + /* update bad channel bitmap */ + if (bps->mem_channel < BITS_PER_TYPE(data->umc_channel_bitmap)) + data->umc_channel_bitmap |= 1 << bps->mem_channel; + return 0; } @@ -579,6 +584,10 @@ static int ras_umc_update_eeprom_ram_data(struct ras_core_context *ras_core, return -EINVAL; } + /* update bad channel bitmap */ + if (bps->mem_channel < BITS_PER_TYPE(data->umc_channel_bitmap)) + data->umc_channel_bitmap |= 1 << bps->mem_channel; + return 0; } @@ -590,6 +599,27 @@ static void ras_umc_update_bad_pages(struct ras_core_context *ras_core) data->bad_page_num_old = data->bad_page_num; } +void ras_umc_report_badpage_info(struct ras_core_context *ras_core) +{ + struct ras_umc *ras_umc = &ras_core->ras_umc; + struct eeprom_store_record *data = &ras_umc->umc_err_data.ram_data; + + if (ras_umc->last_record_count != data->count) { + ras_umc->last_record_count = data->count; + ras_core_event_notify(ras_core, RAS_EVENT_ID__UPDATE_BAD_PAGE_NUM, + &ras_umc->last_record_count); + } + + if (ras_umc->last_channel_bitmap != data->umc_channel_bitmap) { + ras_umc->last_channel_bitmap = data->umc_channel_bitmap; + ras_core_event_notify(ras_core, RAS_EVENT_ID__UPDATE_BAD_CHANNEL_BITMAP, + &ras_umc->last_channel_bitmap); + } + + if (ras_core->is_rma) + ras_core_event_notify(ras_core, RAS_EVENT_ID__DEVICE_RMA, NULL); +} + int ras_umc_add_bad_pages(struct ras_core_context *ras_core, struct eeprom_umc_record *bps, uint32_t bps_sz, uint32_t *valid_sz) { @@ -623,8 +653,11 @@ int ras_umc_add_bad_pages(struct ras_core_context *ras_core, *valid_sz = c; - if (c) + if (c) { ras_eeprom_mgr_check_and_report_status(ras_core, true); + if (!ras_core_in_early_init(ras_core)) + ras_umc_report_badpage_info(ras_core); + } out: mutex_unlock(&ras_umc->umc_lock); @@ -782,11 +815,18 @@ int ras_umc_sw_fini(struct ras_core_context *ras_core) int ras_umc_hw_init(struct ras_core_context *ras_core) { struct ras_umc *ras_umc = &ras_core->ras_umc; + int count = ras_umc_get_badpage_count(ras_core); ras_umc->num_umc = ras_core->config->umc_cfg.num_umc; ras_umc->pa_base = ras_core->config->umc_cfg.pa_base; ras_umc->lfb_size = ras_core->config->umc_cfg.lfb_size; + /* For preloaded bad pages case, bad page info is + * deferred to report in hw init. + */ + if (count > 0) + ras_umc_report_badpage_info(ras_core); + return 0; } diff --git a/drivers/gpu/drm/amd/ras/core/ras_umc.h b/drivers/gpu/drm/amd/ras/core/ras_umc.h index db777f0cc334..f7754e746b9a 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_umc.h +++ b/drivers/gpu/drm/amd/ras/core/ras_umc.h @@ -156,6 +156,7 @@ struct eeprom_store_record { * ras_num_recs * retire_unit */ int bad_page_num_old; + uint64_t umc_channel_bitmap; }; struct ras_umc_err_data { @@ -182,6 +183,9 @@ struct ras_umc { u32 pending_ecc_count; /* number of entries dropped because pending_ecc_list was full */ u32 pending_ecc_dropped; + + u32 last_record_count; + u64 last_channel_bitmap; }; /* @@ -230,4 +234,5 @@ int ras_umc_bank_to_umc_record(struct ras_core_context *ras_core, int ras_umc_record_to_nps_record(struct ras_core_context *ras_core, struct eeprom_umc_record *record, uint32_t nps); int ras_umc_dump_fw_records(struct ras_core_context *ras_core); +void ras_umc_report_badpage_info(struct ras_core_context *ras_core); #endif