summaryrefslogtreecommitdiffstats
path: root/src/occ/amec/amec_oversub.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/occ/amec/amec_oversub.c')
-rwxr-xr-xsrc/occ/amec/amec_oversub.c272
1 files changed, 272 insertions, 0 deletions
diff --git a/src/occ/amec/amec_oversub.c b/src/occ/amec/amec_oversub.c
new file mode 100755
index 0000000..2b967b7
--- /dev/null
+++ b/src/occ/amec/amec_oversub.c
@@ -0,0 +1,272 @@
+/******************************************************************************
+// @file amec_oversub.c
+// @brief Over-subscription
+*/
+/******************************************************************************
+ *
+ * @page ChangeLogs Change Logs
+ * @section _amec_oversub_c amec_oversub.c
+ * @verbatim
+ *
+ * Flag Def/Fea Userid Date Description
+ * ------- ---------- -------- ---------- ----------------------------------
+ * @at010 859992 alvinwan 11/07/2012 Added oversubscription feature
+ * @th028 867841 thallet 01/22/2013 Trace in oversubscription causes panic
+ * @fk001 879727 fmkassem 04/16/2013 PCAP support.
+ * @at020 908666 alvinwan 12/16/2013 Oversubscription Error Handling
+ * @at023 910877 alvinwan 01/09/2014 Excessive fan increase requests error for mfg
+ * @gm026 916029 milesg 02/17/2014 revert back to auto2 mode without reading GPIO's
+ * @gm041 928150 milesg 06/02/2014 add callout for mfg oversubscription elog
+ *
+ * @endverbatim
+ *
+ *///*************************************************************************/
+
+//*************************************************************************
+// Includes
+//*************************************************************************
+#include "ssx.h"
+
+#include <occ_common.h>
+#include <trac.h>
+#include <amec_sys.h>
+#include <proc_pstate.h>
+#include <dcom.h>
+#include <occ_sys_config.h>
+#include <amec_service_codes.h>
+//*************************************************************************
+// Externs
+//*************************************************************************
+
+//*************************************************************************
+// Macros
+//*************************************************************************
+
+//*************************************************************************
+// Defines/Enums
+//*************************************************************************
+#define OVERSUB_REASON_DELAY_4MS 16 // 4ms (unit is 250us)
+#define OVERSUB_REASON_COUNT_TIMEOUT 2
+#define OVERSUB_REASON_DETERMINED 1
+
+//*************************************************************************
+// Structures
+//*************************************************************************
+
+//*************************************************************************
+// Globals
+//*************************************************************************
+
+//*************************************************************************
+// Function Prototypes
+//*************************************************************************
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+
+
+
+
+// Function Specification
+//
+// Name: amec_oversub_pmax_clip
+//
+// Description: Set Pmax_Clip in PMC to lowest Pstate
+//
+//
+// Flow: FN=
+//
+// Task Flags:
+//
+// End Function Specification
+void amec_oversub_pmax_clip(Pstate i_pstate)
+{
+ pmc_rail_bounds_register_t prbr;
+
+ // Set Pmax_Clip in PMC to lowest Pstate
+ prbr.value = in32(PMC_RAIL_BOUNDS_REGISTER);
+ prbr.fields.pmax_rail = i_pstate; //@fk001c
+ out32(PMC_RAIL_BOUNDS_REGISTER, prbr.value);
+}
+
+
+//*************************************************************************
+// Functions
+//*************************************************************************
+// Function Specification
+//
+// Name: amec_oversub_isr
+//
+// Description: Oversubscription ISR
+//
+// Flow: FN=
+//
+// Task Flags:
+//
+// Note: This function is only ever called from Critical interrupt context
+//
+// End Function Specification
+
+void amec_oversub_isr(void)
+{
+ static uint32_t l_isr_count = 0;
+ static uint8_t l_polarity = SSX_IRQ_POLARITY_ACTIVE_LOW; // Default is low
+ uint8_t l_cur_polarity = l_polarity;
+
+ l_isr_count++;
+
+ // SSX_IRQ_POLARITY_ACTIVE_LOW means over-subscription is active
+ if(l_polarity == SSX_IRQ_POLARITY_ACTIVE_LOW)
+ {
+ // 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)); //@fk001c
+ // TODO: Throttle all Centaurs via PORE-GPE by setting 'Emergency Throttle'
+
+ g_amec->oversub_status.oversubReasonLatchCount = OVERSUB_REASON_DELAY_4MS;
+ }
+
+ // Set oversubPinLive and oversubActiveTime
+ g_amec->oversub_status.oversubPinLive = 1;
+ g_amec->oversub_status.oversubActiveTime = ssx_timebase_get();
+
+ // Setup the IRQ
+ ssx_irq_setup(PGP_IRQ_EXTERNAL_TRAP,
+ SSX_IRQ_POLARITY_ACTIVE_HIGH,
+ SSX_IRQ_TRIGGER_LEVEL_SENSITIVE);
+ l_polarity = SSX_IRQ_POLARITY_ACTIVE_HIGH;
+
+ }
+ else // over-subscription is inactive
+ {
+ // Clear oversubPinLive
+ g_amec->oversub_status.oversubPinLive = 0;
+
+ // Set oversubInActiveTime
+ g_amec->oversub_status.oversubInactiveTime = ssx_timebase_get();
+
+ // Setup the IRQ
+ ssx_irq_setup(PGP_IRQ_EXTERNAL_TRAP,
+ SSX_IRQ_POLARITY_ACTIVE_LOW,
+ SSX_IRQ_TRIGGER_LEVEL_SENSITIVE);
+
+ l_polarity = SSX_IRQ_POLARITY_ACTIVE_LOW;
+ }
+
+ // Trace Oversub Event, Polarity and ISR count
+ TRAC_INFO("Oversub IRQ - Polarity (low active):%d, oversubPinLive: %d, count: %d)", l_cur_polarity, g_amec->oversub_status.oversubPinLive, l_isr_count);
+
+}
+
+// Function Specification
+//
+// Name: amec_oversub_check
+//
+// Description: Oversubscription check called in
+// amec_slv_common_tasks_pre()
+//
+//
+// Flow: FN=
+//
+// Task Flags:
+//
+// End Function Specification
+void amec_oversub_check(void)
+{
+ //uint8_t l_cme_pin = G_sysConfigData.apss_gpio_map.cme_throttle_n; //gm026
+ uint8_t l_cme_pin_value = 1; // low active, so set default to high
+ static BOOLEAN l_prev_ovs_state = FALSE; // oversub happened // @at020a
+
+ // Get CME Pin state
+ // No longer reading gpio from APSS in GA1 due to instability in APSS composite mode -- gm026
+ //apss_gpio_get(l_cme_pin, &l_cme_pin_value); // @at020a
+
+ // Check CME Pin? OR CME Oversub Mnfg Active
+ if( (l_cme_pin_value == 0) ||
+ (g_amec->oversub_status.cmeThrottlePinMnfg == 1) )
+ {
+ g_amec->oversub_status.cmeThrottlePinLive = 1;
+ g_amec->oversub_status.cmeThrottleLatchAmec = 1;
+ }
+ else
+ {
+ // Do not clear cmeThrottleLatchAmec.
+ // That will only be done via the PowerCa command from TMGT.
+ g_amec->oversub_status.cmeThrottlePinLive = 0;
+ }
+
+ // @at020a - start
+ // oversubscription condition happened?
+ if ( AMEC_INTF_GET_OVERSUBSCRIPTION() == TRUE )
+ {
+ if ( l_prev_ovs_state != TRUE)
+ {
+ l_prev_ovs_state = TRUE;
+
+ TRAC_ERR("Oversubscription condition happened");
+ /* @
+ * @errortype
+ * @moduleid AMEC_SLAVE_CHECK_PERFORMANCE
+ * @reasoncode OVERSUB_ALERT
+ * @userdata1 Previous OVS State
+ * @userdata4 ERC_AMEC_SLAVE_OVS_STATE
+ * @devdesc Oversubscription condition happened
+ */
+ errlHndl_t l_errl = createErrl(AMEC_SLAVE_CHECK_PERFORMANCE,//modId
+ OVERSUB_ALERT, //reasoncode
+ ERC_AMEC_SLAVE_OVS_STATE, //Extended reason code
+ ERRL_SEV_INFORMATIONAL, //Severity
+ NULL, //Trace Buf
+ DEFAULT_TRACE_SIZE, //Trace Size
+ l_prev_ovs_state, //userdata1
+ 0); //userdata2
+
+ // set the mfg action flag (allows callout to be added to info error)
+ setErrlActions(l_errl, ERRL_ACTIONS_MANUFACTURING_ERROR);
+
+ // add the oversubscription symbolic callout -- gm041
+ addCalloutToErrl(l_errl,
+ ERRL_CALLOUT_TYPE_COMPONENT_ID,
+ ERRL_COMPONENT_ID_OVERSUBSCRIPTION,
+ ERRL_CALLOUT_PRIORITY_HIGH);
+
+ // Commit Error
+ commitErrl(&l_errl);
+ }
+ }
+ else
+ {
+ l_prev_ovs_state = FALSE;
+ }
+ // @at020a - end
+
+
+
+ // TODO: Set any more oversub based on APSS GPIO Pins (i.e. Orlena 12V OC pins)
+
+ // Figure out the over-subscription reason
+ if(g_amec->oversub_status.oversubReasonLatchCount > 1)
+ {
+ // Try to figure out why we throttled based on APSS GPIO pins
+ if( g_amec->oversub_status.oversubReasonLatchCount == OVERSUB_REASON_COUNT_TIMEOUT)
+ {
+ g_amec->oversub_status.oversubReason = INDETERMINATE;
+ g_amec->oversub_status.oversubReasonLatchCount = OVERSUB_REASON_DETERMINED;
+
+ TRAC_INFO("Oversub (oversubReason: %d)", g_amec->oversub_status.oversubReason );
+ }
+ else
+ {
+ // If we can figure out why oversub happened, set oversubReason to valide enum value
+ // then set oversubReasonLatchCount = 1
+
+ // If we can't figure it out, decrease oversubReasonLatchCount and we will try again in 250us
+ g_amec->oversub_status.oversubReasonLatchCount--; // The unit of oversubReasonLatchCount is 250us
+
+ }
+ }
+
+}
OpenPOWER on IntegriCloud