summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/occ_405/amec/amec_parm.h13
-rwxr-xr-xsrc/occ_405/amec/amec_parm_table.c14
-rwxr-xr-xsrc/occ_405/main.c6
-rw-r--r--src/occ_405/occ_service_codes.h3
-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
7 files changed, 272 insertions, 5 deletions
diff --git a/src/occ_405/amec/amec_parm.h b/src/occ_405/amec/amec_parm.h
index 7a0cd30..9223f83 100755
--- a/src/occ_405/amec/amec_parm.h
+++ b/src/occ_405/amec/amec_parm.h
@@ -78,6 +78,7 @@ typedef enum
PARM_TEMPPROCTHERMC,
PARM_TEMPNEST,
PARM_TEMPQ,
+ PARM_VOLTVDN,
PARM_QUAD_X_PSTATES,
PARM_IVRM_STATES,
PARM_IDC_VDD,
@@ -85,7 +86,19 @@ typedef enum
PARM_IDC_QUAD,
PARM_IAC_VDD,
PARM_IAC_VDN,
+ PARM_IAC_TDP_VDD,
+ PARM_IAC_TDP_VDN,
PARM_VOLTAGE_IDX,
+ PARM_V_RATIO,
+ PARM_F_RATIO,
+ PARM_V_CLIP,
+ PARM_F_CLIP,
+ PARM_CEFF_TDP_VDD,
+ PARM_CEFF_VDD,
+ PARM_CEFF_RATIO_VDD,
+ PARM_CEFF_TDP_VDN,
+ PARM_CEFF_VDN,
+ PARM_CEFF_RATIO_VDN,
PARM_ALL_CORES_OFF_ISO,
PARM_ALL_CACHES_ON_ISO,
PARM_QUAD_GOOD_CORES_ONLY,
diff --git a/src/occ_405/amec/amec_parm_table.c b/src/occ_405/amec/amec_parm_table.c
index 01baaff..e1ef156 100755
--- a/src/occ_405/amec/amec_parm_table.c
+++ b/src/occ_405/amec/amec_parm_table.c
@@ -150,6 +150,7 @@ amec_parm_t g_amec_parm_list[] = {
AMEC_PARM_UINT16_ARRAY(PARM_TEMPPROCTHERMC, "tempprocthrmc", &g_amec_sys.wof.tempprocthrmc, MAX_NUM_CORES),
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_UINT16(PARM_VOLTVDN, "voltvdn_sensor", &g_amec_sys.wof.voltvdn_sensor),
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),
@@ -157,6 +158,19 @@ amec_parm_t g_amec_parm_list[] = {
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_UINT32(PARM_IAC_TDP_VDD, "iac_tdp_vdd", &g_amec_sys.wof.iac_tdp_vdd),
+ AMEC_PARM_UINT32(PARM_IAC_TDP_VDN, "iac_tdp_vdn", &g_amec_sys.wof.iac_tdp_vdn),
+ AMEC_PARM_UINT32(PARM_V_RATIO, "Vratio", &g_amec_sys.wof.v_ratio),
+ AMEC_PARM_UINT32(PARM_F_RATIO, "Fratio", &g_amec_sys.wof.f_ratio),
+ AMEC_PARM_UINT32(PARM_V_CLIP, "Vclip", &g_amec_sys.wof.v_clip),
+ AMEC_PARM_UINT32(PARM_F_CLIP, "Fclip", &g_amec_sys.wof.f_clip),
+ AMEC_PARM_UINT32(PARM_CEFF_TDP_VDD, "ceff_tdp_vdd", &g_amec_sys.wof.ceff_tdp_vdd),
+ AMEC_PARM_UINT32(PARM_CEFF_VDD, "ceff_vdd", &g_amec_sys.wof.ceff_vdd),
+ AMEC_PARM_UINT32(PARM_CEFF_RATIO_VDD, "ceff_ratio_vdd", &g_amec_sys.wof.ceff_ratio_vdd),
+ AMEC_PARM_UINT32(PARM_CEFF_TDP_VDN, "ceff_tdp_vdn", &g_amec_sys.wof.ceff_tdp_vdn),
+ AMEC_PARM_UINT32(PARM_CEFF_VDN, "ceff_vdn", &g_amec_sys.wof.ceff_vdn),
+ AMEC_PARM_UINT32(PARM_CEFF_RATIO_VDN, "ceff_ratio_vdn", &g_amec_sys.wof.ceff_ratio_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),
diff --git a/src/occ_405/main.c b/src/occ_405/main.c
index 0779319..eca4705 100755
--- a/src/occ_405/main.c
+++ b/src/occ_405/main.c
@@ -702,12 +702,18 @@ void read_pgpe_header(void)
g_amec->wof.vfrt_tbls_main_mem_addr = in32(PGPE_WOF_TBLS_ADDR_PTR);
g_amec->wof.vfrt_tbls_len = in32(PGPE_WOF_TBLS_LEN_PTR);
+
MAIN_TRAC_IMP("Read WOF Tables Main Memory Address[0x%08x], Len[0x%08x],"
" Active Quads Address[0x%08x]",
g_amec->wof.vfrt_tbls_main_mem_addr,
g_amec->wof.vfrt_tbls_len,
g_amec->wof.active_quads_sram_addr );
+ // TODO: RTC 169955 - Read Vratio, Fratio, Vclip, Fclip from shared SRAM
+ g_amec->wof.v_ratio = 0;
+ g_amec->wof.f_ratio = 0;
+ g_amec->wof.v_clip = 0;
+ g_amec->wof.f_clip = 0;
// Extract important WOF data into global space
read_wof_header();
diff --git a/src/occ_405/occ_service_codes.h b/src/occ_405/occ_service_codes.h
index beb46b5..5df9ecc 100644
--- a/src/occ_405/occ_service_codes.h
+++ b/src/occ_405/occ_service_codes.h
@@ -125,6 +125,9 @@ enum occReasonCode
WOF_VFRT_REQ_FAILURE = 0xD8,
INVALID_MAGIC_NUMBER = 0xDA,
+ DIVIDE_BY_ZERO_ERROR = 0xDB,
+
+
/// Success!
OCC_SUCCESS_REASON_CODE = 0xFF,
};
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