From 6d29cab23da5bacaf0772bb8dd6265c4b442760c Mon Sep 17 00:00:00 2001 From: Wael El-Essawy Date: Mon, 2 May 2016 22:20:14 -0500 Subject: Pstate Infrastructure & Support config data required for active state - Support all config data required for active state. - Set 'active ready' bit in poll response when all config data has been received. - Rewrite & rename proc_gpsm_pstate_initialize() - Delete GPSM, doesn't exist. - Put in TODO call PGPE to enable pstates this will also be telling PGPE how to set PMCR mode register (OCC control pstates or OPAL). - Initialize globals for fmax, fmin, pmax and mhz_per_pstate with temporary hard codes until PGPE is available. - Call to "proc_pstate_initialize()" moved to state transition to observation - Cleanup proc_freq2pstate() - rewrite amec_slv_freq_smh() - the calls to proc_set_core_bounds() and proc_set_core_pstate() will be replaced with 1 IPC call to the PGPE to set pmin/pmax given all cores or set pstate for all given cores. - Remove all DCM related code. Change-Id: I449d188b2cffc345afca19717dcbea037f159114 RTC:130224 RTC:150935 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23977 Tested-by: FSP CI Jenkins Reviewed-by: Wael El-Essawy --- src/include/occhw_common.h | 2 +- src/occ_405/amec/amec_data.c | 6 +- src/occ_405/amec/amec_freq.c | 41 +- src/occ_405/amec/amec_oversub.c | 4 +- src/occ_405/amec/amec_parm_table.c | 3 - src/occ_405/amec/amec_sensors_power.c | 89 ++- src/occ_405/amec/amec_slave_smh.c | 105 ---- src/occ_405/amec/amec_slave_smh.h | 1 - src/occ_405/cent/centaur_control.c | 10 +- src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c | 406 ++++++-------- src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h | 107 ++-- src/occ_405/cmdh/cmdh_mnfg_intf.c | 6 +- src/occ_405/dcom/dcom.c | 50 -- src/occ_405/dcom/dcom.h | 27 +- src/occ_405/dcom/dcomMasterTx.c | 3 - src/occ_405/dcom/dcomSlaveTx.c | 3 - src/occ_405/dcom/dcom_thread.c | 3 - src/occ_405/mode.c | 39 -- src/occ_405/mode.h | 9 +- src/occ_405/occ_sys_config.c | 2 +- src/occ_405/occ_sys_config.h | 16 +- src/occ_405/proc/proc_pstate.c | 879 ++++-------------------------- src/occ_405/proc/proc_pstate.h | 34 +- src/occ_405/state.c | 17 +- src/occ_405/thread/chom.c | 17 +- 25 files changed, 436 insertions(+), 1443 deletions(-) (limited to 'src') diff --git a/src/include/occhw_common.h b/src/include/occhw_common.h index 807a57a..f49ed8a 100644 --- a/src/include/occhw_common.h +++ b/src/include/occhw_common.h @@ -246,7 +246,7 @@ extern unsigned int g_ocb_timer_divider; //grm /// values. To avoid bugs, Pstate register fields should always be extracted /// to a variable of type Pstate. If the size of Pstate variables ever /// changes we will have to revisit this convention. -typedef int8_t Pstate; +typedef uint8_t Pstate; /// A DPLL frequency code /// diff --git a/src/occ_405/amec/amec_data.c b/src/occ_405/amec/amec_data.c index 97aa8a7..61af8fe 100755 --- a/src/occ_405/amec/amec_data.c +++ b/src/occ_405/amec/amec_data.c @@ -64,6 +64,8 @@ // Globals //************************************************************************* extern uint8_t G_occ_interrupt_type; +extern uint32_t G_proc_fmin; +extern uint32_t G_proc_fmax; //************************************************************************* // Function Prototypes @@ -112,8 +114,8 @@ errlHndl_t AMEC_data_write_fcurr(const OCC_MODE i_mode) // min/max for AMEC component if(G_occ_interrupt_type != FSP_SUPPORTED_OCC) { - g_amec->sys.fmax = G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO]; - g_amec->sys.fmin = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY]; + g_amec->sys.fmax = G_proc_fmax; + g_amec->sys.fmin = G_proc_fmin; // = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY] TRAC_INFO("AMEC_data_write_fcurr: New frequency range Fmin[%u] Fmax[%u]", g_amec->sys.fmin, diff --git a/src/occ_405/amec/amec_freq.c b/src/occ_405/amec/amec_freq.c index 025e088..ea14c29 100755 --- a/src/occ_405/amec/amec_freq.c +++ b/src/occ_405/amec/amec_freq.c @@ -501,6 +501,9 @@ void amec_slv_voting_box(void) } } +#endif // @TODO - TEMP - Code not ready yet + + // Function Specification // // Name: amec_slv_freq_smh @@ -518,8 +521,8 @@ void amec_slv_freq_smh(void) /*------------------------------------------------------------------------*/ /* Local Variables */ /*------------------------------------------------------------------------*/ - uint16_t k = 0; - int8_t l_pstate = 0; + uint16_t k = 0; + Pstate l_pstate[MAX_NUM_CORES]; /*------------------------------------------------------------------------*/ /* Code */ @@ -527,30 +530,24 @@ void amec_slv_freq_smh(void) for (k=0; kproc[0].core[k].f_sms) - { - case AMEC_CORE_FREQ_IDLE_STATE: - // Translate frequency request into a Pstate - l_pstate = proc_freq2pstate(g_amec->proc[0].core[k].f_request); + // Translate frequency requests into pstates + l_pstate[k]= proc_freq2pstate(g_amec->proc[0].core[k].f_request); + } - // Fall through - case AMEC_CORE_FREQ_PROCESS_STATE: - if(G_sysConfigData.system_type.kvm) - { - // update core bounds on kvm systems - proc_set_core_bounds(gpst_pmin(&G_global_pstate_table) + 1, (Pstate) l_pstate, k); - } - else - { - // update core pstate request on non-kvm systems - proc_set_core_pstate((Pstate) l_pstate, k); - } - break; - } + // TODO: if this is an OPAL system, send PGPE an IPC to set clipping bounds + // otherwise, set send PGPE an IPC to set pstates + + if(G_sysConfigData.system_type.kvm) + { + // Send IPC with G_proc_pmin and l_pstate to set pmin and pmax clips } + else + { + // send an IPC with l_pstate to set pstates for all Cores + } + } -#endif // @TODO - TEMP - Code not ready yet // Function Specification // diff --git a/src/occ_405/amec/amec_oversub.c b/src/occ_405/amec/amec_oversub.c index beff792..3aaf6ac 100755 --- a/src/occ_405/amec/amec_oversub.c +++ b/src/occ_405/amec/amec_oversub.c @@ -110,9 +110,6 @@ void amec_oversub_isr(void) // If RTL doesn't control it, do it here if(g_amec->oversub_status.oversubLatchAmec == 0) { - // Set PMC Pmax_clip to Pmin and throttle all Cores via OCI write to PMC - amec_oversub_pmax_clip(gpst_pmin(&G_global_pstate_table)); - // TODO: Throttle all Centaurs via PORE-GPE by setting 'Emergency Throttle' g_amec->oversub_status.oversubReasonLatchCount = OVERSUB_REASON_DELAY_4MS; @@ -150,6 +147,7 @@ void amec_oversub_isr(void) } + // Function Specification // // Name: amec_oversub_check diff --git a/src/occ_405/amec/amec_parm_table.c b/src/occ_405/amec/amec_parm_table.c index 282a695..cbd994d 100755 --- a/src/occ_405/amec/amec_parm_table.c +++ b/src/occ_405/amec/amec_parm_table.c @@ -118,9 +118,6 @@ amec_parm_t g_amec_parm_list[] = { AMEC_PARM_UINT16(PARM_SYS_FMAX,"sys_fmax",&g_amec_sys.sys.fmax), AMEC_PARM_UINT16(PARM_SYS_FMIN,"sys_fmin",&g_amec_sys.sys.fmin), - // Global Pstate table -// @TODO - TEMP - global state table changes in P9 -// AMEC_PARM_RAW(PARM_GPST,"gpst",&G_global_pstate_table,sizeof(GlobalPstateTable)), // MHz per pstate AMEC_PARM_UINT32(PARM_PSTATE_MHZ,"pstate_mhz",&G_mhz_per_pstate), // frequency reason code per-core diff --git a/src/occ_405/amec/amec_sensors_power.c b/src/occ_405/amec/amec_sensors_power.c index ef70864..fd3e950 100755 --- a/src/occ_405/amec/amec_sensors_power.c +++ b/src/occ_405/amec/amec_sensors_power.c @@ -433,69 +433,60 @@ void amec_update_vrm_sensors(void) /* Code */ /*------------------------------------------------------------------------*/ - // Check if we have access to SPIVID. In DCMs only Master OCC has access to - // the SPIVID. - if (G_dcm_occ_role == OCC_DCM_MASTER) + // VR_FAN and SOFT_OC come from SPIVID + l_rc = vrm_read_state(SPIVRM_PORT(0), + &l_minus_np1_regmode, + &l_minus_n_regmode, + &l_vrfan, + &l_softoc); + if (l_rc == 0) { - // VR_FAN and SOFT_OC come from SPIVID - l_rc = vrm_read_state(SPIVRM_PORT(0), - &l_minus_np1_regmode, - &l_minus_n_regmode, - &l_vrfan, - &l_softoc); - - if (l_rc == 0) - { - // Update the VR_FAN sensor - sensor_update( AMECSENSOR_PTR(VRFAN250USPROC), (uint16_t)l_vrfan ); + // Update the VR_FAN sensor + sensor_update( AMECSENSOR_PTR(VRFAN250USPROC), (uint16_t)l_vrfan ); - // Clear our error count - L_error_count = 0; + // Clear our error count + L_error_count = 0; - // No longer reading gpio from APSS in GA1 due to instability in - // APSS composite mode - //apss_gpio_get(l_pin, &l_pin_value); + // No longer reading gpio from APSS in GA1 due to instability in + // APSS composite mode + //apss_gpio_get(l_pin, &l_pin_value); - // VR_HOT sensor is a counter of number of times the VRHOT signal - // has been asserted - l_vrhot_count = AMECSENSOR_PTR(VRHOT250USPROC)->sample; + // VR_HOT sensor is a counter of number of times the VRHOT signal + // has been asserted + l_vrhot_count = AMECSENSOR_PTR(VRHOT250USPROC)->sample; - // Check if VR_FAN is asserted AND if 'fans_full_speed' GPIO is ON. - // Note that this GPIO is active low. - if (AMECSENSOR_PTR(VRFAN250USPROC)->sample && !(l_pin_value)) - { - // VR_FAN is asserted and 'fans_full_speed' GPIO is ON, - // then increment our VR_HOT counter - if (l_vrhot_count < g_amec->vrhotproc.setpoint) - { - l_vrhot_count++; - } - } - else + // Check if VR_FAN is asserted AND if 'fans_full_speed' GPIO is ON. + // Note that this GPIO is active low. + if (AMECSENSOR_PTR(VRFAN250USPROC)->sample && !(l_pin_value)) + { + // VR_FAN is asserted and 'fans_full_speed' GPIO is ON, + // then increment our VR_HOT counter + if (l_vrhot_count < g_amec->vrhotproc.setpoint) { - // Reset our VR_HOT counter - l_vrhot_count = 0; + l_vrhot_count++; } - sensor_update(AMECSENSOR_PTR(VRHOT250USPROC), l_vrhot_count); } else { - // Increment our error count - L_error_count++; - - // Don't allow the error count to wrap - if (L_error_count == 0) - { - L_error_count = 0xFF; - } + // Reset our VR_HOT counter + l_vrhot_count = 0; } + sensor_update(AMECSENSOR_PTR(VRHOT250USPROC), l_vrhot_count); } - - if( 1 ) + else { - sensor_update( AMECSENSOR_PTR(VRFAN250USMEM), 0 ); - sensor_update( AMECSENSOR_PTR(VRHOT250USMEM), 0 ); + // Increment our error count + L_error_count++; + + // Don't allow the error count to wrap + if (L_error_count == 0) + { + L_error_count = 0xFF; + } } + + sensor_update( AMECSENSOR_PTR(VRFAN250USMEM), 0 ); + sensor_update( AMECSENSOR_PTR(VRHOT250USMEM), 0 ); } #endif // #if 0 @TODO - TEMP - SPIVRMs are no longer defined, pgp_vrm.h and vrm.c are not present diff --git a/src/occ_405/amec/amec_slave_smh.c b/src/occ_405/amec/amec_slave_smh.c index 1b7543f..07ad2ff 100755 --- a/src/occ_405/amec/amec_slave_smh.c +++ b/src/occ_405/amec/amec_slave_smh.c @@ -273,107 +273,6 @@ void amec_slv_check_apss_fail(void) g_amec->proc[0].pwr_votes.apss_pmax_clip_freq = l_pmax_rail_freq; } -// Function Specification -// -// Name: amec_slv_pstate_uplift_check -// -// Description: This function checks if the Global Pstate table needs to be -// modified with a voltage uplift. If an uplift has been requested, it will -// proceed to update every entry of the table. -// -// End Function Specification -void amec_slv_pstate_uplift_check(void) -{ - /*------------------------------------------------------------------------*/ - /* Local Variables */ - /*------------------------------------------------------------------------*/ - Pstate l_pmin = 0; - Pstate l_pmax = 0; - uint16_t i = 0; - - /*------------------------------------------------------------------------*/ - /* Code */ - /*------------------------------------------------------------------------*/ - - // Check if a new uplift request for Vdd has been made - if ((G_sysConfigData.vdd_vid_delta != 0) || - (G_sysConfigData.vcs_vid_delta != 0)) - { - TRAC_INFO("Updating Global Pstate table with requested uplift values!"); - - // STEP 1: - // Prevent any Pstate changes by locking the PMC Rail so that - // Pmax_rail = Pmin_rail + 1 - l_pmin = gpst_pmin(&G_global_pstate_table) + 1; - - // Set the Pmax_rail register via OCI write - amec_oversub_pmax_clip(l_pmin); - - // STEP 2: - // Update all entries of the Global Pstate table using uplift provided - for (i=0; ipstate_foverride_enable = 1; - if (g_amec->proc[0].core_max_freq == - G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO]) - { - // If we are at turbo frequency, then perform a single -1 Pstate - // jump instead - g_amec->pstate_foverride = g_amec->proc[0].core_max_freq - - (uint16_t)(G_global_pstate_table.frequency_step_khz / 1000); - } - else - { - g_amec->pstate_foverride = g_amec->proc[0].core_max_freq + - (uint16_t)(G_global_pstate_table.frequency_step_khz / 1000); - } - - // After updating Global Pstate table, reset the delta to 0 - G_sysConfigData.vdd_vid_delta = 0; - G_sysConfigData.vcs_vid_delta = 0; - } - else - { - // Check if we updated the Global Pstate table - if (g_amec->pstate_foverride_enable) - { - // STEP 5: - // Go back to the initial Pstate by disabling the override enable - // and maxing out the frequency request so it doesn't influence - // the final vote in the voting box - g_amec->pstate_foverride_enable = 0; - g_amec->pstate_foverride = 0xFFFF; - } - } -} - #endif // #if 0 @TODO - TEMP - Not ready yet in Phase 1 // Function Specification @@ -393,10 +292,6 @@ void amec_slv_common_tasks_pre(void) AMEC_DBG("\tAMEC Slave Pre-State Common\n"); - // Check if we need to apply a voltage uplift to the Global Pstate table -// @TODO - TEMP: Not Ready yet in Phase 1. -// amec_slv_pstate_uplift_check(); - // Update the FW Worst Case sensors every tick amec_update_fw_sensors(); diff --git a/src/occ_405/amec/amec_slave_smh.h b/src/occ_405/amec/amec_slave_smh.h index 729a2ba..d511c63 100755 --- a/src/occ_405/amec/amec_slave_smh.h +++ b/src/occ_405/amec/amec_slave_smh.h @@ -70,7 +70,6 @@ extern bool G_apss_lower_pmax_rail; // Function Prototypes //************************************************************************* void amec_slv_check_apss_fail(void); -void amec_slv_pstate_uplift_check(void); void amec_update_proc_core_group(uint8_t); diff --git a/src/occ_405/cent/centaur_control.c b/src/occ_405/cent/centaur_control.c index 801bd04..82fddc9 100755 --- a/src/occ_405/cent/centaur_control.c +++ b/src/occ_405/cent/centaur_control.c @@ -179,8 +179,8 @@ void cent_update_nlimits(uint32_t i_cent) &G_sysConfigData.mem_throt_limits[i_cent][1]; //Minimum N value is not state dependent - l_active_limits01->min_n_per_mba = l_state_limits01->min_ot_n_per_mba; - l_active_limits23->min_n_per_mba = l_state_limits23->min_ot_n_per_mba; + l_active_limits01->min_n_per_mba = l_state_limits01->min_n_per_mba; + l_active_limits23->min_n_per_mba = l_state_limits23->min_n_per_mba; //oversubscription? if(AMEC_INTF_GET_OVERSUBSCRIPTION()) @@ -199,10 +199,8 @@ void cent_update_nlimits(uint32_t i_cent) } else //DPS, TURBO, FFO, and SPS modes will use these settings { - l_mba01_mba_maxn = l_state_limits01->turbo_n_per_mba; - l_mba01_chip_maxn = l_state_limits01->turbo_n_per_chip; - l_mba23_mba_maxn = l_state_limits23->turbo_n_per_mba; - l_mba23_chip_maxn = l_state_limits23->turbo_n_per_chip; + l_mba01_mba_maxn = l_state_limits01->pcap1_n_per_mba; + l_mba23_mba_maxn = l_state_limits23->pcap1_n_per_mba; } l_active_limits01->max_n_per_chip = l_mba01_chip_maxn; diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c index 00c041b..2474600 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c @@ -45,15 +45,14 @@ #define FREQ_FORMAT_PWR_MODE_NUM 6 #define FREQ_FORMAT_BYTES_PER_MODE 3 #define FREQ_FORMAT_BASE_DATA_SZ (sizeof(cmdh_store_mode_freqs_t) - sizeof(cmdh_fsp_cmd_header_t)) -#define FREQ_FORMAT_10_NUM_FREQS 3 + #define FREQ_FORMAT_11_NUM_FREQS 4 +#define FREQ_FORMAT_20_NUM_FREQS 6 -#define DATA_FREQ_VERSION_0 0 -#define DATA_FREQ_VERSION_10 0x10 #define DATA_FREQ_VERSION_11 0x11 +#define DATA_FREQ_VERSION_20 0x20 -#define DATA_PCAP_VERSION_0 0 -#define DATA_PCAP_VERSION_10 0x10 +#define DATA_PCAP_VERSION_20 0x20 #define DATA_SYS_VERSION_20 0x20 @@ -66,13 +65,19 @@ #define DATA_MEM_CFG_VERSION_20 0x20 -#define DATA_MEM_THROT_VERSION_1 1 -#define DATA_MEM_THROT_VERSION_10 0x10 +#define DATA_MEM_THROT_VERSION_20 0x20 #define DATA_VOLT_UPLIFT_VERSION 0 extern uint8_t G_occ_interrupt_type; +extern uint32_t G_proc_fmin; +extern uint32_t G_proc_fmax; +extern uint32_t G_khz_per_pstate; + +extern uint8_t G_proc_pmin; +extern uint8_t G_proc_pmax; + typedef struct data_req_table { uint32_t mask; @@ -244,14 +249,11 @@ errlHndl_t data_store_freq_data(const cmdh_fsp_cmd_t * i_cmd_ptr, cmdh_fsp_rsp_t * o_rsp_ptr) { errlHndl_t l_err = NULL; - uint16_t l_req_freq; cmdh_store_mode_freqs_t* l_cmdp = (cmdh_store_mode_freqs_t*)i_cmd_ptr; uint8_t* l_buf = ((uint8_t*)(l_cmdp)) + sizeof(cmdh_store_mode_freqs_t); uint16_t l_data_length; uint32_t l_mode_data_sz; - uint32_t i; uint16_t l_freq = 0; - uint8_t l_mode = 0; uint8_t l_count = FREQ_FORMAT_PWR_MODE_NUM; uint16_t l_table[OCC_MODE_COUNT] = {0}; @@ -267,10 +269,9 @@ errlHndl_t data_store_freq_data(const cmdh_fsp_cmd_t * i_cmd_ptr, // the format is 0x10 and we don't have room for the 3 2B frequencies, OR // the format is 0x11 and we don;t have room for the 4 2B frequencies. if((l_data_length < FREQ_FORMAT_BASE_DATA_SZ) || - ((l_cmdp->version != DATA_FREQ_VERSION_0) && (l_cmdp->version != DATA_FREQ_VERSION_10) && - (l_cmdp->version != DATA_FREQ_VERSION_11)) || - ((DATA_FREQ_VERSION_10 == l_cmdp->version) && (l_mode_data_sz != (FREQ_FORMAT_10_NUM_FREQS * 2))) || - ((DATA_FREQ_VERSION_11 == l_cmdp->version) && (l_mode_data_sz != (FREQ_FORMAT_11_NUM_FREQS * 2)))) + ((l_cmdp->version != DATA_FREQ_VERSION_11) && (l_cmdp->version != DATA_FREQ_VERSION_20)) || + ((DATA_FREQ_VERSION_11 == l_cmdp->version) && (l_mode_data_sz != (FREQ_FORMAT_11_NUM_FREQS * 2))) || + ((DATA_FREQ_VERSION_20 == l_cmdp->version) && (l_mode_data_sz != (FREQ_FORMAT_20_NUM_FREQS * 2)))) { CMDH_TRAC_ERR("Invalid Frequency Data packet: data_length[%u] version[%u] l_count[%u] l_mode_data_sz[%u]", l_data_length, l_cmdp->version, l_count, l_mode_data_sz); @@ -281,135 +282,120 @@ errlHndl_t data_store_freq_data(const cmdh_fsp_cmd_t * i_cmd_ptr, if(OCC_MASTER != G_occ_role) { // We want to ignore this cnfg data if we are not the master. + CMDH_TRAC_INFO("Received a Frequncy Data Packet on a Slave OCC: Ignore!"); break; } - if(DATA_FREQ_VERSION_0 == l_cmdp->version) - { - // parse the packed 3-byte data entries and store them - // in the global data structure. - for(i = 0; i < l_mode_data_sz; i += FREQ_FORMAT_BYTES_PER_MODE) - { - l_mode = l_buf[i]; - l_freq = (l_buf[i+1] << 8 | l_buf[i+2]); - - if(l_mode == OCC_MODE_NOMINAL && !l_freq) - { - CMDH_TRAC_ERR("Received a frequency of 0 MHZ for nominal"); - cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); - break; - } - - if(l_mode >= OCC_MODE_COUNT) - { - CMDH_TRAC_ERR("Unrecognized frequency mode=%d ", - l_mode); - cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); - break; - } - - // FFO Mode Checks - only need to verify when *in* FFO mode - if( ( OCC_MODE_FFO == CURRENT_MODE() ) - && ( OCC_MODE_FFO == l_mode ) ) - { - l_req_freq = l_freq; - - // Check and make sure that FFO freq >= Fmin, if not, log an error. - if( l_freq < l_table[OCC_MODE_MIN_FREQUENCY] ) - { - l_freq = l_table[OCC_MODE_MIN_FREQUENCY]; - } - - // Check and make sure that FFO freq <= Fmax, if not, log an error. - else if ( l_freq > l_table[OCC_MODE_TURBO] ) - { - l_freq = l_table[OCC_MODE_TURBO]; - } - - // Log an error if we could not honor the requested FFO frequency, but keep going. - if(l_req_freq != l_freq) - { - CMDH_TRAC_ERR("FFO Freq out of range. request=%d, limit=%d ", - l_req_freq, l_freq); - /* @ - * @errortype - * @moduleid DATA_STORE_FREQ_DATA - * @reasoncode INVALID_INPUT_DATA - * @userdata1 requested frequency - * @userdata2 frequency used - * @userdata4 OCC_NO_EXTENDED_RC - * @devdesc OCC recieved an invalid FFO frequency - */ - l_err = createErrl(DATA_STORE_FREQ_DATA, - INVALID_INPUT_DATA, - OCC_NO_EXTENDED_RC, - ERRL_SEV_INFORMATIONAL, - NULL, - DEFAULT_TRACE_SIZE, - l_req_freq, - l_freq); - commitErrl(&l_err); - } - } - - // Set the frequency for the passed in mode - CMDH_TRAC_INFO("Mode %d frequency set: %d MHz",l_mode, l_freq); - l_table[l_mode] = l_freq; - - // If the mode is Turbo, also stored that frequency for DPS modes - if(l_mode == OCC_MODE_TURBO) - { - l_table[OCC_MODE_DYN_POWER_SAVE] = l_freq; - l_table[OCC_MODE_DYN_POWER_SAVE_FP] = l_freq; - } - } - } - else if(DATA_FREQ_VERSION_10 == l_cmdp->version) // Version 0x10 - OpenPower + if(DATA_FREQ_VERSION_11 == l_cmdp->version) // Version 0x11 { - // First Nominal Freq, then Max Freq, then Min Freq, which we'll + // 1) Nominal, 2) Turbo, + // 3) Minimum, 4) Ultra Turbo // store under the existing enums. + + // Bytes 3-4 Nominal Frequency Point l_freq = (l_buf[0] << 8 | l_buf[1]); l_table[OCC_MODE_NOMINAL] = l_freq; - CMDH_TRAC_INFO("Nominal frequency = %d", l_freq); + // Bytes 5-6 Turbo Frequency Point l_freq = (l_buf[2] << 8 | l_buf[3]); l_table[OCC_MODE_TURBO] = l_freq; + CMDH_TRAC_INFO("Turbo frequency = %d", l_freq); - CMDH_TRAC_INFO("Max frequency = %d", l_freq); - + // Bytes 7-8 Minimum Frequency Point l_freq = (l_buf[4] << 8 | l_buf[5]); l_table[OCC_MODE_PWRSAVE] = l_freq; l_table[OCC_MODE_MIN_FREQUENCY] = l_freq; + G_proc_fmin = l_freq; + CMDH_TRAC_INFO("Minimum frequency = %d", l_freq); - CMDH_TRAC_INFO("Min frequency = %d", l_freq); + // Bytes 9-10 Ultr Turbo Frequency Point + l_freq = (l_buf[6] << 8 | l_buf[7]); + if(l_freq) + { + G_proc_fmax = l_freq; + } + else // If Ultra Turbo Frequency Point = 0, Fmax = Turbo Frequency + { + G_proc_fmax = l_table[OCC_MODE_TURBO]; + } + l_table[OCC_MODE_UTURBO] = l_freq; + CMDH_TRAC_INFO("UT frequency = %d", l_freq); } - else if(DATA_FREQ_VERSION_11 == l_cmdp->version) // Version 0x11 - OpenPower + else if(DATA_FREQ_VERSION_20 == l_cmdp->version) // Version 0x20 { - // First Nominal Freq, then Max Freq, then Min Freq, which we'll + // 1) Nominal, 2) Turbo, 3) Minimum, + // 4) Ultra Turbo, 5) Static PS, 6) FFO // store under the existing enums. + // Bytes 3-4 Nominal Frequency Point l_freq = (l_buf[0] << 8 | l_buf[1]); l_table[OCC_MODE_NOMINAL] = l_freq; CMDH_TRAC_INFO("Nominal frequency = %d", l_freq); + // Bytes 5-6 Turbo Frequency Point l_freq = (l_buf[2] << 8 | l_buf[3]); l_table[OCC_MODE_TURBO] = l_freq; CMDH_TRAC_INFO("Turbo frequency = %d", l_freq); + // Bytes 7-8 Minimum Frequency Point l_freq = (l_buf[4] << 8 | l_buf[5]); - l_table[OCC_MODE_PWRSAVE] = l_freq; l_table[OCC_MODE_MIN_FREQUENCY] = l_freq; + G_proc_fmin = l_freq; CMDH_TRAC_INFO("Minimum frequency = %d", l_freq); + // Bytes 9-10 Ultr Turbo Frequency Point l_freq = (l_buf[6] << 8 | l_buf[7]); + if(l_freq) + { + G_proc_fmax = l_freq; + } + else // If Ultra Turbo Frequency Point = 0, Fmax = Turbo Frequency + { + G_proc_fmax = l_table[OCC_MODE_TURBO]; + } + l_table[OCC_MODE_UTURBO] = l_freq; CMDH_TRAC_INFO("UT frequency = %d", l_freq); + // Bytes 11-12 Static Power Save Frequency Point + l_freq = (l_buf[8] << 8 | l_buf[9]); + l_table[OCC_MODE_PWRSAVE] = l_freq; + CMDH_TRAC_INFO("Static Power Save frequency = %d", l_freq); + + // Bytes 13-14 FFO Frequency Point + l_freq = (l_buf[10] << 8 | l_buf[11]); + l_table[OCC_MODE_FFO] = l_freq; + CMDH_TRAC_INFO("FFO Frequency = %d", l_freq); + + // Check for FFO Frequency point consistency, + // rest of the frequency points are checked next + if(l_freq < G_proc_fmin || l_freq > G_proc_fmax) + { + CMDH_TRAC_ERR("FFO Freq point is out-of-range - Fmin=0x%x, Fmax=0x%x, FFO=0x%x", + l_freq, G_proc_fmin, G_proc_fmax); + } + } + + // Calculate minimum Pstate: + G_proc_pmin = G_proc_pmax + ((G_proc_fmax - G_proc_fmin)/G_khz_per_pstate); + + // inconsistent Frequency Points? + if((l_table[OCC_MODE_UTURBO] < l_table[OCC_MODE_TURBO] && l_table[OCC_MODE_UTURBO]) || + l_table[OCC_MODE_TURBO] < l_table[OCC_MODE_NOMINAL] || + l_table[OCC_MODE_NOMINAL] < l_table[OCC_MODE_PWRSAVE] || + l_table[OCC_MODE_PWRSAVE] < l_table[OCC_MODE_MIN_FREQUENCY]) + { + CMDH_TRAC_ERR("Inconsistent Frequency points - UT-T=0x%x, NOM-PS=0x%x, MIN=0x%x", + (l_table[OCC_MODE_UTURBO] << 16) + l_table[OCC_MODE_TURBO], + (l_table[OCC_MODE_NOMINAL] << 16) + l_table[OCC_MODE_PWRSAVE], + l_table[OCC_MODE_MIN_FREQUENCY]); } }while(0); + + // Change Data Request Mask to indicate we got this data if(!l_err && (G_occ_role == OCC_MASTER)) { @@ -1135,9 +1121,7 @@ errlHndl_t data_store_power_cap(const cmdh_fsp_cmd_t * i_cmd_ptr, cmdh_fsp_rsp_t * i_rsp_ptr) { errlHndl_t l_err = NULL; -/* TEMP -- NOT SUPPORTED IN PHASE1 */ -CMDH_TRAC_ERR("data_store_power_cap: data config type not yet supported!"); -#if 0 + // Cast the command to the struct for this format cmdh_pcap_config_t * l_cmd_ptr = (cmdh_pcap_config_t *)i_cmd_ptr; uint16_t l_data_length = 0; @@ -1148,7 +1132,7 @@ CMDH_TRAC_ERR("data_store_power_cap: data config type not yet supported!"); l_data_length = CONVERT_UINT8_ARRAY_UINT16(l_cmd_ptr->data_length[0], l_cmd_ptr->data_length[1]); // Check version and length - if(l_cmd_ptr->version == DATA_PCAP_VERSION_0) + if(l_cmd_ptr->version == DATA_PCAP_VERSION_20) { l_pcap_data_sz = sizeof(cmdh_pcap_config_t) - sizeof(cmdh_fsp_cmd_header_t); if(l_pcap_data_sz == l_data_length) @@ -1156,19 +1140,11 @@ CMDH_TRAC_ERR("data_store_power_cap: data config type not yet supported!"); l_invalid_input = FALSE; } } - else if(l_cmd_ptr->version == DATA_PCAP_VERSION_10) - { - l_pcap_data_sz = sizeof(cmdh_pcap_config_v10_t) - sizeof(cmdh_fsp_cmd_header_t); - if(l_pcap_data_sz == l_data_length) - { - l_invalid_input = FALSE; - } - } // This is the master OCC and packet data length and version are valid? // TMGT should never send this packet to a slave OCC. - // if the is not master, OR - // if the version doesn't equal what we expect, OR + // if the OCC is not master, OR + // if the version doesn't equal what we expect (0x20), OR // if the expected data length does not agree with the actual data length... if((OCC_MASTER != G_occ_role) || l_invalid_input) { @@ -1202,25 +1178,11 @@ CMDH_TRAC_ERR("data_store_power_cap: data config type not yet supported!"); } else { - if(l_cmd_ptr->version == DATA_SYS_VERSION_0) + if(l_cmd_ptr->version == DATA_SYS_VERSION_20) { // Copy power cap data into G_master_pcap_data memcpy(&G_master_pcap_data, &l_cmd_ptr->pcap_config, sizeof(cmdh_pcap_config_data_t)); } - else if(l_cmd_ptr->version == DATA_SYS_VERSION_10) - { - // Copy data - cmdh_pcap_config_v10_t * l_cmd2_ptr = (cmdh_pcap_config_v10_t *)i_cmd_ptr; - G_master_pcap_data.soft_min_pcap = l_cmd2_ptr->pcap_config.min_pcap; - G_master_pcap_data.hard_min_pcap = l_cmd2_ptr->pcap_config.min_pcap; - G_master_pcap_data.max_pcap = l_cmd2_ptr->pcap_config.sys_max_pcap; - G_master_pcap_data.oversub_pcap = l_cmd2_ptr->pcap_config.oversub_pcap; - G_master_pcap_data.system_pcap = l_cmd2_ptr->pcap_config.sys_max_pcap; - G_master_pcap_data.unthrottle = 0; - - // NOTE: The customer power cap will be set via a separate command - // from BMC/HTMGT. - } // The last byte in G_master_pcap_data is a counter that needs to be incremented. // It tells the master and slave code that there is new @@ -1234,7 +1196,6 @@ CMDH_TRAC_ERR("data_store_power_cap: data config type not yet supported!"); // will update data mask when slave code acquires data CMDH_TRAC_IMP("data store pcap: Got valid PCAP Config data via TMGT. Count:%i, Data Cfg mask[%x]",G_master_pcap_data.pcap_data_count, G_data_cnfg->data_mask); } -#endif // #if 0 return l_err; } @@ -1718,9 +1679,6 @@ errlHndl_t data_store_mem_throt(const cmdh_fsp_cmd_t * i_cmd_ptr, cmdh_fsp_rsp_t * o_rsp_ptr) { errlHndl_t l_err = NULL; -/* TEMP -- NOT SUPPORTED IN PHASE1 */ -CMDH_TRAC_ERR("data_store_mem_throt: data config type not yet supported!"); -#if 0 cmdh_mem_throt_t* l_cmd_ptr = (cmdh_mem_throt_t*)i_cmd_ptr; uint16_t l_data_length = 0; uint16_t l_exp_data_length = 0; @@ -1735,7 +1693,7 @@ CMDH_TRAC_ERR("data_store_mem_throt: data config type not yet supported!"); // Sanity checks on input data, break if: // * the version doesn't match what we expect, OR // * the actual data length does not match the expected data length. - if(l_cmd_ptr->header.version == DATA_MEM_THROT_VERSION_1) + if(l_cmd_ptr->header.version == DATA_MEM_THROT_VERSION_20) { l_exp_data_length = sizeof(cmdh_mem_throt_header_t) - sizeof(cmdh_fsp_cmd_header_t) + (l_cmd_ptr->header.num_data_sets * sizeof(cmdh_mem_throt_data_set_t)); @@ -1745,16 +1703,6 @@ CMDH_TRAC_ERR("data_store_mem_throt: data config type not yet supported!"); l_invalid_input = FALSE; } } - else if(l_cmd_ptr->header.version == DATA_MEM_THROT_VERSION_10) - { - l_exp_data_length = sizeof(cmdh_mem_throt_header_t) - sizeof(cmdh_fsp_cmd_header_t) + - (l_cmd_ptr->header.num_data_sets * sizeof(cmdh_mem_throt_data_set_v10_t)); - - if(l_exp_data_length == l_data_length) - { - l_invalid_input = FALSE; - } - } if(l_invalid_input) { @@ -1767,106 +1715,106 @@ CMDH_TRAC_ERR("data_store_mem_throt: data config type not yet supported!"); break; } - if(l_cmd_ptr->header.version == DATA_MEM_THROT_VERSION_1) + if(l_cmd_ptr->header.version == DATA_MEM_THROT_VERSION_20) { - // Store the memory throttle settings - for(i=0; iheader.num_data_sets; i++) + if(MEM_TYPE_NIMBUS == G_sysConfigData.mem_type) { - cmdh_mem_throt_data_set_t* l_data_set = &l_cmd_ptr->data_set[i]; - mem_throt_config_data_t l_temp_set; - uint16_t * l_n_ptr; - - // Validate the centaur and mba #'s for this data set - if(l_data_set->centaur_num >= MAX_NUM_CENTAURS || - l_data_set->mba_num >= NUM_MBAS_PER_CENTAUR) - { - CMDH_TRAC_ERR("data_store_mem_throt: Invalid mba or centaur number. entry=%d, cent=%d, mba=%d", - i, - l_data_set->centaur_num, - l_data_set->mba_num); - cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); - break; - } - - // Copy into a temporary buffer while we check for N values of 0 - memcpy(&l_temp_set, &(l_data_set->min_ot_n_per_mba), sizeof(mem_throt_config_data_t)); - - // A 0 for any N value is an error - for(l_n_ptr = &l_temp_set.min_ot_n_per_mba; l_n_ptr <= &l_temp_set.ovs_n_per_chip; l_n_ptr++) + // Store the memory throttle settings + for(i=0; iheader.num_data_sets; i++) { - if(!(*l_n_ptr)) + nimbus_mem_throt_t* l_data_set = &l_cmd_ptr->data_set[i].nimbus; + mem_throt_config_data_t l_temp_set; + uint16_t * l_n_ptr; + + // Validate the validity of Nimbus: + // - MC num (0 for MC01, and 2 for MC23) + // - and Port Number (0-3) + if((l_data_set->mc_num != 0 && l_data_set->mc_num != 2) || + l_data_set->port_num >= MAX_NUM_MCU_PORTS) { - CMDH_TRAC_ERR("data_store_mem_throt: Memory Throttle N value is 0! cent[%d] mba[%d]", - l_data_set->centaur_num, l_data_set->mba_num); + CMDH_TRAC_ERR("data_store_mem_throt: Invalid MC# or Port#. entry=%d, cent=%d, mba=%d", + i, + l_data_set->mc_num, + l_data_set->port_num); cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); break; } - } - if(l_err) - { - break; - } + // Copy into a temporary buffer while we check for N values of 0 + memcpy(&l_temp_set, &(l_data_set->min_n_per_port), sizeof(mem_throt_config_data_t)); - memcpy(&G_sysConfigData.mem_throt_limits[l_data_set->centaur_num][l_data_set->mba_num], - &(l_data_set->min_ot_n_per_mba), - sizeof(mem_throt_config_data_t)); + // A 0 for any N value, or power value, is an error + for(l_n_ptr = &l_temp_set.min_n_per_mba; l_n_ptr <= &l_temp_set.ovs_mem_power; l_n_ptr++) + { + if(!(*l_n_ptr)) + { + CMDH_TRAC_ERR("data_store_mem_throt: Memory Throttle N/Power value is 0! MC[%d] Port[%d]", + l_data_set->mc_num, l_data_set->port_num); + cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); + break; + } - l_configured_mbas |= 1 << ((l_data_set->centaur_num * 2) + l_data_set->mba_num); + } + if(l_err) + { + break; + } + + memcpy(&G_sysConfigData.mem_throt_limits[l_data_set->mc_num][l_data_set->port_num], + &(l_data_set->min_n_per_port), + sizeof(mem_throt_config_data_t)); + + l_configured_mbas |= 1 << (((l_data_set->mc_num<<1) * 2) + l_data_set->port_num); + } } - } - else if(l_cmd_ptr->header.version == DATA_MEM_THROT_VERSION_10) - { - // Store the memory throttle settings - for(i=0; iheader.num_data_sets; i++) + else if (MEM_TYPE_CUMULUS == G_sysConfigData.mem_type) { - cmdh_mem_throt_v10_t* l_cmd2_ptr = (cmdh_mem_throt_v10_t*)i_cmd_ptr; - cmdh_mem_throt_data_set_v10_t* l_data_set = &l_cmd2_ptr->data_set[i]; - mem_throt_config_data_t l_temp_set; - uint16_t * l_n_ptr; - - // Validate the centaur and mba #'s for this data set - if(l_data_set->centaur_num >= MAX_NUM_CENTAURS || - l_data_set->mba_num >= NUM_MBAS_PER_CENTAUR) + // Store the memory throttle settings + for(i=0; iheader.num_data_sets; i++) { - CMDH_TRAC_ERR("data_store_mem_throt: Invalid mba or centaur number. entry=%d, cent=%d, mba=%d", - i, - l_data_set->centaur_num, - l_data_set->mba_num); - cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); - break; - } + cumulus_mem_throt_t* l_data_set = &l_cmd_ptr->data_set[i].cumulus; + mem_throt_config_data_t l_temp_set; + uint16_t * l_n_ptr; - // Copy into a temporary buffer while we check for N values of 0 - l_temp_set.min_ot_n_per_mba = l_data_set->min_ot_n_per_mba; - l_temp_set.nom_n_per_mba = l_data_set->redupwr_n_per_mba; - l_temp_set.nom_n_per_chip = l_data_set->redupwr_n_per_chip; - l_temp_set.turbo_n_per_mba = l_data_set->redupwr_n_per_mba; - l_temp_set.turbo_n_per_chip = l_data_set->redupwr_n_per_chip; - l_temp_set.ovs_n_per_mba = l_data_set->ovs_n_per_mba; - l_temp_set.ovs_n_per_chip = l_data_set->ovs_n_per_chip; - - // A 0 for any N value is an error - for(l_n_ptr = &l_temp_set.min_ot_n_per_mba; l_n_ptr <= &l_temp_set.ovs_n_per_chip; l_n_ptr++) - { - if(!(*l_n_ptr)) + // Validate the centaur and mba #'s for this data set + if(l_data_set->centaur_num >= MAX_NUM_CENTAURS || + l_data_set->mba_num >= NUM_MBAS_PER_CENTAUR) { - CMDH_TRAC_ERR("data_store_mem_throt: Memory Throttle N value is 0! cent[%d] mba[%d]", - l_data_set->centaur_num, l_data_set->mba_num); + CMDH_TRAC_ERR("data_store_mem_throt: Invalid mba or centaur number. entry=%d, cent=%d, mba=%d", + i, + l_data_set->centaur_num, + l_data_set->mba_num); cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); break; } - } - if(l_err) - { - break; - } - memcpy(&G_sysConfigData.mem_throt_limits[l_data_set->centaur_num][l_data_set->mba_num], - &l_temp_set, - sizeof(mem_throt_config_data_t)); + // Copy into a temporary buffer while we check for N values of 0 + memcpy(&l_temp_set, &(l_data_set->min_n_per_mba), sizeof(mem_throt_config_data_t)); + + // A 0 for any N value is an error + for(l_n_ptr = &l_temp_set.min_n_per_mba; l_n_ptr <= &l_temp_set.ovs_mem_power; l_n_ptr++) + { + if(!(*l_n_ptr)) + { + CMDH_TRAC_ERR("data_store_mem_throt: Memory Throttle N value is 0! cent[%d] mba[%d]", + l_data_set->centaur_num, l_data_set->mba_num); + cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); + break; + } + + } + if(l_err) + { + break; + } - l_configured_mbas |= 1 << ((l_data_set->centaur_num * 2) + l_data_set->mba_num); + memcpy(&G_sysConfigData.mem_throt_limits[l_data_set->centaur_num][l_data_set->mba_num], + &(l_data_set->min_n_per_mba), + sizeof(mem_throt_config_data_t)); + + l_configured_mbas |= 1 << ((l_data_set->centaur_num * 2) + l_data_set->mba_num); + + } } } @@ -1880,9 +1828,9 @@ CMDH_TRAC_ERR("data_store_mem_throt: data config type not yet supported!"); l_configured_mbas); // Update the configured mba bitmap - G_configured_mbas = l_configured_mbas; +// @TEMP @TODO: defined in centaur_control - Not ready yet +// G_configured_mbas = l_configured_mbas; } -#endif return l_err; } diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h index 06b3ef4..0f2c959 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h +++ b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.h @@ -146,13 +146,10 @@ typedef struct __attribute__ ((packed)) // Used by TMGT to send OCC the PCAP config data. typedef struct __attribute__ ((packed)) { - uint16_t current_pcap; // Node power cap requested by customer (AEM) in 1W units - uint16_t soft_min_pcap; // Minimum node power cap allowed in 1W units - uint16_t hard_min_pcap; // Minimum guaranteed node power cap in 1W units - uint16_t max_pcap; // Maximum customer settable node power cap in 1W units - uint16_t oversub_pcap; // Node power cap to be used for oversubscripion in 1W units - uint16_t system_pcap; // Fixed node power cap required by the system in 1W units - uint8_t unthrottle; // Only used on ITEs -- is indicated from CMM + uint16_t soft_min_pcap; // Min node power cap allowed in 1W units (1WU) + uint16_t hard_min_pcap; // Min guaranteed node power cap in 1WU + uint16_t sys_max_pcap; // Max system (max user settable) power cap in 1WU + uint16_t qpd_pcap; // Quick Power Drop (Oversubscription) power cap in 1WU } cmdh_pcap_config_data_t; // Used by TMGT to send OCC the PCAP config data. @@ -164,21 +161,6 @@ typedef struct __attribute__ ((packed)) cmdh_pcap_config_data_t pcap_config; }cmdh_pcap_config_t; -typedef struct __attribute__ ((packed)) -{ - uint16_t min_pcap; // Minimum guaranteed node power cap in 1W units - uint16_t sys_max_pcap; // Fixed node power cap required by the system in 1W units - uint16_t oversub_pcap; // Node power cap to be used for oversubscripion in 1W units -} cmdh_pcap_config_data_v10_t; - -typedef struct __attribute__ ((packed)) -{ - struct cmdh_fsp_cmd_header; - uint8_t format; - uint8_t version; - cmdh_pcap_config_data_v10_t pcap_config; -}cmdh_pcap_config_v10_t; - typedef struct __attribute__ ((packed)) { uint8_t system_type; // General system type @@ -310,45 +292,68 @@ typedef struct __attribute__ ((packed)) uint8_t num_data_sets; }cmdh_mem_throt_header_t; -// Provides memory throttle min and max values + +// Provides memory throttle min and max values for Nimbus systems typedef struct __attribute__ ((packed)) { - uint8_t centaur_num; - uint8_t mba_num; - uint16_t min_ot_n_per_mba; - uint16_t nom_n_per_mba; - uint16_t nom_n_per_chip; - uint16_t turbo_n_per_mba; - uint16_t turbo_n_per_chip; - uint16_t ovs_n_per_mba; - uint16_t ovs_n_per_chip; -}cmdh_mem_throt_data_set_t; + uint8_t mc_num; // Physical MC: [0=MC01, 2=MC23] + uint8_t port_num; // Physical port # [0-3] -// Config packet definition used by TMGT to -// send mem throttle min/max settings. + uint16_t min_n_per_port; // Lowest per port allowed numerator + uint16_t min_mem_power; // Max mem Power @min (x0.1W) + + uint16_t pcap1_n_per_port; // Static per port numerator @PCAP1 + uint16_t pcap1_mem_power; // Max memory power @PCAP1 (x0.1W) + + uint16_t pcap2_n_per_port; // Static per port numerator @PCAP2 + uint16_t pcap2_mem_power; // Max memory power @PCAP2 (x0.1W) + + uint16_t nom_n_per_port; // Static per port @Redundant (no ovs) + uint16_t nom_n_per_slot; // Static per slot @Redundant + uint16_t nom_mem_power; // Max memory power @Redundant(x0.1W) + + uint16_t ovs_n_per_port; // Static per port @Oversubscription + uint16_t ovs_n_per_slot; // Static per slot @Oversubscription + uint16_t ovs_mem_power; // Max memory power @Oversubscription (x0.1W) +}nimbus_mem_throt_t; + +// Provides memory throttle min and max values for Cumulus systems typedef struct __attribute__ ((packed)) { - cmdh_mem_throt_header_t header; - cmdh_mem_throt_data_set_t data_set[1]; -}cmdh_mem_throt_t; + uint8_t centaur_num; // Physical centaur# [0-7] + uint8_t mba_num; // Memory Buffer within centaur [0-1] -typedef struct __attribute__ ((packed)) + uint16_t min_n_per_mba; // Lowest per MBA allowed numerator + uint16_t min_mem_power; // Max mem Power @min (x0.1W) + + uint16_t pcap1_n_per_mba; // Static per MBA numerator @PCAP1 + uint16_t pcap1_mem_power; // Max memory power @PCAP1 (x0.1W) + + uint16_t pcap2_n_per_mba; // Static per MBA numerator @PCAP2 + uint16_t pcap2_mem_power; // Max memory power @PCAP2 (x0.1W) + + uint16_t nom_n_per_mba; // Static per MBA @Redundant (no ovs) + uint16_t nom_n_per_chip; // Static per chip @Redundant + uint16_t nom_mem_power; // Max memory power @Redundant(x0.1W) + + uint16_t ovs_n_per_mba; // Static per MBA @Oversubscription + uint16_t ovs_n_per_chip; // Static per chip @Oversubscription + uint16_t ovs_mem_power; // Max memory power @Oversubscription (x0.1W) +}cumulus_mem_throt_t; + +typedef union cmdh_mem_throt_data_set { - uint8_t centaur_num; - uint8_t mba_num; - uint16_t min_ot_n_per_mba; - uint16_t redupwr_n_per_mba; - uint16_t redupwr_n_per_chip; - uint16_t ovs_n_per_mba; - uint16_t ovs_n_per_chip; -}cmdh_mem_throt_data_set_v10_t; + nimbus_mem_throt_t nimbus; + cumulus_mem_throt_t cumulus; +} cmdh_mem_throt_data_set_t; +// Config packet definition used by TMGT to +// send mem throttle min/max settings. typedef struct __attribute__ ((packed)) { - cmdh_mem_throt_header_t header; - cmdh_mem_throt_data_set_v10_t data_set[1]; -}cmdh_mem_throt_v10_t; - + cmdh_mem_throt_header_t header; + cmdh_mem_throt_data_set_t data_set[1]; +}cmdh_mem_throt_t; // Used to mark present the config data TMGT has sent us. typedef struct data_cnfg diff --git a/src/occ_405/cmdh/cmdh_mnfg_intf.c b/src/occ_405/cmdh/cmdh_mnfg_intf.c index ff941cc..54bc662 100755 --- a/src/occ_405/cmdh/cmdh_mnfg_intf.c +++ b/src/occ_405/cmdh/cmdh_mnfg_intf.c @@ -282,11 +282,11 @@ uint8_t cmdh_mnfg_mem_slew(const cmdh_fsp_cmd_t * i_cmd_ptr, &G_sysConfigData.mem_throt_limits[l_cent][l_mba]; // Uses values seen on tuleta as defaults - l_throt_ptr->min_ot_n_per_mba = 13; + l_throt_ptr->min_n_per_mba = 13; l_throt_ptr->nom_n_per_mba = 72; l_throt_ptr->nom_n_per_chip = 72; - l_throt_ptr->turbo_n_per_mba = 72; - l_throt_ptr->turbo_n_per_chip = 72; + l_throt_ptr->pcap1_n_per_mba = 72; + l_throt_ptr->pcap2_n_per_mba = 72; l_throt_ptr->ovs_n_per_mba = 72; l_throt_ptr->ovs_n_per_chip = 72; } diff --git a/src/occ_405/dcom/dcom.c b/src/occ_405/dcom/dcom.c index 3f4c268..eed1cee 100755 --- a/src/occ_405/dcom/dcom.c +++ b/src/occ_405/dcom/dcom.c @@ -71,9 +71,6 @@ dcom_fail_count_t G_dcomSlvInboxCounter = {0}; uint8_t G_occ_role = OCC_SLAVE; - -uint8_t G_dcm_occ_role = OCC_DCM_SLAVE; - // PBAX ID of this OCC is also its PowerBus ID. Contains ChipId & NodeId. pob_id_t G_pbax_id = {0}; @@ -88,9 +85,6 @@ PbaxTarget G_pbax_unicast_target; // Number of occ's that *should* be present uint8_t G_occ_num_present; -// DCM Status from all Slaves -proc_gpsm_dcm_sync_occfw_t G_dcm_sync_occfw_table[MAX_OCCS]; - // Master/slave event flags uint32_t G_master_event_flags = 0; uint32_t G_slave_event_flags = 0; @@ -397,47 +391,6 @@ void dcom_error_check( const dcom_error_type_t i_error_type, const bool i_clear_ } } -// Function Specification -// -// Name: dcom_build_dcm_sync_msg -// -// Description: Copy messages from DCM Master (OCC Slave) to -// DCM Slave (also OCC Slave) and vice versa -// -// End Function Specification -void dcom_build_dcm_sync_msg(const dcom_error_type_t i_which_msg) -{ - // If the OCC Master isn't a DCM, no one else is a DCM either, so - // no need to bother sending these messages back & forth. - if(proc_is_dcm()) - { - if ( i_which_msg == SLAVE_INBOX ) - { - uint32_t l_slv_idx = 0; - for(l_slv_idx = 0; l_slv_idx < MAX_OCCS; l_slv_idx++) - { - // Populate G_dcm_sync_occfw_table with the data from all OCC Slaves - G_dcm_sync_occfw_table[l_slv_idx] = G_dcom_slv_outbox_rx[l_slv_idx].dcm_sync; - } - - // DCM are always in even/odd numbered pairs sequentially as - // DCM master = even number[0,2,4,6] DCM Slave = odd number [1,3,5,7] - // with DCM pairs being [0,1], [2,3], [4,5], [6,7] - // so we can do this simple swizzle here and not need a table to - // do the conversion. - for(l_slv_idx = 0; l_slv_idx < MAX_OCCS; l_slv_idx+=2) - { - G_dcom_slv_inbox_tx[l_slv_idx].dcm_sync = G_dcm_sync_occfw_table[l_slv_idx+1]; - G_dcom_slv_inbox_tx[l_slv_idx+1].dcm_sync = G_dcm_sync_occfw_table[l_slv_idx]; - } - } - else if ( i_which_msg == SLAVE_OUTBOX ) - { - G_dcom_slv_outbox_tx.dcm_sync = proc_gpsm_dcm_sync_get_state(); - } - } -} - // Function Specification // // Name: dcom_build_occfw_msg @@ -631,9 +584,6 @@ void task_dcom_parse_occfwmsg(task_t *i_self) g_amec->part_config.part_list[0].soft_fmin = G_dcom_slv_inbox_rx.soft_fmin; g_amec->part_config.part_list[0].soft_fmax = G_dcom_slv_inbox_rx.soft_fmax; - // Update DCM Sync var that will be used in thread - proc_gpsm_dcm_sync_update_from_mbox(&G_dcom_slv_inbox_rx.dcm_sync); - // acknowledge all masters event flags G_master_event_flags_ack = G_dcom_slv_inbox_rx.occ_fw_mailbox[2]; diff --git a/src/occ_405/dcom/dcom.h b/src/occ_405/dcom/dcom.h index dc960d0..1ff263d 100755 --- a/src/occ_405/dcom/dcom.h +++ b/src/occ_405/dcom/dcom.h @@ -45,10 +45,6 @@ #define OCC_MASTER 1 #define OCC_BACKUP_MASTER 2 -// OCC roles inside a DCM socket -#define OCC_DCM_SLAVE 0 -#define OCC_DCM_MASTER 1 - // Memory address space where DCOM, sensor data, OPAL communications, // etc take place. Uses BAR2, with pba_region = 0b10 #define COMMON_BASE_ADDRESS 0xA0000000 @@ -99,16 +95,16 @@ #define NUM_ENTRIES_PBAX_QUEUE0 32 #define NUM_ENTRIES_PBAX_QUEUE1 16 -// Wait for defines number of retries for task +// Wait for defines number of retries for task #define MAX_WAIT_FOR_SLAVES 400 #define MAX_WAIT_FOR_MASTER 400 // general defines #define TOD_SIZE 6 #define NUM_TOD_SENSORS 3 -#define SLV_INBOX_RSV_SIZE 64 +#define SLV_INBOX_RSV_SIZE 68 #define SLV_MAILBOX_SIZE 32 -#define SLV_OUTBOX_RSV_SIZE 614 +#define SLV_OUTBOX_RSV_SIZE 618 #define DOORBELL_RSV_SIZE 1 #define DCOM_250us_GAP 1 @@ -180,12 +176,9 @@ typedef struct freqConfig_t sys_mode_freq; uint8_t tb_record; }; - uint8_t reserved[ SLV_INBOX_RSV_SIZE ]; // [154] - 64 bytes + uint8_t reserved[ SLV_INBOX_RSV_SIZE ]; // [154] - 68 bytes }; - // GPSM DCM Synchronization - proc_gpsm_dcm_sync_occfw_t dcm_sync; // [220] - 4 bytes - // General Firmware Message Passing uint8_t occ_fw_mailbox[ SLV_MAILBOX_SIZE ]; // [224] - 32 bytes @@ -234,7 +227,7 @@ typedef struct __attribute__ ((packed)) // Reserved Bytes union { - uint8_t reserved[SLV_OUTBOX_RSV_SIZE]; // [374] - 614 bytes + uint8_t reserved[SLV_OUTBOX_RSV_SIZE]; // [374] - 618 bytes struct __attribute__ ((packed)) { uint8_t _reserved_1; @@ -243,9 +236,6 @@ typedef struct __attribute__ ((packed)) }; }; - // GPSM DCM Synchronization - proc_gpsm_dcm_sync_occfw_t dcm_sync; // [988] - 4 bytes - // General Firmware Message Passing uint8_t occ_fw_mailbox[SLV_MAILBOX_SIZE]; // [992] - 32 bytes } dcom_slv_outbox_t __attribute__ ((aligned (128))); @@ -410,10 +400,6 @@ extern uint8_t G_slv_outbox_complete; // Specifies if the OCC is a MASTER or SLAVE extern uint8_t G_occ_role; -// Specifies if the OCC is configured to be a Master or Slave inside the DCM -// chip. In the case of SCMs, it will always return the Master role. -extern uint8_t G_dcm_occ_role; - // Holds PowerBus ID of this OCC (Chip & node). For P9, this is the same // for pob_id and PBAX ID. extern pob_id_t G_pbax_id; @@ -532,7 +518,4 @@ void task_dcom_parse_occfwmsg(task_t *i_self); // Copy occ fw msg void dcom_build_occfw_msg( dcom_error_type_t i_which_msg ); -// Copy OCC DCM Sync Messages -void dcom_build_dcm_sync_msg(const dcom_error_type_t i_which_msg); - #endif //_DCOM_H diff --git a/src/occ_405/dcom/dcomMasterTx.c b/src/occ_405/dcom/dcomMasterTx.c index 8d660c0..ad1beba 100644 --- a/src/occ_405/dcom/dcomMasterTx.c +++ b/src/occ_405/dcom/dcomMasterTx.c @@ -165,9 +165,6 @@ uint32_t dcom_build_slv_inbox(void) G_mst_tunable_parameter_overwrite = 0; dcom_build_occfw_msg( SLAVE_INBOX ); - // Copy Data from one DCM pair's Outbox to other DCM pair's inbox - dcom_build_dcm_sync_msg( SLAVE_INBOX ); - l_addr_of_slv_inbox_in_main_mem = dcom_which_buffer(); //DOORBELL................. diff --git a/src/occ_405/dcom/dcomSlaveTx.c b/src/occ_405/dcom/dcomSlaveTx.c index e6cf2d2..3f05b08 100755 --- a/src/occ_405/dcom/dcomSlaveTx.c +++ b/src/occ_405/dcom/dcomSlaveTx.c @@ -78,9 +78,6 @@ uint32_t dcom_build_slv_outbox(void) // Call dcom_build_occfw_msg dcom_build_occfw_msg( SLAVE_OUTBOX ); - // Create message that will be sent to DCM peer - dcom_build_dcm_sync_msg( SLAVE_OUTBOX ); - l_addr_of_slv_outbox_in_main_mem = dcom_which_buffer_slv_outbox(); l_addr_of_slv_outbox_in_main_mem += G_pbax_id.chip_id*sizeof(dcom_slv_outbox_t); diff --git a/src/occ_405/dcom/dcom_thread.c b/src/occ_405/dcom/dcom_thread.c index 61606b1..c151482 100755 --- a/src/occ_405/dcom/dcom_thread.c +++ b/src/occ_405/dcom/dcom_thread.c @@ -163,9 +163,6 @@ void Dcom_thread_routine(void *arg) } } - // TEMP/TODO: In P8, we would call proc_gpsm_dcm_sync_enable_pstates_smh() here, - // if not in safe mode. Do we need to do something similar in P9? - // -------------------------------------------------- // SSX Sleep // -------------------------------------------------- diff --git a/src/occ_405/mode.c b/src/occ_405/mode.c index fc533b5..e4a6715 100755 --- a/src/occ_405/mode.c +++ b/src/occ_405/mode.c @@ -39,7 +39,6 @@ errlHndl_t SMGR_mode_transition_to_powersave(); errlHndl_t SMGR_mode_transition_to_dynpowersave(); errlHndl_t SMGR_mode_transition_to_dynpowersave_fp(); errlHndl_t SMGR_mode_transition_to_turbo(); -errlHndl_t SMGR_mode_transition_to_superturbo(); errlHndl_t SMGR_mode_transition_to_ffo(); // Mode that OCC is currently in @@ -72,26 +71,12 @@ SsxSemaphore G_smgrModeChangeSem; // transition. const smgr_state_trans_t G_smgr_mode_trans[] = { - /* ----- SPECIFIC CASE MODE TRANSITIONS ----- */ - /* These are specific mode transitions for when it matters what - * mode we were in before the transition. These must come before - * the agnostic mode transitions below, and will be run instead of - * those catch-all transition functions. */ - - /* Current Mode New Mode Transition Function */ - {OCC_MODE_STURBO, OCC_MODE_NOMINAL, NULL}, - - /* ----- DEFAULT MODE TRANSITIONS ----- */ - /* These are default mode transitions for when it doesn't matter what - * mode we were in before the transition. */ - /* Current Mode New Mode Transition Function */ {OCC_MODE_ALL, OCC_MODE_NOMINAL, &SMGR_mode_transition_to_nominal}, {OCC_MODE_ALL, OCC_MODE_PWRSAVE, &SMGR_mode_transition_to_powersave}, {OCC_MODE_ALL, OCC_MODE_DYN_POWER_SAVE, &SMGR_mode_transition_to_dynpowersave}, {OCC_MODE_ALL, OCC_MODE_DYN_POWER_SAVE_FP, &SMGR_mode_transition_to_dynpowersave_fp}, {OCC_MODE_ALL, OCC_MODE_TURBO, &SMGR_mode_transition_to_turbo}, - {OCC_MODE_ALL, OCC_MODE_STURBO, &SMGR_mode_transition_to_superturbo}, {OCC_MODE_ALL, OCC_MODE_FFO, &SMGR_mode_transition_to_ffo}, }; const uint8_t G_smgr_mode_trans_count = sizeof(G_smgr_mode_trans)/sizeof(smgr_state_trans_t); @@ -193,7 +178,6 @@ errlHndl_t SMGR_set_mode(const OCC_MODE i_mode, case OCC_MODE_DYN_POWER_SAVE: // FALL THROUGH case OCC_MODE_DYN_POWER_SAVE_FP: // FALL THROUGH case OCC_MODE_TURBO: // FALL THROUGH - case OCC_MODE_STURBO: // FALL THROUGH case OCC_MODE_FFO: // FALL THROUGH // Notify AMEC of mode change @@ -388,29 +372,6 @@ errlHndl_t SMGR_mode_transition_to_turbo() } -// Function Specification -// -// Name: SMGR_mode_transition_to_superturbo -// -// Description: -// -// End Function Specification -errlHndl_t SMGR_mode_transition_to_superturbo() -{ - errlHndl_t l_errlHndl = NULL; - - TRAC_IMP("SMGR: Mode to SuperTurbo Transition Started"); - - // Set Freq Mode for AMEC to use - l_errlHndl = amec_set_freq_range(OCC_MODE_STURBO); - - CURRENT_MODE() = OCC_MODE_STURBO; - TRAC_IMP("SMGR: Mode to SuperTurbo Transition Completed"); - - return l_errlHndl; -} - - // Function Specification // // Name: SMGR_mode_transition_to_ffo diff --git a/src/occ_405/mode.h b/src/occ_405/mode.h index 648ad8b..818cada 100755 --- a/src/occ_405/mode.h +++ b/src/occ_405/mode.h @@ -48,7 +48,7 @@ typedef enum { OCC_MODE_NOCHANGE = 0x00, OCC_MODE_NOMINAL = 0x01, - // OCC_MODE_BENCHMARK = 0x02, + // reserved = 0x02, OCC_MODE_TURBO = 0x03, OCC_MODE_SAFE = 0x04, OCC_MODE_PWRSAVE = 0x05, @@ -56,10 +56,13 @@ typedef enum OCC_MODE_MIN_FREQUENCY = 0x07, // Mode 0x08-0x0A reserved by TMGT - // OCC_MODE_SAFE_LOW_POWER = 0x09, + // reserved = 0x08, + // reserved = 0x09, OCC_MODE_DYN_POWER_SAVE_FP = 0x0A, OCC_MODE_FFO = 0x0B, - OCC_MODE_STURBO = 0x0C, + OCC_MODE_FMF = 0x0C, + + OCC_MODE_UTURBO = 0x0D, // Make sure this is after the last valid mode OCC_MODE_COUNT, diff --git a/src/occ_405/occ_sys_config.c b/src/occ_405/occ_sys_config.c index 9d7a40f..448692f 100755 --- a/src/occ_405/occ_sys_config.c +++ b/src/occ_405/occ_sys_config.c @@ -468,7 +468,7 @@ void sysConfigFspLess(void) | DATA_MASK_PCAP_PRESENT ); // Install the Pstate Table - proc_gpsm_pstate_initialize((PstateSuperStructure*) G_defaultOccPstateSuperStructure); +// proc_pstate_initialize((PstateSuperStructure*) G_defaultOccPstateSuperStructure); } diff --git a/src/occ_405/occ_sys_config.h b/src/occ_405/occ_sys_config.h index 796d0bf..ec5e9aa 100755 --- a/src/occ_405/occ_sys_config.h +++ b/src/occ_405/occ_sys_config.h @@ -45,6 +45,7 @@ #define MAX_NUM_MEM_CONTROLLERS 8 #define MAX_NUM_CENTAURS 8 #define NUM_PROC_VRMS 2 +#define MAX_NUM_MCU_PORTS 4 #define NUM_PROC_CHIPS_PER_OCC 1 #define NUM_CENTAURS_PER_MEM_CONTROLLER 1 @@ -225,13 +226,22 @@ typedef struct // Memory Throttle settings typedef struct { - uint16_t min_ot_n_per_mba; //minimum value + uint16_t min_n_per_mba; //minimum value + uint16_t min_mem_power; // Max mem Power @min (x0.1W) + + uint16_t pcap1_n_per_mba; //max mba value for Power Cap Level 1 + uint16_t pcap1_mem_power; //max memory power @PCAP L1 + + uint16_t pcap2_n_per_mba; //max mba value for Power Cap Level 2 + uint16_t pcap2_mem_power; //max memory power @PCAP L2 + uint16_t nom_n_per_mba; //max mba value for nominal mode uint16_t nom_n_per_chip; //chip setting for nominal mode - uint16_t turbo_n_per_mba; //max mba value for turbo mode - uint16_t turbo_n_per_chip; //chip setting for nominal mode + uint16_t nom_mem_power; //max memory power @Redundant + uint16_t ovs_n_per_mba; //max mba value for oversubscription uint16_t ovs_n_per_chip; //chip setting for oversubscription + uint16_t ovs_mem_power; //max memory power @oversubscription } mem_throt_config_data_t; // Sys Config Structure diff --git a/src/occ_405/proc/proc_pstate.c b/src/occ_405/proc/proc_pstate.c index 1d4d65e..4c4030d 100755 --- a/src/occ_405/proc/proc_pstate.c +++ b/src/occ_405/proc/proc_pstate.c @@ -32,48 +32,30 @@ #include "occ_common.h" #include "state.h" #include "cmdh_fsp_cmds.h" -// @TODO - TEMP Pstate include files -//#include "gpsm.h" -//#include "pstates.h" #include "proc_data.h" #include "proc_pstate.h" #include "scom.h" #include "homer.h" -// GPSM DCM Synchronization States -typedef enum -{ - PROC_GPSM_SYNC_NO_PSTATE_TABLE = 0, - PROC_GPSM_SYNC_PSTATE_TABLE_INSTALLED = 1, - PROC_GPSM_SYNC_READY_TO_ENABLE_MASTER = 2, - PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED = 3, - PROC_GPSM_SYNC_READY_TO_ENABLE_SLAVE = 4, - PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED = 5, - PROC_GPSM_SYNC_PSTATE_HW_MODE = 6, - PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED = 7, - PROC_GPSM_SYNC_PSTATE_ERROR, -} eProcGpsmDcmSyncStates; - +// Holds Fmax for ease of proc_freq2pstate calculation +uint32_t G_proc_fmax = 0; -// Instance of the PState Table in OCC SRAM. Should be placed in RO section -// so that OCC FW can't corrupt it -// @TODO - TEMP Pstates changed in P9 -//GLOBAL_PSTATE_TABLE(G_global_pstate_table); +// Holds Fmin for ease of proc_freq2pstate calculation +uint32_t G_proc_fmin = 0; -// Used for passing DCM Master & Slave States to each other over MBOX -proc_gpsm_dcm_sync_occfw_t G_proc_dcm_sync_state = {0, PROC_GPSM_SYNC_NO_PSTATE_TABLE, PROC_GPSM_SYNC_NO_PSTATE_TABLE,0,0}; +// Holds frequency steps between consequtive Pstates +uint32_t G_khz_per_pstate = 0; -// Holds Fmax from GPST for ease of proc_freq2pstate calculation -uint32_t G_proc_gpst_fmax = 0; +// Holds Pmax for ease of proc_freq2pstate calculation +uint8_t G_proc_pmax = 0; -// Holds Fmin from GPST for ease of proc_freq2pstate calculation -uint32_t G_proc_gpst_fmin = 0; +// Holds Pmin for ease of proc_freq2pstate calculation +uint8_t G_proc_pmin = 0; -// Holds Pmax from GPST for ease of proc_freq2pstate calculation -int8_t G_proc_gpst_pmax = 0; - -// Remembers if we are a DCM, for DCOM's sake -bool G_isDcm = FALSE; +// Holds a flag indicating whether the pstates have been enabled. +// initialized to FALSE, turns TRUE only after the PGPE IPC that +// enable pstates completes successfully. +bool G_proc_pstate_enabled = FALSE; // Used for OPAL DMA_BUFFER( opal_table_t G_opal_table ) = {{0}}; @@ -81,212 +63,43 @@ DMA_BUFFER( opal_table_t G_opal_table ) = {{0}}; //KVM throttle reason coming from the frequency voting box. extern uint8_t G_amec_kvm_throt_reason; -// Set DCM Sync State -void proc_gpsm_dcm_sync_set_state(eProcGpsmDcmSyncStates i_dcm_sync_state); - -// Tracing out pstate table when it gets installed -void proc_trace_pstate_table_quick(void); - // Function Specification // // Name: proc_is_hwpstate_enabled // -// Description: Checks DCM Master (or SCM) state to see if Pstate HW Mode -// is enabled. We can check the DCM master state, since DCM -// slave also knows the master and DCM master can't be in this -// state if DCM slave isn't in HW mode +// Description: Checks OCC to see if Pstate HW Mode is enabled. // // End Function Specification bool proc_is_hwpstate_enabled(void) { - return ((PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED == G_proc_dcm_sync_state.sync_state_master) ? TRUE : FALSE); -} - - -// Function Specification -// -// Name: proc_gpsm_dcm_sync_update_from_mbox -// -// Description: Updates the global variable used for DCM sync based on the -// data that was received via the master/slave mailbox. -// -// Thread: Interrupt; Callback when Slave Inbox is received -// -// End Function Specification -void proc_gpsm_dcm_sync_update_from_mbox(proc_gpsm_dcm_sync_occfw_t * i_dcm_sync_state) -{ -// @TODO - TEMP - global state table changes in P9 -/* if(!gpsm_dcm_slave_p()) - { - G_proc_dcm_sync_state.sync_state_slave = i_dcm_sync_state->sync_state_slave; - } - else - { -*/ G_proc_dcm_sync_state.sync_state_master = i_dcm_sync_state->sync_state_master; - G_proc_dcm_sync_state.pstate_v = i_dcm_sync_state->pstate_v; - G_proc_dcm_sync_state.pstate_f = i_dcm_sync_state->pstate_f; -/* } */ -} - - -// Function Specification -// -// Name: proc_gpsm_dcm_sync_get_state -// -// Description: Return the global variable used for DCM sync -// -// End Function Specification -inline proc_gpsm_dcm_sync_occfw_t proc_gpsm_dcm_sync_get_state(void) -{ - return G_proc_dcm_sync_state; -} - - -// Function Specification -// -// Name: proc_is_dcm -// -// Description: Return if we are a DCM or not -// -// End Function Specification -inline bool proc_is_dcm(void) -{ - return G_isDcm; + return ( G_proc_pstate_enabled ? TRUE : FALSE); } -#if 0 // @TODO - TEMP - global state table changes in P9 - -// Function Specification -// -// Name: proc_gpsm_dcm_sync_set_state -// -// Description: Set the state of global variable used for DCM sync -// Differnt nybble will get set depending on if we are -// DCM Master or DCM Slave -// -// End Function Specification -inline void proc_gpsm_dcm_sync_set_state(eProcGpsmDcmSyncStates i_dcm_sync_state) -{ - if(!gpsm_dcm_slave_p()) - { - G_proc_dcm_sync_state.sync_state_master = i_dcm_sync_state; - } - else - { - G_proc_dcm_sync_state.sync_state_slave = i_dcm_sync_state; - } -} - - -// Function Specification -// -// Name: proc_gpsm_dcm_sync_get_state -// -// Description: Return the state of global variable used for DCM sync -// -// End Function Specification -eProcGpsmDcmSyncStates proc_gpsm_dcm_sync_get_my_state(void) -{ - if(!gpsm_dcm_slave_p()) - { - return G_proc_dcm_sync_state.sync_state_master; - } - else - { - return G_proc_dcm_sync_state.sync_state_slave; - } -} - - -// Function Specification -// -// Name: proc_trace_pstate_table_quick -// -// Description: Debug Function to Print portion of Pstate Table -// Eventually, this should trace key elements of Pstate -// table to Trace Buffer. -// -// End Function Specification -void proc_trace_pstate_table_quick(void) -{ - GlobalPstateTable * l_gpst_ptr = NULL; - - l_gpst_ptr = gpsm_gpst(); - // Check the pointer since it may not have been installed on chips with 0 configured cores - if(l_gpst_ptr == &G_global_pstate_table) - { - TRAC_IMP("GPST Installed: Pstate[0]: %d kHz, Step: %d kHz, Entries: %d, Pvsafe[%d], Psafe[%d]", - l_gpst_ptr->pstate0_frequency_khz, - l_gpst_ptr->frequency_step_khz, - (int8_t) l_gpst_ptr->entries, - (int8_t) l_gpst_ptr->pvsafe, - (int8_t) l_gpst_ptr->psafe - ); - - TRAC_IMP("Pmin[%d]: %d kHz, Pmax[%d]: %d kHz", - (int8_t) l_gpst_ptr->pmin, - (l_gpst_ptr->pstate0_frequency_khz + ((int8_t) l_gpst_ptr->pmin) * l_gpst_ptr->frequency_step_khz), - ((int8_t) l_gpst_ptr->pmin + l_gpst_ptr->entries - 1), - (l_gpst_ptr->pstate0_frequency_khz + ((int8_t) l_gpst_ptr->pmin + l_gpst_ptr->entries - 1) * l_gpst_ptr->frequency_step_khz) - ); - } - else - { - //This likely means that the processor has no configured cores (may not be an error scenario) - TRAC_IMP("GPST not installed. hw pointer= 0x%08x, present cores= 0x%08x", (uint32_t)l_gpst_ptr, G_present_cores); - } -} - - // Function Specification // // Name: proc_pstate2freq // -// Description: Convert Pstate to Frequency +// Description: Convert Pstate to Frequency in kHz // // End Function Specification uint32_t proc_pstate2freq(Pstate i_pstate) { - uint32_t l_freq = 0; - int8_t l_pmax = 0; - GlobalPstateTable * l_gpst_ptr = NULL; - - do + // If passed in Pstate is lower than Pmin, just use Pmin + if(i_pstate < G_proc_pmin) { - // Get pointer to Pstate table - l_gpst_ptr = gpsm_gpst(); - - // Return the zero frequency if we don't have a PstateTable installed - if(&G_global_pstate_table != l_gpst_ptr) - { - l_freq = 0; - break; - } - - // Calculate Pmax, since it is derived instead of being a explicit member - l_pmax = ((int8_t) l_gpst_ptr->pmin + l_gpst_ptr->entries - 1); - - if(i_pstate < l_gpst_ptr->pmin) - { - // If passed in Pstate is lower than Pmin, just use Pmin - i_pstate = l_gpst_ptr->pmin; - } - else if (i_pstate > l_pmax) - { - // If passed in Pstate is greater than Pmax, just use Pmax - i_pstate = l_pmax; - } + i_pstate = G_proc_pmin; + } - // Calculate Frequency based on Pstate - l_freq = (l_gpst_ptr->pstate0_frequency_khz + ((int8_t) i_pstate) * l_gpst_ptr->frequency_step_khz); - l_freq /= 1000; // Convert to MHz + // If passed in Pstate is greater than Pmax, just use Pmax + else if (i_pstate > G_proc_pmax) + { + i_pstate = G_proc_pmax; } - while(0); - return l_freq; // MHz + // Calculate Frequency in kHz based on Pstate + return (G_proc_fmin + (G_proc_pmin - i_pstate) * G_khz_per_pstate); } - // Function Specification // // Name: proc_freq2pstate @@ -296,7 +109,6 @@ uint32_t proc_pstate2freq(Pstate i_pstate) // End Function Specification Pstate proc_freq2pstate(uint32_t i_freq_mhz) { - GlobalPstateTable * l_gpst_ptr = NULL; int8_t l_pstate = PSTATE_MIN; int8_t l_temp_pstate = 0; int32_t l_temp_freq = 0; @@ -304,15 +116,6 @@ Pstate proc_freq2pstate(uint32_t i_freq_mhz) do { - // Get pointer to Pstate table - l_gpst_ptr = gpsm_gpst(); - - // Return the minimum PState if we don't have a PstateTable installed - if(&G_global_pstate_table != l_gpst_ptr) - { - break; - } - // Freq Units need to be in kHz, not Mhz for the following calculations l_freq_khz = i_freq_mhz * 1000; @@ -323,30 +126,29 @@ Pstate proc_freq2pstate(uint32_t i_freq_mhz) l_freq_khz = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY] * 1000; } - if(l_freq_khz < G_proc_gpst_fmax) + if(l_freq_khz < G_proc_fmax) { // First, calculate the delta between passed in freq, and Pmin - l_temp_freq = l_freq_khz - G_proc_gpst_fmin; + l_temp_freq = l_freq_khz - G_proc_fmin; - // Check if the passed in frequency is smaller than anything in the - // table - if(l_freq_khz <= G_proc_gpst_fmin) + // Check if the passed in frequency is lower than Minimum Frequency + if(l_freq_khz <= G_proc_fmin) { // We need to substract a full step (minus 1) to make sure we // are keeping things safe - l_temp_freq -= (l_gpst_ptr->frequency_step_khz - 1); + l_temp_freq -= (G_khz_per_pstate - 1); } // Next, calculate how many Pstate steps there are in that delta - l_temp_pstate = l_temp_freq / (int32_t)l_gpst_ptr->frequency_step_khz; + l_temp_pstate = l_temp_freq / (int32_t) G_khz_per_pstate; // Lastly, calculate Pstate, by adding delta Pstate steps to Pmin - l_pstate = l_gpst_ptr->pmin + l_temp_pstate; + l_pstate = G_proc_pmin - l_temp_pstate; } else { - // Freq is bigger than anything in table -- return Pmax - l_pstate = G_proc_gpst_pmax; + // Freq is higher than maximum frequency -- return Pmax + l_pstate = G_proc_pmax; } } while(0); @@ -354,133 +156,6 @@ Pstate proc_freq2pstate(uint32_t i_freq_mhz) return (Pstate) l_pstate; } - -// Function Specification -// -// Name: proc_gpsm_pstate_initialize -// -// Description: Initialize Pstate Table (and the rest of the Pstate -// SuperStructure). Also, initialize Global variables -// that will speed up the proc_freq2pstate function. -// -// End Function Specification -errlHndl_t proc_gpsm_pstate_initialize(const PstateSuperStructure* i_pss) -{ - errlHndl_t l_errlHndl = NULL; - GlobalPstateTable * l_gpst_ptr = NULL; - int l_rc = 0; - - do - { - /// Because early EC's of the Murano chip did not have valid #V data, - /// we need to exclude them from loading a pstate table created by a - /// hardware procedure. If we run a table created from a #V on these - /// chips, we could crash the box (or worse, burn something up!) - if ( (cfam_id() == CFAM_CHIP_ID_MURANO_10) - || (cfam_id() == CFAM_CHIP_ID_MURANO_11) ) - { - TRAC_ERR("OCC not supported on murano dd10 or dd11 due to bad #V data. chip id = 0x%08x"); - // Create Error Log and return to caller - /* @ - * @errortype - * @moduleid PROC_GPST_INIT_FAILURE_MOD - * @reasoncode INTERNAL_FAILURE - * @userdata1 chip id - * @userdata2 0 - * @userdata4 OCC_NO_EXTENDED_RC - * @devdesc OCC not supported on Murano DD10 or DD11 - */ - l_errlHndl = createErrl( - PROC_GPST_INIT_FAILURE_MOD, //modId - INTERNAL_FAILURE, //reasoncode - OCC_NO_EXTENDED_RC, //Extended reason code - ERRL_SEV_UNRECOVERABLE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - cfam_id(), //userdata1 - 0 //userdata2 - ); - - //callout the processor - addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_HUID, - G_sysConfigData.proc_huid, - ERRL_CALLOUT_PRIORITY_HIGH); - break; - } - - l_rc = gpsm_initialize(i_pss, &G_global_pstate_table); - - // Print key elements of table for debug - proc_trace_pstate_table_quick(); - - // Get Pstate Table Ptr - l_gpst_ptr = gpsm_gpst(); - - if(l_rc || (l_gpst_ptr != &G_global_pstate_table)) - { - TRAC_ERR("gpsm_initialize failed with rc=0x%08x or l_gpstr_ptr=0x%08x", l_rc, l_gpst_ptr); - - // Create Error Log and return to caller - /* @ - * @errortype - * @moduleid PROC_GPST_INIT_FAILURE_MOD - * @reasoncode INTERNAL_FAILURE - * @userdata1 SRAM Address of the Pstate Table - * @userdata2 Return Code of call that failed - * @userdata4 ERC_PROC_PSTATE_INSTALL_FAILURE - * @devdesc Failed to install Pstate Table - */ - l_errlHndl = createErrl( - PROC_GPST_INIT_FAILURE_MOD, //modId - INTERNAL_FAILURE, //reasoncode - ERC_PROC_PSTATE_INSTALL_FAILURE, //Extended reason code - ERRL_SEV_UNRECOVERABLE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - (uint32_t) &G_global_pstate_table, //userdata1 - l_rc //userdata2 - ); - - addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_HUID, - G_sysConfigData.proc_huid, - ERRL_CALLOUT_PRIORITY_HIGH); - addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_COMPONENT_ID, - ERRL_COMPONENT_ID_FIRMWARE, - ERRL_CALLOUT_PRIORITY_MED); - break; - } - - - // set up key globals based on the pstate table. - - // Set the pstate state (state machine will start enabling pstates - // when it sees this) - proc_gpsm_dcm_sync_set_state(PROC_GPSM_SYNC_PSTATE_TABLE_INSTALLED); - - // Set up Key Globals for use by proc_freq2pstate functions - G_proc_gpst_fmax = l_gpst_ptr->pstate0_frequency_khz - + (((int8_t) l_gpst_ptr->pmin + l_gpst_ptr->entries - 1) - * l_gpst_ptr->frequency_step_khz); - G_proc_gpst_fmin = l_gpst_ptr->pstate0_frequency_khz - + (((int8_t) l_gpst_ptr->pmin) - * l_gpst_ptr->frequency_step_khz); - G_proc_gpst_pmax = l_gpst_ptr->pmin + l_gpst_ptr->entries - 1; - - // Dcom uses this to know whether to pass DCM msgs or not. - G_isDcm = gpsm_dcm_mode_p(); - - // Set globals used by amec for pcap calculation - G_mhz_per_pstate = (l_gpst_ptr->frequency_step_khz)/1000; - - }while(0); - - return l_errlHndl; -} - - // Function Specification // // Name: proc_pstate_kvm_setup @@ -490,432 +165,23 @@ errlHndl_t proc_gpsm_pstate_initialize(const PstateSuperStructure* i_pss) // End Function Specification void proc_pstate_kvm_setup() { - int l_core; - int l_rc = 0; - uint32_t l_configured_cores; - pcbs_pcbspm_mode_reg_t l_ppmr; - pcbs_pmgp1_reg_t l_pmgp1; - pcbs_power_management_bounds_reg_t l_pmbr; - errlHndl_t l_errlHndl; - do { //only run this in KVM mode if(!G_sysConfigData.system_type.kvm) { + TRAC_ERR("proc_pstate_kvm_setup: called in a non OPAL system"); break; } - l_configured_cores = ~in32(PMC_CORE_DECONFIGURATION_REG); - - // Do per-core configuration - for(l_core = 0; l_core < PGP_NCORES; l_core++, l_configured_cores <<= 1) - { - if(!(l_configured_cores & 0x80000000)) continue; - - //do read-modify-write to allow pmax clip to also clip voltage (not just frequency) - l_rc = getscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PCBSPM_MODE_REG, l_core), - &(l_ppmr.value), NULL); //commit errors internally - if(l_rc) - { - TRAC_ERR("proc_pstate_kvm_setup: getscom(PCBS_PCBSPM_MODE_REG) failed. rc=%d, hw_core=%d", - l_rc, l_core); - break; - } - l_ppmr.fields.enable_clipping_of_global_pstate_req = 1; - l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PCBSPM_MODE_REG, l_core), - l_ppmr.value, NULL); //commit errors internally - if(l_rc) - { - TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_PCBSPM_MODE_REG) failed. rc=%d, hw_core=%d", - l_rc, l_core); - break; - } - - //per Vaidy Srinivasan, clear bit 11 in the Power Management GP1 register - l_pmgp1.value = 0; - l_pmgp1.fields.pm_spr_override_en = 1; - l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PMGP1_REG_AND, l_core), - ~l_pmgp1.value, NULL); //commit errors internally - if(l_rc) - { - TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_PMGB1_REG_OR) failed. rc=0x%08x, hw_core=%d", - l_rc, l_core); - break; - } - - //set pmax/pmin clip initial settings - l_pmbr.value = 0; - l_pmbr.fields.pmin_clip = gpst_pmin(&G_global_pstate_table)+1; //Per David Du, we must use pmin+1 to avoid gpsa hang - l_pmbr.fields.pmax_clip = gpst_pmax(&G_global_pstate_table); - l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_POWER_MANAGEMENT_BOUNDS_REG, l_core), - l_pmbr.value, NULL); //commit errors internally - if(l_rc) - { - TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_POWER_MANAGEMENT_BOUNDS_REG) failed. rc=0x%08x, hw_core=%d", - l_rc, l_core); - break; - } - - }// end of per-core config - - if(l_rc) - { - break; - } - - // Set the voltage clipping register to match the pmax/pmin clip values set above. - pmc_rail_bounds_register_t prbr; - prbr.value = in32(PMC_RAIL_BOUNDS_REGISTER); - prbr.fields.pmin_rail = gpst_pmin(&G_global_pstate_table); - prbr.fields.pmax_rail = gpst_pmax(&G_global_pstate_table); - TRAC_IMP("pmin clip pstate = %d, pmax clip pstate = %d", prbr.fields.pmin_rail, prbr.fields.pmax_rail); - out32(PMC_RAIL_BOUNDS_REGISTER, prbr.value); - // Initialize the opal table in SRAM (sets valid bit) populate_pstate_to_opal_tbl(); // copy sram image into mainstore HOMER populate_opal_tbl_to_mem(); TRAC_IMP("proc_pstate_kvm_setup: RUNNING IN KVM MODE"); - }while(0); - - if(l_rc) - { - // Create Error Log and request reset - /* @ - * @errortype - * @moduleid PROC_PSTATE_KVM_SETUP_MOD - * @reasoncode PROC_SCOM_ERROR - * @userdata1 l_configured_cores - * @userdata2 Return Code of call that failed - * @userdata4 OCC_NO_EXTENDED_RC - * @devdesc OCC failed to scom a core register - */ - l_errlHndl = createErrl( - PROC_PSTATE_KVM_SETUP_MOD, //modId - PROC_SCOM_ERROR, //reasoncode - OCC_NO_EXTENDED_RC, //Extended reason code - ERRL_SEV_PREDICTIVE, //Severity - NULL, //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - l_configured_cores, //userdata1 - l_rc //userdata2 - ); - - addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_HUID, - G_sysConfigData.proc_huid, - ERRL_CALLOUT_PRIORITY_HIGH); - addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_COMPONENT_ID, - ERRL_COMPONENT_ID_FIRMWARE, - ERRL_CALLOUT_PRIORITY_MED); - - REQUEST_RESET(l_errlHndl); - } -} - -// Function Specification -// -// Name: proc_gpsm_dcm_sync_enable_pstates_smh -// -// Description: Step through all the states & synch needed to enable -// Pstates on both master & slave on a DCM. This also -// works for a SCM, which will act as DCM master (as far -// as this function is concerned.) -// -// End Function Specification -void proc_gpsm_dcm_sync_enable_pstates_smh(void) -{ - // Static Locals - static GpsmEnablePstatesMasterInfo l_master_info; - static Pstate l_voltage_pstate, l_freq_pstate; - - // Local Variables - int l_rc = 0; - errlHndl_t l_errlHndl = NULL; - - if(!gpsm_dcm_slave_p()) - { - // --------------------------------------- - // SCM or DCM Master - // --------------------------------------- - switch( G_proc_dcm_sync_state.sync_state_master ) - { - case PROC_GPSM_SYNC_NO_PSTATE_TABLE: - // Waiting for Pstate Table from TMGT - break; - - case PROC_GPSM_SYNC_PSTATE_TABLE_INSTALLED: - PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master); - // DCM SYNC (MasterWaitForSlave): Wait for slave to install Pstate table - if(gpsm_dcm_mode_p()){ - if( G_proc_dcm_sync_state.sync_state_slave == PROC_GPSM_SYNC_PSTATE_TABLE_INSTALLED) - { - // Move to next state in state machine - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_READY_TO_ENABLE_MASTER; - } - } - else - { - // Move to next state in state machine - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_READY_TO_ENABLE_MASTER; - } - break; - - case PROC_GPSM_SYNC_READY_TO_ENABLE_MASTER: - PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master); - - // Pstate tables has been installed, so now Master can start to enable Pstates - l_rc = gpsm_enable_pstates_master(&l_master_info, &l_voltage_pstate, &l_freq_pstate); - if(l_rc) - { - // Error - TRAC_ERR("MSTR: gpsm_enable_pstates_master failed with rc=0x%08x", l_rc); - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_ERROR; - break; - } - TRAC_IMP("MSTR: Initial Pstates: V: %d, F: %d\n",l_voltage_pstate, l_freq_pstate); - // DCM SYNC (Master2Slave): Send V & F Pstate to slave - G_proc_dcm_sync_state.dcm_pair_id = G_pbax_id.chip_id; - G_proc_dcm_sync_state.pstate_v = l_voltage_pstate; - G_proc_dcm_sync_state.pstate_f = l_freq_pstate; - - // Move to next state in state machine - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED; - break; - - case PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED: - PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master); - // DCM SYNC (MasterWaitForSlave): Wait for slave to complete gpsm_enable_pstates_slave() - if(gpsm_dcm_mode_p()){ - if( G_proc_dcm_sync_state.sync_state_slave == PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED) - { - // Move to next state in state machine - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_READY_TO_ENABLE_SLAVE; - } - } - else - { - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_READY_TO_ENABLE_SLAVE; - } - break; - - - case PROC_GPSM_SYNC_READY_TO_ENABLE_SLAVE: - PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master); - - // Master does next step of enabling Pstates, now that slave has done it's enable - l_rc = gpsm_enable_pstates_slave(&l_master_info, l_voltage_pstate, l_freq_pstate); - if(l_rc) - { - // Error - TRAC_ERR("MSTR: gpsm_enable_pstates_slave failed with rc=0x%08x", l_rc); - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_ERROR; - break; - } - TRAC_INFO("MSTR: Completed DCM Pstate Slave Init\n"); - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED; - break; - - case PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED: - PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master); - // Master puts this chip in Pstate HW mode - l_rc = gpsm_hw_mode(); - if(l_rc) - { - // Error - TRAC_ERR("MSTR: gpsm_hw_mode failed with rc=0x%08x", l_rc); - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_ERROR; - break; - } - // DCM SYNC (Master2Slave): Tell Slave Master has entered HW mmode - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_HW_MODE; - break; - - case PROC_GPSM_SYNC_PSTATE_HW_MODE: - PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master); - // DCM SYNC (Master2Slave): Wait for Slave to Enter HW Mode - if(gpsm_dcm_mode_p()){ - if( G_proc_dcm_sync_state.sync_state_slave == PROC_GPSM_SYNC_PSTATE_HW_MODE) - { - TRAC_INFO("MSTR: Completed DCM Pstate Enable"); - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED; - - //do additional setup if in kvm mode - proc_pstate_kvm_setup(); - } - } - else - { - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED; - TRAC_INFO("MSTR: Completed SCM Pstate Enable"); - - //do additional setup if in kvm mode - proc_pstate_kvm_setup(); - } - break; - - case PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED: - // Final State - // Pstates Enabled on both modules in DCM - break; - - case PROC_GPSM_SYNC_PSTATE_ERROR: - // Do nothing, something will have to come and kick us out of this state - break; - - default: - G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_NO_PSTATE_TABLE; - break; - } - } - else if (gpsm_dcm_slave_p()) - { - // --------------------------------------- - // DCM Slave - // - Don't need to check if DCM, since we can't come in here unless DCM - // --------------------------------------- - - switch( G_proc_dcm_sync_state.sync_state_slave) - { - case PROC_GPSM_SYNC_NO_PSTATE_TABLE: - // Waiting for Pstate Table from TMGT - break; - - case PROC_GPSM_SYNC_PSTATE_TABLE_INSTALLED: - // Pstate table has been installed, but slave needs to wait - // for master before it can do anything else. - - // DCM SYNC (SlaveWaitForMaster): Send V & F Pstate to slave - // Wait for Master to complete gpsm_enable_pstates_master() - // before running gpsm_enable_pstates_slave() - if( G_proc_dcm_sync_state.sync_state_master == PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED) - { - // Go to next state - G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED; - } - break; - - - case PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED: - PROC_DBG("GPST DCM Slave State %d\n",G_proc_dcm_sync_state.sync_state_slave); - // Read the initial Pstates from the data DCM master sent - l_voltage_pstate = G_proc_dcm_sync_state.pstate_v; - l_freq_pstate = G_proc_dcm_sync_state.pstate_f; - - // NULL is passed to this function when run on dcm slave - l_rc = gpsm_enable_pstates_slave(NULL, l_voltage_pstate, l_freq_pstate); - if(l_rc) - { - // Error - TRAC_ERR("SLV: gpsm_enable_pstates_slave failed with rc=0x%08x", l_rc); - G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_ERROR; - break; - } - TRAC_INFO("SLV: Completed DCM Pstate Slave Init\n"); - - // DCM SYNC (Slave2Master): - // Tell Master that slave has run gpsm_enable_pstates_slave() - - // Go to next state - G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED; - break; - - case PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED: - // DCM SYNC (SlaveWaitForMaster): Wait for Master to run gpsm_hw_mode - if( G_proc_dcm_sync_state.sync_state_master == PROC_GPSM_SYNC_PSTATE_HW_MODE) - { - // Enter Pstate HW mode - l_rc = gpsm_hw_mode(); - if(l_rc) - { - // Error - TRAC_ERR("SLV: gpsm_hw_mode failed with rc=0x%08x", l_rc); - G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_ERROR; - break; - } - - // DCM SYNC (Slave2Master): Tell master that DCM slave made it to HW mode - - // Go to next state - G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_HW_MODE; - } - break; - - case PROC_GPSM_SYNC_PSTATE_HW_MODE: - // Slave & Master now both know each other has HW mode enabled - if( G_proc_dcm_sync_state.sync_state_master == PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED) - { - G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED; - TRAC_INFO("SLV: Completed DCM Pstate Enable"); - - //do additional setup if in kvm mode - proc_pstate_kvm_setup(); - } - break; - - case PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED: - // Final State - // Pstates Enabled on both modules in DCM - break; - - case PROC_GPSM_SYNC_PSTATE_ERROR: - // Do nothing, something will have to come and kick us out of this state - break; - - default: - G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_NO_PSTATE_TABLE; - break; - - } - } - - // If we are in the process of running through the state machine, - // we will do a sem_post to speed up the DCOM Thread and step us - // through faster. - if( PROC_GPSM_SYNC_NO_PSTATE_TABLE != proc_gpsm_dcm_sync_get_my_state() - && !proc_is_hwpstate_enabled() ) - { - ssx_semaphore_post(&G_dcomThreadWakeupSem); - } - - // If we broke out of loops above because of an error, create an - // error log and return it to caller. - if(l_rc) - { - /* @ - * @errortype - * @moduleid PROC_ENABLE_PSTATES_SMH_MOD - * @reasoncode SSX_GENERIC_FAILURE - * @userdata1 SRAM Address of the Pstate Table - * @userdata2 Return Code of call that failed - * @userdata4 OCC_NO_EXTENDED_RC - * @devdesc Failed to install Pstate Table - */ - l_errlHndl = createErrl( - PROC_ENABLE_PSTATES_SMH_MOD, //modId - SSX_GENERIC_FAILURE, //reasoncode - OCC_NO_EXTENDED_RC, //Extended reason code - ERRL_SEV_PREDICTIVE, //Severity - NULL, //TODO: create trace //Trace Buf - DEFAULT_TRACE_SIZE, //Trace Size - (uint32_t) &G_global_pstate_table, //userdata1 - l_rc); //userdata2 - addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_COMPONENT_ID, - ERRL_COMPONENT_ID_FIRMWARE, - ERRL_CALLOUT_PRIORITY_HIGH); - addCalloutToErrl(l_errlHndl, - ERRL_CALLOUT_TYPE_HUID, - G_sysConfigData.proc_huid, - ERRL_CALLOUT_PRIORITY_LOW); - REQUEST_RESET(l_errlHndl); - } - - return; + }while(0); } // Function Specification @@ -928,26 +194,27 @@ void proc_gpsm_dcm_sync_enable_pstates_smh(void) void populate_pstate_to_opal_tbl() { uint8_t i = 0; - GlobalPstateTable * l_gpst_ptr = NULL; memset(&G_opal_table, 0, sizeof(opal_table_t)); - l_gpst_ptr = gpsm_gpst(); - const int8_t l_pmax = (int8_t) l_gpst_ptr->pmin + l_gpst_ptr->entries - 1; - G_opal_table.config.valid = 1; // default 0x01 - G_opal_table.config.version = 1; // default 0x01 + G_opal_table.config.valid = 1; // default 0x01 + G_opal_table.config.version = 1; // default 0x01 G_opal_table.config.throttle = NO_THROTTLE; // default 0x00 - G_opal_table.config.pmin = gpst_pmin(&G_global_pstate_table)+1; //Per David Du, we must use pmin+1 to avoid gpsa hang - G_opal_table.config.pnominal = (int8_t)proc_freq2pstate(G_sysConfigData.sys_mode_freq.table[OCC_MODE_NOMINAL]); - G_opal_table.config.pmax = gpst_pmax(&G_global_pstate_table); - const uint16_t l_entries = G_opal_table.config.pmax - G_opal_table.config.pmin + 1; - const uint8_t l_idx = l_gpst_ptr->entries-1; + G_opal_table.config.pmin = G_proc_pmin - 1; + G_opal_table.config.pnominal = proc_freq2pstate(G_sysConfigData.sys_mode_freq.table[OCC_MODE_NOMINAL]); + G_opal_table.config.pmax = G_proc_pmax; + const uint16_t l_entries = G_opal_table.config.pmin - G_opal_table.config.pmax + 1; +// const uint8_t l_idx = l_entries-1; for (i = 0; i < l_entries; i++) { - G_opal_table.data[i].pstate = (int8_t) l_pmax - i; - G_opal_table.data[i].flag = 0; // default 0x00 - if (i < l_gpst_ptr->entries) + G_opal_table.data[i].pstate = (Pstate) G_proc_pmax + i; + G_opal_table.data[i].flag = 0; // default 0x00 + +// @TODO: what are parameters used to calculte evids in P9? +// Use it to calculate evids and complete OPAL Pstate table: + +/* if (i < l_gpst_ptr->entries) { G_opal_table.data[i].evid_vdd = l_gpst_ptr->pstate[i].fields.evid_vdd; G_opal_table.data[i].evid_vcs = l_gpst_ptr->pstate[i].fields.evid_vcs; @@ -958,12 +225,48 @@ void populate_pstate_to_opal_tbl() G_opal_table.data[i].evid_vdd = l_gpst_ptr->pstate[l_idx].fields.evid_vdd; G_opal_table.data[i].evid_vcs = l_gpst_ptr->pstate[l_idx].fields.evid_vcs; } - // extrapolate the frequency - G_opal_table.data[i].freq_khz = l_gpst_ptr->pstate0_frequency_khz + (G_opal_table.data[i].pstate * l_gpst_ptr->frequency_step_khz); +*/ + // calculate frequency for pstate + G_opal_table.data[i].freq_khz = proc_pstate2freq(G_opal_table.data[i].pstate); } } -#endif // @TODO - TEMP - global state table changes in P9 + + +// Function Specification +// +// Name: proc_pstate_initialize +// +// Description: initialize Global variables required for +// the proc_freq2pstate function. +// +// End Function Specification +void proc_pstate_initialize(void) +{ + + // @TODO: Schedule a PGPE IPC to enable pstates. This will also tell + // PGPE how to set PMCR mode register (OCC control pstates or OPAL). + + // the call back IPC function that gets executed after this IPC finishes + // sets the G_proc_pstate_enabled flag to true, so that the OCC is then + // able to switch to the active state. + + // Set up Key Globals for use by proc_freq2pstate functions + G_proc_fmax = 4322500; + G_proc_fmin = 2028250; + G_khz_per_pstate = 33250; + G_proc_pmax = 0; + G_proc_pmin = G_proc_pmax + ((G_proc_fmax - G_proc_fmin)/G_khz_per_pstate); + + // Set globals used by amec for pcap calculation + // could have used G_khz_per_pstate in PCAP calculations + // instead, but using a separate varaible speeds up PCAP related + // calculations significantly, by eliminating division operations. + G_mhz_per_pstate = G_khz_per_pstate/1000; + + TRAC_INFO("proc_pstate_initialize: Pstate Key globals initialized to default values"); + +} // Function Specification // diff --git a/src/occ_405/proc/proc_pstate.h b/src/occ_405/proc/proc_pstate.h index 8ca02ea..f10500d 100755 --- a/src/occ_405/proc/proc_pstate.h +++ b/src/occ_405/proc/proc_pstate.h @@ -38,16 +38,6 @@ //#include "gpsm.h" //#include "pstates.h" -// GPSM DCM Synchronization - used by MBOX to transfer between DCM M & S -typedef struct -{ - uint8_t dcm_pair_id; - uint8_t sync_state_master :4; - uint8_t sync_state_slave :4; - uint8_t pstate_v; - uint8_t pstate_f; -} proc_gpsm_dcm_sync_occfw_t; - typedef struct __attribute__ ((packed)) { uint8_t valid; @@ -87,38 +77,22 @@ enum { POWER_SUPPLY_FAILURE = 0x03, OVERCURRENT = 0x04, OCC_RESET = 0x05, -}; - -//extern GlobalPstateTable G_global_pstate_table; +}; extern uint32_t G_mhz_per_pstate; extern opal_table_t G_opal_table; -// Initialize PState Table -// TEMP -- PstateSuperStructure no longer exists -//errlHndl_t proc_gpsm_pstate_initialize(const PstateSuperStructure* i_pss); - -// Entry function for enabling Pstates once table is installed -//void proc_gpsm_dcm_sync_enable_pstates_smh(void); - -// Get DCM Sync State -proc_gpsm_dcm_sync_occfw_t proc_gpsm_dcm_sync_get_state(void); - -// Pull down DCM pair's Sync State & Info via Mbox -void proc_gpsm_dcm_sync_update_from_mbox(proc_gpsm_dcm_sync_occfw_t * i_dcm_sync_state); +// Initialize PState Key parameters +void proc_pstate_initialize(void); // Helper function to translate from Frequency to nearest Pstate -// TEMP -- Pstate no longer exists -//Pstate proc_freq2pstate(uint32_t i_freq_mhz); +Pstate proc_freq2pstate(uint32_t i_freq_mhz); // Helper function to translate from Pstate to nearest Frequency // TEMP -- Pstate no longer exists //uint32_t proc_pstate2freq(Pstate i_pstate); -// Helper function to determine if we are a DCM -inline bool proc_is_dcm(); - // Helper function to determine if we are in HW Pstate mode inline bool proc_is_hwpstate_enabled(void); diff --git a/src/occ_405/state.c b/src/occ_405/state.c index 5cc0b40..20d711b 100755 --- a/src/occ_405/state.c +++ b/src/occ_405/state.c @@ -42,7 +42,6 @@ #include #include -extern proc_gpsm_dcm_sync_occfw_t G_proc_dcm_sync_state; extern bool G_mem_monitoring_allowed; extern task_t G_task_table[TASK_END]; // Global task table @@ -143,10 +142,14 @@ errlHndl_t SMGR_standby_to_observation() rtl_clr_run_mask_deferred(RTL_FLAG_STANDBY); rtl_set_run_mask_deferred(RTL_FLAG_OBS); + // Initialize key freq2pstate Global parameters + proc_pstate_initialize(); + // Set the actual STATE now that we have finished everything else CURRENT_STATE() = OCC_STATE_OBSERVATION; TRAC_IMP("SMGR: Standby to Observation Transition Completed"); + } else if(FALSE == l_error_logged) { @@ -223,7 +226,9 @@ errlHndl_t SMGR_observation_to_active() int l_extRc = OCC_NO_EXTENDED_RC; int l_rc = 0; - // First check to make sure Pstates are enabled. If they aren't, then + // Pstates are enabled via an IPC call to PGPE once the OCC reaches the + // observation state. We still have to check that the enable_pstates() IPC job + // on the PGPE has completed before transitioned to the active state. otherwise, // wait TBD seconds in case we are going directly from Standby to Active // (pstate init only happens in observation state, so it might not be // done yet...must call it in this while loop since it is done in this @@ -238,8 +243,7 @@ errlHndl_t SMGR_observation_to_active() // If we have all data we need to go to active state, but don't have pstates // enabled yet...then we will do the aforementioned wait if(((DATA_get_present_cnfgdata() & SMGR_VALIDATE_DATA_ACTIVE_MASK) == - SMGR_VALIDATE_DATA_ACTIVE_MASK) - && !proc_is_hwpstate_enabled() ) + SMGR_VALIDATE_DATA_ACTIVE_MASK)) { SsxTimebase start = ssx_timebase_get(); while( ! proc_is_hwpstate_enabled() ) @@ -249,9 +253,7 @@ errlHndl_t SMGR_observation_to_active() { if(FALSE == l_error_logged) { - TRAC_ERR("SMGR: Timeout waiting for Pstates to be enabled, master state=%d, slave state=%d, pmc_mode[%08x], chips_present[%02x], pmc_deconfig[%08x]", - G_proc_dcm_sync_state.sync_state_master, - G_proc_dcm_sync_state.sync_state_slave, + TRAC_ERR("SMGR: Timeout waiting for Pstates to be enabled, pmc_mode[%08x], chips_present[%02x], pmc_deconfig[%08x]", in32(PMC_MODE_REG), G_sysConfigData.is_occ_present, in32(PMC_CORE_DECONFIGURATION_REG)); @@ -259,7 +261,6 @@ errlHndl_t SMGR_observation_to_active() l_extRc = ERC_GENERIC_TIMEOUT; break; } - proc_gpsm_dcm_sync_enable_pstates_smh(); ssx_sleep(SSX_MICROSECONDS(500)); } if(proc_is_hwpstate_enabled() && G_sysConfigData.system_type.kvm) diff --git a/src/occ_405/thread/chom.c b/src/occ_405/thread/chom.c index 35e0bf1..ffa652e 100755 --- a/src/occ_405/thread/chom.c +++ b/src/occ_405/thread/chom.c @@ -291,21 +291,8 @@ void chom_update_sensors() { // update sample, min, max, average sensor data if (NULL != g_chom_sensor_table[i]) { - //Report all sensors listed in g_chom_sensor_table, unless - //we have a Murano (DCM), then we only report the power from the - //OCC_DCM_MASTER occ. The DCM occ pairs (OCC_DCM_MASTER,OCC_DCM_SLAVE) are - //((0,1),(2,3),(4,5),(6,7)). - if( ((i >= CHOMPWRS0) && (i <= CHOMPWRS7)) && - (CFAM_CHIP_TYPE_MURANO == cfam_chip_type()) && - (((i-CHOMPWRS0) % 2) == 1) ) - { - //Do nothing - } - else - { - // directly mapping to mini-sensor - g_chom->sensorData[0].sensor[i].sample = *g_chom_sensor_table[i]; - } + // directly mapping to mini-sensor + g_chom->sensorData[0].sensor[i].sample = *g_chom_sensor_table[i]; } l_sample = g_chom->sensorData[0].sensor[i].sample; -- cgit v1.2.1