From c9954444fc8df5fa0bd79b57ce8a6434a7e0714e Mon Sep 17 00:00:00 2001 From: mbroyles Date: Tue, 30 Jan 2018 15:35:23 -0600 Subject: Calculate Pstate from a frequency starting at max frequency instead of min Change-Id: Ic5c59d9a633a0c278b2dc20e3a04cefc13bd63dc CQ: SW415606 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/52948 Tested-by: FSP CI Jenkins Reviewed-by: Andres A. Lugo-Reyes Reviewed-by: William A. Bryan Reviewed-by: Christopher J. Cain Reviewed-by: Martha Broyles --- src/occ_405/amec/amec_pcap.c | 30 +++++++----------------------- src/occ_405/amec/amec_sys.h | 1 - src/occ_405/cmdh/cmdh_fsp_cmds.c | 24 ++++++++++++++++++++++++ src/occ_405/cmdh/cmdh_fsp_cmds.h | 1 + src/occ_405/gpu/gpu.c | 2 +- src/occ_405/proc/proc_pstate.c | 36 +++++++++++++++++++++++++----------- 6 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/occ_405/amec/amec_pcap.c b/src/occ_405/amec/amec_pcap.c index d2295ee..6d65a89 100755 --- a/src/occ_405/amec/amec_pcap.c +++ b/src/occ_405/amec/amec_pcap.c @@ -281,18 +281,6 @@ void amec_gpu_pcap(bool i_oversubscription, bool i_active_pcap_changed, int32_t l_gpu_cap_mw = g_amec->gpu[i].pcap.gpu_max_pcap_mw; } - // If not already at the min then set to min if trying to reduce power and proc/memory are at min - if( (i_avail_power < 0) && (g_amec->proc[0].pwr_votes.ppb_fmax == g_amec->sys.fmin) && - (g_amec->pcap.active_mem_level) && (l_gpu_cap_mw != g_amec->gpu[i].pcap.gpu_min_pcap_mw) ) - { - l_gpu_cap_mw = g_amec->gpu[i].pcap.gpu_min_pcap_mw; - if(g_amec->gpu[i].pcap.gpu_desired_pcap_mw != l_gpu_cap_mw) - { - TRAC_ERR("amec_gpu_pcap: Forcing GPU%d to minimum pwr limit %dmW", i, l_gpu_cap_mw); - g_amec->gpu[i].pcap.gpu_min_cap_required = TRUE; - } - } - // check if this is a new power limit if(g_amec->gpu[i].pcap.gpu_desired_pcap_mw != l_gpu_cap_mw) { @@ -306,12 +294,6 @@ void amec_gpu_pcap(bool i_oversubscription, bool i_active_pcap_changed, int32_t } g_amec->gpu[i].pcap.gpu_desired_pcap_mw = l_gpu_cap_mw; - - if( (g_amec->gpu[i].pcap.gpu_min_cap_required) && (l_gpu_cap_mw != g_amec->gpu[i].pcap.gpu_min_pcap_mw) ) - { - TRAC_ERR("amec_gpu_pcap: GPU%d no longer requires minimum pwr limit %dmW", i, g_amec->gpu[i].pcap.gpu_min_pcap_mw); - g_amec->gpu[i].pcap.gpu_min_cap_required = FALSE; - } } } } // for each GPU @@ -417,15 +399,17 @@ void amec_pcap_calc(const bool i_oversub_state) } } // check if need to reduce power and frequency is already at the min - else if((l_avail_power < 0) && (g_amec->proc[0].pwr_votes.ppb_fmax == g_amec->sys.fmin)) + else if(l_avail_power < 0) { - // frequency at min now shed additional power by throttling - // memory if memory is currently un-throttled due to power - if (g_amec->pcap.active_mem_level == 0) + L_ticks_mem_pwr_available = 0; + + // if memory is not throttled and frequency is at min shed additional power + // by throttling memory + if( (g_amec->pcap.active_mem_level == 0) && + (g_amec->proc[0].pwr_votes.ppb_fmax == g_amec->sys.fmin) ) { TRAC_IMP("PCAP: Throttling memory"); g_amec->pcap.active_mem_level = 1; - L_ticks_mem_pwr_available = 0; } } else diff --git a/src/occ_405/amec/amec_sys.h b/src/occ_405/amec/amec_sys.h index d253889..2d26547 100755 --- a/src/occ_405/amec/amec_sys.h +++ b/src/occ_405/amec/amec_sys.h @@ -460,7 +460,6 @@ typedef struct { bool check_pwr_limit; // Indicates if need to read power limits from GPU bool pwr_limits_read; // Indicates if power limits were read i.e. have min/max bool set_failed; // Indicates if failed to set power limit - bool gpu_min_cap_required; // Indicates if GPU requires min cap uint32_t gpu_min_pcap_mw; // Min GPU power limit in mW read from the GPU uint32_t gpu_max_pcap_mw; // Max GPU power limit in mW read from the GPU uint32_t gpu_desired_pcap_mw; // AMEC determined pcap in mW to set diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.c b/src/occ_405/cmdh/cmdh_fsp_cmds.c index c28add1..c1f29cf 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds.c @@ -707,6 +707,30 @@ ERRL_RC cmdh_poll_v20(cmdh_fsp_rsp_t * o_rsp_ptr) l_extnSensorList[l_sensorHeader.count].data[5] = CONVERT_UINT32_UINT8_LOWER_LOW(g_amec->proc[0].chip_f_reason_history); l_sensorHeader.count++; + // WOF clip info from PGPE + l_extnSensorList[l_sensorHeader.count].name = EXTN_NAME_WOFC; + if(g_amec->wof.wof_disabled) + { + // WOF disabled put 0xFF for clip followed by WOF disable reason + l_extnSensorList[l_sensorHeader.count].data[0] = 0xFF; + l_extnSensorList[l_sensorHeader.count].data[1] = 0x00; + l_extnSensorList[l_sensorHeader.count].data[2] = CONVERT_UINT32_UINT8_UPPER_HIGH(g_amec->wof.wof_disabled); + l_extnSensorList[l_sensorHeader.count].data[3] = CONVERT_UINT32_UINT8_UPPER_LOW(g_amec->wof.wof_disabled); + l_extnSensorList[l_sensorHeader.count].data[4] = CONVERT_UINT32_UINT8_LOWER_HIGH(g_amec->wof.wof_disabled); + l_extnSensorList[l_sensorHeader.count].data[5] = CONVERT_UINT32_UINT8_LOWER_LOW(g_amec->wof.wof_disabled); + } + else + { + // WOF is enabled return WOF information from PGPE + // These are read from PGPE shared SRAM every WOF cycle + l_extnSensorList[l_sensorHeader.count].data[0] = g_amec->wof.f_clip_ps; + l_extnSensorList[l_sensorHeader.count].data[1] = CONVERT_UINT16_UINT8_HIGH(g_amec->wof.v_clip); + l_extnSensorList[l_sensorHeader.count].data[2] = CONVERT_UINT16_UINT8_LOW(g_amec->wof.v_clip); + l_extnSensorList[l_sensorHeader.count].data[3] = CONVERT_UINT16_UINT8_HIGH(g_amec->wof.v_ratio); + l_extnSensorList[l_sensorHeader.count].data[4] = CONVERT_UINT16_UINT8_LOW(g_amec->wof.v_ratio); + } + l_sensorHeader.count++; + // add any non-0 error history counts for(l_err_hist_idx=0; l_err_hist_idx < ERR_HISTORY_SIZE; l_err_hist_idx++) { diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.h b/src/occ_405/cmdh/cmdh_fsp_cmds.h index 5ab7fe1..4405b1d 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds.h +++ b/src/occ_405/cmdh/cmdh_fsp_cmds.h @@ -70,6 +70,7 @@ typedef enum #define EXTN_NAME_FTURBO 0x46540000 // "FT" #define EXTN_NAME_FUTURBO 0x46555400 // "FUT" #define EXTN_NAME_CLIP 0x434C4950 // "CLIP" +#define EXTN_NAME_WOFC 0x574F4643 // "WOFC" #define EXTN_NAME_ERRHIST 0x45525248 // "ERRH" #define MAX_EXTN_SENSORS 32 diff --git a/src/occ_405/gpu/gpu.c b/src/occ_405/gpu/gpu.c index 72697eb..6e01d67 100755 --- a/src/occ_405/gpu/gpu.c +++ b/src/occ_405/gpu/gpu.c @@ -51,7 +51,7 @@ // Number calls with assumption the GPU SM task is called every other tick #define GPU_TEMP_READ_1S ( 1000000 / (MICS_PER_TICK * 2) ) -#define GPU_TIMEOUT ( 5000000 / (MICS_PER_TICK *2) ) +#define GPU_TIMEOUT ( 10000000 / (MICS_PER_TICK *2) ) #define GPU_TICKS_TO_100MS ( 100000 / (MICS_PER_TICK * 2) ) #define GPU_TICKS_TO_1S ( 1000000 / (MICS_PER_TICK * 2) ) diff --git a/src/occ_405/proc/proc_pstate.c b/src/occ_405/proc/proc_pstate.c index 6d68863..12e3ac1 100755 --- a/src/occ_405/proc/proc_pstate.c +++ b/src/occ_405/proc/proc_pstate.c @@ -123,7 +123,7 @@ Pstate proc_freq2pstate(uint32_t i_freq_mhz) { int8_t l_pstate = 0; int8_t l_temp_pstate = 0; - int32_t l_temp_freq = 0; + int32_t l_temp_freq_khz = 0; uint32_t l_freq_khz = 0; do @@ -131,28 +131,42 @@ Pstate proc_freq2pstate(uint32_t i_freq_mhz) // Freq Units need to be in kHz, not Mhz for the following calculations l_freq_khz = i_freq_mhz * 1000; - // Make sure that we don't ever get a frequency below the min Freq from - // def file + // Return Pmin if the frequency is below or equal to the min Freq for the lowest Pstate + if(l_freq_khz <= G_oppb.frequency_min_khz ) + { + l_pstate = G_oppb.pstate_min; + break; + } + if(i_freq_mhz < G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY]) { l_freq_khz = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY] * 1000; } - if(l_freq_khz < G_proc_fmax_mhz * 1000) + if(l_freq_khz < G_oppb.frequency_max_khz) { - // First, calculate the delta between passed in freq, and Pmin - l_temp_freq = l_freq_khz - G_oppb.frequency_min_khz; + // First, calculate the delta between passed in freq, and Pmax + l_temp_freq_khz = G_oppb.frequency_max_khz - l_freq_khz; // Next, calculate how many Pstate steps there are in that delta - l_temp_pstate = l_temp_freq / (int32_t) G_oppb.frequency_step_khz; + l_temp_pstate = l_temp_freq_khz / (int32_t) G_oppb.frequency_step_khz; - // Lastly, calculate Pstate, by adding delta Pstate steps to Pmin - l_pstate = G_oppb.pstate_min - l_temp_pstate; + // Higher Pstates are lower frequency, add number of steps to the highest frequency Pstate + l_pstate = PMAX + l_temp_pstate; + + // As an extra safety check make sure the calculated Pstate is not out of the PGPE range + // this should never happen! + if(l_pstate > G_oppb.pstate_min) + { + TRAC_ERR("proc_freq2pstate: Invalid calculated Pstate[%d] for freq[%dkHz] PGPE min Pstate[%d] freq[%dkHz]", + l_pstate, l_freq_khz, G_oppb.pstate_min, G_oppb.frequency_min_khz); + l_pstate = G_oppb.pstate_min; + } } else { - // Freq is higher than maximum frequency -- return Pmax - l_pstate = PMAX + (G_oppb.frequency_max_khz - G_proc_fmax_mhz*1000)/G_oppb.frequency_step_khz; + // Freq is higher than or equal to the maximum frequency -- return Pmax + l_pstate = PMAX; } } while(0); -- cgit v1.2.1