mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 09:20:13 -04:00
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:
@@ -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) \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user