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; |
