diff options
author | Aristeu Rozanski <aris@redhat.com> | 2014-06-02 14:15:24 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-06-26 14:46:29 -0400 |
commit | b976bcf249f4d3b28963e67b5194bc2690da260c (patch) | |
tree | 1e902cc3cd8c6955113d133c211191283d40ac83 | |
parent | f14d6892e4a6086d48fa77ac8e59003d3f4f8e16 (diff) |
sb_edac: make RIR limit retrieval per model
Haswell has a different way to retrieve RIR limits, make this procedure per
model.
Cc: Tony Luck <tony.luck@intel.com>
Signed-off-by: Aristeu Rozanski <aris@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | drivers/edac/sb_edac.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 3335281982dc..c99c595adc2b 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c | |||
@@ -233,7 +233,6 @@ static const u32 rir_way_limit[] = { | |||
233 | 233 | ||
234 | #define IS_RIR_VALID(reg) GET_BITFIELD(reg, 31, 31) | 234 | #define IS_RIR_VALID(reg) GET_BITFIELD(reg, 31, 31) |
235 | #define RIR_WAY(reg) GET_BITFIELD(reg, 28, 29) | 235 | #define RIR_WAY(reg) GET_BITFIELD(reg, 28, 29) |
236 | #define RIR_LIMIT(reg) ((GET_BITFIELD(reg, 1, 10) << 29)| 0x1fffffff) | ||
237 | 236 | ||
238 | #define MAX_RIR_WAY 8 | 237 | #define MAX_RIR_WAY 8 |
239 | 238 | ||
@@ -296,6 +295,7 @@ struct sbridge_info { | |||
296 | u32 rankcfgr; | 295 | u32 rankcfgr; |
297 | u64 (*get_tolm)(struct sbridge_pvt *pvt); | 296 | u64 (*get_tolm)(struct sbridge_pvt *pvt); |
298 | u64 (*get_tohm)(struct sbridge_pvt *pvt); | 297 | u64 (*get_tohm)(struct sbridge_pvt *pvt); |
298 | u64 (*rir_limit)(u32 reg); | ||
299 | const u32 *dram_rule; | 299 | const u32 *dram_rule; |
300 | const u32 *interleave_list; | 300 | const u32 *interleave_list; |
301 | const struct interleave_pkg *interleave_pkg; | 301 | const struct interleave_pkg *interleave_pkg; |
@@ -586,6 +586,11 @@ static u64 ibridge_get_tohm(struct sbridge_pvt *pvt) | |||
586 | return GET_TOHM(reg); | 586 | return GET_TOHM(reg); |
587 | } | 587 | } |
588 | 588 | ||
589 | static u64 rir_limit(u32 reg) | ||
590 | { | ||
591 | return ((u64)GET_BITFIELD(reg, 1, 10) << 29) | 0x1fffffff; | ||
592 | } | ||
593 | |||
589 | static enum mem_type get_memory_type(struct sbridge_pvt *pvt) | 594 | static enum mem_type get_memory_type(struct sbridge_pvt *pvt) |
590 | { | 595 | { |
591 | u32 reg; | 596 | u32 reg; |
@@ -902,7 +907,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci) | |||
902 | if (!IS_RIR_VALID(reg)) | 907 | if (!IS_RIR_VALID(reg)) |
903 | continue; | 908 | continue; |
904 | 909 | ||
905 | tmp_mb = RIR_LIMIT(reg) >> 20; | 910 | tmp_mb = pvt->info.rir_limit(reg) >> 20; |
906 | rir_way = 1 << RIR_WAY(reg); | 911 | rir_way = 1 << RIR_WAY(reg); |
907 | mb = div_u64_rem(tmp_mb, 1000, &kb); | 912 | mb = div_u64_rem(tmp_mb, 1000, &kb); |
908 | edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n", | 913 | edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n", |
@@ -1196,7 +1201,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, | |||
1196 | if (!IS_RIR_VALID(reg)) | 1201 | if (!IS_RIR_VALID(reg)) |
1197 | continue; | 1202 | continue; |
1198 | 1203 | ||
1199 | limit = RIR_LIMIT(reg); | 1204 | limit = pvt->info.rir_limit(reg); |
1200 | mb = div_u64_rem(limit >> 20, 1000, &kb); | 1205 | mb = div_u64_rem(limit >> 20, 1000, &kb); |
1201 | edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n", | 1206 | edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n", |
1202 | n_rir, | 1207 | n_rir, |
@@ -1993,6 +1998,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) | |||
1993 | pvt->info.dram_rule = ibridge_dram_rule; | 1998 | pvt->info.dram_rule = ibridge_dram_rule; |
1994 | pvt->info.get_memory_type = get_memory_type; | 1999 | pvt->info.get_memory_type = get_memory_type; |
1995 | pvt->info.get_node_id = get_node_id; | 2000 | pvt->info.get_node_id = get_node_id; |
2001 | pvt->info.rir_limit = rir_limit; | ||
1996 | pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule); | 2002 | pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule); |
1997 | pvt->info.interleave_list = ibridge_interleave_list; | 2003 | pvt->info.interleave_list = ibridge_interleave_list; |
1998 | pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); | 2004 | pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list); |
@@ -2010,6 +2016,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type) | |||
2010 | pvt->info.dram_rule = sbridge_dram_rule; | 2016 | pvt->info.dram_rule = sbridge_dram_rule; |
2011 | pvt->info.get_memory_type = get_memory_type; | 2017 | pvt->info.get_memory_type = get_memory_type; |
2012 | pvt->info.get_node_id = get_node_id; | 2018 | pvt->info.get_node_id = get_node_id; |
2019 | pvt->info.rir_limit = rir_limit; | ||
2013 | pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule); | 2020 | pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule); |
2014 | pvt->info.interleave_list = sbridge_interleave_list; | 2021 | pvt->info.interleave_list = sbridge_interleave_list; |
2015 | pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list); | 2022 | pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list); |