summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C')
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C b/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C
index 4fee69a9..504f1645 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_sbe_check_quiesce.C
@@ -53,6 +53,7 @@
#include <p9_perv_scom_addresses_fld.H>
#include <p9_perv_scom_addresses.H>
#include <p9_suspend_io.H>
+#include <p9n2_misc_scom_addresses.H>
#ifndef DD2
#include <p9_thread_control.H>
@@ -94,6 +95,10 @@ extern "C" {
FAPI_TRY(p9_psihb_check_quiesce(i_target), "Error from p9_psihb_check_quiesce");
FAPI_TRY(p9_intp_check_quiesce(i_target), "Error from p9_intp_check_quiesce");
+ //We also need to clean up any active special wakeups, and redirect
+ //special wakeups to the SGPE
+ FAPI_TRY(p9_pm_check_quiesce(i_target), " Error from p9_pm_check_quiesce");
+
fapi_try_exit:
fapi2::ReturnCode saveError = fapi2::current_err;
fapi2::buffer<uint64_t> l_data(0);
@@ -952,5 +957,59 @@ extern "C" {
return fapi2::current_err;
}
+ fapi2::ReturnCode p9_pm_check_quiesce(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
+ {
+ // Bit-13 used to set WAKEUP_NOTIFY_SELECT bit on the Core Power Management Mode Reg
+ static const uint64_t CPPM_WKUP_NOTIFY_SELECT = 0x0004000000000000;
+ // Bit 0 in each SPWKUP_PMM register controls if SPWKUP is asserted from the source
+ static const uint64_t CLEAR_SPWKUP = 0x0000000000000000;
+ // Special wakeup sources
+ static const uint64_t SPWKUP_SRC_REGS[4] = {C_PPM_SPWKUP_OTR, C_PPM_SPWKUP_FSP, C_PPM_SPWKUP_HYP, C_PPM_SPWKUP_OCC};
+
+ //TODO: RTC 166888 Remove unneeded consts when p9_pm_suspend gets pulled into MPIPL flow
+ // Bits 1:3 are XCR control of the PPE_XIXCR, we want to HALT which = 0x010
+ static const uint64_t PPE_XIXCR_XCR_HALT = 0x6000000000000000;
+ // Bit 0 in each C_CPPMR register controls the DISABLE_WRITE functionality
+ static const uint64_t CLEAR_DISABLE_WRITE = 0x8000000000000000;
+ //XIXCR scom regs that control the OCC's GPEs
+ static const uint64_t GPE_XIXCR_REGS[4] = {P9N2_PU_GPE0_GPENXIXCR_SCOM, P9N2_PU_GPE1_GPENXIXCR_SCOM, P9N2_PU_GPE2_GPENXIXCR_SCOM, P9N2_PU_GPE3_GPENXIXCR_SCOM};
+
+ FAPI_IMP("p9_pm_check_quiesce: Entering...");
+
+ //Loop over cores and set the WKUP_NOTIFY_SELECT bit and clear out
+ //SPWK request from all srcs
+ for(auto& l_childCore :
+ i_target.getChildren<fapi2::TARGET_TYPE_CORE>())
+ {
+ //This scom sets WKUP_NOTIFY_SELECT
+ FAPI_TRY(fapi2::putScom(l_childCore, PERV_EC00_CPPM_CPMMR_OR, CPPM_WKUP_NOTIFY_SELECT ));
+
+
+ //This loop clears spwkup asserts from all the possilble srcs
+ for(uint8_t i = 0; i < 4; i++)
+ {
+ FAPI_TRY(fapi2::putScom(l_childCore, SPWKUP_SRC_REGS[i] , CLEAR_SPWKUP));
+ }
+
+ //TODO: RTC 166888 Remove clearing WRITE_DISABLE once p9_powman_suspend is added to MPIPL flow
+ //This scom clears the WRITE_DISABLE bit, this step enables SBE writes
+ FAPI_TRY(fapi2::putScom(l_childCore, C_CPPM_CPMMR_CLEAR, CLEAR_DISABLE_WRITE ));
+
+ }
+
+ //TODO: RTC 166888 Remove GPE halts once p9_powman_suspend is added to MPIPL flow
+ //Need to halt the GPEs so wakeups are handled correctly later on
+ //Loop over the differnt GPE XIXCR scom regs and send the halt command
+ // to each by writing 0x6 to bits 1:3 of the XIXCR register
+ for(uint8_t i = 0; i < 4; i++)
+ {
+ FAPI_TRY(fapi2::putScom(i_target, GPE_XIXCR_REGS[i], PPE_XIXCR_XCR_HALT));
+ }
+
+ fapi_try_exit:
+ FAPI_IMP("p9_pm_check_quiece: Exiting...");
+ return fapi2::current_err;
+ }
+
} // extern "C"
OpenPOWER on IntegriCloud