From 0e1231ddb7cf7fa07ab0521c89de21ea203b5ef7 Mon Sep 17 00:00:00 2001 From: Andres Lugo-Reyes Date: Thu, 2 Feb 2017 15:00:01 -0600 Subject: WOF: Functions to calculate nest leakage and AC currents Change-Id: Icfead61f432707b1d6314152b74f2adb215fd514 RTC:130216 Depends-on: Ica95c4030c81c959e834797ef998af7d025cf250 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35846 Tested-by: FSP CI Jenkins Reviewed-by: William A. Bryan --- src/occ_405/amec/amec_parm.h | 4 +++ src/occ_405/amec/amec_parm_table.c | 8 +++-- src/occ_405/wof/wof.c | 64 +++++++++++++++++++++++++++++--------- src/occ_405/wof/wof.h | 31 ++++++++++++++---- 4 files changed, 84 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/occ_405/amec/amec_parm.h b/src/occ_405/amec/amec_parm.h index 43a4462..7a0cd30 100755 --- a/src/occ_405/amec/amec_parm.h +++ b/src/occ_405/amec/amec_parm.h @@ -81,7 +81,10 @@ typedef enum PARM_QUAD_X_PSTATES, PARM_IVRM_STATES, PARM_IDC_VDD, + PARM_IDC_VDN, PARM_IDC_QUAD, + PARM_IAC_VDD, + PARM_IAC_VDN, PARM_VOLTAGE_IDX, PARM_ALL_CORES_OFF_ISO, PARM_ALL_CACHES_ON_ISO, @@ -97,6 +100,7 @@ typedef enum PARM_TVPD_LEAK_OFF, PARM_TVPD_LEAK_ON, PARM_TVPD_LEAK_CACHE, + PARM_TVPD_LEAK_NEST, PARM_REQ_ACTIVE_QUAD_UPDATE, PARM_PREV_REQ_ACTIVE_QUADS, PARM_CURR_PING_PONG_BUF, diff --git a/src/occ_405/amec/amec_parm_table.c b/src/occ_405/amec/amec_parm_table.c index bcc7059..01baaff 100755 --- a/src/occ_405/amec/amec_parm_table.c +++ b/src/occ_405/amec/amec_parm_table.c @@ -146,14 +146,17 @@ amec_parm_t g_amec_parm_list[] = { AMEC_PARM_UINT32(PARM_CORE_PWR_ON, "core_pwr_on", &g_amec_sys.wof.core_pwr_on), AMEC_PARM_UINT8_ARRAY(PARM_CORES_ON_PER_QUAD, "coreson_per_quad", &g_amec_sys.wof.cores_on_per_quad, MAX_NUM_QUADS), AMEC_PARM_UINT16(PARM_WOF_DISABLED, "wof_disabled", &g_amec_sys.wof.wof_disabled), - AMEC_PARM_UINT32(PARM_VOLT_VDD_SENSE, "volt_vdd_sense", &g_amec_sys.wof.volt_vdd_sense), + AMEC_PARM_UINT32(PARM_VOLT_VDD_SENSE, "voltvddsense", &g_amec_sys.wof.voltvddsense_sensor), AMEC_PARM_UINT16_ARRAY(PARM_TEMPPROCTHERMC, "tempprocthrmc", &g_amec_sys.wof.tempprocthrmc, MAX_NUM_CORES), - AMEC_PARM_UINT16(PARM_TEMPNEST, "tempnest_sense", &g_amec_sys.wof.tempnest_sense), + AMEC_PARM_UINT16(PARM_TEMPNEST, "tempnest_sensor", &g_amec_sys.wof.tempnest_sensor), AMEC_PARM_UINT16_ARRAY(PARM_TEMPQ, "tempq", &g_amec_sys.wof.tempq, MAX_NUM_QUADS), AMEC_PARM_UINT8_ARRAY(PARM_QUAD_X_PSTATES, "quad_x_pstates", &g_amec_sys.wof.quad_x_pstates, MAX_NUM_QUADS), AMEC_PARM_UINT8(PARM_IVRM_STATES, "quad_ivrm_states", &g_amec_sys.wof.quad_ivrm_states), AMEC_PARM_UINT32(PARM_IDC_VDD, "idc_vdd", &g_amec_sys.wof.idc_vdd), + AMEC_PARM_UINT32(PARM_IDC_VDN, "idc_vdn", &g_amec_sys.wof.idc_vdn), AMEC_PARM_UINT32(PARM_IDC_QUAD, "idc_quad", &g_amec_sys.wof.idc_quad), + AMEC_PARM_UINT32(PARM_IAC_VDD, "iac_vdd", &g_amec_sys.wof.iac_vdd), + AMEC_PARM_UINT32(PARM_IAC_VDN, "iac_vdn", &g_amec_sys.wof.iac_vdn), AMEC_PARM_UINT8(PARM_VOLTAGE_IDX, "voltage_idx", &g_amec_sys.wof.voltage_idx), AMEC_PARM_UINT32(PARM_ALL_CORES_OFF_ISO, "allcores_off_iso", &g_amec_sys.wof.all_cores_off_iso), AMEC_PARM_UINT32(PARM_ALL_CACHES_ON_ISO, "allcaches_on_iso", &g_amec_sys.wof.all_caches_on_iso), @@ -169,6 +172,7 @@ amec_parm_t g_amec_parm_list[] = { AMEC_PARM_UINT16(PARM_TVPD_LEAK_OFF, "tvpd_leak_off", &g_amec_sys.wof.tvpd_leak_off), AMEC_PARM_UINT16(PARM_TVPD_LEAK_ON, "tvpd_leak_on", &g_amec_sys.wof.tvpd_leak_on), AMEC_PARM_UINT16(PARM_TVPD_LEAK_CACHE, "tvpd_leak_cache", &g_amec_sys.wof.tvpd_leak_cache), + AMEC_PARM_UINT16(PARM_TVPD_LEAK_NEST, "tvpd_leak_nest", &g_amec_sys.wof.tvpd_leak_nest), AMEC_PARM_UINT8(PARM_REQ_ACTIVE_QUAD_UPDATE, "req_active_quad", &g_amec_sys.wof.req_active_quad_update), AMEC_PARM_UINT8(PARM_PREV_REQ_ACTIVE_QUADS, "prevActiveQuads", &g_amec_sys.wof.prev_req_active_quads), AMEC_PARM_UINT32(PARM_CURR_PING_PONG_BUF, "currPingPongBuf", &g_amec_sys.wof.curr_ping_pong_buf), diff --git a/src/occ_405/wof/wof.c b/src/occ_405/wof/wof.c index 08a204b..b5df7b2 100644 --- a/src/occ_405/wof/wof.c +++ b/src/occ_405/wof/wof.c @@ -110,12 +110,9 @@ int16_t G_wof_iddq_mult_table[][2] = { void wof_main(void) { - // TODO Read out necessary Sensor data for WOF calculation - // uint16_t l_current_vdd = getSensorByGsid(CURVDD)->sample; - // uint16_t l_current_vdn = getSensorByGsid(CURVDN)->sample - // Read VOLTVDDSENSE once here to be used in the algorithm and save it to amec - g_wof->volt_vdd_sense = getSensorByGsid(VOLTVDDSENSE)->sample; + // Read out the sensor data needed for calculations + read_sensor_data(); // Functions to calculate Ceff_vdd and Ceff_vdn here. uint16_t ceff_vdd = 0; // TODO: replace with future function call @@ -629,7 +626,7 @@ void calculate_core_voltage( void ) // 0 = BYPASS, 1 = REGULATION if( (g_wof->quad_ivrm_states & l_quad_mask ) == 0 ) { - l_voltage = g_wof->volt_vdd_sense; + l_voltage = g_wof->voltvddsense_sensor;; } else { @@ -675,7 +672,7 @@ void calculate_core_leakage( void ) // Get the VOLTVDDSENSE sensor and choose the appropriate // chip voltage index - uint32_t l_v_chip = g_wof->volt_vdd_sense; + uint32_t l_v_chip = g_wof->voltvddsense_sensor; if( l_v_chip <= G_iddq_voltages[0] ) { @@ -707,9 +704,6 @@ void calculate_core_leakage( void ) // Calculate all variables that will be used in the core // loop that only need to be calculated once. - // Read the Nest Temperature sensor for calculations & save to amec - g_wof->tempnest_sense = getSensorByGsid(TEMPNEST)->sample; - // Look up Tvpd_leak for calculations when either the core or quad is off // avttemp values in 0.5C. Divide by 2 to convert to 1C g_wof->tvpd_leak_off = @@ -721,7 +715,7 @@ void calculate_core_leakage( void ) // Take the difference between the temperature and tvpd_leak_off // used for multiplier calculation - g_wof->nest_delta_temp = g_wof->tempnest_sense - + g_wof->nest_delta_temp = g_wof->tempnest_sensor - g_wof->tvpd_leak_off; // Calculate IDDQ_TEMP_FACTOR^((TEMPNEST - tvpd_leak)/10) @@ -838,7 +832,7 @@ void calculate_core_leakage( void ) // If TEMPQx is also 0, use TEMPNEST if(temperature == 0) { - temperature = g_wof->tempnest_sense; + temperature = g_wof->tempnest_sensor; } } @@ -883,7 +877,7 @@ void calculate_core_leakage( void ) // If TEMPQ0 is 0, use TEMPNEST if( temperature == 0 ) { - temperature = g_wof->tempnest_sense; + temperature = g_wof->tempnest_sensor; } // Save selected temperature off to amec @@ -916,6 +910,40 @@ void calculate_core_leakage( void ) } + +/** + * calculate_nest_leakage + * + * Description: Function to calculate the nest leakage using VPD leakage data, + * temperature, and voltage + */ +void calculate_nest_leakage( void ) +{ + // Get the desired tvpd leak for nest calculation + // avgtemp in IDDQ table is 0.5C units. Divide by 2 to get 1C + g_wof->tvpd_leak_nest = G_oppb.iddq.avgtemp_vdn >> 1; + + // Subtract tvpd_leak from TEMPNEST sensor + int16_t nest_delta_temp = g_wof->tempnest_sensor - g_wof->tvpd_leak_nest; + + // Calculate multiplier for final calculation; + uint32_t nest_mult = calculate_multiplier( nest_delta_temp ); + + // Save nest leakage to amec structure + g_wof->idc_vdn = (G_oppb.iddq.ivdn*nest_mult) >> 10; +} + +/** + * calculate_AC_currents + * + * Description: Calculate the AC currents + */ +inline void calculate_AC_currents( void ) +{ + g_wof->iac_vdd = g_wof->curvdd_sensor - g_wof->idc_vdd; + g_wof->iac_vdn = g_wof->curvdn_sensor - g_wof->idc_vdn; +} + /** * core_powered_on * @@ -1026,5 +1054,11 @@ int32_t calculate_multiplier( int32_t i_temp ) (int32_t)G_wof_iddq_mult_table[mult_idx+1][1]); } - - +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; +} diff --git a/src/occ_405/wof/wof.h b/src/occ_405/wof/wof.h index 2167843..6d231a0 100644 --- a/src/occ_405/wof/wof.h +++ b/src/occ_405/wof/wof.h @@ -81,21 +81,31 @@ typedef struct // Number of cores on per quad uint8_t cores_on_per_quad[MAX_NUM_QUADS]; // The most recently read value in the sensor VOLTVDDSENSE - uint32_t volt_vdd_sense; + uint32_t voltvddsense_sensor; // The most recently read value in the sensor TEMPPROCTHRMCy where y is core num uint16_t tempprocthrmc[MAX_NUM_CORES]; // The most recently read value in the sensor TEMPNEST - uint16_t tempnest_sense; + uint16_t tempnest_sensor; // The most recently read value in the sensor TEMPQx where x is the quad num uint16_t tempq[MAX_NUM_QUADS]; + // The most recently read value in the sensor CURVDD + uint16_t curvdd_sensor; + // The most recently read value in the sensor CURVDN + uint16_t curvdn_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 uint8_t quad_ivrm_states; // Contains the estimated core leakage based on temp, voltage, and vpd-leak uint32_t idc_vdd; + // Contains the estimated nest leakage based on temp, voltage and vpd-leak + uint32_t idc_vdn; // Contains the leakage current for quads uint32_t idc_quad; + // Contains the AC component of the workload for the core + uint32_t iac_vdd; + // Contains the AC component of the workload for the nest + uint32_t iac_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 @@ -129,6 +139,8 @@ typedef struct uint32_t tvpd_leak_on; // tvpd leak to use when performing cache calculations uint32_t tvpd_leak_cache; + // tvpd leak used for nest leakage calculations + uint32_t tvpd_leak_nest; // Contains the most recently read value from SRAM for Requested active quads uint8_t req_active_quad_update; // Contains the previous value read from shared SRAM for requested active quads @@ -196,15 +208,22 @@ void calculate_core_voltage( void ); void calculate_core_leakage( void ); +void calculate_nest_leakage( void ); + +inline void calculate_AC_currents( void ); + inline bool core_powered_on( uint8_t i_core_num ); uint8_t num_cores_on_in_quad( uint8_t i_quad_num ); inline int32_t interpolate_linear( int32_t i_X, - int32_t i_x1, - int32_t i_x2, - int32_t i_y1, - int32_t i_y2 ); + int32_t i_x1, + int32_t i_x2, + int32_t i_y1, + int32_t i_y2 ); int32_t calculate_multiplier( int32_t i_temp ); + +void read_sensor_data( void ); + #endif -- cgit v1.2.1