diff options
author | Doug Thompson <dougthompson@xmission.com> | 2009-04-27 10:12:00 -0400 |
---|---|---|
committer | Borislav Petkov <borislav.petkov@amd.com> | 2009-06-10 06:18:53 -0400 |
commit | 94be4bff21990674ac418c970c708a1a01cf709f (patch) | |
tree | 35eea3c55f5ef344e3ac0417970bfbb8891b8f71 /drivers/edac/amd64_edac.c | |
parent | 2da11654ea4d32c5700693675dfbd55c70619519 (diff) |
amd64_edac: assign DRAM chip select base and mask in a family-specific way
Borislav:
- cleanup/fix comments
- fix function return value patterns
- cleanup debug calls
Reviewed-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Doug Thompson <dougthompson@xmission.com>
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers/edac/amd64_edac.c')
-rw-r--r-- | drivers/edac/amd64_edac.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 3d6d0007ed5d..5ec44a440d65 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -871,3 +871,145 @@ err_reg: | |||
871 | debugf0("Error reading F2x%03x.\n", reg); | 871 | debugf0("Error reading F2x%03x.\n", reg); |
872 | } | 872 | } |
873 | 873 | ||
874 | /* | ||
875 | * NOTE: CPU Revision Dependent code: Rev E and Rev F | ||
876 | * | ||
877 | * Set the DCSB and DCSM mask values depending on the CPU revision value. Also | ||
878 | * set the shift factor for the DCSB and DCSM values. | ||
879 | * | ||
880 | * ->dcs_mask_notused, RevE: | ||
881 | * | ||
882 | * To find the max InputAddr for the csrow, start with the base address and set | ||
883 | * all bits that are "don't care" bits in the test at the start of section | ||
884 | * 3.5.4 (p. 84). | ||
885 | * | ||
886 | * The "don't care" bits are all set bits in the mask and all bits in the gaps | ||
887 | * between bit ranges [35:25] and [19:13]. The value REV_E_DCS_NOTUSED_BITS | ||
888 | * represents bits [24:20] and [12:0], which are all bits in the above-mentioned | ||
889 | * gaps. | ||
890 | * | ||
891 | * ->dcs_mask_notused, RevF and later: | ||
892 | * | ||
893 | * To find the max InputAddr for the csrow, start with the base address and set | ||
894 | * all bits that are "don't care" bits in the test at the start of NPT section | ||
895 | * 4.5.4 (p. 87). | ||
896 | * | ||
897 | * The "don't care" bits are all set bits in the mask and all bits in the gaps | ||
898 | * between bit ranges [36:27] and [21:13]. | ||
899 | * | ||
900 | * The value REV_F_F1Xh_DCS_NOTUSED_BITS represents bits [26:22] and [12:0], | ||
901 | * which are all bits in the above-mentioned gaps. | ||
902 | */ | ||
903 | static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt) | ||
904 | { | ||
905 | if (pvt->ext_model >= OPTERON_CPU_REV_F) { | ||
906 | pvt->dcsb_base = REV_F_F1Xh_DCSB_BASE_BITS; | ||
907 | pvt->dcsm_mask = REV_F_F1Xh_DCSM_MASK_BITS; | ||
908 | pvt->dcs_mask_notused = REV_F_F1Xh_DCS_NOTUSED_BITS; | ||
909 | pvt->dcs_shift = REV_F_F1Xh_DCS_SHIFT; | ||
910 | |||
911 | switch (boot_cpu_data.x86) { | ||
912 | case 0xf: | ||
913 | pvt->num_dcsm = REV_F_DCSM_COUNT; | ||
914 | break; | ||
915 | |||
916 | case 0x10: | ||
917 | pvt->num_dcsm = F10_DCSM_COUNT; | ||
918 | break; | ||
919 | |||
920 | case 0x11: | ||
921 | pvt->num_dcsm = F11_DCSM_COUNT; | ||
922 | break; | ||
923 | |||
924 | default: | ||
925 | amd64_printk(KERN_ERR, "Unsupported family!\n"); | ||
926 | break; | ||
927 | } | ||
928 | } else { | ||
929 | pvt->dcsb_base = REV_E_DCSB_BASE_BITS; | ||
930 | pvt->dcsm_mask = REV_E_DCSM_MASK_BITS; | ||
931 | pvt->dcs_mask_notused = REV_E_DCS_NOTUSED_BITS; | ||
932 | pvt->dcs_shift = REV_E_DCS_SHIFT; | ||
933 | pvt->num_dcsm = REV_E_DCSM_COUNT; | ||
934 | } | ||
935 | } | ||
936 | |||
937 | /* | ||
938 | * Function 2 Offset F10_DCSB0; read in the DCS Base and DCS Mask hw registers | ||
939 | */ | ||
940 | static void amd64_read_dct_base_mask(struct amd64_pvt *pvt) | ||
941 | { | ||
942 | int cs, reg, err = 0; | ||
943 | |||
944 | amd64_set_dct_base_and_mask(pvt); | ||
945 | |||
946 | for (cs = 0; cs < CHIPSELECT_COUNT; cs++) { | ||
947 | reg = K8_DCSB0 + (cs * 4); | ||
948 | err = pci_read_config_dword(pvt->dram_f2_ctl, reg, | ||
949 | &pvt->dcsb0[cs]); | ||
950 | if (unlikely(err)) | ||
951 | debugf0("Reading K8_DCSB0[%d] failed\n", cs); | ||
952 | else | ||
953 | debugf0(" DCSB0[%d]=0x%08x reg: F2x%x\n", | ||
954 | cs, pvt->dcsb0[cs], reg); | ||
955 | |||
956 | /* If DCT are NOT ganged, then read in DCT1's base */ | ||
957 | if (boot_cpu_data.x86 >= 0x10 && !dct_ganging_enabled(pvt)) { | ||
958 | reg = F10_DCSB1 + (cs * 4); | ||
959 | err = pci_read_config_dword(pvt->dram_f2_ctl, reg, | ||
960 | &pvt->dcsb1[cs]); | ||
961 | if (unlikely(err)) | ||
962 | debugf0("Reading F10_DCSB1[%d] failed\n", cs); | ||
963 | else | ||
964 | debugf0(" DCSB1[%d]=0x%08x reg: F2x%x\n", | ||
965 | cs, pvt->dcsb1[cs], reg); | ||
966 | } else { | ||
967 | pvt->dcsb1[cs] = 0; | ||
968 | } | ||
969 | } | ||
970 | |||
971 | for (cs = 0; cs < pvt->num_dcsm; cs++) { | ||
972 | reg = K8_DCSB0 + (cs * 4); | ||
973 | err = pci_read_config_dword(pvt->dram_f2_ctl, reg, | ||
974 | &pvt->dcsm0[cs]); | ||
975 | if (unlikely(err)) | ||
976 | debugf0("Reading K8_DCSM0 failed\n"); | ||
977 | else | ||
978 | debugf0(" DCSM0[%d]=0x%08x reg: F2x%x\n", | ||
979 | cs, pvt->dcsm0[cs], reg); | ||
980 | |||
981 | /* If DCT are NOT ganged, then read in DCT1's mask */ | ||
982 | if (boot_cpu_data.x86 >= 0x10 && !dct_ganging_enabled(pvt)) { | ||
983 | reg = F10_DCSM1 + (cs * 4); | ||
984 | err = pci_read_config_dword(pvt->dram_f2_ctl, reg, | ||
985 | &pvt->dcsm1[cs]); | ||
986 | if (unlikely(err)) | ||
987 | debugf0("Reading F10_DCSM1[%d] failed\n", cs); | ||
988 | else | ||
989 | debugf0(" DCSM1[%d]=0x%08x reg: F2x%x\n", | ||
990 | cs, pvt->dcsm1[cs], reg); | ||
991 | } else | ||
992 | pvt->dcsm1[cs] = 0; | ||
993 | } | ||
994 | } | ||
995 | |||
996 | static enum mem_type amd64_determine_memory_type(struct amd64_pvt *pvt) | ||
997 | { | ||
998 | enum mem_type type; | ||
999 | |||
1000 | if (boot_cpu_data.x86 >= 0x10 || pvt->ext_model >= OPTERON_CPU_REV_F) { | ||
1001 | /* Rev F and later */ | ||
1002 | type = (pvt->dclr0 & BIT(16)) ? MEM_DDR2 : MEM_RDDR2; | ||
1003 | } else { | ||
1004 | /* Rev E and earlier */ | ||
1005 | type = (pvt->dclr0 & BIT(18)) ? MEM_DDR : MEM_RDDR; | ||
1006 | } | ||
1007 | |||
1008 | debugf1(" Memory type is: %s\n", | ||
1009 | (type == MEM_DDR2) ? "MEM_DDR2" : | ||
1010 | (type == MEM_RDDR2) ? "MEM_RDDR2" : | ||
1011 | (type == MEM_DDR) ? "MEM_DDR" : "MEM_RDDR"); | ||
1012 | |||
1013 | return type; | ||
1014 | } | ||
1015 | |||