+
+static void recalculateVsSlamTimeSettingOnCorePre(device_t dev)
+{
+ u8 pviModeFlag;
+ u8 highVoltageVid, lowVoltageVid, bValue;
+ u16 minimumSlamTime;
+ u16 vSlamTimes[7]={1000,2000,3000,4000,6000,10000,20000}; /* Reg settings scaled by 100 */
+ u32 dtemp;
+ msr_t msr;
+
+ /* 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.
+ */
+
+ /* Calculate Slam Time
+ * Vslam = 0.4us/mV * Vp0 - (lowest out of Vpmin or Valt)
+ * In our case, we will scale the values by 100 to avoid
+ * decimals.
+ */
+
+
+
+ /* Determine if this is a PVI or SVI system */
+ dtemp = pci_read_config32(dev, 0xA0);
+
+ if( dtemp & PVI_MODE )
+ pviModeFlag = 1;
+ else
+ pviModeFlag = 0;
+
+ /* Get P0's voltage */
+ msr = rdmsr(0xC0010064);
+ highVoltageVid = (u8) ((msr.lo >> PS_CPU_VID_SHFT) & 0x7F);
+
+ /* If SVI, we only care about CPU VID.
+ * If PVI, determine the higher voltage b/t NB and CPU
+ */
+ if (pviModeFlag) {
+ bValue = (u8) ((msr.lo >> PS_NB_VID_SHFT) & 0x7F);
+ if( highVoltageVid > bValue )
+ highVoltageVid = bValue;
+ }
+
+ /* Get Pmin's index */
+ msr = rdmsr(0xC0010061);
+ bValue = (u8) ((msr.lo >> PS_CUR_LIM_SHFT) & BIT_MASK_3);
+
+ /* Get Pmin's VID */
+ msr = rdmsr(0xC0010064 + bValue);
+ lowVoltageVid = (u8) ((msr.lo >> PS_CPU_VID_SHFT) & 0x7F);
+
+ /* If SVI, we only care about CPU VID.
+ * If PVI, determine the higher voltage b/t NB and CPU
+ */
+ if (pviModeFlag) {
+ bValue = (u8) ((msr.lo >> PS_NB_VID_SHFT) & 0x7F);
+ if( lowVoltageVid > bValue )
+ lowVoltageVid = bValue;
+ }
+
+ /* Get AltVID */
+ dtemp = pci_read_config32(dev, 0xDC);
+ bValue = (u8) (dtemp & BIT_MASK_7);
+
+ /* Use the VID with the lowest voltage (higher VID) */
+ 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);
+
+ /* 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
+ * will fall through to a value of 7
+ */
+ for(bValue=0; bValue < 7; bValue++) {
+ if(minimumSlamTime <= vSlamTimes[bValue])
+ break;
+ }
+
+ /* Apply the value */
+ dtemp = pci_read_config32(dev, 0xD8);
+ dtemp &= VSSLAM_MASK;
+ dtemp |= bValue;
+ pci_write_config32(dev, 0xd8, dtemp);
+}
+
+