summaryrefslogtreecommitdiffstats
path: root/drivers/edac/i7core_edac.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab2009-06-23 03:48:29 +0200
committerMauro Carvalho Chehab2010-05-10 16:44:46 +0200
commitf122a89222510e8f57e8e0b9b5cdd3ec8863fe4c (patch)
treeae68dd91ff982cabfeb83e11243ada9cb82829f8 /drivers/edac/i7core_edac.c
parenti7core_edac: Registers all supported MC functions (diff)
downloadkernel-qcow2-linux-f122a89222510e8f57e8e0b9b5cdd3ec8863fe4c.tar.gz
kernel-qcow2-linux-f122a89222510e8f57e8e0b9b5cdd3ec8863fe4c.tar.xz
kernel-qcow2-linux-f122a89222510e8f57e8e0b9b5cdd3ec8863fe4c.zip
i7core_edac: Show read/write virtual/physical channel association
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac/i7core_edac.c')
-rw-r--r--drivers/edac/i7core_edac.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 79aa84eaa12d..09a0998e1c3f 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -68,6 +68,10 @@
#define QUAD_RANK_PRESENT (1 << 22)
#define REGISTERED_DIMM (1 << 15)
+#define MC_CHANNEL_MAPPER 0x60
+ #define RDLCH(r, ch) ((((r) >> (3 + (ch * 6))) & 0x07) - 1)
+ #define WRLCH(r, ch) ((((r) >> (ch * 6)) & 0x07) - 1)
+
#define MC_CHANNEL_RANK_PRESENT 0x7c
#define RANK_PRESENT_MASK 0xffff
@@ -100,6 +104,8 @@
#define NUMCOL_MASK 3
#define NUMCOL(x) ((x) & NUMCOL_MASK)
+#define MC_RANK_PRESENT 0x7c
+
#define MC_SAG_CH_0 0x80
#define MC_SAG_CH_1 0x84
#define MC_SAG_CH_2 0x88
@@ -135,6 +141,7 @@ struct i7core_info {
u32 mc_control;
u32 mc_status;
u32 max_dod;
+ u32 ch_map;
};
@@ -289,9 +296,19 @@ static int get_dimm_config(struct mem_ctl_info *mci)
if (!pvt->pci_mcr[0])
return -ENODEV;
- pci_read_config_dword(pvt->pci_mcr[0], MC_CONTROL, &pvt->info.mc_control);
- pci_read_config_dword(pvt->pci_mcr[0], MC_STATUS, &pvt->info.mc_status);
- pci_read_config_dword(pvt->pci_mcr[0], MC_MAX_DOD, &pvt->info.max_dod);
+ /* Device 3 function 0 reads */
+ pci_read_config_dword(pvt->pci_mcr[0], MC_CONTROL,
+ &pvt->info.mc_control);
+ pci_read_config_dword(pvt->pci_mcr[0], MC_STATUS,
+ &pvt->info.mc_status);
+ pci_read_config_dword(pvt->pci_mcr[0], MC_MAX_DOD,
+ &pvt->info.max_dod);
+ pci_read_config_dword(pvt->pci_mcr[0], MC_CHANNEL_MAPPER,
+ &pvt->info.ch_map);
+
+ debugf0("MC control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
+ pvt->info.mc_control, pvt->info.mc_status,
+ pvt->info.max_dod, pvt->info.ch_map);
if (ECC_ENABLED(pvt))
debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt)?8:4);
@@ -318,6 +335,7 @@ static int get_dimm_config(struct mem_ctl_info *mci)
continue;
}
+ /* Devices 4-6 function 0 */
pci_read_config_dword(pvt->pci_ch[i][0],
MC_CHANNEL_DIMM_INIT_PARAMS, &data);
@@ -330,10 +348,13 @@ static int get_dimm_config(struct mem_ctl_info *mci)
else
pvt->channel[i].dimms = 2;
- debugf0("Channel %d (0x%08x): %d ranks, %d dimms "
- "(%sregistered)\n", i, data,
+ debugf0("Ch%d (0x%08x): rd ch %d, wr ch %d, "
+ "%d ranks, %d %cDIMMs\n",
+ i, data,
+ RDLCH(pvt->info.ch_map, i),
+ WRLCH(pvt->info.ch_map, i),
pvt->channel[i].ranks, pvt->channel[i].dimms,
- (data & REGISTERED_DIMM)? "" : "un" );
+ (data & REGISTERED_DIMM)? 'R' : 'U' );
}
return 0;