For specific old eeprom data, mca address is not stored, get mca
address from physical address(pa) and then convert it into pa in
current nps mode.

Signed-off-by: Tao Zhou <[email protected]>
---
 drivers/gpu/drm/amd/ras/rascore/ras_umc.c | 38 +++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c 
b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
index becbf8d2d09e..c3cd1e84468b 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
@@ -323,6 +323,31 @@ int ras_umc_ma2pa(struct ras_core_context *ras_core,
        return ret;
 }
 
+static int ras_umc_pa2ma(struct ras_core_context *ras_core, uint64_t pa,
+               uint64_t *mca, uint32_t nps)
+{
+       struct ras_ta_query_address_input addr_in;
+       struct ras_ta_query_address_output addr_out;
+       int ret;
+
+       if (!ras_psp_check_supported_cmd(ras_core, 
RAS_TA_CMD_ID__QUERY_ADDRESS))
+               return -EOPNOTSUPP;
+
+       /* nps: the pa belongs to */
+       addr_in.pa.pa = pa | ((uint64_t)nps << 58);
+       addr_in.addr_type = RAS_TA_PA_TO_MCA;
+       ret = ras_psp_query_address(ras_core, &addr_in, &addr_out);
+       if (ret) {
+               RAS_DEV_ERR(ras_core->dev,
+                       "Failed to query RAS MCA address for 0x%llx", pa);
+
+               return ret;
+       }
+
+       *mca = addr_out.ma.err_addr;
+       return 0;
+}
+
 static int __eeprom_rec2nps_addr(struct ras_core_context *ras_core,
        struct eeprom_umc_record *record, uint64_t *pa,
        uint32_t nps, uint32_t die_id)
@@ -389,6 +414,7 @@ static int ras_umc_eeprom_rec2nps_rec(struct 
ras_core_context *ras_core,
        save_nps = EEPROM_RECORD_UMC_NPS_MODE(record);
        /* eeprom v2 has no stored nps, always convert if the flag is set */
        ch_idx_v2 = record->retired_row_pfn & UMC_CHANNEL_IDX_V2;
+       record->cur_nps = nps;
 
        if (save_nps || ch_idx_v2) {
                if ((nps == save_nps) && !ras_fw_eeprom_supported(ras_core)) {
@@ -400,6 +426,16 @@ static int ras_umc_eeprom_rec2nps_rec(struct 
ras_core_context *ras_core,
                                record->cur_nps_retired_row_pfn = 
RAS_ADDR_TO_PFN(pa);
                }
        } else {
+               /* for specific old eeprom data, mca address is not stored,
+                * calc it from pa
+                */
+               if (record->address == 0) {
+                       ret = ras_umc_pa2ma(ras_core, record->retired_row_pfn,
+                                       &(record->address), 
UMC_MEMORY_PARTITION_MODE_NPS1);
+                       if (ret)
+                               return ret;
+               }
+
                /* old eeprom data format, the scope of channel index is
                 * limited to umc instance
                 */
@@ -407,8 +443,6 @@ static int ras_umc_eeprom_rec2nps_rec(struct 
ras_core_context *ras_core,
                        return -EOPNOTSUPP;
        }
 
-       record->cur_nps = nps;
-
        return ret;
 }
 
-- 
2.34.1

Reply via email to