diff options
| -rw-r--r-- | drivers/edac/amd64_edac.c | 113 | ||||
| -rw-r--r-- | drivers/edac/amd64_edac.h | 5 |
2 files changed, 56 insertions, 62 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 4c0239aeff2f..e2a99466faaa 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
| @@ -941,94 +941,89 @@ static void prep_chip_selects(struct amd64_pvt *pvt) | |||
| 941 | } else if (pvt->fam == 0x15 && pvt->model == 0x30) { | 941 | } else if (pvt->fam == 0x15 && pvt->model == 0x30) { |
| 942 | pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 4; | 942 | pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 4; |
| 943 | pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 2; | 943 | pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 2; |
| 944 | } else if (pvt->fam >= 0x17) { | ||
| 945 | int umc; | ||
| 946 | |||
| 947 | for_each_umc(umc) { | ||
| 948 | pvt->csels[umc].b_cnt = 8; | ||
| 949 | pvt->csels[umc].m_cnt = 4; | ||
| 950 | } | ||
| 951 | |||
| 952 | } else { | 944 | } else { |
| 953 | pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8; | 945 | pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8; |
| 954 | pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 4; | 946 | pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 4; |
| 955 | } | 947 | } |
| 956 | } | 948 | } |
| 957 | 949 | ||
| 958 | static void read_umc_base_mask(struct amd64_pvt *pvt) | ||
| 959 | { | ||
| 960 | int cs, umc; | ||
| 961 | |||
| 962 | for_each_umc(umc) { | ||
| 963 | u32 umc_base_reg = get_umc_base(umc) + UMCCH_BASE_ADDR; | ||
| 964 | u32 umc_mask_reg = get_umc_base(umc) + UMCCH_ADDR_MASK; | ||
| 965 | |||
| 966 | for_each_chip_select(cs, 0, pvt) { | ||
| 967 | u32 *base = &pvt->csels[umc].csbases[cs]; | ||
| 968 | u32 *mask = &pvt->csels[umc].csmasks[cs]; | ||
| 969 | |||
| 970 | u32 base_reg = umc_base_reg + (cs * 4); | ||
| 971 | u32 mask_reg = umc_mask_reg + ((cs >> 1) * 4); | ||
| 972 | |||
| 973 | if (!amd_smn_read(pvt->mc_node_id, base_reg, base)) | ||
| 974 | edac_dbg(0, " DCSB%d[%d]=0x%08x reg: 0x%x\n", | ||
| 975 | umc, cs, *base, base_reg); | ||
| 976 | |||
| 977 | if (!amd_smn_read(pvt->mc_node_id, mask_reg, mask)) | ||
| 978 | edac_dbg(0, " DCSM%d[%d]=0x%08x reg: 0x%x\n", | ||
| 979 | umc, cs, *mask, mask_reg); | ||
| 980 | } | ||
| 981 | } | ||
| 982 | } | ||
| 983 | |||
| 984 | /* | 950 | /* |
| 985 | * Function 2 Offset F10_DCSB0; read in the DCS Base and DCS Mask registers | 951 | * Function 2 Offset F10_DCSB0; read in the DCS Base and DCS Mask registers |
| 986 | */ | 952 | */ |
| 987 | static void read_dct_base_mask(struct amd64_pvt *pvt) | 953 | static void read_dct_base_mask(struct amd64_pvt *pvt) |
| 988 | { | 954 | { |
| 989 | int cs; | 955 | int base_reg0, base_reg1, mask_reg0, mask_reg1, cs; |
| 990 | 956 | ||
| 991 | prep_chip_selects(pvt); | 957 | prep_chip_selects(pvt); |
| 992 | 958 | ||
| 993 | if (pvt->umc) | 959 | if (pvt->umc) { |
| 994 | return read_umc_base_mask(pvt); | 960 | base_reg0 = get_umc_base(0) + UMCCH_BASE_ADDR; |
| 961 | base_reg1 = get_umc_base(1) + UMCCH_BASE_ADDR; | ||
| 962 | mask_reg0 = get_umc_base(0) + UMCCH_ADDR_MASK; | ||
| 963 | mask_reg1 = get_umc_base(1) + UMCCH_ADDR_MASK; | ||
| 964 | } else { | ||
| 965 | base_reg0 = DCSB0; | ||
| 966 | base_reg1 = DCSB1; | ||
| 967 | mask_reg0 = DCSM0; | ||
| 968 | mask_reg1 = DCSM1; | ||
| 969 | } | ||
| 995 | 970 | ||
| 996 | for_each_chip_select(cs, 0, pvt) { | 971 | for_each_chip_select(cs, 0, pvt) { |
| 997 | int reg0 = DCSB0 + (cs * 4); | 972 | int reg0 = base_reg0 + (cs * 4); |
| 998 | int reg1 = DCSB1 + (cs * 4); | 973 | int reg1 = base_reg1 + (cs * 4); |
| 999 | u32 *base0 = &pvt->csels[0].csbases[cs]; | 974 | u32 *base0 = &pvt->csels[0].csbases[cs]; |
| 1000 | u32 *base1 = &pvt->csels[1].csbases[cs]; | 975 | u32 *base1 = &pvt->csels[1].csbases[cs]; |
| 1001 | 976 | ||
| 1002 | if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, base0)) | 977 | if (pvt->umc) { |
| 1003 | edac_dbg(0, " DCSB0[%d]=0x%08x reg: F2x%x\n", | 978 | if (!amd_smn_read(pvt->mc_node_id, reg0, base0)) |
| 1004 | cs, *base0, reg0); | 979 | edac_dbg(0, " DCSB0[%d]=0x%08x reg: 0x%x\n", |
| 980 | cs, *base0, reg0); | ||
| 1005 | 981 | ||
| 1006 | if (pvt->fam == 0xf) | 982 | if (!amd_smn_read(pvt->mc_node_id, reg1, base1)) |
| 1007 | continue; | 983 | edac_dbg(0, " DCSB1[%d]=0x%08x reg: 0x%x\n", |
| 984 | cs, *base1, reg1); | ||
| 985 | } else { | ||
| 986 | if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, base0)) | ||
| 987 | edac_dbg(0, " DCSB0[%d]=0x%08x reg: F2x%x\n", | ||
| 988 | cs, *base0, reg0); | ||
| 989 | |||
| 990 | if (pvt->fam == 0xf) | ||
| 991 | continue; | ||
| 1008 | 992 | ||
| 1009 | if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, base1)) | 993 | if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, base1)) |
| 1010 | edac_dbg(0, " DCSB1[%d]=0x%08x reg: F2x%x\n", | 994 | edac_dbg(0, " DCSB1[%d]=0x%08x reg: F2x%x\n", |
| 1011 | cs, *base1, (pvt->fam == 0x10) ? reg1 | 995 | cs, *base1, (pvt->fam == 0x10) ? reg1 |
| 1012 | : reg0); | 996 | : reg0); |
| 997 | } | ||
| 1013 | } | 998 | } |
| 1014 | 999 | ||
| 1015 | for_each_chip_select_mask(cs, 0, pvt) { | 1000 | for_each_chip_select_mask(cs, 0, pvt) { |
| 1016 | int reg0 = DCSM0 + (cs * 4); | 1001 | int reg0 = mask_reg0 + (cs * 4); |
| 1017 | int reg1 = DCSM1 + (cs * 4); | 1002 | int reg1 = mask_reg1 + (cs * 4); |
| 1018 | u32 *mask0 = &pvt->csels[0].csmasks[cs]; | 1003 | u32 *mask0 = &pvt->csels[0].csmasks[cs]; |
| 1019 | u32 *mask1 = &pvt->csels[1].csmasks[cs]; | 1004 | u32 *mask1 = &pvt->csels[1].csmasks[cs]; |
| 1020 | 1005 | ||
| 1021 | if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, mask0)) | 1006 | if (pvt->umc) { |
| 1022 | edac_dbg(0, " DCSM0[%d]=0x%08x reg: F2x%x\n", | 1007 | if (!amd_smn_read(pvt->mc_node_id, reg0, mask0)) |
| 1023 | cs, *mask0, reg0); | 1008 | edac_dbg(0, " DCSM0[%d]=0x%08x reg: 0x%x\n", |
| 1009 | cs, *mask0, reg0); | ||
| 1024 | 1010 | ||
| 1025 | if (pvt->fam == 0xf) | 1011 | if (!amd_smn_read(pvt->mc_node_id, reg1, mask1)) |
| 1026 | continue; | 1012 | edac_dbg(0, " DCSM1[%d]=0x%08x reg: 0x%x\n", |
| 1013 | cs, *mask1, reg1); | ||
| 1014 | } else { | ||
| 1015 | if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, mask0)) | ||
| 1016 | edac_dbg(0, " DCSM0[%d]=0x%08x reg: F2x%x\n", | ||
| 1017 | cs, *mask0, reg0); | ||
| 1027 | 1018 | ||
| 1028 | if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, mask1)) | 1019 | if (pvt->fam == 0xf) |
| 1029 | edac_dbg(0, " DCSM1[%d]=0x%08x reg: F2x%x\n", | 1020 | continue; |
| 1030 | cs, *mask1, (pvt->fam == 0x10) ? reg1 | 1021 | |
| 1031 | : reg0); | 1022 | if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, mask1)) |
| 1023 | edac_dbg(0, " DCSM1[%d]=0x%08x reg: F2x%x\n", | ||
| 1024 | cs, *mask1, (pvt->fam == 0x10) ? reg1 | ||
| 1025 | : reg0); | ||
| 1026 | } | ||
| 1032 | } | 1027 | } |
| 1033 | } | 1028 | } |
| 1034 | 1029 | ||
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 4dce6a2ac75f..8f66472f7adc 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
| @@ -96,7 +96,6 @@ | |||
| 96 | /* Hardware limit on ChipSelect rows per MC and processors per system */ | 96 | /* Hardware limit on ChipSelect rows per MC and processors per system */ |
| 97 | #define NUM_CHIPSELECTS 8 | 97 | #define NUM_CHIPSELECTS 8 |
| 98 | #define DRAM_RANGES 8 | 98 | #define DRAM_RANGES 8 |
| 99 | #define NUM_CONTROLLERS 8 | ||
| 100 | 99 | ||
| 101 | #define ON true | 100 | #define ON true |
| 102 | #define OFF false | 101 | #define OFF false |
| @@ -352,8 +351,8 @@ struct amd64_pvt { | |||
| 352 | u32 dbam0; /* DRAM Base Address Mapping reg for DCT0 */ | 351 | u32 dbam0; /* DRAM Base Address Mapping reg for DCT0 */ |
| 353 | u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */ | 352 | u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */ |
| 354 | 353 | ||
| 355 | /* one for each DCT/UMC */ | 354 | /* one for each DCT */ |
| 356 | struct chip_select csels[NUM_CONTROLLERS]; | 355 | struct chip_select csels[2]; |
| 357 | 356 | ||
| 358 | /* DRAM base and limit pairs F1x[78,70,68,60,58,50,48,40] */ | 357 | /* DRAM base and limit pairs F1x[78,70,68,60,58,50,48,40] */ |
| 359 | struct dram_range ranges[DRAM_RANGES]; | 358 | struct dram_range ranges[DRAM_RANGES]; |
