drm/amd/ras: detect old ras eeprom format

Handler of some formats will be implemented in the future.

UMC_CHANNEL_IDX_V2 is a flag to indicate v2 format channel index stored
in eeprom, the flag was retired in v3 and save_nps is introduced in v3,
so they have no conflict.

eeprom format v1: store channel index within a umc instance in eeprom
    range in UMC v12: 0 ~ 7
eeprom format v2: store global channel index in eeprom
    range in UMC v12: 0 ~ 127

v2: change the bit range of save_nps from [40:47] to [40:46],
    UMC_CHANNEL_IDX_V2 use bit 47.

    use RAS_DEV_WARN_RATELIMITED for retire record check, avoid log
    noise.

Signed-off-by: Tao Zhou <tao.zhou1@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Tao Zhou
2026-07-08 18:19:09 +08:00
committed by Alex Deucher
parent 6085f8289e
commit 47a71f452c
4 changed files with 44 additions and 10 deletions

View File

@@ -36,10 +36,10 @@
/*
* Bad address pfn : eeprom_umc_record.retired_row_pfn[39:0],
* nps mode: eeprom_umc_record.retired_row_pfn[47:40]
* nps mode: eeprom_umc_record.retired_row_pfn[46:40]
*/
#define EEPROM_RECORD_UMC_ADDR_MASK 0xFFFFFFFFFFULL
#define EEPROM_RECORD_UMC_NPS_MASK 0xFF0000000000ULL
#define EEPROM_RECORD_UMC_NPS_MASK 0x7F0000000000ULL
#define EEPROM_RECORD_UMC_NPS_SHIFT 40
#define EEPROM_RECORD_UMC_NPS_MODE(RECORD) \

View File

@@ -346,7 +346,7 @@ static bool ras_umc_check_retired_record(struct ras_core_context *ras_core,
if (ras_umc->ip_func && ras_umc->ip_func->eeprom_record_to_nps_record) {
ret = ras_umc->ip_func->eeprom_record_to_nps_record(ras_core, record, nps);
if (ret)
RAS_DEV_WARN(ras_core->dev,
RAS_DEV_WARN_RATELIMITED(ras_core->dev,
"Failed to adjust eeprom record, ret:%d", ret);
}
return false;

View File

@@ -46,6 +46,26 @@
#define UMC_ECC_NEW_DETECTED_TAG 0x1
#define UMC_INV_MEM_PFN (0xFFFFFFFFFFFFFFFF)
/*
* a flag to indicate v2 format channel index stored in eeprom
*
* v1: store channel index within a umc instance in eeprom
* range in UMC v12: 0 ~ 7
* v2: store global channel index in eeprom
* range in UMC v12: 0 ~ 127
*
* NOTE: it's better to store it in eeprom_table_record.mem_channel,
* but there is only 8 bits in mem_channel, and the channel number may
* increase in the future, we decide to save it in
* eeprom_table_record.retired_page. retired_page is useless in v2,
* we depend on eeprom_table_record.address instead of retired_page in v2.
* Only 48 bits are saved on eeprom, use bit 47 here.
*
* UMC_CHANNEL_IDX_V2 is replaced by nps value in cur_nps_retired_row_pfn
* in eeprom v3 format, so they have no conflict.
*/
#define UMC_CHANNEL_IDX_V2 BIT_ULL(47)
/* three column bits and one row bit in MCA address flip
* in bad page retirement
*/

View File

@@ -460,16 +460,30 @@ static int convert_eeprom_record_to_nps_addr(struct ras_core_context *ras_core,
static int umc_v12_0_eeprom_record_to_nps_record(struct ras_core_context *ras_core,
struct eeprom_umc_record *record, uint32_t nps)
{
uint64_t pa = 0;
uint64_t ch_idx_v2, pa = 0;
uint32_t save_nps;
int ret = 0;
if (nps == EEPROM_RECORD_UMC_NPS_MODE(record) && !ras_fw_eeprom_supported(ras_core)) {
record->cur_nps_retired_row_pfn = EEPROM_RECORD_UMC_ADDR_PFN(record);
} else {
ret = convert_eeprom_record_to_nps_addr(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;
if (save_nps || ch_idx_v2) {
if ((nps == save_nps) && !ras_fw_eeprom_supported(ras_core)) {
record->cur_nps_retired_row_pfn =
EEPROM_RECORD_UMC_ADDR_PFN(record);
} else {
ret = convert_eeprom_record_to_nps_addr(ras_core,
record, &pa, nps);
if (!ret)
record->cur_nps_retired_row_pfn = RAS_ADDR_TO_PFN(pa);
if (!ret)
record->cur_nps_retired_row_pfn = RAS_ADDR_TO_PFN(pa);
}
} else {
/* old eeprom data format, the scope of channel index is
* limited to umc instance
*/
/* TODO */
ret = -EOPNOTSUPP;
}
record->cur_nps = nps;