aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/sb_edac.c
diff options
context:
space:
mode:
authorAristeu Rozanski <arozansk@redhat.com>2013-10-30 12:27:02 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-11-14 13:49:04 -0500
commitcc311991a7ac68b60df1bb5ec26e4978cf66f6b0 (patch)
treea55d8e896a5f03db02032273fd39817e0528fcb4 /drivers/edac/sb_edac.c
parentef1ce51e7b35c0785b2bb1b03f4202de4a702a43 (diff)
sb_edac: rework sad_pkg
This is in preparation for Ivy Bridge support Signed-off-by: Aristeu Rozanski <arozansk@redhat.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/edac/sb_edac.c')
-rw-r--r--drivers/edac/sb_edac.c66
1 files changed, 30 insertions, 36 deletions
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 82318d4062a7..718f623f010f 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -112,37 +112,27 @@ static const u32 sbridge_interleave_list[] = {
112 0xac, 0xb4, 0xbc, 0xc4, 0xcc, 112 0xac, 0xb4, 0xbc, 0xc4, 0xcc,
113}; 113};
114 114
115#define SAD_PKG0(reg) GET_BITFIELD(reg, 0, 2) 115struct interleave_pkg {
116#define SAD_PKG1(reg) GET_BITFIELD(reg, 3, 5) 116 unsigned char start;
117#define SAD_PKG2(reg) GET_BITFIELD(reg, 8, 10) 117 unsigned char end;
118#define SAD_PKG3(reg) GET_BITFIELD(reg, 11, 13) 118};
119#define SAD_PKG4(reg) GET_BITFIELD(reg, 16, 18) 119
120#define SAD_PKG5(reg) GET_BITFIELD(reg, 19, 21) 120static const struct interleave_pkg sbridge_interleave_pkg[] = {
121#define SAD_PKG6(reg) GET_BITFIELD(reg, 24, 26) 121 { 0, 2 },
122#define SAD_PKG7(reg) GET_BITFIELD(reg, 27, 29) 122 { 3, 5 },
123 123 { 8, 10 },
124static inline int sad_pkg(u32 reg, int interleave) 124 { 11, 13 },
125 { 16, 18 },
126 { 19, 21 },
127 { 24, 26 },
128 { 27, 29 },
129};
130
131static inline int sad_pkg(const struct interleave_pkg *table, u32 reg,
132 int interleave)
125{ 133{
126 switch (interleave) { 134 return GET_BITFIELD(reg, table[interleave].start,
127 case 0: 135 table[interleave].end);
128 return SAD_PKG0(reg);
129 case 1:
130 return SAD_PKG1(reg);
131 case 2:
132 return SAD_PKG2(reg);
133 case 3:
134 return SAD_PKG3(reg);
135 case 4:
136 return SAD_PKG4(reg);
137 case 5:
138 return SAD_PKG5(reg);
139 case 6:
140 return SAD_PKG6(reg);
141 case 7:
142 return SAD_PKG7(reg);
143 default:
144 return -EINVAL;
145 }
146} 136}
147 137
148/* Devices 12 Function 7 */ 138/* Devices 12 Function 7 */
@@ -279,6 +269,7 @@ struct sbridge_info {
279 u64 (*get_tohm)(struct sbridge_pvt *pvt); 269 u64 (*get_tohm)(struct sbridge_pvt *pvt);
280 const u32 *dram_rule; 270 const u32 *dram_rule;
281 const u32 *interleave_list; 271 const u32 *interleave_list;
272 const struct interleave_pkg *interleave_pkg;
282 u8 max_sad; 273 u8 max_sad;
283 u8 max_interleave; 274 u8 max_interleave;
284}; 275};
@@ -700,13 +691,14 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
700 691
701 pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[n_sads], 692 pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[n_sads],
702 &reg); 693 &reg);
703 sad_interl = sad_pkg(reg, 0); 694 sad_interl = sad_pkg(pvt->info.interleave_pkg, reg, 0);
704 for (j = 0; j < 8; j++) { 695 for (j = 0; j < 8; j++) {
705 if (j > 0 && sad_interl == sad_pkg(reg, j)) 696 u32 pkg = sad_pkg(pvt->info.interleave_pkg, reg, j);
697 if (j > 0 && sad_interl == pkg)
706 break; 698 break;
707 699
708 edac_dbg(0, "SAD#%d, interleave #%d: %d\n", 700 edac_dbg(0, "SAD#%d, interleave #%d: %d\n",
709 n_sads, j, sad_pkg(reg, j)); 701 n_sads, j, pkg);
710 } 702 }
711 } 703 }
712 704
@@ -874,11 +866,12 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
874 866
875 pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[n_sads], 867 pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[n_sads],
876 &reg); 868 &reg);
877 sad_interl = sad_pkg(reg, 0); 869 sad_interl = sad_pkg(pvt->info.interleave_pkg, reg, 0);
878 for (sad_way = 0; sad_way < 8; sad_way++) { 870 for (sad_way = 0; sad_way < 8; sad_way++) {
879 if (sad_way > 0 && sad_interl == sad_pkg(reg, sad_way)) 871 u32 pkg = sad_pkg(pvt->info.interleave_pkg, reg, sad_way);
872 if (sad_way > 0 && sad_interl == pkg)
880 break; 873 break;
881 sad_interleave[sad_way] = sad_pkg(reg, sad_way); 874 sad_interleave[sad_way] = pkg;
882 edac_dbg(0, "SAD interleave #%d: %d\n", 875 edac_dbg(0, "SAD interleave #%d: %d\n",
883 sad_way, sad_interleave[sad_way]); 876 sad_way, sad_interleave[sad_way]);
884 } 877 }
@@ -1684,6 +1677,7 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev)
1684 pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule); 1677 pvt->info.max_sad = ARRAY_SIZE(sbridge_dram_rule);
1685 pvt->info.interleave_list = sbridge_interleave_list; 1678 pvt->info.interleave_list = sbridge_interleave_list;
1686 pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list); 1679 pvt->info.max_interleave = ARRAY_SIZE(sbridge_interleave_list);
1680 pvt->info.interleave_pkg = sbridge_interleave_pkg;
1687 1681
1688 /* Set the function pointer to an actual operation function */ 1682 /* Set the function pointer to an actual operation function */
1689 mci->edac_check = sbridge_check_error; 1683 mci->edac_check = sbridge_check_error;