summaryrefslogtreecommitdiffstats
path: root/src/occ_405/proc
diff options
context:
space:
mode:
authorWael El-Essawy <welessa@us.ibm.com>2016-05-02 22:20:14 -0500
committerWael El-Essawy <welessa@us.ibm.com>2016-05-25 16:19:23 -0400
commit6d29cab23da5bacaf0772bb8dd6265c4b442760c (patch)
treed7dee4b726108c87734bd1508abccf47d1a230e4 /src/occ_405/proc
parent6f82299cb1e306dabef5bbae1a9d4e5817dbcea9 (diff)
downloadtalos-occ-6d29cab23da5bacaf0772bb8dd6265c4b442760c.tar.gz
talos-occ-6d29cab23da5bacaf0772bb8dd6265c4b442760c.zip
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 <welessa@us.ibm.com>
Diffstat (limited to 'src/occ_405/proc')
-rwxr-xr-xsrc/occ_405/proc/proc_pstate.c879
-rwxr-xr-xsrc/occ_405/proc/proc_pstate.h34
2 files changed, 95 insertions, 818 deletions
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);
OpenPOWER on IntegriCloud