summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRahul Batra <rbatra@us.ibm.com>2017-12-20 13:31:00 -0600
committerJoshua Hunsberger <jahunsbe@us.ibm.com>2018-02-01 15:43:17 -0600
commit8d39c7666e19c0969cb49dbdd5b962a1613252f1 (patch)
tree6b3880d82f346a46242681207b38fa39b1469a3b
parentaa4213acc4c1741dc88bca283738a33c15f48d73 (diff)
downloadtalos-hcode-8d39c7666e19c0969cb49dbdd5b962a1613252f1.tar.gz
talos-hcode-8d39c7666e19c0969cb49dbdd5b962a1613252f1.zip
PM: VDM Prolonged Droop Fix
Key_Cronus_Test=PM_REGRESS Change-Id: Ife6b3c90414b5a07bdab7640e5152c6d3b80df97 Original-Change-Id: I73d38d6029a5b84590d1081855e12c145a535869 CQ: SW413192 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/51338 Reviewed-by: Michael S. Floyd <mfloyd@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Gregory S. Still <stillgs@us.ibm.com> Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: RANGANATHPRASAD G. BRAHMASAMUDRA <prasadbgr@in.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
-rw-r--r--import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c140
1 files changed, 41 insertions, 99 deletions
diff --git a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c
index 0dff4396..e6229062 100644
--- a/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c
+++ b/import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c
@@ -30,21 +30,10 @@
#include <p9_hcd_memmap_occ_sram.H>
#include "p9_pgpe_optrace.h"
-#define THROTTLE_SCOM_MULTICAST_READ_OR 0x41010A9E
-#define THROTTLE_SCOM_MULTICAST_READ_AND 0x49010A9E
-#define THROTTLE_SCOM_MULTICAST_WRITE 0x69010A9E
-
-#define WORKAROUND_SCOM_MULTICAST_WRITE 0x69010800
-
#define AUX_TASK 14
#define GPE2TSEL 0xC0020000
-// Include core offline, address error, and timeout. The timeout is included to avoid
-// an extra mtmsr in the event we need to cleanup from SW407201
-#define MSR_THROTTLE_MASK 0x29000000
-
-
-uint32_t G_orig_throttle; //original value of throttle SCOM before manipulation
+uint32_t G_orig_throttle = 0; //original value of throttle SCOM before manipulation
uint32_t G_throttleOn; //is throttling currently enabled
uint32_t G_throttleCount; //how long has throttle been in current state
@@ -113,105 +102,58 @@ void p9_pgpe_fit_init()
ppe42_fit_setup(p9_pgpe_fit_handler, NULL);
}
-__attribute__((always_inline)) inline void cleanup_SW407201()
-{
- do
- {
- if (((mfmsr() >> 20) & 0x7) == 0x4)
- {
- // Work-around for HW problem. See SW407201
- // If ADDRESS_ERROR then perform a SCOM write of all zeros to
- // 2n010800 where n is the core number. Ignore ADDRESS_ERROR
- // returned.
- out64(WORKAROUND_SCOM_MULTICAST_WRITE, 0);
- }
- }
- while (0);
-}
-
__attribute__((always_inline)) inline void handle_core_throttle()
{
- do
- {
- uint32_t config = in32(OCB_OCCS2); //bits 16-18 in OCC Scratch Register 2
- uint32_t run = (config >> 14) & 0x3; //this looks at the inject and enable bits, if either are high we run
+ uint32_t config = in32(OCB_OCCS2); //bits 16-18 in OCC Scratch Register 2
+ uint32_t run = (config >> 14) & 0x3; //this looks at the inject and enable bits, if either are high we run
- if(run) //Currently running
+ if(run) //Currently running
+ {
+ uint32_t throttleData = G_orig_throttle;
+ uint32_t inject = run & 0x1; //Inject is bit 17, if this is high we run one throttle burst then turn off
+ uint32_t type = (config >> 13) & 0x1; //type is bit 18, this determines which kind of throttling we do
+ uint32_t mask = type ? CORE_SLOWDOWN : CORE_IFU_THROTTLE;
+ uint32_t pgpe_throttle_assert = G_pgpe_header_data->g_pgpe_throttle_assert;
+ uint32_t pgpe_throttle_deassert = G_pgpe_header_data->g_pgpe_throttle_deassert;
+
+ //if currently off, we don't desire always off, this is the first evaluation since become enabled, we are in always on,
+ //or we (re enabled and have reached the count, then we turn throttling on (if both assert and deassert are 0 this statement fails)
+ if(!G_throttleOn && pgpe_throttle_assert != 0 &&
+ (G_throttleCount == 0 || pgpe_throttle_deassert == 0 || pgpe_throttle_deassert == G_throttleCount))
{
- uint32_t value = mfmsr();
-
- if(G_throttleCount == 0) //when throttle control enabled, read current state of throttle SCOM before manipulation
- {
- mtmsr(value | MSR_THROTTLE_MASK); //don't cause halt if all cores offline or address error (PC Timeout)
- G_orig_throttle = in64(THROTTLE_SCOM_MULTICAST_READ_AND) >> 32;
-
- // Fail the throttle on any return code.
- uint32_t fail = ((mfmsr() >> 20) & 0x7);
-
- cleanup_SW407201();
-
- mtmsr(value);
-
- if(fail)
- {
- break;
- }
- }
-
- uint32_t throttleData = G_orig_throttle;
- uint32_t inject = run & 0x1; //Inject is bit 17, if this is high we run one throttle burst then turn off
- uint32_t type = (config >> 13) & 0x1; //type is bit 18, this determines which kind of throttling we do
- uint32_t mask = type ? 0x10000000 : 0x80000000;
- uint32_t pgpe_throttle_assert = G_pgpe_header_data->g_pgpe_throttle_assert;
- uint32_t pgpe_throttle_deassert = G_pgpe_header_data->g_pgpe_throttle_deassert;
-
- //if currently off, we don't desire always off, this is the first evaluation since become enabled, we are in always on,
- //or we (re enabled and have reached the count, then we turn throttling on (if both assert and deassert are 0 this statement fails)
- if(!G_throttleOn && pgpe_throttle_assert != 0 &&
- (G_throttleCount == 0 || pgpe_throttle_deassert == 0 || pgpe_throttle_deassert == G_throttleCount))
- {
- G_throttleOn = 1;
- G_throttleCount = 0;
- throttleData |= mask; //data for start throttle
-
- }
- //if currently on and we desire always off or we don't desire always on and have reached the count,
- //then we turn it off (if both assert and deassert are 0 this statement true)
- else if(G_throttleOn &&
- (pgpe_throttle_assert == 0 || ( pgpe_throttle_deassert != 0 && pgpe_throttle_assert == G_throttleCount)))
- {
- G_throttleOn = 0;
- G_throttleCount = 0;
- throttleData &= ~mask; //data for stop throttle
+ G_throttleOn = 1;
+ G_throttleCount = 0;
+ throttleData |= mask; //data for start throttle
- if(inject == 1)
- {
- out32(OCB_OCCS2, (config & 0xFFFFBFFF)); //write out to indicate inject has finished
- }
- }
+ }
+ //if currently on and we desire always off or we don't desire always on and have reached the count,
+ //then we turn it off (if both assert and deassert are 0 this statement true)
+ else if(G_throttleOn &&
+ (pgpe_throttle_assert == 0 || ( pgpe_throttle_deassert != 0 && pgpe_throttle_assert == G_throttleCount)))
+ {
+ G_throttleOn = 0;
+ G_throttleCount = 0;
+ throttleData &= ~mask; //data for stop throttle
- if(G_throttleCount == 0)
+ if(inject == 1)
{
- mtmsr(value | MSR_THROTTLE_MASK); //don't cause halt if all cores offline or address error (PC Timeout)
- out64(THROTTLE_SCOM_MULTICAST_WRITE, ((uint64_t) throttleData << 32)); //apply new throttle SCOM setting
- cleanup_SW407201();
- mtmsr(value);
+ out32(OCB_OCCS2, (config & 0xFFFFBFFF)); //write out to indicate inject has finished
}
-
- G_throttleCount++; //count always incremented, it is impossible to reach a count of 0 while enabled
}
- else if(G_throttleCount != 0)
+
+ if(G_throttleCount == 0)
{
- G_throttleCount = 0;
- uint32_t value = mfmsr();
- mtmsr(value | MSR_THROTTLE_MASK); //don't cause halt if all cores offline or address error (PC Timeout)
- G_throttleOn = 0;
- out64(THROTTLE_SCOM_MULTICAST_WRITE, ((uint64_t) G_orig_throttle << 32)); //restore throttle scom to original state
- cleanup_SW407201();
- mtmsr(value);
+ p9_pgpe_pstate_write_core_throttle(throttleData, NO_RETRY);
}
+
+ G_throttleCount++; //count always incremented, it is impossible to reach a count of 0 while enabled
+ }
+ else if(G_throttleCount != 0)
+ {
+ G_throttleCount = 0;
+ G_throttleOn = 0;
+ p9_pgpe_pstate_write_core_throttle(G_orig_throttle, NO_RETRY);
}
- while(0);
}
//PGPE beacon needs to be written every 2ms. However, we
OpenPOWER on IntegriCloud