aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorAravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>2013-08-09 12:54:49 -0400
committerBorislav Petkov <bp@suse.de>2013-08-12 10:00:10 -0400
commit18b94f66f9537003cee30d475d79a57c58f1e1d8 (patch)
tree50250574b9e01bfd86b322635b7ef82a89f06538 /drivers/edac
parent7d64ac6422092adbbdaa279ab32f9d4c90a84558 (diff)
amd64_edac: Add ECC decoding support for newer F15h models
On newer models, support has been included for upto 4 DCT's, however, only DCT0 and DCT3 are currently configured (cf BKDG Section 2.10). Also, the routing DRAM Requests algorithm is different for F15h M30h. Thus it is cleaner to use a brand new function rather than adding quirks to the more generic f1x_match_to_this_node(). Refer to "2.10.5 DRAM Routing Requests" in the BKDG for further info. Tested on Fam15h M30h with ECC turned on using mce_amd_inj facility and verified to be functionally correct. While at it, verify if erratum workarounds for E505 and E637 still hold. From email conversations within AMD, the current status of the errata is: * Erratum 505: fixed in model 0x1, stepping 0x1 and later. * Erratum 637: not fixed. Signed-off-by: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com> [ Cleanups, corrections ] Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/amd64_edac.c246
-rw-r--r--drivers/edac/amd64_edac.h58
2 files changed, 270 insertions, 34 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 8b6a0343c220..a5d6348d591f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -123,7 +123,7 @@ static void f15h_select_dct(struct amd64_pvt *pvt, u8 dct)
123 u32 reg = 0; 123 u32 reg = 0;
124 124
125 amd64_read_pci_cfg(pvt->F1, DCT_CFG_SEL, &reg); 125 amd64_read_pci_cfg(pvt->F1, DCT_CFG_SEL, &reg);
126 reg &= 0xfffffffe; 126 reg &= (pvt->model >= 0x30) ? ~3 : ~1;
127 reg |= dct; 127 reg |= dct;
128 amd64_write_pci_cfg(pvt->F1, DCT_CFG_SEL, reg); 128 amd64_write_pci_cfg(pvt->F1, DCT_CFG_SEL, reg);
129} 129}
@@ -133,8 +133,9 @@ static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val,
133{ 133{
134 u8 dct = 0; 134 u8 dct = 0;
135 135
136 /* For F15 M30h, the second dct is DCT 3, refer to BKDG Section 2.10 */
136 if (addr >= 0x140 && addr <= 0x1a0) { 137 if (addr >= 0x140 && addr <= 0x1a0) {
137 dct = 1; 138 dct = (pvt->model >= 0x30) ? 3 : 1;
138 addr -= 0x100; 139 addr -= 0x100;
139 } 140 }
140 141
@@ -205,8 +206,10 @@ static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 bw)
205 if (boot_cpu_data.x86 == 0xf) 206 if (boot_cpu_data.x86 == 0xf)
206 min_scrubrate = 0x0; 207 min_scrubrate = 0x0;
207 208
208 /* F15h Erratum #505 */ 209 /* Erratum #505 for F15h Model 0x00 - Model 0x01, Stepping 0 */
209 if (boot_cpu_data.x86 == 0x15) 210 if (boot_cpu_data.x86 == 0x15 &&
211 boot_cpu_data.x86_model <= 0x01 &&
212 boot_cpu_data.x86_mask < 0x1)
210 f15h_select_dct(pvt, 0); 213 f15h_select_dct(pvt, 0);
211 214
212 return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate); 215 return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate);
@@ -218,8 +221,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci)
218 u32 scrubval = 0; 221 u32 scrubval = 0;
219 int i, retval = -EINVAL; 222 int i, retval = -EINVAL;
220 223
221 /* F15h Erratum #505 */ 224 /* Erratum #505 for F15h Model 0x00 - Model 0x01, Stepping 0 */
222 if (boot_cpu_data.x86 == 0x15) 225 if (boot_cpu_data.x86 == 0x15 &&
226 boot_cpu_data.x86_model <= 0x01 &&
227 boot_cpu_data.x86_mask < 0x1)
223 f15h_select_dct(pvt, 0); 228 f15h_select_dct(pvt, 0);
224 229
225 amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval); 230 amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval);
@@ -335,7 +340,7 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct,
335 u64 csbase, csmask, base_bits, mask_bits; 340 u64 csbase, csmask, base_bits, mask_bits;
336 u8 addr_shift; 341 u8 addr_shift;
337 342
338 if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_F) { 343 if (pvt->fam == 0xf && pvt->ext_model < K8_REV_F) {
339 csbase = pvt->csels[dct].csbases[csrow]; 344 csbase = pvt->csels[dct].csbases[csrow];
340 csmask = pvt->csels[dct].csmasks[csrow]; 345 csmask = pvt->csels[dct].csmasks[csrow];
341 base_bits = GENMASK(21, 31) | GENMASK(9, 15); 346 base_bits = GENMASK(21, 31) | GENMASK(9, 15);
@@ -343,10 +348,11 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct,
343 addr_shift = 4; 348 addr_shift = 4;
344 349
345 /* 350 /*
346 * F16h needs two addr_shift values: 8 for high and 6 for low 351 * F16h and F15h, models 30h and later need two addr_shift values:
347 * (cf. F16h BKDG). 352 * 8 for high and 6 for low (cf. F16h BKDG).
348 */ 353 */
349 } else if (boot_cpu_data.x86 == 0x16) { 354 } else if (pvt->fam == 0x16 ||
355 (pvt->fam == 0x15 && pvt->model >= 0x30)) {
350 csbase = pvt->csels[dct].csbases[csrow]; 356 csbase = pvt->csels[dct].csbases[csrow];
351 csmask = pvt->csels[dct].csmasks[csrow >> 1]; 357 csmask = pvt->csels[dct].csmasks[csrow >> 1];
352 358
@@ -736,13 +742,16 @@ static void dump_misc_regs(struct amd64_pvt *pvt)
736} 742}
737 743
738/* 744/*
739 * see BKDG, F2x[1,0][5C:40], F2[1,0][6C:60] 745 * See BKDG, F2x[1,0][5C:40], F2[1,0][6C:60]
740 */ 746 */
741static void prep_chip_selects(struct amd64_pvt *pvt) 747static void prep_chip_selects(struct amd64_pvt *pvt)
742{ 748{
743 if (boot_cpu_data.x86 == 0xf && pvt->ext_model < K8_REV_F) { 749 if (pvt->fam == 0xf && pvt->ext_model < K8_REV_F) {
744 pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8; 750 pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8;
745 pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 8; 751 pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 8;
752 } else if (pvt->fam == 0x15 && pvt->model >= 0x30) {
753 pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 4;
754 pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 2;
746 } else { 755 } else {
747 pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8; 756 pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8;
748 pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 4; 757 pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 4;
@@ -916,15 +925,15 @@ static struct pci_dev *pci_get_related_function(unsigned int vendor,
916static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) 925static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
917{ 926{
918 struct amd_northbridge *nb; 927 struct amd_northbridge *nb;
919 struct pci_dev *misc, *f1 = NULL; 928 struct pci_dev *f1 = NULL;
920 struct cpuinfo_x86 *c = &boot_cpu_data; 929 unsigned int pci_func;
921 int off = range << 3; 930 int off = range << 3;
922 u32 llim; 931 u32 llim;
923 932
924 amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo); 933 amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo);
925 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo); 934 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo);
926 935
927 if (c->x86 == 0xf) 936 if (pvt->fam == 0xf)
928 return; 937 return;
929 938
930 if (!dram_rw(pvt, range)) 939 if (!dram_rw(pvt, range))
@@ -934,15 +943,17 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
934 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi); 943 amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi);
935 944
936 /* F15h: factor in CC6 save area by reading dst node's limit reg */ 945 /* F15h: factor in CC6 save area by reading dst node's limit reg */
937 if (c->x86 != 0x15) 946 if (pvt->fam != 0x15)
938 return; 947 return;
939 948
940 nb = node_to_amd_nb(dram_dst_node(pvt, range)); 949 nb = node_to_amd_nb(dram_dst_node(pvt, range));
941 if (WARN_ON(!nb)) 950 if (WARN_ON(!nb))
942 return; 951 return;
943 952
944 misc = nb->misc; 953 pci_func = (pvt->model == 0x30) ? PCI_DEVICE_ID_AMD_15H_M30H_NB_F1
945 f1 = pci_get_related_function(misc->vendor, PCI_DEVICE_ID_AMD_15H_NB_F1, misc); 954 : PCI_DEVICE_ID_AMD_15H_NB_F1;
955
956 f1 = pci_get_related_function(nb->misc->vendor, pci_func, nb->misc);
946 if (WARN_ON(!f1)) 957 if (WARN_ON(!f1))
947 return; 958 return;
948 959
@@ -1173,7 +1184,7 @@ static int f15_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
1173} 1184}
1174 1185
1175/* 1186/*
1176 * F16h has only limited cs_modes 1187 * F16h and F15h model 30h have only limited cs_modes.
1177 */ 1188 */
1178static int f16_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, 1189static int f16_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
1179 unsigned cs_mode) 1190 unsigned cs_mode)
@@ -1218,6 +1229,29 @@ static void read_dram_ctl_register(struct amd64_pvt *pvt)
1218} 1229}
1219 1230
1220/* 1231/*
1232 * Determine channel (DCT) based on the interleaving mode (see F15h M30h BKDG,
1233 * 2.10.12 Memory Interleaving Modes).
1234 */
1235static u8 f15_m30h_determine_channel(struct amd64_pvt *pvt, u64 sys_addr,
1236 u8 intlv_en, int num_dcts_intlv,
1237 u32 dct_sel)
1238{
1239 u8 channel = 0;
1240 u8 select;
1241
1242 if (!(intlv_en))
1243 return (u8)(dct_sel);
1244
1245 if (num_dcts_intlv == 2) {
1246 select = (sys_addr >> 8) & 0x3;
1247 channel = select ? 0x3 : 0;
1248 } else if (num_dcts_intlv == 4)
1249 channel = (sys_addr >> 8) & 0x7;
1250
1251 return channel;
1252}
1253
1254/*
1221 * Determine channel (DCT) based on the interleaving mode: F10h BKDG, 2.8.9 Memory 1255 * Determine channel (DCT) based on the interleaving mode: F10h BKDG, 2.8.9 Memory
1222 * Interleaving Modes. 1256 * Interleaving Modes.
1223 */ 1257 */
@@ -1366,6 +1400,10 @@ static int f1x_lookup_addr_in_dct(u64 in_addr, u8 nid, u8 dct)
1366 (in_addr & cs_mask), (cs_base & cs_mask)); 1400 (in_addr & cs_mask), (cs_base & cs_mask));
1367 1401
1368 if ((in_addr & cs_mask) == (cs_base & cs_mask)) { 1402 if ((in_addr & cs_mask) == (cs_base & cs_mask)) {
1403 if (pvt->fam == 0x15 && pvt->model >= 0x30) {
1404 cs_found = csrow;
1405 break;
1406 }
1369 cs_found = f10_process_possible_spare(pvt, dct, csrow); 1407 cs_found = f10_process_possible_spare(pvt, dct, csrow);
1370 1408
1371 edac_dbg(1, " MATCH csrow=%d\n", cs_found); 1409 edac_dbg(1, " MATCH csrow=%d\n", cs_found);
@@ -1492,20 +1530,142 @@ static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range,
1492 return cs_found; 1530 return cs_found;
1493} 1531}
1494 1532
1495static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr, 1533static int f15_m30h_match_to_this_node(struct amd64_pvt *pvt, unsigned range,
1496 int *chan_sel) 1534 u64 sys_addr, int *chan_sel)
1535{
1536 int cs_found = -EINVAL;
1537 int num_dcts_intlv = 0;
1538 u64 chan_addr, chan_offset;
1539 u64 dct_base, dct_limit;
1540 u32 dct_cont_base_reg, dct_cont_limit_reg, tmp;
1541 u8 channel, alias_channel, leg_mmio_hole, dct_sel, dct_offset_en;
1542
1543 u64 dhar_offset = f10_dhar_offset(pvt);
1544 u8 intlv_addr = dct_sel_interleave_addr(pvt);
1545 u8 node_id = dram_dst_node(pvt, range);
1546 u8 intlv_en = dram_intlv_en(pvt, range);
1547
1548 amd64_read_pci_cfg(pvt->F1, DRAM_CONT_BASE, &dct_cont_base_reg);
1549 amd64_read_pci_cfg(pvt->F1, DRAM_CONT_LIMIT, &dct_cont_limit_reg);
1550
1551 dct_offset_en = (u8) ((dct_cont_base_reg >> 3) & BIT(0));
1552 dct_sel = (u8) ((dct_cont_base_reg >> 4) & 0x7);
1553
1554 edac_dbg(1, "(range %d) SystemAddr= 0x%llx Limit=0x%llx\n",
1555 range, sys_addr, get_dram_limit(pvt, range));
1556
1557 if (!(get_dram_base(pvt, range) <= sys_addr) &&
1558 !(get_dram_limit(pvt, range) >= sys_addr))
1559 return -EINVAL;
1560
1561 if (dhar_valid(pvt) &&
1562 dhar_base(pvt) <= sys_addr &&
1563 sys_addr < BIT_64(32)) {
1564 amd64_warn("Huh? Address is in the MMIO hole: 0x%016llx\n",
1565 sys_addr);
1566 return -EINVAL;
1567 }
1568
1569 /* Verify sys_addr is within DCT Range. */
1570 dct_base = (dct_sel_baseaddr(pvt) << 27);
1571 dct_limit = (((dct_cont_limit_reg >> 11) & 0x1FFF) << 27) | 0x7FFFFFF;
1572
1573 if (!(dct_cont_base_reg & BIT(0)) &&
1574 !(dct_base <= sys_addr && dct_limit >= sys_addr))
1575 return -EINVAL;
1576
1577 /* Verify number of dct's that participate in channel interleaving. */
1578 num_dcts_intlv = (int) hweight8(intlv_en);
1579
1580 if (!(num_dcts_intlv % 2 == 0) || (num_dcts_intlv > 4))
1581 return -EINVAL;
1582
1583 channel = f15_m30h_determine_channel(pvt, sys_addr, intlv_en,
1584 num_dcts_intlv, dct_sel);
1585
1586 /* Verify we stay within the MAX number of channels allowed */
1587 if (channel > 4 || channel < 0)
1588 return -EINVAL;
1589
1590 leg_mmio_hole = (u8) (dct_cont_base_reg >> 1 & BIT(0));
1591
1592 /* Get normalized DCT addr */
1593 if (leg_mmio_hole && (sys_addr >= BIT_64(32)))
1594 chan_offset = dhar_offset;
1595 else
1596 chan_offset = dct_base;
1597
1598 chan_addr = sys_addr - chan_offset;
1599
1600 /* remove channel interleave */
1601 if (num_dcts_intlv == 2) {
1602 if (intlv_addr == 0x4)
1603 chan_addr = ((chan_addr >> 9) << 8) |
1604 (chan_addr & 0xff);
1605 else if (intlv_addr == 0x5)
1606 chan_addr = ((chan_addr >> 10) << 9) |
1607 (chan_addr & 0x1ff);
1608 else
1609 return -EINVAL;
1610
1611 } else if (num_dcts_intlv == 4) {
1612 if (intlv_addr == 0x4)
1613 chan_addr = ((chan_addr >> 10) << 8) |
1614 (chan_addr & 0xff);
1615 else if (intlv_addr == 0x5)
1616 chan_addr = ((chan_addr >> 11) << 9) |
1617 (chan_addr & 0x1ff);
1618 else
1619 return -EINVAL;
1620 }
1621
1622 if (dct_offset_en) {
1623 amd64_read_pci_cfg(pvt->F1,
1624 DRAM_CONT_HIGH_OFF + (int) channel * 4,
1625 &tmp);
1626 chan_addr += ((tmp >> 11) & 0xfff) << 27;
1627 }
1628
1629 f15h_select_dct(pvt, channel);
1630
1631 edac_dbg(1, " Normalized DCT addr: 0x%llx\n", chan_addr);
1632
1633 /*
1634 * Find Chip select:
1635 * if channel = 3, then alias it to 1. This is because, in F15 M30h,
1636 * there is support for 4 DCT's, but only 2 are currently functional.
1637 * They are DCT0 and DCT3. But we have read all registers of DCT3 into
1638 * pvt->csels[1]. So we need to use '1' here to get correct info.
1639 * Refer F15 M30h BKDG Section 2.10 and 2.10.3 for clarifications.
1640 */
1641 alias_channel = (channel == 3) ? 1 : channel;
1642
1643 cs_found = f1x_lookup_addr_in_dct(chan_addr, node_id, alias_channel);
1644
1645 if (cs_found >= 0)
1646 *chan_sel = alias_channel;
1647
1648 return cs_found;
1649}
1650
1651static int f1x_translate_sysaddr_to_cs(struct amd64_pvt *pvt,
1652 u64 sys_addr,
1653 int *chan_sel)
1497{ 1654{
1498 int cs_found = -EINVAL; 1655 int cs_found = -EINVAL;
1499 unsigned range; 1656 unsigned range;
1500 1657
1501 for (range = 0; range < DRAM_RANGES; range++) { 1658 for (range = 0; range < DRAM_RANGES; range++) {
1502
1503 if (!dram_rw(pvt, range)) 1659 if (!dram_rw(pvt, range))
1504 continue; 1660 continue;
1505 1661
1506 if ((get_dram_base(pvt, range) <= sys_addr) && 1662 if (pvt->fam == 0x15 && pvt->model >= 0x30)
1507 (get_dram_limit(pvt, range) >= sys_addr)) { 1663 cs_found = f15_m30h_match_to_this_node(pvt, range,
1664 sys_addr,
1665 chan_sel);
1508 1666
1667 else if ((get_dram_base(pvt, range) <= sys_addr) &&
1668 (get_dram_limit(pvt, range) >= sys_addr)) {
1509 cs_found = f1x_match_to_this_node(pvt, range, 1669 cs_found = f1x_match_to_this_node(pvt, range,
1510 sys_addr, chan_sel); 1670 sys_addr, chan_sel);
1511 if (cs_found >= 0) 1671 if (cs_found >= 0)
@@ -1624,6 +1784,17 @@ static struct amd64_family_type amd64_family_types[] = {
1624 .read_dct_pci_cfg = f15_read_dct_pci_cfg, 1784 .read_dct_pci_cfg = f15_read_dct_pci_cfg,
1625 } 1785 }
1626 }, 1786 },
1787 [F15_M30H_CPUS] = {
1788 .ctl_name = "F15h_M30h",
1789 .f1_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F1,
1790 .f3_id = PCI_DEVICE_ID_AMD_15H_M30H_NB_F3,
1791 .ops = {
1792 .early_channel_count = f1x_early_channel_count,
1793 .map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow,
1794 .dbam_to_cs = f16_dbam_to_chip_select,
1795 .read_dct_pci_cfg = f15_read_dct_pci_cfg,
1796 }
1797 },
1627 [F16_CPUS] = { 1798 [F16_CPUS] = {
1628 .ctl_name = "F16h", 1799 .ctl_name = "F16h",
1629 .f1_id = PCI_DEVICE_ID_AMD_16H_NB_F1, 1800 .f1_id = PCI_DEVICE_ID_AMD_16H_NB_F1,
@@ -2387,10 +2558,13 @@ static void setup_mci_misc_attrs(struct mem_ctl_info *mci,
2387 */ 2558 */
2388static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt) 2559static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt)
2389{ 2560{
2390 u8 fam = boot_cpu_data.x86;
2391 struct amd64_family_type *fam_type = NULL; 2561 struct amd64_family_type *fam_type = NULL;
2392 2562
2393 switch (fam) { 2563 pvt->ext_model = boot_cpu_data.x86_model >> 4;
2564 pvt->model = boot_cpu_data.x86_model;
2565 pvt->fam = boot_cpu_data.x86;
2566
2567 switch (pvt->fam) {
2394 case 0xf: 2568 case 0xf:
2395 fam_type = &amd64_family_types[K8_CPUS]; 2569 fam_type = &amd64_family_types[K8_CPUS];
2396 pvt->ops = &amd64_family_types[K8_CPUS].ops; 2570 pvt->ops = &amd64_family_types[K8_CPUS].ops;
@@ -2402,6 +2576,12 @@ static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt)
2402 break; 2576 break;
2403 2577
2404 case 0x15: 2578 case 0x15:
2579 if (pvt->model == 0x30) {
2580 fam_type = &amd64_family_types[F15_M30H_CPUS];
2581 pvt->ops = &amd64_family_types[F15_M30H_CPUS].ops;
2582 break;
2583 }
2584
2405 fam_type = &amd64_family_types[F15_CPUS]; 2585 fam_type = &amd64_family_types[F15_CPUS];
2406 pvt->ops = &amd64_family_types[F15_CPUS].ops; 2586 pvt->ops = &amd64_family_types[F15_CPUS].ops;
2407 break; 2587 break;
@@ -2416,10 +2596,8 @@ static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt)
2416 return NULL; 2596 return NULL;
2417 } 2597 }
2418 2598
2419 pvt->ext_model = boot_cpu_data.x86_model >> 4;
2420
2421 amd64_info("%s %sdetected (node %d).\n", fam_type->ctl_name, 2599 amd64_info("%s %sdetected (node %d).\n", fam_type->ctl_name,
2422 (fam == 0xf ? 2600 (pvt->fam == 0xf ?
2423 (pvt->ext_model >= K8_REV_F ? "revF or later " 2601 (pvt->ext_model >= K8_REV_F ? "revF or later "
2424 : "revE or earlier ") 2602 : "revE or earlier ")
2425 : ""), pvt->mc_node_id); 2603 : ""), pvt->mc_node_id);
@@ -2638,6 +2816,14 @@ static DEFINE_PCI_DEVICE_TABLE(amd64_pci_table) = {
2638 }, 2816 },
2639 { 2817 {
2640 .vendor = PCI_VENDOR_ID_AMD, 2818 .vendor = PCI_VENDOR_ID_AMD,
2819 .device = PCI_DEVICE_ID_AMD_15H_M30H_NB_F2,
2820 .subvendor = PCI_ANY_ID,
2821 .subdevice = PCI_ANY_ID,
2822 .class = 0,
2823 .class_mask = 0,
2824 },
2825 {
2826 .vendor = PCI_VENDOR_ID_AMD,
2641 .device = PCI_DEVICE_ID_AMD_16H_NB_F2, 2827 .device = PCI_DEVICE_ID_AMD_16H_NB_F2,
2642 .subvendor = PCI_ANY_ID, 2828 .subvendor = PCI_ANY_ID,
2643 .subdevice = PCI_ANY_ID, 2829 .subdevice = PCI_ANY_ID,
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 2c6f113bae2b..8fddad7b3b95 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -170,6 +170,8 @@
170/* 170/*
171 * PCI-defined configuration space registers 171 * PCI-defined configuration space registers
172 */ 172 */
173#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F1 0x141b
174#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F2 0x141c
173#define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 175#define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601
174#define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 176#define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602
175#define PCI_DEVICE_ID_AMD_16H_NB_F1 0x1531 177#define PCI_DEVICE_ID_AMD_16H_NB_F1 0x1531
@@ -181,13 +183,22 @@
181#define DRAM_BASE_LO 0x40 183#define DRAM_BASE_LO 0x40
182#define DRAM_LIMIT_LO 0x44 184#define DRAM_LIMIT_LO 0x44
183 185
184#define dram_intlv_en(pvt, i) ((u8)((pvt->ranges[i].base.lo >> 8) & 0x7)) 186/*
187 * F15 M30h D18F1x2[1C:00]
188 */
189#define DRAM_CONT_BASE 0x200
190#define DRAM_CONT_LIMIT 0x204
191
192/*
193 * F15 M30h D18F1x2[4C:40]
194 */
195#define DRAM_CONT_HIGH_OFF 0x240
196
185#define dram_rw(pvt, i) ((u8)(pvt->ranges[i].base.lo & 0x3)) 197#define dram_rw(pvt, i) ((u8)(pvt->ranges[i].base.lo & 0x3))
186#define dram_intlv_sel(pvt, i) ((u8)((pvt->ranges[i].lim.lo >> 8) & 0x7)) 198#define dram_intlv_sel(pvt, i) ((u8)((pvt->ranges[i].lim.lo >> 8) & 0x7))
187#define dram_dst_node(pvt, i) ((u8)(pvt->ranges[i].lim.lo & 0x7)) 199#define dram_dst_node(pvt, i) ((u8)(pvt->ranges[i].lim.lo & 0x7))
188 200
189#define DHAR 0xf0 201#define DHAR 0xf0
190#define dhar_valid(pvt) ((pvt)->dhar & BIT(0))
191#define dhar_mem_hoist_valid(pvt) ((pvt)->dhar & BIT(1)) 202#define dhar_mem_hoist_valid(pvt) ((pvt)->dhar & BIT(1))
192#define dhar_base(pvt) ((pvt)->dhar & 0xff000000) 203#define dhar_base(pvt) ((pvt)->dhar & 0xff000000)
193#define k8_dhar_offset(pvt) (((pvt)->dhar & 0x0000ff00) << 16) 204#define k8_dhar_offset(pvt) (((pvt)->dhar & 0x0000ff00) << 16)
@@ -234,8 +245,6 @@
234#define DDR3_MODE BIT(8) 245#define DDR3_MODE BIT(8)
235 246
236#define DCT_SEL_LO 0x110 247#define DCT_SEL_LO 0x110
237#define dct_sel_baseaddr(pvt) ((pvt)->dct_sel_lo & 0xFFFFF800)
238#define dct_sel_interleave_addr(pvt) (((pvt)->dct_sel_lo >> 6) & 0x3)
239#define dct_high_range_enabled(pvt) ((pvt)->dct_sel_lo & BIT(0)) 248#define dct_high_range_enabled(pvt) ((pvt)->dct_sel_lo & BIT(0))
240#define dct_interleave_enabled(pvt) ((pvt)->dct_sel_lo & BIT(2)) 249#define dct_interleave_enabled(pvt) ((pvt)->dct_sel_lo & BIT(2))
241 250
@@ -297,6 +306,7 @@ enum amd_families {
297 K8_CPUS = 0, 306 K8_CPUS = 0,
298 F10_CPUS, 307 F10_CPUS,
299 F15_CPUS, 308 F15_CPUS,
309 F15_M30H_CPUS,
300 F16_CPUS, 310 F16_CPUS,
301 NUM_FAMILIES, 311 NUM_FAMILIES,
302}; 312};
@@ -337,6 +347,8 @@ struct amd64_pvt {
337 struct pci_dev *F1, *F2, *F3; 347 struct pci_dev *F1, *F2, *F3;
338 348
339 u16 mc_node_id; /* MC index of this MC node */ 349 u16 mc_node_id; /* MC index of this MC node */
350 u8 fam; /* CPU family */
351 u8 model; /* CPU model */
340 int ext_model; /* extended model value of this node */ 352 int ext_model; /* extended model value of this node */
341 int channel_count; 353 int channel_count;
342 354
@@ -414,6 +426,14 @@ static inline u16 extract_syndrome(u64 status)
414 return ((status >> 47) & 0xff) | ((status >> 16) & 0xff00); 426 return ((status >> 47) & 0xff) | ((status >> 16) & 0xff00);
415} 427}
416 428
429static inline u8 dct_sel_interleave_addr(struct amd64_pvt *pvt)
430{
431 if (pvt->fam == 0x15 && pvt->model >= 0x30)
432 return (((pvt->dct_sel_hi >> 9) & 0x1) << 2) |
433 ((pvt->dct_sel_lo >> 6) & 0x3);
434
435 return ((pvt)->dct_sel_lo >> 6) & 0x3;
436}
417/* 437/*
418 * per-node ECC settings descriptor 438 * per-node ECC settings descriptor
419 */ 439 */
@@ -504,3 +524,33 @@ static inline void enable_caches(void *dummy)
504{ 524{
505 write_cr0(read_cr0() & ~X86_CR0_CD); 525 write_cr0(read_cr0() & ~X86_CR0_CD);
506} 526}
527
528static inline u8 dram_intlv_en(struct amd64_pvt *pvt, unsigned int i)
529{
530 if (pvt->fam == 0x15 && pvt->model >= 0x30) {
531 u32 tmp;
532 amd64_read_pci_cfg(pvt->F1, DRAM_CONT_LIMIT, &tmp);
533 return (u8) tmp & 0xF;
534 }
535 return (u8) (pvt->ranges[i].base.lo >> 8) & 0x7;
536}
537
538static inline u8 dhar_valid(struct amd64_pvt *pvt)
539{
540 if (pvt->fam == 0x15 && pvt->model >= 0x30) {
541 u32 tmp;
542 amd64_read_pci_cfg(pvt->F1, DRAM_CONT_BASE, &tmp);
543 return (tmp >> 1) & BIT(0);
544 }
545 return (pvt)->dhar & BIT(0);
546}
547
548static inline u32 dct_sel_baseaddr(struct amd64_pvt *pvt)
549{
550 if (pvt->fam == 0x15 && pvt->model >= 0x30) {
551 u32 tmp;
552 amd64_read_pci_cfg(pvt->F1, DRAM_CONT_BASE, &tmp);
553 return (tmp >> 11) & 0x1FFF;
554 }
555 return (pvt)->dct_sel_lo & 0xFFFFF800;
556}