aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/amd/family_10h-family_15h/fidvid.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/amd/family_10h-family_15h/fidvid.c')
-rw-r--r--src/cpu/amd/family_10h-family_15h/fidvid.c237
1 files changed, 139 insertions, 98 deletions
diff --git a/src/cpu/amd/family_10h-family_15h/fidvid.c b/src/cpu/amd/family_10h-family_15h/fidvid.c
index 3fac165f52..5eb7980514 100644
--- a/src/cpu/amd/family_10h-family_15h/fidvid.c
+++ b/src/cpu/amd/family_10h-family_15h/fidvid.c
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2007 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
@@ -39,7 +40,7 @@ Fam10 Bios and Kernel Development Guide #31116, rev 3.48, April 22, 2010
3.- 2.4.2.7 dualPlaneOnly(dev)
-4.- 2.4.2.8 applyBoostFIDOffset(dev)
+4.- 2.4.2.8 applyBoostFIDOffset(dev, nodeid)
5.- enableNbPState1(dev)
@@ -138,25 +139,33 @@ static void enable_fid_change(u8 fid)
}
}
-static void applyBoostFIDOffset( device_t dev ) {
- // BKDG 2.4.2.8
- // revision E only, but E is apparently not supported yet, therefore untested
- if ((cpuid_edx(0x80000007) & CPB_MASK)
- && ((cpuid_ecx(0x80000008) & NC_MASK) ==5) ) {
- u32 core = get_node_core_id_x().coreid;
- u32 asymetricBoostThisCore = ((pci_read_config32(dev, 0x10C) >> (core*2))) & 3;
- msr_t msr = rdmsr(PS_REG_BASE);
- u32 cpuFid = msr.lo & PS_CPU_FID_MASK;
- cpuFid = cpuFid + asymetricBoostThisCore;
- msr.lo &= ~PS_CPU_FID_MASK;
- msr.lo |= cpuFid ;
- wrmsr(PS_REG_BASE , msr);
-
- }
+static void applyBoostFIDOffset(device_t dev, uint32_t nodeid) {
+ // BKDG 2.4.2.8
+ // Fam10h revision E only, but E is apparently not supported yet, therefore untested
+ if ((cpuid_edx(0x80000007) & CPB_MASK)
+ && ((cpuid_ecx(0x80000008) & NC_MASK) == 5) ) {
+ u32 core = get_node_core_id_x().coreid;
+ u32 asymetricBoostThisCore = ((pci_read_config32(dev, 0x10C) >> (core*2))) & 3;
+ msr_t msr = rdmsr(PS_REG_BASE);
+ u32 cpuFid = msr.lo & PS_CPU_FID_MASK;
+ cpuFid = cpuFid + asymetricBoostThisCore;
+ msr.lo &= ~PS_CPU_FID_MASK;
+ msr.lo |= cpuFid ;
+ wrmsr(PS_REG_BASE , msr);
+ } else if (is_fam15h()) {
+ uint32_t dword = pci_read_config32(NODE_PCI(nodeid, 4), 0x15c);
+ uint8_t boost_count = (dword >> 2) & 0x7;
+ if (boost_count > 0) {
+ /* Enable boost */
+ dword &= ~0x3;
+ dword |= 0x1;
+ pci_write_config32(NODE_PCI(nodeid, 4), 0x15c, dword);
+ }
+ }
}
static void enableNbPState1( device_t dev ) {
- u32 cpuRev = mctGetLogicalCPUID(0xFF);
+ uint64_t cpuRev = mctGetLogicalCPUID(0xFF);
if (cpuRev & AMD_FAM10_C3) {
u32 nbPState = (pci_read_config32(dev, 0x1F0) & NB_PSTATE_MASK);
if ( nbPState){
@@ -198,7 +207,7 @@ static u8 setPStateMaxVal( device_t dev ) {
static void dualPlaneOnly( device_t dev ) {
// BKDG 2.4.2.7
- u32 cpuRev = mctGetLogicalCPUID(0xFF);
+ uint64_t cpuRev = mctGetLogicalCPUID(0xFF);
if ((mctGetProcessorPackageType() == AMD_PKGTYPE_AM3_2r2)
&& (cpuRev & AMD_DR_Cx)) { // should be rev C or rev E but there's no constant for E
if ( (pci_read_config32(dev, 0x1FC) & DUAL_PLANE_ONLY_MASK)
@@ -278,12 +287,16 @@ static void recalculateVsSlamTimeSettingOnCorePre(device_t dev)
*/
/* Determine if this is a PVI or SVI system */
- dtemp = pci_read_config32(dev, 0xA0);
-
- if (dtemp & PVI_MODE)
- pviModeFlag = 1;
- else
+ if (is_fam15h()) {
pviModeFlag = 0;
+ } else {
+ dtemp = pci_read_config32(dev, 0xa0);
+
+ if (dtemp & PVI_MODE)
+ pviModeFlag = 1;
+ else
+ pviModeFlag = 0;
+ }
/* Get P0's voltage */
/* MSRC001_00[68:64] are not programmed yet when called from
@@ -510,59 +523,67 @@ static void config_nb_syn_ptr_adj(device_t dev, u32 cpuRev) {
}
static void config_acpi_pwr_state_ctrl_regs(device_t dev, u32 cpuRev, u8 procPkg) {
- /* step 1, chapter 2.4.2.6 of AMD Fam 10 BKDG #31116 Rev 3.48 22.4.2010 */
- u32 dword;
- u32 c1= 1;
- if (cpuRev & (AMD_DR_Bx)) {
- // will coreboot ever enable cache scrubbing ?
- // if it does, will it be enough to check the current state
- // or should we configure for what we'll set up later ?
- dword = pci_read_config32(dev, 0x58);
- u32 scrubbingCache = dword &
- ( (0x1F << 16) // DCacheScrub
- | (0x1F << 8) ); // L2Scrub
- if (scrubbingCache) {
- c1 = 0x80;
- } else {
- c1 = 0xA0;
- }
- } else { // rev C or later
- // same doubt as cache scrubbing: ok to check current state ?
- dword = pci_read_config32(dev, 0xDC);
- u32 cacheFlushOnHalt = dword & (7 << 16);
- if (!cacheFlushOnHalt) {
- c1 = 0x80;
- }
- }
- dword = (c1 << 24) | (0xE641E6);
- pci_write_config32(dev, 0x84, dword);
-
-
- /* FIXME: BKDG Table 100 says if the link is at a Gen1
-frequency and the chipset does not support a 10us minimum LDTSTOP
-assertion time, then { If ASB2 && SVI then smaf001 = F6h else
-smaf001=87h. } else ... I hardly know what it means or how to check
-it from here, so I bluntly assume it is false and code here the else,
-which is easier */
-
- u32 smaf001 = 0xE6;
- if (cpuRev & AMD_DR_Bx ) {
- smaf001 = 0xA6;
- } else {
- #if CONFIG_SVI_HIGH_FREQ
- if (cpuRev & (AMD_RB_C3 | AMD_DA_C3)) {
- smaf001 = 0xF6;
- }
- #endif
- }
- u32 fidvidChange = 0;
- if (((cpuRev & AMD_DA_Cx) && (procPkg & AMD_PKGTYPE_S1gX))
- || (cpuRev & AMD_RB_C3) ) {
- fidvidChange=0x0B;
- }
- dword = (0xE6 << 24) | (fidvidChange << 16)
- | (smaf001 << 8) | 0x81;
- pci_write_config32(dev, 0x80, dword);
+ if (is_fam15h()) {
+ /* Family 15h BKDG Rev. 3.14 D18F3x80 recommended settings */
+ pci_write_config32(dev, 0x80, 0xe20be281);
+
+ /* Family 15h BKDG Rev. 3.14 D18F3x84 recommended settings */
+ pci_write_config32(dev, 0x84, 0x01e200e2);
+ } else {
+ /* step 1, chapter 2.4.2.6 of AMD Fam 10 BKDG #31116 Rev 3.48 22.4.2010 */
+ u32 dword;
+ u32 c1= 1;
+ if (cpuRev & (AMD_DR_Bx)) {
+ // will coreboot ever enable cache scrubbing ?
+ // if it does, will it be enough to check the current state
+ // or should we configure for what we'll set up later ?
+ dword = pci_read_config32(dev, 0x58);
+ u32 scrubbingCache = dword &
+ ( (0x1F << 16) // DCacheScrub
+ | (0x1F << 8) ); // L2Scrub
+ if (scrubbingCache) {
+ c1 = 0x80;
+ } else {
+ c1 = 0xA0;
+ }
+ } else { // rev C or later
+ // same doubt as cache scrubbing: ok to check current state ?
+ dword = pci_read_config32(dev, 0xDC);
+ u32 cacheFlushOnHalt = dword & (7 << 16);
+ if (!cacheFlushOnHalt) {
+ c1 = 0x80;
+ }
+ }
+ dword = (c1 << 24) | (0xE641E6);
+ pci_write_config32(dev, 0x84, dword);
+
+ /* FIXME: BKDG Table 100 says if the link is at a Gen1
+ * frequency and the chipset does not support a 10us minimum LDTSTOP
+ * assertion time, then { If ASB2 && SVI then smaf001 = F6h else
+ * smaf001=87h. } else ... I hardly know what it means or how to check
+ * it from here, so I bluntly assume it is false and code here the else,
+ * which is easier
+ */
+
+ u32 smaf001 = 0xE6;
+ if (cpuRev & AMD_DR_Bx ) {
+ smaf001 = 0xA6;
+ } else {
+ #if CONFIG_SVI_HIGH_FREQ
+ if (cpuRev & (AMD_RB_C3 | AMD_DA_C3)) {
+ smaf001 = 0xF6;
+ }
+ #endif
+ }
+ u32 fidvidChange = 0;
+ if (((cpuRev & AMD_DA_Cx) && (procPkg & AMD_PKGTYPE_S1gX))
+ || (cpuRev & AMD_RB_C3) ) {
+ fidvidChange=0x0B;
+ }
+ dword = (0xE6 << 24) | (fidvidChange << 16)
+ | (smaf001 << 8) | 0x81;
+ pci_write_config32(dev, 0x80, dword);
+ }
}
static void prep_fid_change(void)
@@ -579,7 +600,7 @@ static void prep_fid_change(void)
for (i = 0; i < nodes; i++) {
printk(BIOS_DEBUG, "Prep FID/VID Node:%02x\n", i);
dev = NODE_PCI(i, 3);
- u32 cpuRev = mctGetLogicalCPUID(0xFF) ;
+ uint64_t cpuRev = mctGetLogicalCPUID(0xFF) ;
u8 procPkg = mctGetProcessorPackageType();
setVSRamp(dev);
@@ -607,7 +628,7 @@ static void prep_fid_change(void)
}
}
-static void waitCurrentPstate(u32 target_pstate){
+static void waitCurrentPstate(u32 target_pstate) {
msr_t initial_msr = rdmsr(TSC_MSR);
msr_t pstate_msr = rdmsr(CUR_PSTATE_MSR);
msr_t tsc_msr;
@@ -640,7 +661,7 @@ static void waitCurrentPstate(u32 target_pstate){
if (pstate_msr.lo != target_pstate) {
msr_t limit_msr = rdmsr(0xc0010061);
- printk(BIOS_ERR, "*** Time out waiting for P-state %01x. Current P-state %01x P-state current limit MSRC001_0061=%02x\n", target_pstate, pstate_msr.lo, limit_msr.lo);
+ printk(BIOS_ERR, "*** Time out waiting for P-state %01x. Current P-state %01x P-state current limit MSRC001_0061=%08x %08x\n", target_pstate, pstate_msr.lo, limit_msr.hi, limit_msr.lo);
do { // should we just go on instead ?
pstate_msr = rdmsr(CUR_PSTATE_MSR);
@@ -650,6 +671,7 @@ static void waitCurrentPstate(u32 target_pstate){
static void set_pstate(u32 nonBoostedPState) {
msr_t msr;
+ uint8_t skip_wait;
// Transition P0 for calling core.
msr = rdmsr(0xC0010062);
@@ -657,12 +679,21 @@ static void set_pstate(u32 nonBoostedPState) {
msr.lo = nonBoostedPState;
wrmsr(0xC0010062, msr);
- /* Wait for P0 to set. */
- waitCurrentPstate(nonBoostedPState);
-}
-
-
+ if (is_fam15h()) {
+ /* Do not wait for the first (even) set of cores to transition on Family 15h systems */
+ if ((cpuid_ebx(0x00000001) & 0x01000000))
+ skip_wait = 0;
+ else
+ skip_wait = 1;
+ } else {
+ skip_wait = 0;
+ }
+ if (!skip_wait) {
+ /* Wait for core to transition to P0 */
+ waitCurrentPstate(nonBoostedPState);
+ }
+}
static void UpdateSinglePlaneNbVid(void)
{
@@ -752,11 +783,14 @@ static u32 needs_NB_COF_VID_update(void)
u8 nodes;
u8 i;
+ if (is_fam15h())
+ return 0;
+
/* If any node has nb_cof_vid_update set all nodes need an update. */
nodes = get_nodes();
nb_cof_vid_update = 0;
for (i = 0; i < nodes; i++) {
- u32 cpuRev = mctGetLogicalCPUID(i) ;
+ uint64_t cpuRev = mctGetLogicalCPUID(i);
u32 nbCofVidUpdateDefined = (cpuRev & (AMD_FAM10_LT_D));
if (nbCofVidUpdateDefined
&& (pci_read_config32(NODE_PCI(i, 3), 0x1FC)
@@ -780,9 +814,11 @@ static u32 init_fidvid_core(u32 nodeid, u32 coreid)
/* Steps 1-6 of BIOS NB COF and VID Configuration
* for SVI and Single-Plane PVI Systems. BKDG 2.4.2.9 #31116 rev 3.48
*/
-
dev = NODE_PCI(nodeid, 3);
- pvimode = pci_read_config32(dev, PW_CTL_MISC) & PVI_MODE;
+ if (is_fam15h())
+ pvimode = 0;
+ else
+ pvimode = pci_read_config32(dev, PW_CTL_MISC) & PVI_MODE;
reg1fc = pci_read_config32(dev, 0x1FC);
if (nb_cof_vid_update) {
@@ -794,7 +830,7 @@ static u32 init_fidvid_core(u32 nodeid, u32 coreid)
fid_max = fid_max + ((reg1fc & DUAL_PLANE_NB_FID_OFF_MASK ) >> DUAL_PLANE_NB_FID_SHIFT );
}
/* write newNbVid to P-state Reg's NbVid always if NbVidUpdatedAll=1 */
- fixPsNbVidBeforeWR(vid_max, coreid,dev,pvimode);
+ fixPsNbVidBeforeWR(vid_max, coreid, dev, pvimode);
/* fid setup is handled by the BSP at the end. */
@@ -814,7 +850,7 @@ static void init_fidvid_ap(u32 apicid, u32 nodeid, u32 coreid)
printk(BIOS_DEBUG, "FIDVID on AP: %02x\n", apicid);
- send = init_fidvid_core(nodeid,coreid);
+ send = init_fidvid_core(nodeid, coreid);
send |= (apicid << 24); // ap apicid
// Send signal to BSP about this AP max fid
@@ -856,7 +892,8 @@ static void init_fidvid_bsp_stage1(u32 ap_apicid, void *gp)
while (--loop > 0) {
if (lapic_remote_read(ap_apicid, LAPIC_MSG_REG, &readback) != 0)
continue;
- if ((readback & 0x3f) == F10_APSTATE_RESET) {
+ if (((readback & 0x3f) == F10_APSTATE_RESET)
+ || (is_fam15h() && ((readback & 0x3f) == F10_APSTATE_ASLEEP))) {
timeout = 0;
break; /* target ap is in stage 1 */
}
@@ -944,7 +981,10 @@ static void init_fidvid_stage2(u32 apicid, u32 nodeid)
/* If any node has nb_cof_vid_update set all nodes need an update. */
dev = NODE_PCI(nodeid, 3);
- pvimode = (pci_read_config32(dev, 0xA0) >> 8) & 1;
+ if (is_fam15h())
+ pvimode = 0;
+ else
+ pvimode = (pci_read_config32(dev, 0xA0) >> 8) & 1;
reg1fc = pci_read_config32(dev, 0x1FC);
nbvid = (reg1fc >> 7) & 0x7F;
NbVidUpdateAll = (reg1fc >> 1) & 1;
@@ -965,15 +1005,17 @@ static void init_fidvid_stage2(u32 apicid, u32 nodeid)
pci_write_config32(dev, 0xA0, dtemp);
dualPlaneOnly(dev);
- applyBoostFIDOffset(dev);
+ applyBoostFIDOffset(dev, nodeid);
enableNbPState1(dev);
finalPstateChange();
- /* Set TSC to tick at the P0 ndfid rate */
- msr = rdmsr(HWCR);
- msr.lo |= 1 << 24;
- wrmsr(HWCR, msr);
+ if (!is_fam15h()) {
+ /* Set TSC to tick at the P0 ndfid rate */
+ msr = rdmsr(HWCR);
+ msr.lo |= 1 << 24;
+ wrmsr(HWCR, msr);
+ }
}
@@ -1007,8 +1049,7 @@ static int init_fidvid_bsp(u32 bsp_apicid, u32 nodes)
/* Steps 1-6 of BIOS NB COF and VID Configuration
* for SVI and Single-Plane PVI Systems.
*/
-
- fv.common_fid = init_fidvid_core(0,0);
+ fv.common_fid = init_fidvid_core(0, 0);
print_debug_fv("BSP fid = ", fv.common_fid);