From: YiPeng Chai <[email protected]>

Add interface to report bad page info.

Signed-off-by: YiPeng Chai <[email protected]>
Reviewed-by: Hawking Zhang <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/ras/core/ras_umc.c | 43 +++++++++++++++++++++++++-
 drivers/gpu/drm/amd/ras/core/ras_umc.h |  5 +++
 2 files changed, 47 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 ee4ad9ffb50c0..0e6a341f0729a 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_umc.c
+++ b/drivers/gpu/drm/amd/ras/core/ras_umc.c
@@ -534,6 +534,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;
 }
 
@@ -578,6 +583,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;
 }
 
@@ -589,6 +598,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)
 {
@@ -622,8 +652,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);
@@ -781,8 +814,16 @@ 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;
 
+       /* 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 5a3e019af8ad9..5b7b497503927 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_umc.h
+++ b/drivers/gpu/drm/amd/ras/core/ras_umc.h
@@ -155,6 +155,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 {
@@ -177,6 +178,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;
 };
 
 /*
@@ -225,4 +229,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
-- 
2.55.0

Reply via email to