Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 174466
b: refs/heads/master
c: 1433eb9
h: refs/heads/master
v: v3
  • Loading branch information
Borislav Petkov committed Dec 7, 2009
1 parent 84e0987 commit 1731c94
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 121 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d16149e8c378ab7011e600980af51d2477aa5307
refs/heads/master: 1433eb9903408d1801d19a9c49893120874abc12
194 changes: 94 additions & 100 deletions trunk/drivers/edac/amd64_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,48 @@ static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
static struct amd64_pvt *pvt_lookup[EDAC_MAX_NUMNODES];

/*
* See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
* for DDR2 DRAM mapping.
* Address to DRAM bank mapping: see F2x80 for K8 and F2x[1,0]80 for Fam10 and
* later.
*/
u32 revf_quad_ddr2_shift[] = {
0, /* 0000b NULL DIMM (128mb) */
28, /* 0001b 256mb */
29, /* 0010b 512mb */
29, /* 0011b 512mb */
29, /* 0100b 512mb */
30, /* 0101b 1gb */
30, /* 0110b 1gb */
31, /* 0111b 2gb */
31, /* 1000b 2gb */
32, /* 1001b 4gb */
32, /* 1010b 4gb */
33, /* 1011b 8gb */
0, /* 1100b future */
0, /* 1101b future */
0, /* 1110b future */
0 /* 1111b future */
static int ddr2_dbam_revCG[] = {
[0] = 32,
[1] = 64,
[2] = 128,
[3] = 256,
[4] = 512,
[5] = 1024,
[6] = 2048,
};

static int ddr2_dbam_revD[] = {
[0] = 32,
[1] = 64,
[2 ... 3] = 128,
[4] = 256,
[5] = 512,
[6] = 256,
[7] = 512,
[8 ... 9] = 1024,
[10] = 2048,
};

static int ddr2_dbam[] = { [0] = 128,
[1] = 256,
[2 ... 4] = 512,
[5 ... 6] = 1024,
[7 ... 8] = 2048,
[9 ... 10] = 4096,
[11] = 8192,
};

static int ddr3_dbam[] = { [0] = -1,
[1] = 256,
[2] = 512,
[3 ... 4] = -1,
[5 ... 6] = 1024,
[7 ... 8] = 2048,
[9 ... 10] = 4096,
[11] = 8192,
};

/*
Expand Down Expand Up @@ -187,7 +209,7 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
/* Map from a CSROW entry to the mask entry that operates on it */
static inline u32 amd64_map_to_dcs_mask(struct amd64_pvt *pvt, int csrow)
{
if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F)
if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_F)
return csrow;
else
return csrow >> 1;
Expand Down Expand Up @@ -435,7 +457,7 @@ int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
u64 base;

/* only revE and later have the DRAM Hole Address Register */
if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_E) {
if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_E) {
debugf1(" revision %d for node %d does not support DHAR\n",
pvt->ext_model, pvt->mc_node_id);
return 1;
Expand Down Expand Up @@ -795,7 +817,7 @@ static void amd64_cpu_display_info(struct amd64_pvt *pvt)
edac_printk(KERN_DEBUG, EDAC_MC, "F10h CPU detected\n");
else if (boot_cpu_data.x86 == 0xf)
edac_printk(KERN_DEBUG, EDAC_MC, "%s detected\n",
(pvt->ext_model >= OPTERON_CPU_REV_F) ?
(pvt->ext_model >= K8_REV_F) ?
"Rev F or later" : "Rev E or earlier");
else
/* we'll hardly ever ever get here */
Expand All @@ -811,7 +833,7 @@ static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt)
int bit;
enum dev_type edac_cap = EDAC_FLAG_NONE;

bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F)
bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= K8_REV_F)
? 19
: 17;

