summaryrefslogtreecommitdiffstats
path: root/src/occ_405/wof
diff options
context:
space:
mode:
authorAndres Lugo-Reyes <aalugore@us.ibm.com>2017-02-03 12:54:23 -0600
committerWilliam A. Bryan <wilbryan@us.ibm.com>2017-03-02 18:10:30 -0500
commit8efb50ee01aae3badc7fd717a9449c2c0632f688 (patch)
tree48d04e24f9566d0c0d955ebf7096bea6da605634 /src/occ_405/wof
parent0e1231ddb7cf7fa07ab0521c89de21ea203b5ef7 (diff)
downloadtalos-occ-8efb50ee01aae3badc7fd717a9449c2c0632f688.tar.gz
talos-occ-8efb50ee01aae3badc7fd717a9449c2c0632f688.zip
WOF: Functions to calculate ceff_vdn/vdd ratios for WOF calc
Change-Id: I9a9c90aa2c00414cd85c845d63be3a3d1e31148e RTC:130216 Depends-on: Icfead61f432707b1d6314152b74f2adb215fd514 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35988 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Martha Broyles <mbroyles@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/occ_405/wof')
-rw-r--r--src/occ_405/wof/wof.c202
-rw-r--r--src/occ_405/wof/wof.h35
-rw-r--r--src/occ_405/wof/wof_service_codes.h4
3 files changed, 236 insertions, 5 deletions
diff --git a/src/occ_405/wof/wof.c b/src/occ_405/wof/wof.c
index b5df7b2..b54b691 100644
--- a/src/occ_405/wof/wof.c
+++ b/src/occ_405/wof/wof.c
@@ -45,7 +45,7 @@ extern GpeRequest G_wof_vfrt_req;
extern uint32_t G_pgpe_shared_sram_address;
extern uint32_t G_pgpe_pstate_table_address;
extern uint32_t G_pgpe_pstate_table_sz;
-
+extern uint32_t G_nest_frequency_mhz;
//******************************************************************************
// Globals
//******************************************************************************
@@ -933,6 +933,191 @@ void calculate_nest_leakage( void )
g_wof->idc_vdn = (G_oppb.iddq.ivdn*nest_mult) >> 10;
}
+
+/**
+ * calculate_effective_capacitance
+ *
+ * Description: Generic function to perform the effective capacitance
+ * calculations.
+ * C_eff = I / (V^1.3 * F)
+ *
+ * I is the AC component of Idd in 0.01 Amps (or10 mA)
+ * V is the silicon voltage in 100 uV
+ * F is the frequency in MHz
+ *
+ * Note: Caller must ensure they check for a 0 return value
+ * and disable wof if that is the case
+ *
+ * Param[in]: i_iAC - the AC component
+ * Param[in]: i_voltage - the voltage component in 100uV
+ * Param[in]: i_frequency - the frequency component
+ *
+ * Return: The calculated effective capacitance
+ */
+uint32_t calculate_effective_capacitance( uint32_t i_iAC,
+ uint32_t i_voltage,
+ uint32_t i_frequency )
+{
+
+ // Prevent divide by zero
+ if( i_frequency == 0 )
+ {
+ // Return 0 causing caller to disable wof.
+ return 0;
+ }
+
+ // Compute V^1.3 using a best-fit equation
+ // (V^1.3) = (21374 * (voltage in 100uV) - 50615296)>>10
+ uint32_t v_exp_1_dot_3 = (21374 * i_voltage - 50615296)>>10;
+
+ // Compute I / (V^1.3)
+ uint32_t I = i_iAC << 14; // * 16384
+
+ // Prevent divide by zero
+ if( v_exp_1_dot_3 == 0 )
+ {
+ // Return 0 causing caller to disable wof.
+ return 0;
+ }
+
+ uint32_t c_eff = (I / v_exp_1_dot_3);
+ c_eff = c_eff << 14; // * 16384
+
+ // Divide by frequency and return the final value.
+ // (I / (V^1.3 * F)) == I / V^1.3 /F
+ return c_eff / i_frequency;
+
+}
+
+
+
+/**
+ * calculate_ceff_ratio_vdn
+ *
+ * Description: Function to calculate the effective capacitance ratio
+ * for the nest
+ */
+void calculate_ceff_ratio_vdn( void )
+{
+ //TODO Read iac_tdp_vdn(@turbo) from OCCPstateParmBlock struct
+ g_wof->iac_tdp_vdn = 0;
+
+ // Calculate Ceff_tdp_vdn
+ // iac_tdp_vdn / (VOLTVDN^1.3 * Fnest)
+ g_wof->ceff_tdp_vdn =
+ calculate_effective_capacitance( g_wof->iac_tdp_vdn,
+ g_wof->voltvdn_sensor,
+ G_nest_frequency_mhz );
+
+ // Calculate ceff_vdn
+ // iac_vdn/ (VOLTVDN^1.3 * Fnest)
+ g_wof->ceff_vdn =
+ calculate_effective_capacitance( g_wof->iac_vdn,
+ g_wof->voltvdn_sensor,
+ G_nest_frequency_mhz );
+
+ // Prevent divide by zero
+ if( g_wof->ceff_tdp_vdn == 0 )
+ {
+ /*
+ * @errortype
+ * @moduleid CALC_CEFF_RATIO_VDN
+ * @reasoncode DIVIDE_BY_ZERO_ERROR
+ * @userdata1 0
+ * @userdata4 OCC_NO_EXTENDED_RC
+ * @devdesc Divide by zero error on ceff_vdn / ceff_tdp_vdn
+ */
+ errlHndl_t l_errl = createErrl(
+ CALC_CEFF_RATIO_VDN,
+ DIVIDE_BY_ZERO_ERROR,
+ OCC_NO_EXTENDED_RC,
+ ERRL_SEV_PREDICTIVE,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ 0,
+ 0 );
+
+ commitErrl( &l_errl );
+
+ // Return 0
+ g_wof->ceff_ratio_vdn = 0;
+
+ //TODO: RTC 166301 - call new disable_wof function
+ }
+ else
+ {
+ g_wof->ceff_ratio_vdn = g_wof->ceff_vdn / g_wof->ceff_tdp_vdn;
+ }
+}
+
+/**
+ * calculate_ceff_ratio_vdd
+ *
+ * Description: Function to calculate the effective capacitance ratio
+ * for the core
+ */
+void calculate_ceff_ratio_vdd( void )
+{
+ //TODO read iac_tdp_vdd from OCCPstateParmBlock struct
+ g_wof->iac_tdp_vdd = 0;
+
+ // Get Vturbo and convert to 100uV (mV -> 100uV) = mV*10
+ // Multiply by Vratio
+ uint32_t V = (G_oppb.operating_points[TURBO].vdd_mv*10) * g_wof->v_ratio;
+
+ // Get Fturbo and multiply by Fratio
+ uint32_t F = G_oppb.operating_points[TURBO].frequency_mhz * g_wof->f_ratio;
+
+ // Calculate ceff_tdp_vdd
+ // iac_tdp_vdd / ((Vturbo*Vratio)^1.3 * (Fturbo*Fratio))
+ g_wof->ceff_tdp_vdd =
+ calculate_effective_capacitance( g_wof->iac_tdp_vdd,
+ V,
+ F );
+
+ // Calculate ceff_vdd
+ // iac_vdd / (Vclip^1.3 * Fclip)
+ g_wof->ceff_vdd =
+ calculate_effective_capacitance( g_wof->iac_vdd,
+ g_wof->v_clip,
+ g_wof->f_clip );
+
+ // Prevent divide by zero
+ if( g_wof->ceff_tdp_vdd == 0 )
+ {
+ /*
+ * @errortype
+ * @moduleid CALC_CEFF_RATIO_VDD
+ * @reasoncode DIVIDE_BY_ZERO_ERROR
+ * @userdata1 0
+ * @userdata4 OCC_NO_EXTENDED_RC
+ * @devdesc Divide by zero error on ceff_vdd / ceff_tdp_vdd
+ */
+ errlHndl_t l_errl = createErrl(
+ CALC_CEFF_RATIO_VDD,
+ DIVIDE_BY_ZERO_ERROR,
+ OCC_NO_EXTENDED_RC,
+ ERRL_SEV_PREDICTIVE,
+ NULL,
+ DEFAULT_TRACE_SIZE,
+ 0,
+ 0 );
+
+ commitErrl( &l_errl );
+
+ // Return 0
+ g_wof->ceff_ratio_vdd = 0;
+
+ //TODO: RTC 166301 - call new disable_wof function
+ }
+ else
+ {
+ g_wof->ceff_ratio_vdd = g_wof->ceff_vdd / g_wof->ceff_tdp_vdd;
+ }
+}
+
+
+
/**
* calculate_AC_currents
*
@@ -1054,11 +1239,18 @@ int32_t calculate_multiplier( int32_t i_temp )
(int32_t)G_wof_iddq_mult_table[mult_idx+1][1]);
}
+/**
+ * read_sensor_data
+ *
+ * Description: One time place to read out all the sensors needed
+ * for wof calculations. First thing wof_main does.
+ */
void read_sensor_data( void )
{
// Read out necessary Sensor data for WOF calculation
- g_wof->curvdd_sensor = getSensorByGsid(CURVDD)->sample;
- g_wof->curvdn_sensor = getSensorByGsid(CURVDN)->sample;
- g_wof->voltvddsense_sensor = getSensorByGsid(VOLTVDDSENSE)->sample;
- g_wof->tempnest_sensor = getSensorByGsid(TEMPNEST)->sample;
+ g_wof->curvdd_sensor = getSensorByGsid(CURVDD)->sample;
+ g_wof->curvdn_sensor = getSensorByGsid(CURVDN)->sample;
+ g_wof->voltvddsense_sensor = getSensorByGsid(VOLTVDDSENSE)->sample;
+ g_wof->tempnest_sensor = getSensorByGsid(TEMPNEST)->sample;
+ g_wof->voltvdn_sensor = getSensorByGsid(VOLTVDN)->sample;
}
diff --git a/src/occ_405/wof/wof.h b/src/occ_405/wof/wof.h
index 6d231a0..740a5f4 100644
--- a/src/occ_405/wof/wof.h
+++ b/src/occ_405/wof/wof.h
@@ -92,6 +92,8 @@ typedef struct
uint16_t curvdd_sensor;
// The most recently read value in the sensor CURVDN
uint16_t curvdn_sensor;
+ // The most recently read value in the sensor VOLTVDN
+ uint16_t voltvdn_sensor;
// Array to hold the current 1-byte pstate values read from SRAM. 0xFF=off
uint8_t quad_x_pstates[MAX_NUM_QUADS];
// Bit vector to hold the ivrm states of the quads. 0=BYPASS, 1=REGULATION
@@ -106,6 +108,30 @@ typedef struct
uint32_t iac_vdd;
// Contains the AC component of the workload for the nest
uint32_t iac_vdn;
+ // Contains iac_tdp_vdd(@turbo) read from the pstate parameter block
+ uint32_t iac_tdp_vdd;
+ // Contains iac_tdp_vdn read from the pstate parameter block
+ uint32_t iac_tdp_vdn;
+ // Contains Vratio, read from OCC-PGPE shared SRAM
+ uint32_t v_ratio;
+ // Contains Fratio, read from OCC-PGPE shared SRAM
+ uint32_t f_ratio;
+ // Contains Vclip, read from OCC-PGPE shared SRAM
+ uint32_t v_clip;
+ // Contains Fclip, read from OCC-PGPE shared SRAM
+ uint32_t f_clip;
+ // Contains the calculated effective capacitance for tdp_vdd
+ uint32_t ceff_tdp_vdd;
+ // Contains the calculated effective capacitance for vdd
+ uint32_t ceff_vdd;
+ // Contains the calculated effective capacitance ratio for vdd
+ uint32_t ceff_ratio_vdd;
+ // Contains the calculated effective capacitance for tdp_vdn
+ uint32_t ceff_tdp_vdn;
+ // Contains the calculated effective capacitance for vdn
+ uint32_t ceff_vdn;
+ // Contains the calculated effective capacitance ratio for vdn
+ uint32_t ceff_ratio_vdn;
// Contains the index used for interpolation in the ALL_CORES_OFF_ISO calc
uint8_t voltage_idx;
// Contains the final calculated value of ALL_CORES_OFF_ISO
@@ -210,6 +236,10 @@ void calculate_core_leakage( void );
void calculate_nest_leakage( void );
+void calculate_ceff_ratio_vdn( void );
+
+void calculate_ceff_ratio_vdd( void );
+
inline void calculate_AC_currents( void );
inline bool core_powered_on( uint8_t i_core_num );
@@ -224,6 +254,11 @@ inline int32_t interpolate_linear( int32_t i_X,
int32_t calculate_multiplier( int32_t i_temp );
+uint32_t calculate_effective_capacitance( uint32_t i_iAC,
+ uint32_t i_voltage,
+ uint32_t i_frequency );
+
+
void read_sensor_data( void );
#endif
diff --git a/src/occ_405/wof/wof_service_codes.h b/src/occ_405/wof/wof_service_codes.h
index 89afb3f..666ffa2 100644
--- a/src/occ_405/wof/wof_service_codes.h
+++ b/src/occ_405/wof/wof_service_codes.h
@@ -33,6 +33,10 @@ enum wofModuleId
SEND_VFRT_TO_PGPE = WOF_COMP_ID | 0x02,
COPY_VFRT_TO_SRAM = WOF_COMP_ID | 0x03,
WOF_VFRT_CALLBACK = WOF_COMP_ID | 0x04,
+ CALC_EFF_CAP_VOLT = WOF_COMP_ID | 0x05,
+ CALC_EFF_CAP_FREQ = WOF_COMP_ID | 0x06,
+ CALC_CEFF_RATIO_VDD = WOF_COMP_ID | 0x07,
+ CALC_CEFF_RATIO_VDN = WOF_COMP_ID | 0x08,
};
OpenPOWER on IntegriCloud