diff options
Diffstat (limited to 'src/northbridge')
-rw-r--r-- | src/northbridge/amd/amdfam10/link_control.c | 81 | ||||
-rw-r--r-- | src/northbridge/amd/amdfam10/northbridge.c | 58 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/AsPsDefs.h | 3 | ||||
-rw-r--r-- | src/northbridge/amd/amdmct/amddefs.h | 66 | ||||
-rw-r--r-- | src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 57 | ||||
-rw-r--r-- | src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c | 8 |
6 files changed, 185 insertions, 88 deletions
diff --git a/src/northbridge/amd/amdfam10/link_control.c b/src/northbridge/amd/amdfam10/link_control.c index 1091ef4f2e..7fa9f12b05 100644 --- a/src/northbridge/amd/amdfam10/link_control.c +++ b/src/northbridge/amd/amdfam10/link_control.c @@ -49,15 +49,94 @@ static inline uint8_t is_fam15h(void) static void nb_control_init(struct device *dev) { + uint8_t enable_c_states; + uint8_t enable_cc6; uint32_t dword; printk(BIOS_DEBUG, "NB: Function 4 Link Control.. "); + /* Configure L3 Power Control */ + dword = pci_read_config32(dev, 0x1c4); + dword |= (0x1 << 8); /* L3PwrSavEn = 1 */ + pci_write_config32(dev, 0x1c4, dword); + if (is_fam15h()) { + /* Configure L3 Control 2 */ + dword = pci_read_config32(dev, 0x1cc); + dword &= ~(0x7 << 6); /* ImplRdProjDelayThresh = 0x2 */ + dword |= (0x2 << 6); + pci_write_config32(dev, 0x1cc, dword); + + /* Configure TDP Accumulator Divisor Control */ + dword = pci_read_config32(dev, 0x104); + dword &= ~(0xfff << 2); /* TdpAccDivRate = 0xc8 */ + dword |= (0xc8 << 2); + dword &= ~0x3; /* TdpAccDivVal = 0x1 */ + dword |= 0x1; + pci_write_config32(dev, 0x104, dword); + + /* Configure Sample and Residency Timers */ + dword = pci_read_config32(dev, 0x110); + dword &= ~0xfff; /* CSampleTimer = 0x1 */ + dword |= 0x1; + pci_write_config32(dev, 0x110, dword); + + /* Configure APM TDP Control */ + dword = pci_read_config32(dev, 0x16c); + dword |= (0x1 << 4); /* ApmTdpLimitIntEn = 1 */ + pci_write_config32(dev, 0x16c, dword); + /* Enable APM */ dword = pci_read_config32(dev, 0x15c); dword |= (0x1 << 7); /* ApmMasterEn = 1 */ pci_write_config32(dev, 0x15c, dword); + + enable_c_states = 0; + enable_cc6 = 0; +#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + uint8_t nvram; + + if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS) + enable_c_states = !!nvram; + + if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS) + enable_cc6 = !!nvram; +#endif + + if (enable_c_states) { + /* Configure C-state Control 1 */ + dword = pci_read_config32(dev, 0x118); + dword |= (0x1 << 24); /* PwrGateEnCstAct1 = 1 */ + dword &= ~(0x7 << 21); /* ClkDivisorCstAct1 = 0x0 */ + dword &= ~(0x3 << 18); /* CacheFlushTmrSelCstAct1 = 0x1 */ + dword |= (0x1 << 18); + dword |= (0x1 << 17); /* CacheFlushEnCstAct1 = 1 */ + dword |= (0x1 << 16); /* CpuPrbEnCstAct1 = 1 */ + dword &= ~(0x1 << 8); /* PwrGateEnCstAct0 = 0 */ + dword &= ~(0x7 << 5); /* ClkDivisorCstAct0 = 0x0 */ + dword &= ~(0x3 << 2); /* CacheFlushTmrSelCstAct0 = 0x2 */ + dword |= (0x2 << 2); + dword |= (0x1 << 1); /* CacheFlushEnCstAct0 = 1 */ + dword |= 0x1; /* CpuPrbEnCstAct0 = 1 */ + pci_write_config32(dev, 0x118, dword); + + /* Configure C-state Control 2 */ + dword = pci_read_config32(dev, 0x11c); + dword &= ~(0x1 << 8); /* PwrGateEnCstAct2 = 0 */ + dword &= ~(0x7 << 5); /* ClkDivisorCstAct2 = 0x0 */ + dword &= ~(0x3 << 2); /* CacheFlushTmrSelCstAct0 = 0x0 */ + dword &= ~(0x1 << 1); /* CacheFlushEnCstAct0 = 0 */ + dword &= ~(0x1); /* CpuPrbEnCstAct0 = 0 */ + pci_write_config32(dev, 0x11c, dword); + + /* Configure C-state Policy Control 1 */ + dword = pci_read_config32(dev, 0x128); + dword &= ~(0x7f << 5); /* CacheFlushTmr = 0x28 */ + dword |= (0x28 << 5); + dword &= ~0x1; /* CoreCstateMode = !enable_cc6 */ + dword |= ((enable_cc6)?0:1); + pci_write_config32(dev, 0x128, dword); + } } printk(BIOS_DEBUG, "done.\n"); @@ -83,4 +162,4 @@ static const struct pci_driver mcf4_driver_fam15 __pci_driver = { .ops = &mcf4_ops, .vendor = PCI_VENDOR_ID_AMD, .device = 0x1604, -};
\ No newline at end of file +}; diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c index 116789ce11..0c1971bbc4 100644 --- a/src/northbridge/amd/amdfam10/northbridge.c +++ b/src/northbridge/amd/amdfam10/northbridge.c @@ -766,53 +766,49 @@ static void amdfam10_domain_read_resources(device_t dev) uint8_t num_nodes; /* Find highest DRAM range (DramLimitAddr) */ + num_nodes = 0; max_node = 0; max_range = -1; interleaved = 0; max_range_limit = 0; - for (range = 0; range < 8; range++) { - dword = f1_read_config32(0x40 + (range * 0x8)); - if (!(dword & 0x3)) - continue; - - if ((dword >> 8) & 0x7) - interleaved = 1; - - dword = f1_read_config32(0x44 + (range * 0x8)); - dword2 = f1_read_config32(0x144 + (range * 0x8)); - qword = ((((uint64_t)dword) >> 16) & 0xffff) << 24; - qword |= (((uint64_t)dword2) & 0xff) << 40; - - if (qword > max_range_limit) { - max_range = range; - max_range_limit = qword; - max_node = dword & 0x7; - } - } - - num_nodes = 0; device_t node_dev; for (node = 0; node < FX_DEVS; node++) { node_dev = get_node_pci(node, 0); /* Test for node presence */ - if ((node_dev) && (pci_read_config32(node_dev, PCI_VENDOR_ID) != 0xffffffff)) - num_nodes++; + if ((!node_dev) || (pci_read_config32(node_dev, PCI_VENDOR_ID) == 0xffffffff)) + continue; + + num_nodes++; + for (range = 0; range < 8; range++) { + dword = pci_read_config32(get_node_pci(node, 1), 0x40 + (range * 0x8)); + if (!(dword & 0x3)) + continue; + + if ((dword >> 8) & 0x7) + interleaved = 1; + + dword = pci_read_config32(get_node_pci(node, 1), 0x44 + (range * 0x8)); + dword2 = pci_read_config32(get_node_pci(node, 1), 0x144 + (range * 0x8)); + qword = 0xffffff; + qword |= ((((uint64_t)dword) >> 16) & 0xffff) << 24; + qword |= (((uint64_t)dword2) & 0xff) << 40; + + if (qword > max_range_limit) { + max_range = range; + max_range_limit = qword; + max_node = dword & 0x7; + } + } } - /* Calculate CC6 sotrage area size */ + /* Calculate CC6 storage area size */ if (interleaved) qword = (0x1000000 * num_nodes); else qword = 0x1000000; /* Reserve the CC6 save segment */ - reserved_ram_resource(dev, 8, max_range_limit >> 10, qword >> 10); - - /* Set up the C-state base address */ - msr_t c_state_addr_msr; - c_state_addr_msr = rdmsr(0xc0010073); - c_state_addr_msr.lo = 0xe0e0; /* CstateAddr = 0xe0e0 */ - wrmsr(0xc0010073, c_state_addr_msr); + reserved_ram_resource(dev, 8, (max_range_limit + 1) >> 10, qword >> 10); } } } diff --git a/src/northbridge/amd/amdht/AsPsDefs.h b/src/northbridge/amd/amdht/AsPsDefs.h index 559c67d990..d4e6a29f42 100644 --- a/src/northbridge/amd/amdht/AsPsDefs.h +++ b/src/northbridge/amd/amdht/AsPsDefs.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. + * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -250,7 +251,7 @@ #define DUAL_PLANE_NB_VID_SHIFT 17/* for CPU rev <= C */ -#define NM_PS_REG 5 /* number of P-state MSR registers */ +#define NM_PS_REG (is_fam15h()?8:5) /* number of P-state MSR registers */ /* sFidVidInit.outFlags defines */ #define PWR_CK_OK 0 /* System board check OK */ diff --git a/src/northbridge/amd/amdmct/amddefs.h b/src/northbridge/amd/amdmct/amddefs.h index 42ad32b1e2..d2dfbccfe9 100644 --- a/src/northbridge/amd/amdmct/amddefs.h +++ b/src/northbridge/amd/amdmct/amddefs.h @@ -49,32 +49,34 @@ /* * Groups - Create as many as you wish, from the above public values */ -#define AMD_NPT_F2 (AMD_NPT_F2C | AMD_NPT_F2D | AMD_NPT_F2E | AMD_NPT_F2G | AMD_NPT_F2J | AMD_NPT_F2K) -#define AMD_NPT_F3 (AMD_NPT_F3L) -#define AMD_NPT_Fx (AMD_NPT_F0 | AMD_NPT_F1 | AMD_NPT_F2 | AMD_NPT_F3) -#define AMD_NPT_Gx (AMD_NPT_G0A | AMD_NPT_G1B) -#define AMD_NPT_ALL (AMD_NPT_Fx | AMD_NPT_Gx) -#define AMD_FINEDELAY (AMD_NPT_F0 | AMD_NPT_F1 | AMD_NPT_F2) -#define AMD_GT_F0 (AMD_NPT_ALL AND NOT AMD_NPT_F0) -#define AMD_DR_Ax (AMD_DR_A0A + AMD_DR_A1B + AMD_DR_A2) -#define AMD_DR_Bx (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_B2 | AMD_DR_B3 | AMD_DR_BA) -#define AMD_DR_LT_B2 (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_BA) -#define AMD_DR_LT_B3 (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_B2 | AMD_DR_BA) -#define AMD_DR_GT_B0 (AMD_DR_ALL & ~(AMD_DR_B0)) -#define AMD_DR_GT_Bx (AMD_DR_ALL & ~(AMD_DR_Ax | AMD_DR_Bx)) -#define AMD_DR_ALL (AMD_DR_Bx) -#define AMD_FAM10_ALL (AMD_DR_ALL | AMD_RB_C2 | AMD_HY_D0 | AMD_DA_C3 | AMD_DA_C2 | AMD_RB_C3 | AMD_HY_D1 | AMD_PH_E0) -#define AMD_FAM10_LT_D (AMD_FAM10_ALL & ~(AMD_HY_D0)) -#define AMD_FAM10_GT_B0 (AMD_FAM10_ALL & ~(AMD_DR_B0)) -#define AMD_FAM10_REV_D (AMD_HY_D0 | AMD_HY_D1) -#define AMD_DA_Cx (AMD_DA_C2 | AMD_DA_C3) -#define AMD_DR_Cx (AMD_RB_C2 | AMD_RB_C3 | AMD_DA_Cx) -#define AMD_FAM10_C3 (AMD_RB_C3 | AMD_DA_C3) -#define AMD_DR_Dx (AMD_HY_D0 | AMD_HY_D1) -#define AMD_DRBH_Cx (AMD_DR_Cx | AMD_HY_D0 ) -#define AMD_DRBA23_RBC2 (AMD_DR_BA | AMD_DR_B2 | AMD_DR_B3 | AMD_RB_C2 ) +#define AMD_NPT_F2 (AMD_NPT_F2C | AMD_NPT_F2D | AMD_NPT_F2E | AMD_NPT_F2G | AMD_NPT_F2J | AMD_NPT_F2K) +#define AMD_NPT_F3 (AMD_NPT_F3L) +#define AMD_NPT_Fx (AMD_NPT_F0 | AMD_NPT_F1 | AMD_NPT_F2 | AMD_NPT_F3) +#define AMD_NPT_Gx (AMD_NPT_G0A | AMD_NPT_G1B) +#define AMD_NPT_ALL (AMD_NPT_Fx | AMD_NPT_Gx) +#define AMD_FINEDELAY (AMD_NPT_F0 | AMD_NPT_F1 | AMD_NPT_F2) +#define AMD_GT_F0 (AMD_NPT_ALL AND NOT AMD_NPT_F0) +#define AMD_DR_Ax (AMD_DR_A0A + AMD_DR_A1B + AMD_DR_A2) +#define AMD_DR_Bx (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_B2 | AMD_DR_B3 | AMD_DR_BA) +#define AMD_DR_Cx (AMD_RB_C2 | AMD_RB_C3 | AMD_DA_Cx) +#define AMD_DR_Dx (AMD_HY_D0 | AMD_HY_D1) +#define AMD_DR_Ex (AMD_PH_E0) +#define AMD_DR_LT_B2 (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_BA) +#define AMD_DR_LT_B3 (AMD_DR_B0 | AMD_DR_B1 | AMD_DR_B2 | AMD_DR_BA) +#define AMD_DR_GT_B0 (AMD_DR_ALL & ~(AMD_DR_B0)) +#define AMD_DR_GT_Bx (AMD_DR_ALL & ~(AMD_DR_Ax | AMD_DR_Bx)) +#define AMD_DR_GT_D0 ((AMD_DR_Dx & ~(AMD_HY_D0)) | AMD_DR_Ex) +#define AMD_DR_ALL (AMD_DR_Bx) +#define AMD_FAM10_ALL (AMD_DR_ALL | AMD_RB_C2 | AMD_HY_D0 | AMD_DA_C3 | AMD_DA_C2 | AMD_RB_C3 | AMD_HY_D1 | AMD_PH_E0) +#define AMD_FAM10_LT_D (AMD_FAM10_ALL & ~(AMD_HY_D0)) +#define AMD_FAM10_GT_B0 (AMD_FAM10_ALL & ~(AMD_DR_B0)) +#define AMD_FAM10_REV_D (AMD_HY_D0 | AMD_HY_D1) +#define AMD_DA_Cx (AMD_DA_C2 | AMD_DA_C3) +#define AMD_FAM10_C3 (AMD_RB_C3 | AMD_DA_C3) +#define AMD_DRBH_Cx (AMD_DR_Cx | AMD_HY_D0 ) +#define AMD_DRBA23_RBC2 (AMD_DR_BA | AMD_DR_B2 | AMD_DR_B3 | AMD_RB_C2 ) #define AMD_DR_DAC2_OR_C3 (AMD_DA_C2 | AMD_DA_C3 | AMD_RB_C3) -#define AMD_FAM15_ALL (AMD_OR_B2 | AMD_OR_C0) +#define AMD_FAM15_ALL (AMD_OR_B2 | AMD_OR_C0) /* * Public Platforms - USE THESE VERSIONS TO MAKE COMPARE WITH CPUPLATFORMTYPE RETURN VALUE @@ -87,9 +89,9 @@ #define AMD_PTYPE_MC 0x020 /* Multi Core (>2) */ #define AMD_PTYPE_UMA 0x040 /* UMA required */ - /* - * Groups - Create as many as you wish, from the above public values - */ +/* + * Groups - Create as many as you wish, from the above public values + */ #define AMD_PTYPE_ALL 0xFFFFFFFF /* A mask for all */ @@ -98,11 +100,11 @@ */ #define HTPHY_LINKTYPE_HT3 0x00000001 #define HTPHY_LINKTYPE_HT1 0x00000002 -#define HTPHY_LINKTYPE_COHERENT 0x00000004 +#define HTPHY_LINKTYPE_COHERENT 0x00000004 #define HTPHY_LINKTYPE_NONCOHERENT 0x00000008 #define HTPHY_LINKTYPE_CONNECTED (HTPHY_LINKTYPE_COHERENT | HTPHY_LINKTYPE_NONCOHERENT) #define HTPHY_LINKTYPE_GANGED 0x00000010 -#define HTPHY_LINKTYPE_UNGANGED 0x00000020 +#define HTPHY_LINKTYPE_UNGANGED 0x00000020 #define HTPHY_LINKTYPE_ALL 0x7FFFFFFF @@ -110,7 +112,7 @@ * CPU HT PHY REGISTERS, FIELDS, AND MASKS */ #define HTPHY_OFFSET_MASK 0xE00001FF -#define HTPHY_WRITE_CMD 0x40000000 +#define HTPHY_WRITE_CMD 0x40000000 #define HTPHY_IS_COMPLETE_MASK 0x80000000 #define HTPHY_DIRECT_MAP 0x20000000 #define HTPHY_DIRECT_OFFSET_MASK 0xE000FFFF @@ -158,4 +160,4 @@ #define AMD_PKGTYPE_S1gX 2 #define AMD_PKGTYPE_G34 3 #define AMD_PKGTYPE_ASB2 4 -#define AMD_PKGTYPE_C32 5 +#define AMD_PKGTYPE_C32 5
\ No newline at end of file diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index 27fa7ae018..1d48070084 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -1203,6 +1203,7 @@ static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat, int8_t max_range; uint8_t max_node; uint64_t max_range_limit; + uint8_t byte; uint32_t dword; uint32_t dword2; uint64_t qword; @@ -1222,7 +1223,8 @@ static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat, dword = Get_NB32(pDCTstat->dev_map, 0x44 + (range * 0x8)); dword2 = Get_NB32(pDCTstat->dev_map, 0x144 + (range * 0x8)); - qword = ((((uint64_t)dword) >> 16) & 0xffff) << 24; + qword = 0xffffff; + qword |= ((((uint64_t)dword) >> 16) & 0xffff) << 24; qword |= (((uint64_t)dword2) & 0xff) << 40; if (qword > max_range_limit) { @@ -1232,26 +1234,35 @@ static void set_up_cc6_storage_fam15(struct MCTStatStruc *pMCTstat, } } - if (pDCTstat->Node_ID == max_node) { - if (max_range >= 0) { - if (interleaved) - /* Move upper limit down by 16M * the number of nodes */ - max_range_limit -= (0x1000000 * num_nodes); - else - /* Move upper limit down by 16M */ - max_range_limit -= 0x1000000; - - /* Store modified range */ - dword = Get_NB32(pDCTstat->dev_map, 0x44 + (range * 0x8)); - dword &= ~(0xffff << 16); /* DramLimit[39:24] = max_range_limit[39:24] */ - dword |= (max_range_limit >> 24) & 0xffff; - Set_NB32(pDCTstat->dev_map, 0x44 + (range * 0x8), dword); - - dword = Get_NB32(pDCTstat->dev_map, 0x144 + (range * 0x8)); - dword &= ~(0xffff << 16); /* DramLimit[47:40] = max_range_limit[47:40] */ - dword |= (max_range_limit >> 40) & 0xff; - Set_NB32(pDCTstat->dev_map, 0x144 + (range * 0x8), dword); - } + if (max_range >= 0) { + if (interleaved) + /* Move upper limit down by 16M * the number of nodes */ + max_range_limit -= (0x1000000 * num_nodes); + else + /* Move upper limit down by 16M */ + max_range_limit -= 0x1000000; + + /* Disable the range */ + dword = Get_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8)); + byte = dword & 0x3; + dword &= ~(0x3); + Set_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8), dword); + + /* Store modified range */ + dword = Get_NB32(pDCTstat->dev_map, 0x44 + (max_range * 0x8)); + dword &= ~(0xffff << 16); /* DramLimit[39:24] = max_range_limit[39:24] */ + dword |= ((max_range_limit >> 24) & 0xffff) << 16; + Set_NB32(pDCTstat->dev_map, 0x44 + (max_range * 0x8), dword); + + dword = Get_NB32(pDCTstat->dev_map, 0x144 + (max_range * 0x8)); + dword &= ~0xff; /* DramLimit[47:40] = max_range_limit[47:40] */ + dword |= (max_range_limit >> 40) & 0xff; + Set_NB32(pDCTstat->dev_map, 0x144 + (max_range * 0x8), dword); + + /* Reenable the range */ + dword = Get_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8)); + dword |= byte; + Set_NB32(pDCTstat->dev_map, 0x40 + (max_range * 0x8), dword); } /* Determine save state destination node */ @@ -1538,8 +1549,8 @@ restartinit: pDCTstat = pDCTstatA + Node; if (pDCTstat->NodePresent) { - lock_dram_config(pMCTstat, pDCTstat); set_cc6_save_enable(pMCTstat, pDCTstat, 1); + lock_dram_config(pMCTstat, pDCTstat); } } } @@ -5118,7 +5129,7 @@ static void mct_HTMemMapExt(struct MCTStatStruc *pMCTstat, /* get base/limit from Node0 */ reg = 0x40 + (Node << 3); /* Node0/Dram Base 0 */ val = Get_NB32(dev, reg); - Drambase = val >> ( 16 + 3); + Drambase = val >> (16 + 3); reg = 0x44 + (Node << 3); /* Node0/Dram Base 0 */ val = Get_NB32(dev, reg); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c index 0a51b1a228..6ab33a3b1e 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c @@ -155,6 +155,14 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) if (MemClrECC) { MCTMemClrSync_D(pMCTstat, pDCTstatA); } + + if (pDCTstat->LogicalCPUID & (AMD_DR_GT_D0 | AMD_FAM15_ALL)) { + /* Set up message triggered C1E */ + val = pci_read_config32(pDCTstat->dev_nbmisc, 0xd4); + val &= ~(0x1 << 15); /* StutterScrubEn = DRAM scrub enabled */ + val |= (mctGet_NVbits(NV_DramBKScrub)?1:0) << 15; + pci_write_config32(pDCTstat->dev_nbmisc, 0xd4, val); + } } /* if Node present */ } |