diff options
author | Aristeu Rozanski <arozansk@redhat.com> | 2013-10-30 12:27:02 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-11-14 13:49:04 -0500 |
commit | cc311991a7ac68b60df1bb5ec26e4978cf66f6b0 (patch) | |
tree | a55d8e896a5f03db02032273fd39817e0528fcb4 | |
parent | ef1ce51e7b35c0785b2bb1b03f4202de4a702a43 (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>
-rw-r--r-- | drivers/edac/sb_edac.c | 66 |
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) | 115 | struct 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) | 120 | static 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 }, | |
124 | static 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 | |||
131 | static 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 | ®); | 693 | ®); |
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 | ®); | 868 | ®); |
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; |