Commit ed623d55 authored by Muralidhara M K's avatar Muralidhara M K Committed by Borislav Petkov (AMD)

EDAC/amd64: Merge struct amd64_family_type into struct amd64_pvt

Future AMD systems will support heterogeneous "AMD Node" types, e.g.
CPU and GPU types. Therefore, a global family type shared across all
AMD nodes is no longer appropriate.

Move struct low_ops routines and members of struct amd64_family_type
to struct amd64_pvt.

Currently, there are many code branches that split between "modern" and
"legacy" systems. Another code branch will be needed in order to cover
GPU cases. However, rather than introduce another branching case in
multiple functions, the current branching code should be switched to a
set of function pointers. This change makes the code more readable and
simplifies adding support for new families/models.

In order to reuse code, define two sets of function pointers. Use one
for modern systems (Family 17h and later). This will not change between
current CPU families. Use another set of function pointers for legacy
systems (before Family 17h). Use the Family 16h versions as default
for the legacy ops since these are the latest, and adjust the function
pointers as needed for older families.

  [ Yazen: rebased/reworked patch and reworded commit message. ]
  [  bp: Fix rev8 or later check. ]
Signed-off-by: default avatarMuralidhara M K <muralidhara.mk@amd.com>
Co-developed-by: default avatarNaveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Signed-off-by: default avatarNaveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Co-developed-by: default avatarYazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: default avatarYazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230127170419.1824692-11-yazen.ghannam@amd.com
parent 5a1adb37
...@@ -13,11 +13,9 @@ module_param(ecc_enable_override, int, 0644); ...@@ -13,11 +13,9 @@ module_param(ecc_enable_override, int, 0644);
static struct msr __percpu *msrs; static struct msr __percpu *msrs;
static struct amd64_family_type *fam_type; static inline u32 get_umc_reg(struct amd64_pvt *pvt, u32 reg)
static inline u32 get_umc_reg(u32 reg)
{ {
if (!fam_type->flags.zn_regs_v2) if (!pvt->flags.zn_regs_v2)
return reg; return reg;
switch (reg) { switch (reg) {
...@@ -437,7 +435,7 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct, ...@@ -437,7 +435,7 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct,
for (i = 0; i < pvt->csels[dct].m_cnt; i++) for (i = 0; i < pvt->csels[dct].m_cnt; i++)
#define for_each_umc(i) \ #define for_each_umc(i) \
for (i = 0; i < fam_type->max_mcs; i++) for (i = 0; i < pvt->max_mcs; i++)
/* /*
* @input_addr is an InputAddr associated with the node given by mci. Return the * @input_addr is an InputAddr associated with the node given by mci. Return the
...@@ -1464,7 +1462,7 @@ static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, ...@@ -1464,7 +1462,7 @@ static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
*/ */
dimm = csrow_nr >> 1; dimm = csrow_nr >> 1;
if (!fam_type->flags.zn_regs_v2) if (!pvt->flags.zn_regs_v2)
cs_mask_nr >>= 1; cs_mask_nr >>= 1;
/* Asymmetric dual-rank DIMM support. */ /* Asymmetric dual-rank DIMM support. */
...@@ -1556,7 +1554,7 @@ static void __dump_misc_regs_df(struct amd64_pvt *pvt) ...@@ -1556,7 +1554,7 @@ static void __dump_misc_regs_df(struct amd64_pvt *pvt)
if (umc->dram_type == MEM_LRDDR4 || umc->dram_type == MEM_LRDDR5) { if (umc->dram_type == MEM_LRDDR4 || umc->dram_type == MEM_LRDDR5) {
amd_smn_read(pvt->mc_node_id, amd_smn_read(pvt->mc_node_id,
umc_base + get_umc_reg(UMCCH_ADDR_CFG), umc_base + get_umc_reg(pvt, UMCCH_ADDR_CFG),
&tmp); &tmp);
edac_dbg(1, "UMC%d LRDIMM %dx rank multiply\n", edac_dbg(1, "UMC%d LRDIMM %dx rank multiply\n",
i, 1 << ((tmp >> 4) & 0x3)); i, 1 << ((tmp >> 4) & 0x3));
...@@ -1629,7 +1627,7 @@ static void prep_chip_selects(struct amd64_pvt *pvt) ...@@ -1629,7 +1627,7 @@ static void prep_chip_selects(struct amd64_pvt *pvt)
for_each_umc(umc) { for_each_umc(umc) {
pvt->csels[umc].b_cnt = 4; pvt->csels[umc].b_cnt = 4;
pvt->csels[umc].m_cnt = fam_type->flags.zn_regs_v2 ? 4 : 2; pvt->csels[umc].m_cnt = pvt->flags.zn_regs_v2 ? 4 : 2;
} }
} else { } else {
...@@ -1669,7 +1667,7 @@ static void read_umc_base_mask(struct amd64_pvt *pvt) ...@@ -1669,7 +1667,7 @@ static void read_umc_base_mask(struct amd64_pvt *pvt)
} }
umc_mask_reg = get_umc_base(umc) + UMCCH_ADDR_MASK; umc_mask_reg = get_umc_base(umc) + UMCCH_ADDR_MASK;
umc_mask_reg_sec = get_umc_base(umc) + get_umc_reg(UMCCH_ADDR_MASK_SEC); umc_mask_reg_sec = get_umc_base(umc) + get_umc_reg(pvt, UMCCH_ADDR_MASK_SEC);
for_each_chip_select_mask(cs, umc, pvt) { for_each_chip_select_mask(cs, umc, pvt) {
mask = &pvt->csels[umc].csmasks[cs]; mask = &pvt->csels[umc].csmasks[cs];
...@@ -1757,7 +1755,7 @@ static void determine_memory_type_df(struct amd64_pvt *pvt) ...@@ -1757,7 +1755,7 @@ static void determine_memory_type_df(struct amd64_pvt *pvt)
* Check if the system supports the "DDR Type" field in UMC Config * Check if the system supports the "DDR Type" field in UMC Config
* and has DDR5 DIMMs in use. * and has DDR5 DIMMs in use.
*/ */
if (fam_type->flags.zn_regs_v2 && ((umc->umc_cfg & GENMASK(2, 0)) == 0x1)) { if (pvt->flags.zn_regs_v2 && ((umc->umc_cfg & GENMASK(2, 0)) == 0x1)) {
if (umc->dimm_cfg & BIT(5)) if (umc->dimm_cfg & BIT(5))
umc->dram_type = MEM_LRDDR5; umc->dram_type = MEM_LRDDR5;
else if (umc->dimm_cfg & BIT(4)) else if (umc->dimm_cfg & BIT(4))
...@@ -2739,112 +2737,6 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, ...@@ -2739,112 +2737,6 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr,
err->channel = get_channel_from_ecc_syndrome(mci, err->syndrome); err->channel = get_channel_from_ecc_syndrome(mci, err->syndrome);
} }
static struct amd64_family_type family_types[] = {
[K8_CPUS] = {
.ctl_name = "K8",
.f1_id = PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP,
.f2_id = PCI_DEVICE_ID_AMD_K8_NB_MEMCTL,
.max_mcs = 2,
.ops = {
.map_sysaddr_to_csrow = k8_map_sysaddr_to_csrow,
.dbam_to_cs = k8_dbam_to_chip_select,
}
},
[F10_CPUS] = {
.ctl_name = "F10h",
.f1_id = PCI_DEVICE_ID_AMD_10H_NB_MAP,
.f2_id = PCI_DEVICE_ID_AMD_10H_NB_DRAM,
.max_mcs = 2,
.ops = {
.map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow,
.dbam_to_cs = f10_dbam_to_chip_select,
}
},
[F15_CPUS] = {
.ctl_name = "F15h",
.f1_id = PCI_DEVICE_ID_AMD_15H_NB_F1,
.f2_id = PCI_DEVICE_ID_AMD_15H_NB_F2,
.max_mcs = 2,
.ops = {
.map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow,
.dbam_to_cs = f15_dbam_to_chip_select,
}
},
[F15_M30H_CPUS] = {
.ctl_name = "F15h_M30h",
.f1_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F1,
.f2_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F2,
.max_mcs = 2,
.ops = {
.map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow,
.dbam_to_cs = f16_dbam_to_chip_select,
}
},
[F15_M60H_CPUS] = {
.ctl_name = "F15h_M60h",
.f1_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F1,
.f2_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F2,
.max_mcs = 2,
.ops = {
.map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow,
.dbam_to_cs = f15_m60h_dbam_to_chip_select,
}
},
[F16_CPUS] = {
.ctl_name = "F16h",
.f1_id = PCI_DEVICE_ID_AMD_16H_NB_F1,
.f2_id = PCI_DEVICE_ID_AMD_16H_NB_F2,
.max_mcs = 2,
.ops = {
.map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow,
.dbam_to_cs = f16_dbam_to_chip_select,
}
},
[F16_M30H_CPUS] = {
.ctl_name = "F16h_M30h",
.f1_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F1,
.f2_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F2,
.max_mcs = 2,
.ops = {
.map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow,
.dbam_to_cs = f16_dbam_to_chip_select,
}
},
[F17_CPUS] = {
.ctl_name = "F17h",
.max_mcs = 2,
},
[F17_M10H_CPUS] = {
.ctl_name = "F17h_M10h",
.max_mcs = 2,
},
[F17_M30H_CPUS] = {
.ctl_name = "F17h_M30h",
.max_mcs = 8,
},
[F17_M60H_CPUS] = {
.ctl_name = "F17h_M60h",
.max_mcs = 2,
},
[F17_M70H_CPUS] = {
.ctl_name = "F17h_M70h",
.max_mcs = 2,
},
[F19_CPUS] = {
.ctl_name = "F19h",
.max_mcs = 8,
},
[F19_M10H_CPUS] = {
.ctl_name = "F19h_M10h",
.max_mcs = 12,
.flags.zn_regs_v2 = 1,
},
[F19_M50H_CPUS] = {
.ctl_name = "F19h_M50h",
.max_mcs = 2,
},
};
/* /*
* These are tables of eigenvectors (one per line) which can be used for the * These are tables of eigenvectors (one per line) which can be used for the
* construction of the syndrome tables. The modified syndrome search algorithm * construction of the syndrome tables. The modified syndrome search algorithm
...@@ -3226,7 +3118,7 @@ static void __read_mc_regs_df(struct amd64_pvt *pvt) ...@@ -3226,7 +3118,7 @@ static void __read_mc_regs_df(struct amd64_pvt *pvt)
umc_base = get_umc_base(i); umc_base = get_umc_base(i);
umc = &pvt->umc[i]; umc = &pvt->umc[i];
amd_smn_read(nid, umc_base + get_umc_reg(UMCCH_DIMM_CFG), &umc->dimm_cfg); amd_smn_read(nid, umc_base + get_umc_reg(pvt, UMCCH_DIMM_CFG), &umc->dimm_cfg);
amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &umc->umc_cfg); amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &umc->umc_cfg);
amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &umc->sdp_ctrl); amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &umc->sdp_ctrl);
amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &umc->ecc_ctrl); amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &umc->ecc_ctrl);
...@@ -3495,7 +3387,7 @@ static int init_csrows(struct mem_ctl_info *mci) ...@@ -3495,7 +3387,7 @@ static int init_csrows(struct mem_ctl_info *mci)
: EDAC_SECDED; : EDAC_SECDED;
} }
for (j = 0; j < fam_type->max_mcs; j++) { for (j = 0; j < pvt->max_mcs; j++) {
dimm = csrow->channels[j]->dimm; dimm = csrow->channels[j]->dimm;
dimm->mtype = pvt->dram_type; dimm->mtype = pvt->dram_type;
dimm->edac_mode = edac_mode; dimm->edac_mode = edac_mode;
...@@ -3767,7 +3659,7 @@ static void setup_mci_misc_attrs(struct mem_ctl_info *mci) ...@@ -3767,7 +3659,7 @@ static void setup_mci_misc_attrs(struct mem_ctl_info *mci)
mci->edac_cap = determine_edac_cap(pvt); mci->edac_cap = determine_edac_cap(pvt);
mci->mod_name = EDAC_MOD_STR; mci->mod_name = EDAC_MOD_STR;
mci->ctl_name = fam_type->ctl_name; mci->ctl_name = pvt->ctl_name;
mci->dev_name = pci_name(pvt->F3); mci->dev_name = pci_name(pvt->F3);
mci->ctl_page_to_phys = NULL; mci->ctl_page_to_phys = NULL;
...@@ -3779,114 +3671,145 @@ static void setup_mci_misc_attrs(struct mem_ctl_info *mci) ...@@ -3779,114 +3671,145 @@ static void setup_mci_misc_attrs(struct mem_ctl_info *mci)
mci->get_sdram_scrub_rate = get_scrub_rate; mci->get_sdram_scrub_rate = get_scrub_rate;
} }
/* static struct low_ops umc_ops = {
* returns a pointer to the family descriptor on success, NULL otherwise. };
*/
static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt) /* Use Family 16h versions for defaults and adjust as needed below. */
static struct low_ops dct_ops = {
.map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow,
.dbam_to_cs = f16_dbam_to_chip_select,
};
static int per_family_init(struct amd64_pvt *pvt)
{ {
pvt->ext_model = boot_cpu_data.x86_model >> 4; pvt->ext_model = boot_cpu_data.x86_model >> 4;
pvt->stepping = boot_cpu_data.x86_stepping; pvt->stepping = boot_cpu_data.x86_stepping;
pvt->model = boot_cpu_data.x86_model; pvt->model = boot_cpu_data.x86_model;
pvt->fam = boot_cpu_data.x86; pvt->fam = boot_cpu_data.x86;
pvt->max_mcs = 2;
/*
* Decide on which ops group to use here and do any family/model
* overrides below.
*/
if (pvt->fam >= 0x17)
pvt->ops = &umc_ops;
else
pvt->ops = &dct_ops;
switch (pvt->fam) { switch (pvt->fam) {
case 0xf: case 0xf:
fam_type = &family_types[K8_CPUS]; pvt->ctl_name = (pvt->ext_model >= K8_REV_F) ?
pvt->ops = &family_types[K8_CPUS].ops; "K8 revF or later" : "K8 revE or earlier";
pvt->f1_id = PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP;
pvt->f2_id = PCI_DEVICE_ID_AMD_K8_NB_MEMCTL;
pvt->ops->map_sysaddr_to_csrow = k8_map_sysaddr_to_csrow;
pvt->ops->dbam_to_cs = k8_dbam_to_chip_select;
break; break;
case 0x10: case 0x10:
fam_type = &family_types[F10_CPUS]; pvt->ctl_name = "F10h";
pvt->ops = &family_types[F10_CPUS].ops; pvt->f1_id = PCI_DEVICE_ID_AMD_10H_NB_MAP;
pvt->f2_id = PCI_DEVICE_ID_AMD_10H_NB_DRAM;
pvt->ops->dbam_to_cs = f10_dbam_to_chip_select;
break; break;
case 0x15: case 0x15:
if (pvt->model == 0x30) { switch (pvt->model) {
fam_type = &family_types[F15_M30H_CPUS]; case 0x30:
pvt->ops = &family_types[F15_M30H_CPUS].ops; pvt->ctl_name = "F15h_M30h";
pvt->f1_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F1;
pvt->f2_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F2;
break; break;
} else if (pvt->model == 0x60) { case 0x60:
fam_type = &family_types[F15_M60H_CPUS]; pvt->ctl_name = "F15h_M60h";
pvt->ops = &family_types[F15_M60H_CPUS].ops; pvt->f1_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F1;
pvt->f2_id = PCI_DEVICE_ID_AMD_15H_M60H_NB_F2;
pvt->ops->dbam_to_cs = f15_m60h_dbam_to_chip_select;
break;
case 0x13:
/* Richland is only client */
return -ENODEV;
default:
pvt->ctl_name = "F15h";
pvt->f1_id = PCI_DEVICE_ID_AMD_15H_NB_F1;
pvt->f2_id = PCI_DEVICE_ID_AMD_15H_NB_F2;
pvt->ops->dbam_to_cs = f15_dbam_to_chip_select;
break; break;
/* Richland is only client */
} else if (pvt->model == 0x13) {
return NULL;
} else {
fam_type = &family_types[F15_CPUS];
pvt->ops = &family_types[F15_CPUS].ops;
} }
break; break;
case 0x16: case 0x16:
if (pvt->model == 0x30) { switch (pvt->model) {
fam_type = &family_types[F16_M30H_CPUS]; case 0x30:
pvt->ops = &family_types[F16_M30H_CPUS].ops; pvt->ctl_name = "F16h_M30h";
pvt->f1_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F1;
pvt->f2_id = PCI_DEVICE_ID_AMD_16H_M30H_NB_F2;
break;
default:
pvt->ctl_name = "F16h";
pvt->f1_id = PCI_DEVICE_ID_AMD_16H_NB_F1;
pvt->f2_id = PCI_DEVICE_ID_AMD_16H_NB_F2;
break; break;
} }
fam_type = &family_types[F16_CPUS];
pvt->ops = &family_types[F16_CPUS].ops;
break; break;
case 0x17: case 0x17:
if (pvt->model >= 0x10 && pvt->model <= 0x2f) { switch (pvt->model) {
fam_type = &family_types[F17_M10H_CPUS]; case 0x10 ... 0x2f:
pvt->ops = &family_types[F17_M10H_CPUS].ops; pvt->ctl_name = "F17h_M10h";
break; break;
} else if (pvt->model >= 0x30 && pvt->model <= 0x3f) { case 0x30 ... 0x3f:
fam_type = &family_types[F17_M30H_CPUS]; pvt->ctl_name = "F17h_M30h";
pvt->ops = &family_types[F17_M30H_CPUS].ops; pvt->max_mcs = 8;
break; break;
} else if (pvt->model >= 0x60 && pvt->model <= 0x6f) { case 0x60 ... 0x6f:
fam_type = &family_types[F17_M60H_CPUS]; pvt->ctl_name = "F17h_M60h";
pvt->ops = &family_types[F17_M60H_CPUS].ops;
break; break;
} else if (pvt->model >= 0x70 && pvt->model <= 0x7f) { case 0x70 ... 0x7f:
fam_type = &family_types[F17_M70H_CPUS]; pvt->ctl_name = "F17h_M70h";
pvt->ops = &family_types[F17_M70H_CPUS].ops; break;
default:
pvt->ctl_name = "F17h";
break; break;
} }
fallthrough; break;
case 0x18:
fam_type = &family_types[F17_CPUS];
pvt->ops = &family_types[F17_CPUS].ops;
if (pvt->fam == 0x18) case 0x18:
family_types[F17_CPUS].ctl_name = "F18h"; pvt->ctl_name = "F18h";
break; break;
case 0x19: case 0x19:
if (pvt->model >= 0x10 && pvt->model <= 0x1f) { switch (pvt->model) {
fam_type = &family_types[F19_M10H_CPUS]; case 0x00 ... 0x0f:
pvt->ops = &family_types[F19_M10H_CPUS].ops; pvt->ctl_name = "F19h";
pvt->max_mcs = 8;
break; break;
} else if (pvt->model >= 0x20 && pvt->model <= 0x2f) { case 0x10 ... 0x1f:
fam_type = &family_types[F17_M70H_CPUS]; pvt->ctl_name = "F19h_M10h";
pvt->ops = &family_types[F17_M70H_CPUS].ops; pvt->max_mcs = 12;
fam_type->ctl_name = "F19h_M20h"; pvt->flags.zn_regs_v2 = 1;
break; break;
} else if (pvt->model >= 0x50 && pvt->model <= 0x5f) { case 0x20 ... 0x2f:
fam_type = &family_types[F19_M50H_CPUS]; pvt->ctl_name = "F19h_M20h";
pvt->ops = &family_types[F19_M50H_CPUS].ops;
fam_type->ctl_name = "F19h_M50h";
break; break;
} else if (pvt->model >= 0xa0 && pvt->model <= 0xaf) { case 0x50 ... 0x5f:
fam_type = &family_types[F19_M10H_CPUS]; pvt->ctl_name = "F19h_M50h";
pvt->ops = &family_types[F19_M10H_CPUS].ops; break;
fam_type->ctl_name = "F19h_MA0h"; case 0xa0 ... 0xaf:
pvt->ctl_name = "F19h_MA0h";
pvt->max_mcs = 12;
pvt->flags.zn_regs_v2 = 1;
break; break;
} }
fam_type = &family_types[F19_CPUS];
pvt->ops = &family_types[F19_CPUS].ops;
family_types[F19_CPUS].ctl_name = "F19h";
break; break;
default: default:
amd64_err("Unsupported family!\n"); amd64_err("Unsupported family!\n");
return NULL; return -ENODEV;
} }
return fam_type; return 0;
} }
static const struct attribute_group *amd64_edac_attr_groups[] = { static const struct attribute_group *amd64_edac_attr_groups[] = {
...@@ -3903,12 +3826,12 @@ static int hw_info_get(struct amd64_pvt *pvt) ...@@ -3903,12 +3826,12 @@ static int hw_info_get(struct amd64_pvt *pvt)
int ret; int ret;
if (pvt->fam >= 0x17) { if (pvt->fam >= 0x17) {
pvt->umc = kcalloc(fam_type->max_mcs, sizeof(struct amd64_umc), GFP_KERNEL); pvt->umc = kcalloc(pvt->max_mcs, sizeof(struct amd64_umc), GFP_KERNEL);
if (!pvt->umc) if (!pvt->umc)
return -ENOMEM; return -ENOMEM;
} else { } else {
pci_id1 = fam_type->f1_id; pci_id1 = pvt->f1_id;
pci_id2 = fam_type->f2_id; pci_id2 = pvt->f2_id;
} }
ret = reserve_mc_sibling_devs(pvt, pci_id1, pci_id2); ret = reserve_mc_sibling_devs(pvt, pci_id1, pci_id2);
...@@ -3938,7 +3861,7 @@ static int init_one_instance(struct amd64_pvt *pvt) ...@@ -3938,7 +3861,7 @@ static int init_one_instance(struct amd64_pvt *pvt)
layers[0].size = pvt->csels[0].b_cnt; layers[0].size = pvt->csels[0].b_cnt;
layers[0].is_virt_csrow = true; layers[0].is_virt_csrow = true;
layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].type = EDAC_MC_LAYER_CHANNEL;
layers[1].size = fam_type->max_mcs; layers[1].size = pvt->max_mcs;
layers[1].is_virt_csrow = false; layers[1].is_virt_csrow = false;
mci = edac_mc_alloc(pvt->mc_node_id, ARRAY_SIZE(layers), layers, 0); mci = edac_mc_alloc(pvt->mc_node_id, ARRAY_SIZE(layers), layers, 0);
...@@ -3968,7 +3891,7 @@ static bool instance_has_memory(struct amd64_pvt *pvt) ...@@ -3968,7 +3891,7 @@ static bool instance_has_memory(struct amd64_pvt *pvt)
bool cs_enabled = false; bool cs_enabled = false;
int cs = 0, dct = 0; int cs = 0, dct = 0;
for (dct = 0; dct < fam_type->max_mcs; dct++) { for (dct = 0; dct < pvt->max_mcs; dct++) {
for_each_chip_select(cs, dct, pvt) for_each_chip_select(cs, dct, pvt)
cs_enabled |= csrow_enabled(cs, dct, pvt); cs_enabled |= csrow_enabled(cs, dct, pvt);
} }
...@@ -3997,9 +3920,8 @@ static int probe_one_instance(unsigned int nid) ...@@ -3997,9 +3920,8 @@ static int probe_one_instance(unsigned int nid)
pvt->mc_node_id = nid; pvt->mc_node_id = nid;
pvt->F3 = F3; pvt->F3 = F3;
ret = -ENODEV; ret = per_family_init(pvt);
fam_type = per_family_init(pvt); if (ret < 0)
if (!fam_type)
goto err_enable; goto err_enable;
ret = hw_info_get(pvt); ret = hw_info_get(pvt);
...@@ -4038,11 +3960,7 @@ static int probe_one_instance(unsigned int nid) ...@@ -4038,11 +3960,7 @@ static int probe_one_instance(unsigned int nid)
goto err_enable; goto err_enable;
} }
amd64_info("%s %sdetected (node %d).\n", fam_type->ctl_name, amd64_info("%s detected (node %d).\n", pvt->ctl_name, pvt->mc_node_id);
(pvt->fam == 0xf ?
(pvt->ext_model >= K8_REV_F ? "revF or later "
: "revE or earlier ")
: ""), pvt->mc_node_id);
dump_misc_regs(pvt); dump_misc_regs(pvt);
......
...@@ -273,25 +273,6 @@ ...@@ -273,25 +273,6 @@
#define UMC_SDP_INIT BIT(31) #define UMC_SDP_INIT BIT(31)
enum amd_families {
K8_CPUS = 0,
F10_CPUS,
F15_CPUS,
F15_M30H_CPUS,
F15_M60H_CPUS,
F16_CPUS,
F16_M30H_CPUS,
F17_CPUS,
F17_M10H_CPUS,
F17_M30H_CPUS,
F17_M60H_CPUS,
F17_M70H_CPUS,
F19_CPUS,
F19_M10H_CPUS,
F19_M50H_CPUS,
NUM_FAMILIES,
};
/* Error injection control structure */ /* Error injection control structure */
struct error_injection { struct error_injection {
u32 section; u32 section;
...@@ -334,6 +315,16 @@ struct amd64_umc { ...@@ -334,6 +315,16 @@ struct amd64_umc {
enum mem_type dram_type; enum mem_type dram_type;
}; };
struct amd64_family_flags {
/*
* Indicates that the system supports the new register offsets, etc.
* first introduced with Family 19h Model 10h.
*/
__u64 zn_regs_v2 : 1,
__reserved : 63;
};
struct amd64_pvt { struct amd64_pvt {
struct low_ops *ops; struct low_ops *ops;
...@@ -375,6 +366,12 @@ struct amd64_pvt { ...@@ -375,6 +366,12 @@ struct amd64_pvt {
/* x4, x8, or x16 syndromes in use */ /* x4, x8, or x16 syndromes in use */
u8 ecc_sym_sz; u8 ecc_sym_sz;
const char *ctl_name;
u16 f1_id, f2_id;
/* Maximum number of memory controllers per die/node. */
u8 max_mcs;
struct amd64_family_flags flags;
/* place to store error injection parameters prior to issue */ /* place to store error injection parameters prior to issue */
struct error_injection injection; struct error_injection injection;
...@@ -465,29 +462,10 @@ struct ecc_settings { ...@@ -465,29 +462,10 @@ struct ecc_settings {
* functions and per device encoding/decoding logic. * functions and per device encoding/decoding logic.
*/ */
struct low_ops { struct low_ops {
void (*map_sysaddr_to_csrow) (struct mem_ctl_info *mci, u64 sys_addr, void (*map_sysaddr_to_csrow)(struct mem_ctl_info *mci, u64 sys_addr,
struct err_info *); struct err_info *err);
int (*dbam_to_cs) (struct amd64_pvt *pvt, u8 dct, int (*dbam_to_cs)(struct amd64_pvt *pvt, u8 dct,
unsigned cs_mode, int cs_mask_nr); unsigned int cs_mode, int cs_mask_nr);
};
struct amd64_family_flags {
/*
* Indicates that the system supports the new register offsets, etc.
* first introduced with Family 19h Model 10h.
*/
__u64 zn_regs_v2 : 1,
__reserved : 63;
};
struct amd64_family_type {
const char *ctl_name;
u16 f1_id, f2_id;
/* Maximum number of memory controllers per die/node. */
u8 max_mcs;
struct amd64_family_flags flags;
struct low_ops ops;
}; };
int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset, int __amd64_read_pci_cfg_dword(struct pci_dev *pdev, int offset,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment