aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2011-01-13 12:02:22 -0500
committerBorislav Petkov <borislav.petkov@amd.com>2011-03-17 09:46:21 -0400
commit614ec9d8532cc6b2f6b471c399daffdfd1c32d03 (patch)
tree3b1df3a950e605047d1fea9a6f3a7598c626cf96 /drivers
parent5d4b58e84a382309dfa4dbe19220cd1f78ffc71f (diff)
amd64_edac: Revamp online spare handling
Replace per-DCT macros with smarter ones, drop hack and look for the spare rank on all chip selects on a channel. Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/edac/amd64_edac.c30
-rw-r--r--drivers/edac/amd64_edac.h6
2 files changed, 15 insertions, 21 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 1cbe9cac6539..4bba43e7ee85 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -393,6 +393,9 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct,
393#define for_each_chip_select(i, dct, pvt) \ 393#define for_each_chip_select(i, dct, pvt) \
394 for (i = 0; i < pvt->csels[dct].b_cnt; i++) 394 for (i = 0; i < pvt->csels[dct].b_cnt; i++)
395 395
396#define chip_select_base(i, dct, pvt) \
397 pvt->csels[dct].csbases[i]
398
396#define for_each_chip_select_mask(i, dct, pvt) \ 399#define for_each_chip_select_mask(i, dct, pvt) \
397 for (i = 0; i < pvt->csels[dct].m_cnt; i++) 400 for (i = 0; i < pvt->csels[dct].m_cnt; i++)
398 401
@@ -1254,30 +1257,23 @@ static u64 f10_get_norm_dct_addr(struct amd64_pvt *pvt, int range,
1254 return (sys_addr & GENMASK(6,47)) - (chan_off & GENMASK(23,47)); 1257 return (sys_addr & GENMASK(6,47)) - (chan_off & GENMASK(23,47));
1255} 1258}
1256 1259
1257/* Hack for the time being - Can we get this from BIOS?? */
1258#define CH0SPARE_RANK 0
1259#define CH1SPARE_RANK 1
1260
1261/* 1260/*
1262 * checks if the csrow passed in is marked as SPARED, if so returns the new 1261 * checks if the csrow passed in is marked as SPARED, if so returns the new
1263 * spare row 1262 * spare row
1264 */ 1263 */
1265static int f10_process_possible_spare(struct amd64_pvt *pvt, u8 dct, int csrow) 1264static int f10_process_possible_spare(struct amd64_pvt *pvt, u8 dct, int csrow)
1266{ 1265{
1267 u32 swap_done; 1266 int tmp_cs;
1268 u32 bad_dram_cs;
1269 1267
1270 /* Depending on channel, isolate respective SPARING info */ 1268 if (online_spare_swap_done(pvt, dct) &&
1271 if (dct) { 1269 csrow == online_spare_bad_dramcs(pvt, dct)) {
1272 swap_done = F10_ONLINE_SPARE_SWAPDONE1(pvt->online_spare); 1270
1273 bad_dram_cs = F10_ONLINE_SPARE_BADDRAM_CS1(pvt->online_spare); 1271 for_each_chip_select(tmp_cs, dct, pvt) {
1274 if (swap_done && (csrow == bad_dram_cs)) 1272 if (chip_select_base(tmp_cs, dct, pvt) & 0x2) {
1275 csrow = CH1SPARE_RANK; 1273 csrow = tmp_cs;
1276 } else { 1274 break;
1277 swap_done = F10_ONLINE_SPARE_SWAPDONE0(pvt->online_spare); 1275 }
1278 bad_dram_cs = F10_ONLINE_SPARE_BADDRAM_CS0(pvt->online_spare); 1276 }
1279 if (swap_done && (csrow == bad_dram_cs))
1280 csrow = CH0SPARE_RANK;
1281 } 1277 }
1282 return csrow; 1278 return csrow;
1283} 1279}
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 85e3acbc087a..3c60b2f2aeb6 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -259,10 +259,8 @@
259#define SCRCTRL 0x58 259#define SCRCTRL 0x58
260 260
261#define F10_ONLINE_SPARE 0xB0 261#define F10_ONLINE_SPARE 0xB0
262#define F10_ONLINE_SPARE_SWAPDONE0(x) ((x) & BIT(1)) 262#define online_spare_swap_done(pvt, c) (((pvt)->online_spare >> (1 + 2 * (c))) & 0x1)
263#define F10_ONLINE_SPARE_SWAPDONE1(x) ((x) & BIT(3)) 263#define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7)
264#define F10_ONLINE_SPARE_BADDRAM_CS0(x) (((x) >> 4) & 0x00000007)
265#define F10_ONLINE_SPARE_BADDRAM_CS1(x) (((x) >> 8) & 0x00000007)
266 264
267#define F10_NB_ARRAY_ADDR 0xB8 265#define F10_NB_ARRAY_ADDR 0xB8
268#define F10_NB_ARRAY_DRAM_ECC BIT(31) 266#define F10_NB_ARRAY_DRAM_ECC BIT(31)