Expand Down Expand Up @@ -936,7 +958,7 @@ static void amd64_read_dbam_reg(struct amd64_pvt *pvt)
static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt)
{

if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F) {
if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_F) {
pvt->dcsb_base = REV_E_DCSB_BASE_BITS;
pvt->dcsm_mask = REV_E_DCSM_MASK_BITS;
pvt->dcs_mask_notused = REV_E_DCS_NOTUSED_BITS;
Expand Down Expand Up @@ -1009,7 +1031,7 @@ static enum mem_type amd64_determine_memory_type(struct amd64_pvt *pvt)
{
enum mem_type type;

if (boot_cpu_data.x86 >= 0x10 || pvt->ext_model >= OPTERON_CPU_REV_F) {
if (boot_cpu_data.x86 >= 0x10 || pvt->ext_model >= K8_REV_F) {
/* Rev F and later */
type = (pvt->dclr0 & BIT(16)) ? MEM_DDR2 : MEM_RDDR2;
} else {
Expand Down Expand Up @@ -1042,7 +1064,7 @@ static int k8_early_channel_count(struct amd64_pvt *pvt)
if (err)
return err;

if ((boot_cpu_data.x86_model >> 4) >= OPTERON_CPU_REV_F) {
if ((boot_cpu_data.x86_model >> 4) >= K8_REV_F) {
/* RevF (NPT) and later */
flag = pvt->dclr0 & F10_WIDTH_128;
} else {
Expand Down Expand Up @@ -1158,36 +1180,18 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
}
}

/*
* determrine the number of PAGES in for this DIMM's size based on its DRAM
* Address Mapping.
*
* First step is to calc the number of bits to shift a value of 1 left to
* indicate show many pages. Start with the DBAM value as the starting bits,
* then proceed to adjust those shift bits, based on CPU rev and the table.
* See BKDG on the DBAM
*/
static int k8_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map)
static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, int cs_mode)
{
int nr_pages;
int *dbam_map;

if (pvt->ext_model >= OPTERON_CPU_REV_F) {
nr_pages = 1 << (revf_quad_ddr2_shift[dram_map] - PAGE_SHIFT);
} else {
/*
* RevE and less section; this line is tricky. It collapses the
* table used by RevD and later to one that matches revisions CG
* and earlier.
*/
dram_map -= (pvt->ext_model >= OPTERON_CPU_REV_D) ?
(dram_map > 8 ? 4 : (dram_map > 5 ?
3 : (dram_map > 2 ? 1 : 0))) : 0;

/* 25 shift is 32MiB minimum DIMM size in RevE and prior */
nr_pages = 1 << (dram_map + 25 - PAGE_SHIFT);
}
if (pvt->ext_model >= K8_REV_F)
dbam_map = ddr2_dbam;
else if (pvt->ext_model >= K8_REV_D)
dbam_map = ddr2_dbam_revD;
else
dbam_map = ddr2_dbam_revCG;

return nr_pages;
return dbam_map[cs_mode];
}

/*
Expand Down Expand Up @@ -1249,9 +1253,16 @@ static int f10_early_channel_count(struct amd64_pvt *pvt)

}

static int f10_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map)
static int f10_dbam_to_chip_select(struct amd64_pvt *pvt, int cs_mode)
{
return 1 << (revf_quad_ddr2_shift[dram_map] - PAGE_SHIFT);
int *dbam_map;

if (pvt->dchr0 & DDR3_MODE || pvt->dchr1 & DDR3_MODE)
dbam_map = ddr3_dbam;
else
dbam_map = ddr2_dbam;

return dbam_map[cs_mode];
}

/* Enable extended configuration access via 0xCF8 feature */
Expand Down Expand Up @@ -1705,23 +1716,6 @@ static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
}
}

/*
* Input (@index) is the DBAM DIMM value (1 of 4) used as an index into a shift
* table (revf_quad_ddr2_shift) which starts at 128MB DIMM size. Index of 0
* indicates an empty DIMM slot, as reported by Hardware on empty slots.
*
* Normalize to 128MB by subracting 27 bit shift.
*/
static int map_dbam_to_csrow_size(int index)
{
int mega_bytes = 0;

if (index > 0 && index <= DBAM_MAX_VALUE)
mega_bytes = ((128 << (revf_quad_ddr2_shift[index]-27)));

return mega_bytes;
}

/*
* debug routine to display the memory sizes of all logical DIMMs and its
* CSROWs as well
Expand All @@ -1734,7 +1728,7 @@ static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt)

if (boot_cpu_data.x86 == 0xf) {
/* K8 families < revF not supported yet */
if (pvt->ext_model < OPTERON_CPU_REV_F)
if (pvt->ext_model < K8_REV_F)
return;
else
WARN_ON(ctrl != 0);
Expand All @@ -1753,11 +1747,11 @@ static void amd64_debug_display_dimm_sizes(int ctrl, struct amd64_pvt *pvt)

size0 = 0;
if (dcsb[dimm*2] & K8_DCSB_CS_ENABLE)
size0 = map_dbam_to_csrow_size(DBAM_DIMM(dimm, dbam));
size0 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam));

size1 = 0;
if (dcsb[dimm*2 + 1] & K8_DCSB_CS_ENABLE)
size1 = map_dbam_to_csrow_size(DBAM_DIMM(dimm, dbam));
size1 = pvt->ops->dbam_to_cs(pvt, DBAM_DIMM(dimm, dbam));

