From 730a043fb6cb4dd3cb5af8f8640365727b598648 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Fri, 16 Oct 2015 13:51:51 -0500 Subject: cpu/amd: Add initial AMD Family 15h support TEST: Booted ASUS KGPE-D16 with single Opteron 6380 * Unbuffered DDR3 DIMMs tested and working * Suspend to RAM (S3) tested and working Change-Id: Idffd2ce36ce183fbfa087e5ba69a9148f084b45e Signed-off-by: Timothy Pearson Reviewed-on: http://review.coreboot.org/11966 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/cpu/amd/family_10h-family_15h/powernow_acpi.c | 50 +++++++++++++++++------ 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'src/cpu/amd/family_10h-family_15h/powernow_acpi.c') diff --git a/src/cpu/amd/family_10h-family_15h/powernow_acpi.c b/src/cpu/amd/family_10h-family_15h/powernow_acpi.c index 295a0bfe96..0c53e86b4a 100644 --- a/src/cpu/amd/family_10h-family_15h/powernow_acpi.c +++ b/src/cpu/amd/family_10h-family_15h/powernow_acpi.c @@ -70,8 +70,7 @@ static void write_pstates_for_core(u8 pstate_num, u16 *pstate_feq, u32 *pstate_p /* Revision C or greater single-link processor */ cpuid1 = cpuid(0x80000008); acpigen_write_PSD_package(0, (cpuid1.ecx & 0xff) + 1, SW_ALL); - } - else { + } else { /* Find the local APIC ID for the specified core ID */ struct device* cpu; int cpu_index = 0; @@ -95,7 +94,9 @@ static void write_pstates_for_core(u8 pstate_num, u16 *pstate_feq, u32 *pstate_p } /* -* For details of this algorithm, please refer to the BDKG 3.62 page 69 +* For details of this algorithm, please refer to: +* Family 10h BDKG 3.62 page 69 +* Family 15h BDKG 3.14 page 74 * * WARNING: The core count algorithm below assumes that all processors * are identical, with the same number of active cores. While the BKDG @@ -145,6 +146,13 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP) uint8_t node_count; uint8_t cores_per_node; uint8_t total_core_count; + uint8_t fam15h; + uint8_t fam10h_rev_e = 0; + + /* Detect Revision E processors via method used in fidvid.c */ + if ((cpuid_edx(0x80000007) & CPB_MASK) + && ((cpuid_ecx(0x80000008) & NC_MASK) == 5)) + fam10h_rev_e = 1; /* * Based on the CPU socket type,cmp_cap and pwr_lmt , get the power limit. @@ -152,11 +160,17 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP) * cmp_cap : 0x0 SingleCore ; 0x1 DualCore ; 0x2 TripleCore ; 0x3 QuadCore ; 0x4 QuintupleCore ; 0x5 HexCore */ printk(BIOS_INFO, "Pstates algorithm ...\n"); + fam15h = !!(mctGetLogicalCPUID(0) & AMD_FAM15_ALL); /* Get number of cores */ - dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xE8); - cmp_cap = (dtemp & 0x3000) >> 12; - if (mctGetLogicalCPUID(0) & AMD_FAM10_REV_D) /* revision D */ - cmp_cap |= (dtemp & 0x8000) >> 13; + if (fam15h) { + cmp_cap = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 5)), 0x84) & 0xff; + } else { + dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xe8); + cmp_cap = (dtemp & 0x3000) >> 12; + if (mctGetLogicalCPUID(0) & (AMD_FAM10_REV_D | AMD_FAM15_ALL)) /* revision D or higher */ + cmp_cap |= (dtemp & 0x8000) >> 13; + } + /* Get number of nodes */ dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 0)), 0x60); node_count = ((dtemp & 0x70) >> 4) + 1; @@ -165,6 +179,14 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP) /* Compute total number of cores installed in system */ total_core_count = cores_per_node * node_count; + /* Get number of boost states */ + uint8_t boost_count = 0; + dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 4)), 0x15c); + if (fam10h_rev_e) + boost_count = (dtemp >> 2) & 0x1; + else if (mctGetLogicalCPUID(0) & AMD_FAM15_ALL) + boost_count = (dtemp >> 2) & 0x7; + Pstate_num = 0; /* See if the CPUID(0x80000007) returned EDX[7]==1b */ @@ -201,7 +223,7 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP) /* Get PSmax's index */ msr = rdmsr(0xC0010061); - Pstate_max = (uint8_t) ((msr.lo >> PS_MAX_VAL_SHFT) & BIT_MASK_3); + Pstate_max = (uint8_t) ((msr.lo >> PS_MAX_VAL_SHFT) & ((fam15h)?BIT_MASK_7:BIT_MASK_3)); /* Determine if all enabled Pstates have the same fidvid */ uint8_t i; @@ -215,10 +237,14 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP) } } + /* Family 15h uses slightly different PSmax numbering */ + if (fam15h) + Pstate_max++; + /* Populate tables with all Pstate information */ for (Pstate_num = 0; Pstate_num < Pstate_max; Pstate_num++) { /* Get power state information */ - msr = rdmsr(0xC0010064 + Pstate_num); + msr = rdmsr(0xC0010064 + Pstate_num + boost_count); cpufid = (msr.lo & 0x3f); cpudid = (msr.lo & 0x1c0) >> 6; cpuvid = (msr.lo & 0xfe00) >> 9; @@ -228,12 +254,10 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP) if (pviModeFlag) { if (cpuvid >= 0x20) { core_voltage = 7625 - (((cpuvid - 0x20) * 10000) / 80); - } - else { + } else { core_voltage = 15500 - ((cpuvid * 10000) / 40); } - } - else { + } else { cpuvid = cpuvid & 0x7f; if (cpuvid >= 0x7c) core_voltage = 0; -- cgit v1.2.3