mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-29 04:45:05 +00:00
sb_edac: make memory type detection per memory controller
Haswell has different register, offset to determine memory type and supports DDR4 in some models. This patch makes it easier to have a different method depending on the memory controller type. 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>
This commit is contained in:
parent
a497c3ba1d
commit
9e37544615
@ -279,8 +279,6 @@ static const u32 correrrthrsld[] = {
|
|||||||
|
|
||||||
#define IB_RANK_CFG_A 0x0320
|
#define IB_RANK_CFG_A 0x0320
|
||||||
|
|
||||||
#define IS_RDIMM_ENABLED(reg) GET_BITFIELD(reg, 11, 11)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sbridge structs
|
* sbridge structs
|
||||||
*/
|
*/
|
||||||
@ -305,6 +303,7 @@ struct sbridge_info {
|
|||||||
const struct interleave_pkg *interleave_pkg;
|
const struct interleave_pkg *interleave_pkg;
|
||||||
u8 max_sad;
|
u8 max_sad;
|
||||||
u8 max_interleave;
|
u8 max_interleave;
|
||||||
|
enum mem_type (*get_memory_type)(struct sbridge_pvt *pvt);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sbridge_channel {
|
struct sbridge_channel {
|
||||||
@ -588,6 +587,25 @@ static u64 ibridge_get_tohm(struct sbridge_pvt *pvt)
|
|||||||
return GET_TOHM(reg);
|
return GET_TOHM(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum mem_type get_memory_type(struct sbridge_pvt *pvt)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
enum mem_type mtype;
|
||||||
|
|
||||||
|
if (pvt->pci_ddrio) {
|
||||||
|
pci_read_config_dword(pvt->pci_ddrio, pvt->info.rankcfgr,
|
||||||
|
®);
|
||||||
|
if (GET_BITFIELD(reg, 11, 11))
|
||||||
|
/* FIXME: Can also be LRDIMM */
|
||||||
|
mtype = MEM_RDDR3;
|
||||||
|
else
|
||||||
|
mtype = MEM_DDR3;
|
||||||
|
} else
|
||||||
|
mtype = MEM_UNKNOWN;
|
||||||
|
|
||||||
|
return mtype;
|
||||||
|
}
|
||||||
|
|
||||||
static inline u8 sad_pkg_socket(u8 pkg)
|
static inline u8 sad_pkg_socket(u8 pkg)
|
||||||
{
|
{
|
||||||
/* on Ivy Bridge, nodeID is SASS, where A is HA and S is node id */
|
/* on Ivy Bridge, nodeID is SASS, where A is HA and S is node id */
|
||||||
@ -698,21 +716,13 @@ static int get_dimm_config(struct mem_ctl_info *mci)
|
|||||||
pvt->is_close_pg = false;
|
pvt->is_close_pg = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pvt->pci_ddrio) {
|
mtype = pvt->info.get_memory_type(pvt);
|
||||||
pci_read_config_dword(pvt->pci_ddrio, pvt->info.rankcfgr,
|
if (mtype == MEM_RDDR3)
|
||||||
®);
|
edac_dbg(0, "Memory is registered\n");
|
||||||
if (IS_RDIMM_ENABLED(reg)) {
|
else if (mtype == MEM_UNKNOWN)
|
||||||
/* FIXME: Can also be LRDIMM */
|
|
||||||
edac_dbg(0, "Memory is registered\n");
|
|
||||||
mtype = MEM_RDDR3;
|
|
||||||
} else {
|
|
||||||
edac_dbg(0, "Memory is unregistered\n");
|
|
||||||
mtype = MEM_DDR3;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
edac_dbg(0, "Cannot determine memory type\n");
|
edac_dbg(0, "Cannot determine memory type\n");
|
||||||
mtype = MEM_UNKNOWN;
|
else
|
||||||
}
|
edac_dbg(0, "Memory is unregistered\n");
|
||||||
|
|
||||||
/* On all supported DDR3 DIMM types, there are 8 banks available */
|
/* On all supported DDR3 DIMM types, there are 8 banks available */
|
||||||
banks = 8;
|
banks = 8;
|
||||||
@ -1976,6 +1986,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
|
|||||||
pvt->info.get_tolm = ibridge_get_tolm;
|
pvt->info.get_tolm = ibridge_get_tolm;
|
||||||
pvt->info.get_tohm = ibridge_get_tohm;
|
pvt->info.get_tohm = ibridge_get_tohm;
|
||||||
pvt->info.dram_rule = ibridge_dram_rule;
|
pvt->info.dram_rule = ibridge_dram_rule;
|
||||||
|
pvt->info.get_memory_type = get_memory_type;
|
||||||
pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
|
pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
|
||||||
pvt->info.interleave_list = ibridge_interleave_list;
|
pvt->info.interleave_list = ibridge_interleave_list;
|
||||||
pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
|
pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
|
||||||
@ -1991,6 +2002,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
|
|||||||
pvt->info.get_tolm = sbridge_get_tolm;
|
pvt->info.get_tolm = sbridge_get_tolm;
|
||||||
pvt->info.get_tohm = sbridge_get_tohm;
|
pvt->info.get_tohm = sbridge_get_tohm;
|
||||||
pvt->info.dram_rule = sbridge_dram_rule;
|
pvt->info.dram_rule = sbridge_dram_rule;
|
||||||
|
pvt->info.get_memory_type = get_memory_type;
|
||||||
pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule);
|
pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule);
|
||||||
pvt->info.interleave_list = sbridge_interleave_list;
|
pvt->info.interleave_list = sbridge_interleave_list;
|
||||||
pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
|
pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
|
||||||
|
Loading…
Reference in New Issue
Block a user