From: YiPeng Chai <[email protected]>

Add interface to obtain FW eeprom records at runtime.

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/aca.c         |  4 ++-
 drivers/gpu/drm/amd/ras/core/ras_process.c |  3 ++
 drivers/gpu/drm/amd/ras/core/ras_umc.c     | 40 ++++++++++++++++++++++
 drivers/gpu/drm/amd/ras/core/ras_umc.h     |  1 +
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/ras/core/aca.c 
b/drivers/gpu/drm/amd/ras/core/aca.c
index 07a9cc030ca14..a2529645af098 100644
--- a/drivers/gpu/drm/amd/ras/core/aca.c
+++ b/drivers/gpu/drm/amd/ras/core/aca.c
@@ -247,7 +247,9 @@ static int aca_log_bad_bank(struct ras_core_context 
*ras_core,
        ecc_err->total_de_count += bank_ecc->de_count;
        mutex_unlock(&ras_core->ras_aca.aca_lock);
 
-       if ((aca_blk->blk_info->ras_block_id == RAS_BLOCK_ID__UMC) &&
+       /* Log ACA bad bank when FW management EEPROM is disabled. */
+       if (!ras_eeprom_mgr_fw_record_enabled(ras_core) &&
+           (aca_blk->blk_info->ras_block_id == RAS_BLOCK_ID__UMC) &&
            bank_ecc->de_count) {
                struct ras_bank_ecc  ras_ecc = {0};
 
diff --git a/drivers/gpu/drm/amd/ras/core/ras_process.c 
b/drivers/gpu/drm/amd/ras/core/ras_process.c
index c001074c8c568..dd4a4c5673bdd 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_process.c
+++ b/drivers/gpu/drm/amd/ras/core/ras_process.c
@@ -170,6 +170,9 @@ int ras_process_handle_ras_event(struct ras_core_context 
*ras_core)
        ras_aca_clear_fatal_flag(ras_core);
        ras_umc_log_pending_bad_bank(ras_core);
 
+       if (ras_eeprom_mgr_fw_record_enabled(ras_core))
+               ras_umc_dump_fw_records(ras_core);
+
        do {
                umc_event_count = atomic_read(&ras_proc->umc_interrupt_count);
                ret = ras_process_umc_event(ras_core, umc_event_count);
diff --git a/drivers/gpu/drm/amd/ras/core/ras_umc.c 
b/drivers/gpu/drm/amd/ras/core/ras_umc.c
index 9cf1515dfd02e..b9961796a5395 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_umc.c
+++ b/drivers/gpu/drm/amd/ras/core/ras_umc.c
@@ -675,6 +675,10 @@ static int ras_umc_save_bad_pages(struct ras_core_context 
*ras_core)
        int save_count;
        int ret = -ENODATA;
 
+       /* Not need to save bad pages when FW management EEPROM is enabled. */
+       if (ras_eeprom_mgr_fw_record_enabled(ras_core))
+               return 0;
+
        if (!data->bps)
                return -EINVAL;
 
@@ -918,3 +922,39 @@ int ras_umc_record_to_nps_record(struct ras_core_context 
*ras_core,
 
        return ras_umc_eeprom_rec2nps_rec(ras_core, record, nps);
 }
+
+int ras_umc_dump_fw_records(struct ras_core_context *ras_core)
+{
+       struct eeprom_umc_record rec;
+       int eeprom_count, umc_count, new_count = 0;
+       uint32_t c;
+       int i, ret;
+
+       eeprom_count = ras_eeprom_mgr_get_record_count(ras_core);
+       /* no bad page record, skip eeprom access */
+       if (!eeprom_count)
+               return 0;
+
+       umc_count = ras_umc_get_saved_eeprom_count(ras_core);
+       if (umc_count == eeprom_count) {
+               return 0;
+       } else if (umc_count > eeprom_count) {
+               RAS_DEV_ERR(ras_core->dev, "Invalid error count: eeprom:%d, 
umc:%d\n",
+                       eeprom_count, umc_count);
+               return 0;
+       }
+
+       for (i = umc_count; i < eeprom_count; i++) {
+               memset(&rec, 0, sizeof(rec));
+               ret = ras_eeprom_mgr_get_records(ras_core, i, &rec, 1);
+               if (ret)
+                       return 0;
+
+               c = 0;
+               ret = ras_umc_add_bad_pages(ras_core, &rec, 1, &c);
+               if (!ret)
+                       new_count += c;
+       }
+
+       return new_count;
+}
diff --git a/drivers/gpu/drm/amd/ras/core/ras_umc.h 
b/drivers/gpu/drm/amd/ras/core/ras_umc.h
index 221cd008e55a0..5a3e019af8ad9 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_umc.h
+++ b/drivers/gpu/drm/amd/ras/core/ras_umc.h
@@ -224,4 +224,5 @@ int ras_umc_bank_to_umc_record(struct ras_core_context 
*ras_core,
                struct ras_bank_ecc *bank, struct eeprom_umc_record *record);
 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);
 #endif
-- 
2.55.0

Reply via email to