diff options
author | Borislav Petkov <borislav.petkov@amd.com> | 2011-09-19 17:34:45 +0200 |
---|---|---|
committer | Borislav Petkov <borislav.petkov@amd.com> | 2011-10-06 12:34:05 +0200 |
commit | 73ba85937b2a07b6401ba0b7ca06a112762de9f7 (patch) | |
tree | f4905768cf9cc469b79e92a3c7cf9dec2c6079b1 /drivers | |
parent | b0b07a2bd4fbb6198d4e7142337214eeb77c417a (diff) | |
download | linux-stable-73ba85937b2a07b6401ba0b7ca06a112762de9f7.tar.gz linux-stable-73ba85937b2a07b6401ba0b7ca06a112762de9f7.tar.bz2 linux-stable-73ba85937b2a07b6401ba0b7ca06a112762de9f7.zip |
amd64_edac: Add a fix for Erratum 505
When accessing the scrub rate control register (F3x58) on F15h, the DRAM
controller selector (F1x10C[DctCfgSel]) has to point to DCT0 so that the
scrub rate configuration can take effect. See Erratum 505 in the AMD
F15h revision guide for more details.
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/edac/amd64_edac.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 9bf0b6228529..367756a48ebe 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -114,10 +114,22 @@ static int f10_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func); } +/* + * Select DCT to which PCI cfg accesses are routed + */ +static void f15h_select_dct(struct amd64_pvt *pvt, u8 dct) +{ + u32 reg = 0; + + amd64_read_pci_cfg(pvt->F1, DCT_CFG_SEL, ®); + reg &= 0xfffffffe; + reg |= dct; + amd64_write_pci_cfg(pvt->F1, DCT_CFG_SEL, reg); +} + static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, const char *func) { - u32 reg = 0; u8 dct = 0; if (addr >= 0x140 && addr <= 0x1a0) { @@ -125,10 +137,7 @@ static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, addr -= 0x100; } - amd64_read_pci_cfg(pvt->F1, DCT_CFG_SEL, ®); - reg &= 0xfffffffe; - reg |= dct; - amd64_write_pci_cfg(pvt->F1, DCT_CFG_SEL, reg); + f15h_select_dct(pvt, dct); return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func); } @@ -198,6 +207,10 @@ static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 bw) if (boot_cpu_data.x86 == 0xf) min_scrubrate = 0x0; + /* F15h Erratum #505 */ + if (boot_cpu_data.x86 == 0x15) + f15h_select_dct(pvt, 0); + return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate); } @@ -207,6 +220,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci) u32 scrubval = 0; int i, retval = -EINVAL; + /* F15h Erratum #505 */ + if (boot_cpu_data.x86 == 0x15) + f15h_select_dct(pvt, 0); + amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval); scrubval = scrubval & 0x001F; |