Author: mjones
Date: Mon Feb 28 04:59:34 2011
New Revision: 6411
URL: https://tracker.coreboot.org/trac/coreboot/changeset/6411
Log:
Improving BKDG implementation of P-states,
CPU and northbridge frequency and voltage
handling for Fam 10 in SVI mode.
I don't understand what this was doing nor find docs for these regs
Maybe it was left over from some copy & paste ?
Signed-off-by: Xavi Drudis Ferran <xdrudis(a)tinet.cat>
Acked-by: Marc Jones <marcj303(a)gmail.com>
Modified:
trunk/src/cpu/amd/model_10xxx/fidvid.c
Modified: trunk/src/cpu/amd/model_10xxx/fidvid.c
==============================================================================
--- trunk/src/cpu/amd/model_10xxx/fidvid.c Mon Feb 28 04:56:52 2011 (r6410)
+++ trunk/src/cpu/amd/model_10xxx/fidvid.c Mon Feb 28 04:59:34 2011 (r6411)
@@ -16,8 +16,93 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+/*
+ * This file initializes the CPU cores for voltage and frequency settings
+ * in the different power states.
+ */
+/*
+
+checklist (functions are in this file if no source file named)
+Fam10 Bios and Kernel Development Guide #31116, rev 3.48, April 22, 2010
+
+2.4.2.6 Requirements for p-states
+
+1.- F3x[84:80] According to table 100 : prep_fid_change
+
+2.- COF/VID :
+ 2.4.2.9.1 Steps 1,3-6 and warning for 2,7 if they apply
+ fixPsNbVidBeforeWR(...)
+ 2.4.2.9.1 Step 8 enable_fid_change
+ We do this for all nodes, I don't understand BKDG 100% on
+ whether this is or isn't meant by "on the local
+ processor". Must be OK.
+ 2.4.2.9.1 Steps 9-10 (repeat 1-7 and reset) romstage.c/init_cpus ?
+ 2.4.2.9.1 Steps 11-12 init_fidvid_stage2
+ 2.4.2.9.2 DualPlane PVI : Not supported, don't know how to detect,
+ needs specific circuitry.
+
+3.- 2.4.2.7 dualPlaneOnly(dev)
+
+4.- 2.4.2.8 applyBoostFIDOffset(dev)
+
+5.- enableNbPState1(dev)
+
+6.- 2.4.1.7
+ a) UpdateSinglePlaneNbVid()
+ b) setVSRamp(), called from prep_fid_change
+ c) prep_fid_change
+ d) improperly, for lack of voltage regulator details?,
+ F3xA0[PsiVidEn] in defaults.h
+ F3xA0[PsiVid] in init_cpus.c AMD_SetupPSIVID_d (before prep_fid_change)
+
+7.- TODO (Core Performance Boost is only available in revision E cpus, and we
+ don't seem to support those yet, at least they don't have any
+ constant in amddefs.h )
+
+8.- FIXME ? Transition to min Pstate according to 2.4.2.15.3 is required
+ by 2.4.2.6 after warm reset. But 2.4.2.15 states that it is not required
+ if the warm reset is issued by coreboot to update NbFid. So it is required
+ or not ? How can I tell who issued warm reset ?
+ Coreboot transitions to P0 instead, which is not recommended, and does
+ not follow 2.4.2.15.2 to do so.
+
+9.- TODO Requires information on current delivery capability
+ (depends on mainboard and maybe power supply ?). One might use a config
+ option with the maximum number of Ampers that the board can deliver to CPU.
+
+10.- [Multiprocessor] TODO 2.4.2.12
+ [Uniprocessor] FIXME ? We call setPStateMaxVal() in init_fidvid_stage2,
+ but not sure this is what is meant by "Determine the valid set of
+ P-states based on enabled P-states indicated
+ in MSRC001_00[68:64][PstateEn]" in 2.4.2.6-10
+
+11.- finalPstateChange() from init_fidvid_Stage2 (BKDG says just "may", anyway)
+
+12.- generate ACPI for p-states. FIXME
+ Needs more assesment. There's some kind of fixed support that
+ does not seem to depend on CPU revision or actual MSRC001_00[68:64]
+ as BKDG apparently requires.
+ http://www.coreboot.org/ACPI#CPU_Power_Management
+ At least for Tilapia board:
+ src/mainboard/<vendor>/<model>/acpi_tables.c write_acpi_tables(...) calls
+ acpi_add_ssdt_pstates(...)
+ in /src/northbridge/amd/amdfam10/amdfam10_acpi.c
+ which apparently copies them from static info in
+ src/mainboard/<vendor>/<model>/acpi/cpstate.asl
+
+"must also be completed"
+
+a.- PllLockTime set in ruleset in defaults.h
+ BKDG says set it "If MSRC001_00[68:64][CpuFid] is different between
+ any two enabled P-states", but since it does not say "only if"
+ I guess it is safe to do it always.
+
+b.- prep_fid_change(...)
+
+ */
#if CONFIG_SET_FIDVID
+
#include <northbridge/amd/amdht/AsPsDefs.h>
static inline void print_debug_fv(const char *str, u32 val)
Author: mjones
Date: Mon Feb 28 04:53:47 2011
New Revision: 6409
URL: https://tracker.coreboot.org/trac/coreboot/changeset/6409
Log:
Improving BKDG implementation of P-states,
CPU and northbridge frequency and voltage
handling for Fam 10 in SVI mode.
I don't understand what this was doing nor find docs for these regs
Maybe it was left over from some copy & paste ?
Signed-off-by: Xavi Drudis Ferran <xdrudis(a)tinet.cat>
Acked-by: Marc Jones <marcj303(a)gmail.com>
Modified:
trunk/src/cpu/amd/model_10xxx/fidvid.c
Modified: trunk/src/cpu/amd/model_10xxx/fidvid.c
==============================================================================
--- trunk/src/cpu/amd/model_10xxx/fidvid.c Mon Feb 28 04:49:28 2011 (r6408)
+++ trunk/src/cpu/amd/model_10xxx/fidvid.c Mon Feb 28 04:53:47 2011 (r6409)
@@ -394,19 +394,6 @@
} else { /* SVI */
/* set slamVidMode to 1 for SVI */
dword |= VID_SLAM_ON;
-
- u32 dtemp = dword;
-
- /* Program F3xD8[PwrPlanes] according F3xA0[DulaVdd] */
- dword = pci_read_config32(dev, 0xD8);
-
- if (dtemp & DUAL_VDD_BIT)
- dword |= PWR_PLN_ON;
- else
- dword &= PWR_PLN_OFF;
- pci_write_config32(dev, 0xD8, dword);
-
- dword = dtemp;
}
/* set the rest of A0 since we're at it... */
Author: mjones
Date: Mon Feb 28 04:35:43 2011
New Revision: 6407
URL: https://tracker.coreboot.org/trac/coreboot/changeset/6407
Log:
Improving BKDG implementation of P-states,
CPU and northbridge frequency and voltage
handling for Fam 10 in SVI mode.
bits 13 - 15 of F3xd4 (StutterScrubEn, CacheFlushImmOnAllHalt and MTC1eEn
are reserved for revisions D0 and earlier, so whe should not set them
to 0 in fidvid.c config_clk_power_ctrl_reg0(...), called from prep_fid_change.
For revisions > D0 (when we support them) it is ok not ot clear them,
because they are documented as 0 on reset. bit 12 should be left alone
according to BKDG. Should I set 11:8 ClkRampHystSel to 0 in the mask
too, just to indicate we're touching them ? We'll OR them to 1111 anyway...
Signed-off-by: Xavi Drudis Ferran <xdrudis(a)tinet.cat>
Acked-by: Marc Jones <marcj303(a)gmail.com>
Modified:
trunk/src/northbridge/amd/amdht/AsPsDefs.h
Modified: trunk/src/northbridge/amd/amdht/AsPsDefs.h
==============================================================================
--- trunk/src/northbridge/amd/amdht/AsPsDefs.h Mon Feb 28 04:32:23 2011 (r6406)
+++ trunk/src/northbridge/amd/amdht/AsPsDefs.h Mon Feb 28 04:35:43 2011 (r6407)
@@ -111,7 +111,7 @@
#define STC_PS_LMT_MASK 0x8fffffff /* StcPstateLimit mask off */
#define CPTC0 0x0d4 /* Clock Power/Timing Control0 Register*/
-#define CPTC0_MASK 0x000c0fff /* Reset mask for this register */
+#define CPTC0_MASK 0x000cffff /* Reset mask for this register */
#define CPTC0_NBFID_MASK 0xffffffe0 /* NbFid mask off for this register */
#define CPTC0_NBFID_MON 0x1f /* NbFid mask on for this register */
#define NB_FID_EN 0x20 /* NbFidEn bit ON */
Author: mjones
Date: Mon Feb 28 04:32:23 2011
New Revision: 6406
URL: https://tracker.coreboot.org/trac/coreboot/changeset/6406
Log:
Improving BKDG implementation of P-states,
CPU and northbridge frequency and voltage
handling for Fam 10 in SVI mode.
Well, I understand it better like this, but maybe
it's only me, part of the changes are paranoic, and
the only effective change is for a factor depending on
mobile or not that I can't test.
Signed-off-by: Xavi Drudis Ferran <xdrudis(a)tinet.cat>
Acked-by: Marc Jones <marcj303(a)gmail.com>
Modified:
trunk/src/cpu/amd/model_10xxx/fidvid.c
trunk/src/northbridge/amd/amdht/AsPsDefs.h
Modified: trunk/src/cpu/amd/model_10xxx/fidvid.c
==============================================================================
--- trunk/src/cpu/amd/model_10xxx/fidvid.c Mon Feb 28 04:25:07 2011 (r6405)
+++ trunk/src/cpu/amd/model_10xxx/fidvid.c Mon Feb 28 04:32:23 2011 (r6406)
@@ -155,6 +155,18 @@
}
}
+static int vidTo100uV(u8 vid)
+{// returns voltage corresponding to vid in tenths of mV, i.e. hundreds of uV
+ // BKDG #31116 rev 3.48 2.4.1.6
+ int voltage;
+ if (vid >= 0x7c) {
+ voltage = 0;
+ } else {
+ voltage = (15500 - (125*vid));
+ }
+ return voltage;
+}
+
static void setVSRamp(device_t dev) {
/* BKDG r31116 2010-04-22 2.4.1.7 step b F3xD8[VSRampTime]
* If this field accepts 8 values between 10 and 500 us why
@@ -181,12 +193,14 @@
/* This function calculates the VsSlamTime using the range of possible
* voltages instead of a hardcoded 200us.
- * Note:This function is called from setFidVidRegs and setUserPs after
- * programming a custom Pstate.
+ * Note: his function is called only from prep_fid_change,
+ * and that from init_cpus.c finalize_node_setup()
+ * (after set AMD MSRs and init ht )
*/
+ /* BKDG r31116 2010-04-22 2.4.1.7 step b F3xD8[VSSlamTime] */
/* Calculate Slam Time
- * Vslam = 0.4us/mV * Vp0 - (lowest out of Vpmin or Valt)
+ * Vslam = (mobileCPU?0.2:0.4)us/mV * (Vp0 - (lowest out of Vpmin or Valt)) mV
* In our case, we will scale the values by 100 to avoid
* decimals.
*/
@@ -200,8 +214,17 @@
pviModeFlag = 0;
/* Get P0's voltage */
+ /* MSRC001_00[68:64] are not programmed yet when called from
+ prep_fid_change, one might use F4x1[F0:E0] instead, but
+ theoretically MSRC001_00[68:64] are equal to them after
+ reset. */
msr = rdmsr(0xC0010064);
highVoltageVid = (u8) ((msr.lo >> PS_CPU_VID_SHFT) & 0x7F);
+ if (!(msr.hi & 0x80000000)) {
+ printk(BIOS_ERR,"P-state info in MSRC001_0064 is invalid !!!\n");
+ highVoltageVid = (u8) ((pci_read_config32(dev, 0x1E0)
+ >> PS_CPU_VID_SHFT) & 0x7F);
+ }
/* If SVI, we only care about CPU VID.
* If PVI, determine the higher voltage b/t NB and CPU
@@ -212,17 +235,23 @@
highVoltageVid = bValue;
}
- /* Get Pmin's index */
+ /* Get PSmax's index */
msr = rdmsr(0xC0010061);
- bValue = (u8) ((msr.lo >> PS_CUR_LIM_SHFT) & BIT_MASK_3);
-
- /* Get Pmin's VID */
+ bValue = (u8) ((msr.lo >> PS_MAX_VAL_SHFT) & BIT_MASK_3);
+
+ /* Get PSmax's VID */
msr = rdmsr(0xC0010064 + bValue);
lowVoltageVid = (u8) ((msr.lo >> PS_CPU_VID_SHFT) & 0x7F);
+ if (!(msr.hi & 0x80000000)) {
+ printk(BIOS_ERR,"P-state info in MSR%8x is invalid !!!\n",0xC0010064 + bValue);
+ lowVoltageVid = (u8) ((pci_read_config32(dev, 0x1E0+(bValue*4))
+ >> PS_CPU_VID_SHFT) & 0x7F);
+ }
/* If SVI, we only care about CPU VID.
* If PVI, determine the higher voltage b/t NB and CPU
- */
+ * BKDG 2.4.1.7 (a)
+ */
if (pviModeFlag) {
bValue = (u8) ((msr.lo >> PS_NB_VID_SHFT) & 0x7F);
if (lowVoltageVid > bValue)
@@ -237,20 +266,9 @@
if (lowVoltageVid < bValue)
lowVoltageVid = bValue;
- /* If Vids are 7Dh - 7Fh, force 7Ch to keep calculations linear */
- if (lowVoltageVid > 0x7C) {
- lowVoltageVid = 0x7C;
- if (highVoltageVid > 0x7C)
- highVoltageVid = 0x7C;
- }
-
- bValue = (u8) (lowVoltageVid - highVoltageVid);
+ u8 mobileFlag = get_platform_type() & AMD_PTYPE_MOB;
+ minimumSlamTime = (mobileFlag?2:4) * (vidTo100uV(highVoltageVid) - vidTo100uV(lowVoltageVid)); /* * 0.01 us */
- /* Each Vid increment is 12.5 mV. The minimum slam time is:
- * vidCodeDelta * 12.5mV * 0.4us/mV
- * Scale by 100 to avoid decimals.
- */
- minimumSlamTime = bValue * (125 * 4);
/* Now round up to nearest register setting.
* Note that if we don't find a value, we
Modified: trunk/src/northbridge/amd/amdht/AsPsDefs.h
==============================================================================
--- trunk/src/northbridge/amd/amdht/AsPsDefs.h Mon Feb 28 04:25:07 2011 (r6405)
+++ trunk/src/northbridge/amd/amdht/AsPsDefs.h Mon Feb 28 04:32:23 2011 (r6406)
@@ -25,7 +25,7 @@
#define APIC_BAR_BP 0x100 /* APIC_BAR BSP bit */
#define PS_LIM_REG 0xC0010061 /* P-state Current Limit Register */
-#define PS_CUR_LIM_SHFT 4 /* P-state Current Limit shift position */
+#define PS_MAX_VAL_SHFT 4 /* P-state Maximum Value shift position */
#define PS_CTL_REG 0xC0010062 /* P-state Control Register */
#define PS_CMD_MASK_OFF 0xfffffff8 /* P-state Control Register CMD Mask OFF */
Author: mjones
Date: Mon Feb 28 04:08:06 2011
New Revision: 6402
URL: https://tracker.coreboot.org/trac/coreboot/changeset/6402
Log:
Improving BKDG implementation of P-states,
CPU and northbridge frequency and voltage
handling for Fam 10 in SVI mode.
Looking at BKDG the process for updating
Pstate Nb vid after warn reset seemed
more similar to the codethat was there fo
pvi than the one for svi, so I called the
pvi function passing a pvi/svi flag. I don't
find documentation on why should UpdateSinglePlaneNbVid()
be called in PVI, but since I can't test it,
I leave it as it was.
This patch showed some progress beyond fidvid in my
boar,d but only sometimes, most times it just didn't
work.
Signed-off-by: Xavi Drudis Ferran <xdrudis(a)tinet.cat>
Acked-by: Marc Jones <marcj303(a)gmail.com>
Modified:
trunk/src/cpu/amd/model_10xxx/fidvid.c
trunk/src/northbridge/amd/amdht/AsPsDefs.h
Modified: trunk/src/cpu/amd/model_10xxx/fidvid.c
==============================================================================
--- trunk/src/cpu/amd/model_10xxx/fidvid.c Mon Feb 28 04:02:40 2011 (r6401)
+++ trunk/src/cpu/amd/model_10xxx/fidvid.c Mon Feb 28 04:08:06 2011 (r6402)
@@ -712,36 +712,17 @@
}
-static void updateSviPsNbVidAfterWR(u32 newNbVid)
-{
- msr_t msr;
- u8 i;
-
- /* This function copies newNbVid to NbVid bits in P-state Registers[4:0]
- * for SVI mode.
- */
-
- for (i = 0; i < 5; i++) {
- msr = rdmsr(0xC0010064 + i);
- if ((msr.hi >> 31) & 1) { /* PstateEn? */
- msr.lo &= ~(0x7F << 25);
- msr.lo |= (newNbVid & 0x7F) << 25;
- wrmsr(0xC0010064 + i, msr);
- }
- }
-}
-
-
-static void fixPsNbVidAfterWR(u32 newNbVid, u8 NbVidUpdatedAll)
+static void fixPsNbVidAfterWR(u32 newNbVid, u8 NbVidUpdatedAll,u8 pviMode)
{
msr_t msr;
u8 i;
u8 StartupPstate;
- /* This function copies newNbVid to NbVid bits in P-state
- * Registers[4:0] if its NbDid bit=0 and PstateEn bit =1 in case of
- * NbVidUpdatedAll =0 or copies copies newNbVid to NbVid bits in
- * P-state Registers[4:0] if its and PstateEn bit =1 in case of
+ /* BKDG 2.4.2.9.1 11-12
+ * This function copies newNbVid to NbVid bits in P-state
+ * Registers[4:0] if its NbDid bit=0, and IddValue!=0 in case of
+ * NbVidUpdatedAll =0 or copies newNbVid to NbVid bits in
+ * P-state Registers[4:0] if its IddValue!=0 in case of
* NbVidUpdatedAll=1. Then transition to StartPstate.
*/
@@ -749,26 +730,28 @@
for (i = 0; i < 5; i++) {
msr = rdmsr(0xC0010064 + i);
/* NbDid (bit 22 of P-state Reg) == 0 or NbVidUpdatedAll = 1 */
- if ((((msr.lo >> 22) & 1) == 0) || NbVidUpdatedAll) {
- msr.lo &= ~(0x7F << 25);
- msr.lo |= (newNbVid & 0x7F) << 25;
+ if ( (msr.hi & PS_IDD_VALUE_MASK)
+ && (msr.hi & PS_EN_MASK)
+ &&(((msr.lo & PS_NB_DID_MASK) == 0) || NbVidUpdatedAll)) {
+ msr.lo &= PS_NB_VID_M_OFF;
+ msr.lo |= (newNbVid & 0x7F) << PS_NB_VID_SHFT;
wrmsr(0xC0010064 + i, msr);
}
}
- UpdateSinglePlaneNbVid();
-
+ /* Not documented. Would overwrite Nb_Vids just copied
+ * should we just update cpu_vid or nothing at all ?
+ */
+ if (pviMode) { //single plane
+ UpdateSinglePlaneNbVid();
+ }
/* For each core in the system, transition all cores to StartupPstate */
msr = rdmsr(0xC0010071);
StartupPstate = msr.hi & 0x07;
- msr = rdmsr(0xC0010062);
- msr.lo = StartupPstate;
- wrmsr(0xC0010062, msr);
-
- /* Wait for StartupPstate to set. */
- do {
- msr = rdmsr(0xC0010063);
- } while (msr.lo != StartupPstate);
+
+ /* Set and wait for StartupPstate to set. */
+ set_pstate(StartupPstate);
+
}
static void finalPstateChange(void)
@@ -803,15 +786,12 @@
NbVidUpdateAll = (reg1fc >> 1) & 1;
if (nb_cof_vid_update) {
- if (pvimode) {
- nbvid = (reg1fc >> 7) & 0x7F;
- /* write newNbVid to P-state Reg's NbVid if its NbDid=0 */
- fixPsNbVidAfterWR(nbvid, NbVidUpdateAll);
- } else { /* SVI */
- nbvid = ((reg1fc >> 7) & 0x7F) - ((reg1fc >> 17) & 0x1F);
- updateSviPsNbVidAfterWR(nbvid);
+ if (!pvimode) { /* SVI */
+ nbvid = nbvid - ((reg1fc >> 17) & 0x1F);
}
- } else { /* !nb_cof_vid_update */
+ /* write newNbVid to P-state Reg's NbVid if its NbDid=0 */
+ fixPsNbVidAfterWR(nbvid, NbVidUpdateAll,pvimode);
+ } else { /* !nb_cof_vid_update */
if (pvimode)
UpdateSinglePlaneNbVid();
}
Modified: trunk/src/northbridge/amd/amdht/AsPsDefs.h
==============================================================================
--- trunk/src/northbridge/amd/amdht/AsPsDefs.h Mon Feb 28 04:02:40 2011 (r6401)
+++ trunk/src/northbridge/amd/amdht/AsPsDefs.h Mon Feb 28 04:08:06 2011 (r6402)
@@ -44,6 +44,10 @@
#define PS_REG3 3 /* offset for P3 */
#define PS_REG4 4 /* offset for P4 */
+#define PS_IDD_VALUE_SHFT 0 /* IddValue: current value
+ field offset for msr.hi */
+#define PS_IDD_VALUE_MASK 0xFF /* IddValue: current value
+ field mask for msr.hi */
#define PS_PSDIS_MASK 0x7fffffff /* disable P-state register */
#define PS_EN_MASK 0x80000000 /* P-state register enable mask */
#define PS_NB_DID_MASK 0x400000 /* P-state Reg[NbDid] Mask */