edac_printk(KERN_DEBUG, EDAC_MC, " %d: %5dMB %d: %5dMB\n",
dimm * 2, size0, dimm * 2 + 1, size1);
Expand All @@ -1780,8 +1774,8 @@ static int f10_probe_valid_hardware(struct amd64_pvt *pvt)
* If we are on a DDR3 machine, we don't know yet if
* we support that properly at this time
*/
if ((pvt->dchr0 & F10_DCHR_Ddr3Mode) ||
(pvt->dchr1 & F10_DCHR_Ddr3Mode)) {
if ((pvt->dchr0 & DDR3_MODE) ||
(pvt->dchr1 & DDR3_MODE)) {

amd64_printk(KERN_WARNING,
"%s() This machine is running with DDR3 memory. "
Expand Down Expand Up @@ -1817,39 +1811,39 @@ static struct amd64_family_type amd64_family_types[] = {
.addr_f1_ctl = PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP,
.misc_f3_ctl = PCI_DEVICE_ID_AMD_K8_NB_MISC,
.ops = {
.early_channel_count = k8_early_channel_count,
.get_error_address = k8_get_error_address,
.read_dram_base_limit = k8_read_dram_base_limit,
.map_sysaddr_to_csrow = k8_map_sysaddr_to_csrow,
.dbam_map_to_pages = k8_dbam_map_to_pages,
.early_channel_count = k8_early_channel_count,
.get_error_address = k8_get_error_address,
.read_dram_base_limit = k8_read_dram_base_limit,
.map_sysaddr_to_csrow = k8_map_sysaddr_to_csrow,
.dbam_to_cs = k8_dbam_to_chip_select,
}
},
[F10_CPUS] = {
.ctl_name = "Family 10h",
.addr_f1_ctl = PCI_DEVICE_ID_AMD_10H_NB_MAP,
.misc_f3_ctl = PCI_DEVICE_ID_AMD_10H_NB_MISC,
.ops = {
.probe_valid_hardware = f10_probe_valid_hardware,
.early_channel_count = f10_early_channel_count,
.get_error_address = f10_get_error_address,
.read_dram_base_limit = f10_read_dram_base_limit,
.read_dram_ctl_register = f10_read_dram_ctl_register,
.map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
.dbam_map_to_pages = f10_dbam_map_to_pages,
.probe_valid_hardware = f10_probe_valid_hardware,
.early_channel_count = f10_early_channel_count,
.get_error_address = f10_get_error_address,
.read_dram_base_limit = f10_read_dram_base_limit,
.read_dram_ctl_register = f10_read_dram_ctl_register,
.map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
.dbam_to_cs = f10_dbam_to_chip_select,
}
},
[F11_CPUS] = {
.ctl_name = "Family 11h",
.addr_f1_ctl = PCI_DEVICE_ID_AMD_11H_NB_MAP,
.misc_f3_ctl = PCI_DEVICE_ID_AMD_11H_NB_MISC,
.ops = {
.probe_valid_hardware = f10_probe_valid_hardware,
.early_channel_count = f10_early_channel_count,
.get_error_address = f10_get_error_address,
.read_dram_base_limit = f10_read_dram_base_limit,
.read_dram_ctl_register = f10_read_dram_ctl_register,
.map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
.dbam_map_to_pages = f10_dbam_map_to_pages,
.probe_valid_hardware = f10_probe_valid_hardware,
.early_channel_count = f10_early_channel_count,
.get_error_address = f10_get_error_address,
.read_dram_base_limit = f10_read_dram_base_limit,
.read_dram_ctl_register = f10_read_dram_ctl_register,
.map_sysaddr_to_csrow = f10_map_sysaddr_to_csrow,
.dbam_to_cs = f10_dbam_to_chip_select,
}
},
};
Expand Down Expand Up @@ -2425,7 +2419,7 @@ static void amd64_read_mc_registers(struct amd64_pvt *pvt)
*/
static u32 amd64_csrow_nr_pages(int csrow_nr, struct amd64_pvt *pvt)
{
u32 dram_map, nr_pages;
u32 cs_mode, nr_pages;

/*
* The math on this doesn't look right on the surface because x/2*4 can
Expand All @@ -2434,17 +2428,17 @@ static u32 amd64_csrow_nr_pages(int csrow_nr, struct amd64_pvt *pvt)
* number of bits to shift the DBAM register to extract the proper CSROW
* field.
*/
dram_map = (pvt->dbam0 >> ((csrow_nr / 2) * 4)) & 0xF;
cs_mode = (pvt->dbam0 >> ((csrow_nr / 2) * 4)) & 0xF;

nr_pages = pvt->ops->dbam_map_to_pages(pvt, dram_map);
nr_pages = pvt->ops->dbam_to_cs(pvt, cs_mode) << (20 - PAGE_SHIFT);

/*
* If dual channel then double the memory size of single channel.
* Channel count is 1 or 2
*/
nr_pages <<= (pvt->channel_count - 1);

debugf0(" (csrow=%d) DBAM map index= %d\n", csrow_nr, dram_map);
debugf0(" (csrow=%d) DBAM map index= %d\n", csrow_nr, cs_mode);
debugf0(" nr_pages= %u channel-count = %d\n",
nr_pages, pvt->channel_count);

Expand Down
Loading

0 comments on commit 1731c94

Please sign in to comment.