summaryrefslogtreecommitdiffstats
path: root/import/chips/p9
diff options
context:
space:
mode:
authorYue Du <daviddu@us.ibm.com>2016-01-13 17:11:37 -0600
committerJoshua Hunsberger <jahunsbe@us.ibm.com>2017-10-23 15:56:59 -0500
commit35cebfb7ba9d37a3fc65665d4ea9c0196afdffd7 (patch)
tree293c0aa38b4f3b71ace1819ccab17b045a243f20 /import/chips/p9
parentd0a5117fe30d2e231e9cf96e8c1f0a63c2348aae (diff)
downloadtalos-hcode-35cebfb7ba9d37a3fc65665d4ea9c0196afdffd7.tar.gz
talos-hcode-35cebfb7ba9d37a3fc65665d4ea9c0196afdffd7.zip
CME/SGPE: Complete Working STOP8 CME/SGPE Images Snapshot
Change-Id: I5e8cc9cbdccb10edcc4e2474f1c9a15e41f2c6ed Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/23292 Tested-by: Jenkins Server Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Diffstat (limited to 'import/chips/p9')
-rw-r--r--import/chips/p9/common/pmlib/include/cmehw_common.h8
-rw-r--r--import/chips/p9/common/pmlib/include/cmehw_interrupts.h167
-rw-r--r--import/chips/p9/common/pmlib/include/gpehw_common.h73
-rw-r--r--import/chips/p9/common/pmlib/include/occhw_irq_config.h2
-rw-r--r--import/chips/p9/common/pmlib/include/p9_stop_common.h2
-rw-r--r--import/chips/p9/common/pmlib/include/ppehw_common.h14
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h47
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h10
-rwxr-xr-ximport/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c526
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c228
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h8
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c50
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c27
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c7
-rw-r--r--import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_startclocks.c44
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c25
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c76
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c56
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c26
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c163
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h50
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h42
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c543
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c93
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h46
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c23
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h16
-rw-r--r--import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk3
28 files changed, 1428 insertions, 947 deletions
diff --git a/import/chips/p9/common/pmlib/include/cmehw_common.h b/import/chips/p9/common/pmlib/include/cmehw_common.h
index 6575ab01..0aba0f73 100644
--- a/import/chips/p9/common/pmlib/include/cmehw_common.h
+++ b/import/chips/p9/common/pmlib/include/cmehw_common.h
@@ -26,14 +26,6 @@
#define __CMEHW_COMMON_H__
-/// Wait Macro
-
-#define CME_CORE_CYCLE_RATIO 8 // core is 8 times faster than cme
-#define CME_FOR_LOOP_CYCLES 4 // fused compare branch(3), addition(1)
-#define CME_CORE_CYCLE_DIVIDER (CME_CORE_CYCLE_RATIO*CME_FOR_LOOP_CYCLES)
-#define CME_WAIT_CORE_CYCLES(l,cc) for(l=0;l<cc/CME_CORE_CYCLE_DIVIDER;l++);
-
-
/// Second Half Local Register Access
/// use in32/out32 for first half
#define in32_sh(addr) in32(addr+4)
diff --git a/import/chips/p9/common/pmlib/include/cmehw_interrupts.h b/import/chips/p9/common/pmlib/include/cmehw_interrupts.h
index 2f98dd34..738d9269 100644
--- a/import/chips/p9/common/pmlib/include/cmehw_interrupts.h
+++ b/import/chips/p9/common/pmlib/include/cmehw_interrupts.h
@@ -36,7 +36,7 @@
////////////////////////////////////////////////////////////////////////////
-// IRQ
+// IRQ Definition
////////////////////////////////////////////////////////////////////////////
// The CME interrupt controller consists of 1 x 64-bit controller.
@@ -47,21 +47,21 @@
#define CMEHW_IRQ_DEBUGGER 0 /* 0x00 */
#define CMEHW_IRQ_DEBUG_TRIGGER 1 /* 0x01 */
#define CMEHW_IRQ_QUAD_CHECKSTOP 2 /* 0x02 */
-#define CMEHW_IRQ_SPARE_3 3 /* 0x03 */
+#define CMEHW_IRQ_PVREF_FAIL 3 /* 0x03 */
#define CMEHW_IRQ_OCC_HEARTBEAT_LOST 4 /* 0x04 */
#define CMEHW_IRQ_CORE_CHECKSTOP 5 /* 0x05 */
-#define CMEHW_IRQ_BCE_BUSY_HIGH 6 /* 0x06 */
+#define CMEHW_IRQ_DROPOUT_DETECT 6 /* 0x06 */
#define CMEHW_IRQ_SPARE_7 7 /* 0x07 */
-#define CMEHW_IRQ_DOORBELL3_C0 8 /* 0x08 */
-#define CMEHW_IRQ_DOORBELL3_C1 9 /* 0x09 */
-#define CMEHW_IRQ_PC_INTR_PENDING_C0 10 /* 0x0a */
-#define CMEHW_IRQ_PC_INTR_PENDING_C1 11 /* 0x0b */
-#define CMEHW_IRQ_REG_WAKEUP_C0 12 /* 0x0c */
-#define CMEHW_IRQ_REG_WAKEUP_C1 13 /* 0x0d */
-#define CMEHW_IRQ_SPECIAL_WAKEUP_C0 14 /* 0x0e */
-#define CMEHW_IRQ_SPECIAL_WAKEUP_C1 15 /* 0x0f */
-#define CMEHW_IRQ_SPARE_16 16 /* 0x10 */
-#define CMEHW_IRQ_SPARE_17 17 /* 0x11 */
+#define CMEHW_IRQ_BCE_BUSY_HIGH 8 /* 0x08 */
+#define CMEHW_IRQ_BCE_TIMEOUT 9 /* 0x09 */
+#define CMEHW_IRQ_DOORBELL3_C0 10 /* 0x0a */
+#define CMEHW_IRQ_DOORBELL3_C1 11 /* 0x0b */
+#define CMEHW_IRQ_PC_INTR_PENDING_C0 12 /* 0x0c */
+#define CMEHW_IRQ_PC_INTR_PENDING_C1 13 /* 0x0d */
+#define CMEHW_IRQ_REG_WAKEUP_C0 14 /* 0x0e */
+#define CMEHW_IRQ_REG_WAKEUP_C1 15 /* 0x0f */
+#define CMEHW_IRQ_SPECIAL_WAKEUP_C0 16 /* 0x10 */
+#define CMEHW_IRQ_SPECIAL_WAKEUP_C1 17 /* 0x11 */
#define CMEHW_IRQ_DOORBELL2_C0 18 /* 0x12 */
#define CMEHW_IRQ_DOORBELL2_C1 19 /* 0x13 */
#define CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0 20 /* 0x14 */
@@ -71,8 +71,8 @@
#define CMEHW_IRQ_CHTM_PURGE_DONE_C0 24 /* 0x18 */
#define CMEHW_IRQ_CHTM_PURGE_DONE_C1 25 /* 0x19 */
#define CMEHW_IRQ_BCE_BUSY_LOW 26 /* 0x1a */
-#define CMEHW_IRQ_SPARE_27 27 /* 0x1b */
-#define CMEHW_IRQ_SPARE_28 28 /* 0x1c */
+#define CMEHW_IRQ_FINAL_VDM_DATA0 27 /* 0x1b */
+#define CMEHW_IRQ_FINAL_VDM_DATA1 28 /* 0x1c */
#define CMEHW_IRQ_COMM_RECVD 29 /* 0x1d */
#define CMEHW_IRQ_COMM_SEND_ACK 30 /* 0x1e */
#define CMEHW_IRQ_COMM_SEND_NACK 31 /* 0x1f */
@@ -118,11 +118,13 @@
"CMEHW_IRQ_DEBUGGER", \
"CMEHW_IRQ_DEBUG_TRIGGER", \
"CMEHW_IRQ_QUAD_CHECKSTOP", \
- "CMEHW_IRQ_SPARE_3", \
+ "CMEHW_IRQ_PVREF_FAIL", \
"CMEHW_IRQ_OCC_HEARTBEAT_LOST", \
"CMEHW_IRQ_CORE_CHECKSTOP", \
- "CMEHW_IRQ_BCE_BUSY_HIGH", \
+ "CMEHW_IRQ_DROPOUT_DETECT", \
"CMEHW_IRQ_SPARE_7", \
+ "CMEHW_IRQ_BCE_BUSY_HIGH", \
+ "CMEHW_IRQ_BCE_TIMEOUT", \
"CMEHW_IRQ_DOORBELL3_C0", \
"CMEHW_IRQ_DOORBELL3_C1", \
"CMEHW_IRQ_PC_INTR_PENDING_C0", \
@@ -131,8 +133,6 @@
"CMEHW_IRQ_REG_WAKEUP_C1", \
"CMEHW_IRQ_SPECIAL_WAKEUP_C0", \
"CMEHW_IRQ_SPECIAL_WAKEUP_C1", \
- "CMEHW_IRQ_SPARE_16", \
- "CMEHW_IRQ_SPARE_17", \
"CMEHW_IRQ_DOORBELL2_C0", \
"CMEHW_IRQ_DOORBELL2_C1", \
"CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0", \
@@ -142,8 +142,8 @@
"CMEHW_IRQ_CHTM_PURGE_DONE_C0", \
"CMEHW_IRQ_CHTM_PURGE_DONE_C1", \
"CMEHW_IRQ_BCE_BUSY_LOW", \
- "CMEHW_IRQ_SPARE_27", \
- "CMEHW_IRQ_SPARE_28", \
+ "CMEHW_IRQ_FANAL_VDM_DATA0", \
+ "CMEHW_IRQ_FANAL_VDM_DATA1", \
"CMEHW_IRQ_COMM_RECVD", \
"CMEHW_IRQ_COMM_SEND_ACK", \
"CMEHW_IRQ_COMM_SEND_NACK", \
@@ -182,4 +182,129 @@
};
+////////////////////////////////////////////////////////////////////////////
+// IRQ Configuration
+////////////////////////////////////////////////////////////////////////////
+
+/// Static configuration data for external interrupts:
+///
+/// IRQ#, TYPE, POLARITY, ENABLE
+///
+#define APPCFG_EXT_IRQS_CONFIG \
+ CMEHW_IRQ_DEBUGGER STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DEBUG_TRIGGER STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_QUAD_CHECKSTOP STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PVREF_FAIL STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_ENABLED \
+ CMEHW_IRQ_OCC_HEARTBEAT_LOST STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_CORE_CHECKSTOP STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DROPOUT_DETECT STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_SPARE_7 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_BCE_BUSY_HIGH STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_BCE_TIMEOUT STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DOORBELL3_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DOORBELL3_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PC_INTR_PENDING_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PC_INTR_PENDING_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_REG_WAKEUP_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_REG_WAKEUP_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_SPECIAL_WAKEUP_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_SPECIAL_WAKEUP_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DOORBELL2_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DOORBELL2_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PC_PM_STATE_ACTIVE_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_L2_PURGE_DONE STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_NCU_PURGE_DONE STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_CHTM_PURGE_DONE_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_CHTM_PURGE_DONE_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_BCE_BUSY_LOW STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_FINAL_VDM_DATA0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_FINAL_VDM_DATA1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_COMM_RECVD STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_COMM_SEND_ACK STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_COMM_SEND_NACK STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_SPARE_32 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_SPARE_33 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PMCR_UPDATE_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PMCR_UPDATE_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DOORBELL0_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DOORBELL0_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_SPARE_38 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_SPARE_39 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DOORBELL1_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_DOORBELL1_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PECE_INTR_DISABLED_C0 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_PECE_INTR_DISABLED_C1 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_44 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_45 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_46 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_47 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_48 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_49 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_50 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_51 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_52 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_53 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_54 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_55 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_56 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_57 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_58 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_59 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_60 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_61 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_62 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED \
+ CMEHW_IRQ_RESERVED_63 STD_IRQ_TYPE_EDGE STD_IRQ_POLARITY_RISING STD_IRQ_MASKED
+
+
+#define APPCFG_IRQ_INVALID_MASK 0
+/*
+/// This 64 bit mask specifies which of the interrupts are not to be used.
+#define APPCFG_IRQ_INVALID_MASK \
+(\
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_44) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_45) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_46) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_47) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_48) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_49) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_50) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_51) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_52) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_53) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_54) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_55) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_56) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_57) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_58) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_59) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_60) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_61) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_62) | \
+ STD_IRQ_MASK64(CMEHW_IRQ_RESERVED_63))
+*/
+
+////////////////////////////////////////////////////////////////////////////
+// Interrupt Mask Vector
+////////////////////////////////////////////////////////////////////////////
+
+// First, it should always be true to mask the given interrupt and every
+// interrupts has larger irq id number than the given one. Then if the given
+// interrupt belongs to a group of interrupts with same priority and the given
+// one is not the first one in the group(in which case it will automatically
+// work by first rule along), then an override bit mask can be used to mask out
+// every one else in the group above the given one, or used for special cases.
+#define CME_IRQ_MASK_VECTOR(irq) ((0xffffffffffffffffull << (irq)) >> (irq))
+#define CME_IRQ_MASK_VECTOR_AND(irq, amask) (CME_IRQ_MASK_VECTOR(irq) & amask)
+#define CME_IRQ_MASK_VECTOR_OR(irq, omask) (CME_IRQ_MASK_VECTOR(irq) | omask)
+
+#define CME_IRQ_MASK_DB3 CME_IRQ_MASK_VECTOR(CMEHW_IRQ_DOORBELL3_C0)
+#define CME_IRQ_MASK_WAKE CME_IRQ_MASK_VECTOR(CMEHW_IRQ_PC_INTR_PENDING_C0)
+#define CME_IRQ_MASK_DB2 CME_IRQ_MASK_VECTOR(CMEHW_IRQ_DOORBELL2_C0)
+#define CME_IRQ_MASK_STOP CME_IRQ_MASK_VECTOR(CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0)
+#define CME_IRQ_MASK_DB0 CME_IRQ_MASK_VECTOR(CMEHW_IRQ_PMCR_UPDATE_C0)
+#define CME_IRQ_MASK_DB1 CME_IRQ_MASK_VECTOR(CMEHW_IRQ_DOORBELL1_C0)
+
+
+
#endif /* __CMEHW_INTERRUPTS_H__ */
diff --git a/import/chips/p9/common/pmlib/include/gpehw_common.h b/import/chips/p9/common/pmlib/include/gpehw_common.h
index 7433b91b..41c4eb93 100644
--- a/import/chips/p9/common/pmlib/include/gpehw_common.h
+++ b/import/chips/p9/common/pmlib/include/gpehw_common.h
@@ -67,36 +67,63 @@ enum GPE_CHIPLET_MASKS
enum GPE_SCOM_ADDRESS_PARAMETERS
{
- QUAD_ADDR_OFFSET = 0x01000000,
- QUAD_ADDR_BASE = 0x10000000,
- CORE_ADDR_OFFSET = 0x01000000,
CORE_ADDR_BASE = 0x20000000,
- CME_ADDR_OFFSET = 0x00000400,
- CME_ADDR_OFFSET_EX0 = 0x00000400,
- CME_ADDR_OFFSET_EX1 = 0x00000800,
- CME_ADDR_BASE = 0x10012000
+ CORE_ADDR_OFFSET = 0x01000000,
+ QUAD_ADDR_BASE = 0x10000000,
+ QUAD_ADDR_OFFSET = 0x01000000,
+ EX_ADDR_BASE = 0x00000800,
+ EX0_ADDR_OFFSET = 0x00000800,
+ EX1_ADDR_OFFSET = 0x00000C00,
+ CME_ADDR_BASE = 0x10012000,
+ CME0_ADDR_OFFSET = 0x00000400,
+ CME1_ADDR_OFFSET = 0x00000800
};
/// GPE SCOM
-#define GPE_SCOM_ADDR(addr, base, offset) (addr | base | (offset << 24))
-#define GPE_SCOM_ADDR_CORE(addr, core) GPE_SCOM_ADDR(addr, CORE_ADDR_BASE, core)
-#define GPE_SCOM_ADDR_QUAD(addr, quad) GPE_SCOM_ADDR(addr, QUAD_ADDR_BASE, quad)
-
-#define GPE_GETSCOM(addr, base, offset, data) \
- rc = getscom(0, GPE_SCOM_ADDR(addr, base, offset), &data); \
- if (rc) { \
- PK_TRACE("getscom@%d failed w/rc=0x%08x", \
- GPE_SCOM_ADDR(addr, base, offset), rc); \
- pk_halt(); \
+#define GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select) \
+ (addr | cplt_base | (cq_offset << 24) | (ex_select << 10))
+
+#define GPE_SCOM_ADDR_CORE(addr, core) \
+ GPE_SCOM_ADDR(addr, CORE_ADDR_BASE, core, 0)
+
+#define GPE_SCOM_ADDR_EX(addr, quad, ex) \
+ GPE_SCOM_ADDR(addr, QUAD_ADDR_BASE|EX_ADDR_BASE, quad, ex)
+
+#define GPE_SCOM_ADDR_QUAD(addr, quad) \
+ GPE_SCOM_ADDR(addr, QUAD_ADDR_BASE, quad, 0)
+
+#define GPE_SCOM_ADDR_CME(addr, quad, cme) \
+ GPE_SCOM_ADDR(addr, QUAD_ADDR_BASE|CME_ADDR_BASE, quad, cme)
+
+#define GPE_GETSCOM(addr, data) \
+ rc = getscom(0, addr, &data); \
+ if (rc) { \
+ PK_TRACE("getscom@%d failed w/rc=0x%08x", addr, rc); \
+ pk_halt(); \
+ }
+
+#define GPE_PUTSCOM(addr, data) \
+ rc = putscom(0, addr, data); \
+ if (rc) { \
+ PK_TRACE("putscom@%d failed w/rc=0x%08x", addr, rc); \
+ pk_halt(); \
+ }
+
+#define GPE_GETSCOM_VAR(addr, cplt_base, cq_offset, ex_select, data) \
+ rc = getscom(0,GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select),&data);\
+ if (rc) { \
+ PK_TRACE("getscom@%d failed w/rc=0x%08x", \
+ GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select), rc); \
+ pk_halt(); \
}
-#define GPE_PUTSCOM(addr, base, offset, data) \
- rc = putscom(0, GPE_SCOM_ADDR(addr, base, offset), data); \
- if (rc) { \
- PK_TRACE("putscom@%d failed w/rc=0x%08x", \
- GPE_SCOM_ADDR(addr, base, offset), rc); \
- pk_halt(); \
+#define GPE_PUTSCOM_VAR(addr, cplt_base, cq_offset, ex_select, data) \
+ rc = putscom(0,GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select), data);\
+ if (rc) { \
+ PK_TRACE("putscom@%d failed w/rc=0x%08x", \
+ GPE_SCOM_ADDR(addr, cplt_base, cq_offset, ex_select), rc); \
+ pk_halt(); \
}
diff --git a/import/chips/p9/common/pmlib/include/occhw_irq_config.h b/import/chips/p9/common/pmlib/include/occhw_irq_config.h
index 6d7b5163..a9bb3613 100644
--- a/import/chips/p9/common/pmlib/include/occhw_irq_config.h
+++ b/import/chips/p9/common/pmlib/include/occhw_irq_config.h
@@ -118,7 +118,7 @@
OCCHW_IRQ_STRM3_PULL OCCHW_IRQ_TARGET_ID_405_NONCRIT \
OCCHW_IRQ_STRM3_PUSH OCCHW_IRQ_TARGET_ID_405_NONCRIT \
OCCHW_IRQ_PMC_PCB_INTR_TYPE0_PENDING OCCHW_IRQ_TARGET_ID_NONE \
- OCCHW_IRQ_PMC_PCB_INTR_TYPE1_PENDING OCCHW_IRQ_TARGET_ID_NONE \
+ OCCHW_IRQ_PMC_PCB_INTR_TYPE1_PENDING OCCHW_IRQ_TARGET_ID_GPE2 \
OCCHW_IRQ_PMC_PCB_INTR_TYPE2_PENDING OCCHW_IRQ_TARGET_ID_GPE3 \
OCCHW_IRQ_PMC_PCB_INTR_TYPE3_PENDING OCCHW_IRQ_TARGET_ID_NONE \
OCCHW_IRQ_PMC_PCB_INTR_TYPE4_PENDING OCCHW_IRQ_TARGET_ID_NONE \
diff --git a/import/chips/p9/common/pmlib/include/p9_stop_common.h b/import/chips/p9/common/pmlib/include/p9_stop_common.h
index 98af6c7a..21e07aeb 100644
--- a/import/chips/p9/common/pmlib/include/p9_stop_common.h
+++ b/import/chips/p9/common/pmlib/include/p9_stop_common.h
@@ -35,7 +35,7 @@ enum P9_HCD_COMMON_INIT_VECTORS
// (13)VITL_MPW2
// (14)VITL_MPW3
// (18)FENCE_EN
- NET_CTRL0_INIT_VECTOR = BIT64(0) | BIT64(1) | BITS64(3, 3) | BITS64(12, 3) | BIT64(18),
+ NET_CTRL0_INIT_VECTOR = (BIT64(0) | BIT64(1) | BITS64(3, 3) | BITS64(12, 3) | BIT64(18)),
HANG_PULSE1_INIT_VECTOR = BIT64(5)
};
diff --git a/import/chips/p9/common/pmlib/include/ppehw_common.h b/import/chips/p9/common/pmlib/include/ppehw_common.h
index b9a78956..cf9353ea 100644
--- a/import/chips/p9/common/pmlib/include/ppehw_common.h
+++ b/import/chips/p9/common/pmlib/include/ppehw_common.h
@@ -55,15 +55,23 @@
#define CODE2REGA(code) ((code & 0x1F00) >> 8)
#define CODE2REGB(code) ((code & 0xF8) >> 3)
-#define CODE2TAG(code,core) ((core << 10) | (code >> 3))
+#define CODE2TAG(code,tag) ((tag << 10) | (code >> 3))
#define TAG_SPRG0(tag) {ppe42_app_ctx_set(tag);}
#define MARK_TRAP(code) \
{asm volatile ("tw 0, %0, %1" : : \
"i" (CODE2REGA(code)), \
"i" (CODE2REGB(code)));}
#define MARK_TAG(code, tag) \
- MARK_TRAP(code) \
- TAG_SPRG0(CODE2TAG(code, tag))
+ TAG_SPRG0(CODE2TAG(code, tag)) \
+ MARK_TRAP(code)
+
+
+/// Wait Macro
+
+#define PPE_CORE_CYCLE_RATIO 8 // core is 8 times faster than cme
+#define PPE_FOR_LOOP_CYCLES 4 // fused compare branch(3), addition(1)
+#define PPE_CORE_CYCLE_DIVIDER (PPE_CORE_CYCLE_RATIO*PPE_FOR_LOOP_CYCLES)
+#define PPE_WAIT_CORE_CYCLES(l,cc) for(l=0;l<cc/PPE_CORE_CYCLE_DIVIDER;l++);
/// IRQ Setup
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h
index 57d9c7d8..4a0d0968 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop.h
@@ -53,25 +53,36 @@
#define RAM_MODEREG 0x20010A51
#define RAM_CTRL 0x20010A52
#define RAM_STATUS 0x20010A53
+
+#define C_SYNC_CONFIG 0x20030000
+#define C_OPCG_ALIGN 0x20030001
#define C_SCAN_REGION_TYPE 0x20030005
#define C_CLK_REGION 0x20030006
#define C_CLOCK_STAT_SL 0x20030008
#define C_CLOCK_STAT_NSL 0x20030009
#define C_CLOCK_STAT_ARY 0x2003000a
-#define C_SLAVE_CONFIG_REG 0x200F001E
-#define C_CPLT_CTRL0_CLEAR 0x20000020
-#define C_CPLT_CTRL1_CLEAR 0x20000021
#define C_BIST 0x2003000B
+
+#define C_SLAVE_CONFIG_REG 0x200F001E
#define C_ERROR_REG 0x200F001F
#define C_HANG_PULSE_1_REG 0x200F0021
+#define C_PPM_CGCR 0x200F0164
+
+#define C_CPLT_CTRL0_OR 0x20000010
+#define C_CPLT_CTRL0_CLEAR 0x20000020
+#define C_CPLT_CTRL1_OR 0x20000011
+#define C_CPLT_CTRL1_CLEAR 0x20000021
+
#define PERV_CPLT_CTRL0_OR 0x00000010
#define PERV_CPLT_CTRL0_CLEAR 0x00000020
-#define PERV_BIST 0x0003000B
-#define PERV_CLK_REGION 0x00030006
#define PERV_OPCG_REG0 0x00030002
#define PERV_OPCG_REG1 0x00030003
+#define PERV_CLK_REGION 0x00030006
+#define PERV_BIST 0x0003000B
#define PERV_CPLT_STAT0 0x00000100
+#define NCU_STATUS_REG 0x1001140F
+
/// Macro to update STOP History
#define CME_STOP_UPDATE_HISTORY(core,gated,trans,req_l,act_l,req_e,act_e) \
hist.fields.stop_gated = gated; \
@@ -99,14 +110,8 @@ enum CME_STOP_RETURN_CODE
/// CME STOP IRQs with shorter names
enum CME_STOP_IRQ_SHORT_NAME
{
- IRQ_DB0_C0 = CMEHW_IRQ_DOORBELL0_C0,
- IRQ_DB0_C1 = CMEHW_IRQ_DOORBELL0_C1,
IRQ_DB1_C0 = CMEHW_IRQ_DOORBELL1_C0,
IRQ_DB1_C1 = CMEHW_IRQ_DOORBELL1_C1,
- IRQ_DB2_C0 = CMEHW_IRQ_DOORBELL2_C0,
- IRQ_DB2_C1 = CMEHW_IRQ_DOORBELL2_C1,
- IRQ_DB3_C0 = CMEHW_IRQ_DOORBELL3_C0,
- IRQ_DB3_C1 = CMEHW_IRQ_DOORBELL3_C1,
IRQ_STOP_C0 = CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0,
IRQ_STOP_C1 = CMEHW_IRQ_PC_PM_STATE_ACTIVE_C1,
IRQ_PC_C0 = CMEHW_IRQ_PC_INTR_PENDING_C0,
@@ -126,23 +131,30 @@ enum CME_STOP_FLAGS
FLAG_PARTIAL_GOOD_C1 = BIT32(31)
};
+
/// Stop Score Board Structure
typedef struct
{
- uint8_t pm_state_c0;
- uint8_t pm_state_c1;
- uint8_t cme_wakenup;
- uint8_t cme_flags;
+ uint8_t req_stop_c0;
+ uint8_t req_stop_c1;
+ uint8_t act_stop_c0;
+ uint8_t act_stop_c1;
+ uint8_t active_core;
+ uint8_t cme_flags;
+ uint64_t mask_vector;
+ PkSemaphore sem[2];
} CmeStopRecord;
/// CME STOP Entry and Exit Prototypes
void p9_cme_stop_enter_thread(void*);
+void p9_cme_stop_exit_thread(void*);
int p9_cme_stop_entry();
int p9_cme_stop_exit();
-void p9_cme_stop_enter_handler(void*, PkIrqId);
-void p9_cme_stop_exit_handler(void*, PkIrqId);
+void p9_cme_stop_enter_semaphore_callback(void*);
+void p9_cme_stop_exit_semaphore_callback(void*);
+void p9_cme_stop_event_handler(void*, PkIrqId);
void p9_cme_stop_doorbell_handler(void*, PkIrqId);
int p9_hcd_core_pcb_arb(uint32_t, uint8_t);
@@ -158,4 +170,3 @@ int p9_hcd_core_scominit(uint32_t);
int p9_hcd_core_scomcust(uint32_t);
int p9_hcd_core_ras_runtime_scom(uint32_t);
int p9_hcd_core_occ_runtime_scom(uint32_t);
-int p9_hcd_core_selfrestore(uint32_t);
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h
index 34ad6a55..deb1a86f 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_enter_marks.h
@@ -53,8 +53,10 @@ enum CME_SE_MARKS
SE_IS2_END = 0xf0,
SE_L2_PURGE_DONE = 0xf8,
SE_SGPE_HANDOFF = 0x100,
- BEGINSCOPE_STOP_ENTRY = 0x1f00,
- ENDSCOPE_STOP_ENTRY = 0x1f08
+ BEGINSCOPE_STOP_ENTRY = 0x1f08,
+ ENDSCOPE_STOP_ENTRY = 0x1f10,
+ STOP_EVENT_HANDLER = 0x1f18,
+ STOP_DOORBELL_HANDLER = 0x1f20
};
@@ -80,7 +82,9 @@ const std::vector<CME_SE_MARKS> MARKS =
SE_L2_PURGE_DONE,
SE_SGPE_HANDOFF,
BEGINSCOPE_STOP_ENTRY,
- ENDSCOPE_STOP_ENTRY
+ ENDSCOPE_STOP_ENTRY,
+ STOP_EVENT_HANDLER,
+ STOP_DOORBELL_HANDLER
};
}
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c
index 62c5d79c..6bf5afdf 100755
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_entry.c
@@ -46,13 +46,16 @@
#include "p9_cme_stop.h"
#include "p9_cme_stop_enter_marks.h"
-CmeStopRecord G_cme_stop_record = {0, 0, 0};
+extern CmeStopRecord G_cme_stop_record;
int
p9_cme_stop_entry()
{
int rc = 0;
+ uint8_t core_aborted = 0;
+ uint8_t core_catchup = 0;
+ uint8_t catchup_ongoing = 0;
uint8_t entry_ongoing = 1;
uint8_t target_level;
uint8_t deeper_level = 0;
@@ -73,6 +76,7 @@ p9_cme_stop_entry()
// STOP PM_STATE. If both have fired by the time we get to this point,
// CME will do Daul-cast to both cores at the same time in entry flow.
core = (in32(CME_LCL_EISR) & BITS32(20, 2)) >> SHIFT32(21);
+
// override with partial good core mask
core = core & G_cme_stop_record.cme_flags & CME_MASK_BC;
@@ -88,62 +92,49 @@ p9_cme_stop_entry()
MARK_TAG(BEGINSCOPE_STOP_ENTRY, core)
//===================================
- //--------------------------------------------------------------------------
- // STOP LEVEL 1 (should be done by hardware)
- //--------------------------------------------------------------------------
-
- // Read SISR for pm_state_cX
- pm_states = in32_sh(CME_LCL_SISR);
- G_cme_stop_record.pm_state_c0 = (pm_states & BITS32(4, 4)) >> SHIFT32(7);
- G_cme_stop_record.pm_state_c1 = (pm_states & BITS32(8, 4)) >> SHIFT32(11);
-#if LAB_MODE == 1
-
- if (G_cme_stop_record.pm_state_c0 == STOP_LEVEL_11)
- {
- G_cme_stop_record.pm_state_c0 = STOP_LEVEL_9;
- }
-
- if (G_cme_stop_record.pm_state_c1 == STOP_LEVEL_11)
+ do // while(0) loop for stop flow control
{
- G_cme_stop_record.pm_state_c1 = STOP_LEVEL_9;
- }
-#endif
+ //--------------------------------------------------------------------------
+ // STOP LEVEL 1 (should be done by hardware)
+ //--------------------------------------------------------------------------
- // pm_active AND waken_up : pm_state = sisr (new state)
- // pm_active AND !waken_up : pm_state = sisr (only with auto promote)
- // !pm_active AND waken_up : pm_state = 0 (state out of date)
- // !pm_active AND !waken_up : pm_state = sisr (current state)
- if (~core & G_cme_stop_record.cme_wakenup & CME_MASK_C0)
- {
- G_cme_stop_record.pm_state_c0 = 0;
- }
+ // Read SISR for pm_state_cX
+ pm_states = in32_sh(CME_LCL_SISR);
+ G_cme_stop_record.req_stop_c0 = (pm_states & BITS32(4, 4)) >> SHIFT32(7);
+ G_cme_stop_record.req_stop_c1 = (pm_states & BITS32(8, 4)) >> SHIFT32(11);
- if (~core & G_cme_stop_record.cme_wakenup & CME_MASK_C1)
- {
- G_cme_stop_record.pm_state_c1 = 0;
- }
+ // pm_active AND waken_up : pm_state = sisr (new state)
+ // pm_active AND !waken_up : pm_state = sisr (only with auto promote)
+ // !pm_active AND waken_up : pm_state = 0 (out dated state)
+ // !pm_active AND !waken_up : pm_state = sisr (current state)
+ if (~core & G_cme_stop_record.active_core & CME_MASK_C0)
+ {
+ G_cme_stop_record.req_stop_c0 = 0;
+ }
- G_cme_stop_record.cme_wakenup &= ~core;
+ if (~core & G_cme_stop_record.active_core & CME_MASK_C1)
+ {
+ G_cme_stop_record.req_stop_c1 = 0;
+ }
- PK_TRACE("SE1: Stop Levels[%d %d]",
- G_cme_stop_record.pm_state_c0, G_cme_stop_record.pm_state_c1);
+ G_cme_stop_record.active_core &= ~core;
- // Return error if target STOP level == 1(Nap)
- if((core == CME_MASK_C0 && G_cme_stop_record.pm_state_c0 <= STOP_LEVEL_1) ||
- (core == CME_MASK_C1 && G_cme_stop_record.pm_state_c1 <= STOP_LEVEL_1) ||
- (core == CME_MASK_BC && (G_cme_stop_record.pm_state_c0 <= STOP_LEVEL_1 ||
- G_cme_stop_record.pm_state_c1 <= STOP_LEVEL_1)))
- {
- return CME_STOP_ENTRY_STOP1_SENT_IRQ;
- }
+ PK_TRACE("SE1: Request Stop Levels[%d %d]",
+ G_cme_stop_record.req_stop_c0, G_cme_stop_record.req_stop_c1);
- //--------------------------------------------------------------------------
- // STOP LEVEL 2
- //--------------------------------------------------------------------------
+ // Return error if target STOP level == 1(Nap)
+ if((core == CME_MASK_C0 && G_cme_stop_record.req_stop_c0 <= STOP_LEVEL_1) ||
+ (core == CME_MASK_C1 && G_cme_stop_record.req_stop_c1 <= STOP_LEVEL_1) ||
+ (core == CME_MASK_BC && (G_cme_stop_record.req_stop_c0 <= STOP_LEVEL_1 ||
+ G_cme_stop_record.req_stop_c1 <= STOP_LEVEL_1)))
+ {
+ return CME_STOP_ENTRY_STOP1_SENT_IRQ;
+ }
- do // while(0) loop for stop flow control
- {
+ //--------------------------------------------------------------------------
+ // STOP LEVEL 2
+ //--------------------------------------------------------------------------
PK_TRACE("SE2.a");
// Disable fired Stop and corresponding Wakeup interrupts
@@ -165,22 +156,22 @@ p9_cme_stop_entry()
CME_PUTSCOM(CPPM_CPMMR_OR, core, BIT64(0));
// set target_level from pm_state for both cores or just one core
- target_level = (core == CME_MASK_C0) ? G_cme_stop_record.pm_state_c0 :
- G_cme_stop_record.pm_state_c1;
+ target_level = (core == CME_MASK_C0) ? G_cme_stop_record.req_stop_c0 :
+ G_cme_stop_record.req_stop_c1;
// If both cores are going into STOP but targeting different levels,
if ((core == CME_MASK_BC) &&
- (G_cme_stop_record.pm_state_c0 != G_cme_stop_record.pm_state_c1))
+ (G_cme_stop_record.req_stop_c0 != G_cme_stop_record.req_stop_c1))
{
// set target_level to the lighter level targeted by one core
// set deeper_level to the deeper level targeted by deeper core
- deeper_level = G_cme_stop_record.pm_state_c0;
+ deeper_level = G_cme_stop_record.req_stop_c0;
deeper_core = CME_MASK_C0;
- if (G_cme_stop_record.pm_state_c0 < G_cme_stop_record.pm_state_c1)
+ if (G_cme_stop_record.req_stop_c0 < G_cme_stop_record.req_stop_c1)
{
- target_level = G_cme_stop_record.pm_state_c0;
- deeper_level = G_cme_stop_record.pm_state_c1;
+ target_level = G_cme_stop_record.req_stop_c0;
+ deeper_level = G_cme_stop_record.req_stop_c1;
deeper_core = CME_MASK_C1;
}
}
@@ -239,7 +230,7 @@ p9_cme_stop_entry()
PK_TRACE("SE2.i");
// Waits quiesce done for at least 512 core cycles
// MF: verify generate FCB otherwise math is wrong.
- CME_WAIT_CORE_CYCLES(loop, 512)
+ PPE_WAIT_CORE_CYCLES(loop, 512)
PK_TRACE("SE2.j");
// Raise Core Chiplet Fence
@@ -289,7 +280,7 @@ p9_cme_stop_entry()
PK_TRACE("SE2.p");
// Switch glsmux to refclk to save clock grid power
- CME_PUTSCOM(PPM_CGCR_CLR, core, BIT64(3));
+ CME_PUTSCOM(C_PPM_CGCR, core, BIT64(3));
// Assert PCB Fence
CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(25));
@@ -327,6 +318,16 @@ p9_cme_stop_entry()
entry_ongoing = 1;
}
+ if (core & CME_MASK_C0)
+ {
+ G_cme_stop_record.act_stop_c0 = STOP_LEVEL_2;
+ }
+
+ if (core & CME_MASK_C1)
+ {
+ G_cme_stop_record.act_stop_c1 = STOP_LEVEL_2;
+ }
+
PK_TRACE("SE2: Clock Sync Dropped");
//===========================
@@ -336,13 +337,80 @@ p9_cme_stop_entry()
//===========================
MARK_TRAP(SE_IS0_BEGIN)
//===========================
- // todo: open wakeup interrupt window if we are not done
- // todo: open catchup interrupt window if we are not done
+#if !SKIP_ABORT
+ out32(CME_LCL_EIMR_CLR, /*TODO(core << SHIFT32(13)) |*/
+ (core << SHIFT32(15)) |
+ (core << SHIFT32(17)));
+ sync();
+ out32(CME_LCL_EIMR_OR, (core << SHIFT32(13)) |
+ (core << SHIFT32(15)) |
+ (core << SHIFT32(17)));
+#endif
//===================
MARK_TRAP(SE_IS0_END)
//===================
- // If we are done at STOP level 2
+ core_aborted = 0;
+
+ if ((core & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_0 &&
+ G_cme_stop_record.req_stop_c0 != STOP_LEVEL_0)
+ {
+ core_aborted |= CME_MASK_C0;
+ core -= CME_MASK_C0;
+ deeper_core = 0;
+
+ if (deeper_core == CME_MASK_C1)
+ {
+ target_level = deeper_level;
+ }
+
+ }
+
+ if ((core & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_0 &&
+ G_cme_stop_record.req_stop_c1 != STOP_LEVEL_0)
+ {
+ core_aborted |= CME_MASK_C1;
+ core -= CME_MASK_C1;
+ deeper_core = 0;
+
+ if (deeper_core == CME_MASK_C0)
+ {
+ target_level = deeper_level;
+ }
+ }
+
+ if (!core)
+ {
+ core |= core_aborted;
+ entry_ongoing = 0;
+ break;
+ }
+
+ if (catchup_ongoing)
+ {
+ core = CME_MASK_BC;
+ break;
+ }
+
+#if !SKIP_CATCHUP
+ core_catchup = (in32(CME_LCL_EISR) & BITS32(20, 2)) >> SHIFT32(21);
+#endif
+
+ if (core_catchup > core)
+ {
+ core = core_catchup - core;
+ catchup_ongoing = 1;
+ }
+
+ }
+ while(catchup_ongoing);
+
+ do
+ {
+
+ // If we are done at STOP level 2 or aborted
if (!entry_ongoing)
{
break;
@@ -403,6 +471,16 @@ p9_cme_stop_entry()
entry_ongoing = 0;
}
+ if(core & CME_MASK_C0)
+ {
+ G_cme_stop_record.act_stop_c0 = STOP_LEVEL_3;
+ }
+
+ if(core & CME_MASK_C1)
+ {
+ G_cme_stop_record.act_stop_c1 = STOP_LEVEL_3;
+ }
+
//===========================
MARK_TAG(SE_STOP3_DONE, core)
//===========================
@@ -418,185 +496,224 @@ p9_cme_stop_entry()
// STOP LEVEL 4
//--------------------------------------------------------------------------
- // Skip Power off completely only if single or both core target STOP L9
- // that is target_level == 9 and deeper_core == 0
- if (target_level != 9 || (deeper_core && deeper_level != 9))
- {
-
- //===============================
- MARK_TAG(SE_POWER_OFF_CORE, core)
- //===============================
-
- // We may skip one of the cores in deeper_core case
- if (deeper_core)
- {
- if (deeper_level == 9)
- {
- core = deeper_core ^ CME_MASK_BC;
- }
-
- if (target_level == 9)
- {
- core = deeper_core;
- }
- }
+ //===============================
+ MARK_TAG(SE_POWER_OFF_CORE, core)
+ //===============================
#if !STOP_PRIME
- // Assert Cores Electrical Fences
- PK_TRACE("SE4.a");
- CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(26));
+ // Assert Cores Electrical Fences
+ PK_TRACE("SE4.a");
+ CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(26));
- // Make sure we are not forcing PFET for VDD off
- // vdd_pfet_force_state == 00 (Nop)
- PK_TRACE("SE4.b");
- CME_GETSCOM(PPM_PFCS, core, CME_SCOM_AND, scom_data);
+ // Make sure we are not forcing PFET for VDD off
+ // vdd_pfet_force_state == 00 (Nop)
+ PK_TRACE("SE4.b");
+ CME_GETSCOM(PPM_PFCS, core, CME_SCOM_AND, scom_data);
- if (scom_data & BITS64(0, 2))
- {
- return CME_STOP_ENTRY_VDD_PFET_NOT_IDLE;
- }
+ if (scom_data & BITS64(0, 2))
+ {
+ return CME_STOP_ENTRY_VDD_PFET_NOT_IDLE;
+ }
- // Prepare PFET Controls
- // vdd_pfet_val/sel_override = 0 (disbaled)
- // vdd_pfet_regulation_finger_en = 0 (controled by FSM)
- PK_TRACE("SE4.c");
- CME_PUTSCOM(PPM_PFCS_CLR, core, BIT64(4) | BIT64(5) | BIT64(8));
+ // Prepare PFET Controls
+ // vdd_pfet_val/sel_override = 0 (disbaled)
+ // vdd_pfet_regulation_finger_en = 0 (controled by FSM)
+ PK_TRACE("SE4.c");
+ CME_PUTSCOM(PPM_PFCS_CLR, core, BIT64(4) | BIT64(5) | BIT64(8));
- // Power Off Core VDD
- // vdd_pfet_force_state = 01 (Force Voff)
- PK_TRACE("SE4.d");
- CME_PUTSCOM(PPM_PFCS_OR, core, BIT64(1));
+ // Power Off Core VDD
+ // vdd_pfet_force_state = 01 (Force Voff)
+ PK_TRACE("SE4.d");
+ CME_PUTSCOM(PPM_PFCS_OR, core, BIT64(1));
- // Poll for power gate sequencer state: 0x8 (FSM Idle)
- PK_TRACE("SE4.e");
+ // Poll for power gate sequencer state: 0x8 (FSM Idle)
+ PK_TRACE("SE4.e");
- do
- {
- CME_GETSCOM(PPM_PFCS, core, CME_SCOM_AND, scom_data);
- }
- while(!(scom_data & BIT64(42)));
+ do
+ {
+ CME_GETSCOM(PPM_PFCS, core, CME_SCOM_AND, scom_data);
+ }
+ while(!(scom_data & BIT64(42)));
#if !EPM_P9_TUNING
- // Optional: Poll for vdd_pg_sel being: 0x8
- PK_TRACE("SE4.f");
+ // Optional: Poll for vdd_pg_sel being: 0x8
+ PK_TRACE("SE4.f");
- do
- {
- CME_GETSCOM(PPM_PFCS, core, CME_SCOM_AND, scom_data);
- }
- while(!(scom_data & BIT64(46)));
+ do
+ {
+ CME_GETSCOM(PPM_PFCS, core, CME_SCOM_AND, scom_data);
+ }
+ while(!(scom_data & BIT64(46)));
#endif
- // Turn Off Force Voff
- // vdd_pfet_force_state = 00 (Nop)
- PK_TRACE("SE4.g");
- CME_PUTSCOM(PPM_PFCS_CLR, core, BITS64(0, 2));
+ // Turn Off Force Voff
+ // vdd_pfet_force_state = 00 (Nop)
+ PK_TRACE("SE4.g");
+ CME_PUTSCOM(PPM_PFCS_CLR, core, BITS64(0, 2));
#endif
- PK_TRACE("SE4.h");
- // Update Stop History: In Core Stop Level 4
- // Check if STOP level 4 reaches the target for both or one core
- entry_ongoing =
- target_level == STOP_LEVEL_4 ? STOP_TRANS_COMPLETE :
- STOP_TRANS_ENTRY;
- CME_STOP_UPDATE_HISTORY(core,
+ PK_TRACE("SE4.h");
+ // Update Stop History: In Core Stop Level 4
+ // Check if STOP level 4 reaches the target for both or one core
+ entry_ongoing =
+ target_level == STOP_LEVEL_4 ? STOP_TRANS_COMPLETE :
+ STOP_TRANS_ENTRY;
+ CME_STOP_UPDATE_HISTORY(core,
+ STOP_CORE_IS_GATED,
+ entry_ongoing,
+ target_level,
+ STOP_LEVEL_4,
+ STOP_REQ_DISABLE,
+ STOP_ACT_ENABLE);
+
+ // If both cores targeting different levels
+ // deeper core should have at least deeper stop level than 2
+ // only need to modify deeper core history if another one was done
+ if (deeper_core && !entry_ongoing)
+ {
+ CME_STOP_UPDATE_HISTORY(deeper_core,
STOP_CORE_IS_GATED,
- entry_ongoing,
- target_level,
+ STOP_TRANS_ENTRY,
+ deeper_level,
STOP_LEVEL_4,
STOP_REQ_DISABLE,
- STOP_ACT_ENABLE);
+ STOP_ACT_DISABLE);
+ // from now on, proceed with only deeper core
+ core = deeper_core;
+ target_level = deeper_level;
+ deeper_level = 0;
+ deeper_core = 0;
+ entry_ongoing = 1;
+ }
- // restore back to both cores in deeper_core case
- if (deeper_core)
- {
- core = CME_MASK_BC;
- }
+ if (core & CME_MASK_C0)
+ {
+ G_cme_stop_record.act_stop_c0 = STOP_LEVEL_4;
+ }
- // If both cores targeting different levels
- // deeper core should have at least deeper stop level than 2
- // only need to modify deeper core history if another one was done
- if (deeper_core && !entry_ongoing)
+ if (core & CME_MASK_C1)
+ {
+ G_cme_stop_record.act_stop_c1 = STOP_LEVEL_4;
+ }
+
+ PK_TRACE("SE4: Core Powered Off");
+
+ //===========================
+ MARK_TAG(SE_STOP4_DONE, core)
+ //===========================
+
+ //===========================
+ MARK_TRAP(SE_IS1_BEGIN)
+ //===========================
+#if !SKIP_ABORT
+ out32(CME_LCL_EIMR_CLR, /*TODO(core << SHIFT32(13)) |*/
+ (core << SHIFT32(15)) |
+ (core << SHIFT32(17)));
+ sync();
+ out32(CME_LCL_EIMR_OR, (core << SHIFT32(13)) |
+ (core << SHIFT32(15)) |
+ (core << SHIFT32(17)));
+#endif
+ //===================
+ MARK_TRAP(SE_IS1_END)
+ //===================
+
+ if ((core & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_0 &&
+ G_cme_stop_record.req_stop_c0 != STOP_LEVEL_0)
+ {
+ core_aborted |= CME_MASK_C0;
+ core -= CME_MASK_C0;
+ deeper_core = 0;
+
+ if (deeper_core == CME_MASK_C1)
{
- CME_STOP_UPDATE_HISTORY(deeper_core,
- STOP_CORE_IS_GATED,
- STOP_TRANS_ENTRY,
- deeper_level,
- STOP_LEVEL_4,
- STOP_REQ_DISABLE,
- STOP_ACT_DISABLE);
- // from now on, proceed with only deeper core
- core = deeper_core;
- target_level = deeper_level;
- deeper_level = 0;
- deeper_core = 0;
- entry_ongoing = 1;
+ target_level = deeper_level;
}
- PK_TRACE("SE4: Core Powered Off");
-
- //===========================
- MARK_TAG(SE_STOP4_DONE, core)
- //===========================
+ }
- //===========================
- MARK_TRAP(SE_IS1_BEGIN)
- //===========================
- // todo: open wakeup interrupt window if we are not done
- //===================
- MARK_TRAP(SE_IS1_END)
- //===================
+ if ((core & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_0 &&
+ G_cme_stop_record.req_stop_c1 != STOP_LEVEL_0)
+ {
+ core_aborted |= CME_MASK_C1;
+ core -= CME_MASK_C1;
+ deeper_core = 0;
- // If we are done at STOP level 4
- if (!entry_ongoing)
+ if (deeper_core == CME_MASK_C0)
{
- break;
+ target_level = deeper_level;
}
+ }
- PK_TRACE("SE4+:core[%d],deeper_core[%d],\
- target_level[%d],deeper_level[%d]",
- core, deeper_core, target_level, deeper_level);
+ if (!core)
+ {
+ core |= core_aborted;
+ entry_ongoing = 0;
}
+ // If we are done at STOP level 4 or aborted
+ if (!entry_ongoing)
+ {
+ break;
+ }
+
+ PK_TRACE("SE4+:core[%d],deeper_core[%d],\
+ target_level[%d],deeper_level[%d]",
+ core, deeper_core, target_level, deeper_level);
+
//--------------------------------------------------------------------------
// STOP LEVEL 5 (preparsion of STOP LEVEL 8 and above)
//--------------------------------------------------------------------------
- if ((G_cme_stop_record.pm_state_c0 >= STOP_LEVEL_8) &&
- (G_cme_stop_record.pm_state_c1 >= STOP_LEVEL_8))
+ // block all wake up before purge L2,
+ // this is last chance either core can exit
+ out32(CME_LCL_EIMR_OR, BITS32(12, 6));
+
+ if ((G_cme_stop_record.req_stop_c0 >= STOP_LEVEL_8) &&
+ (G_cme_stop_record.req_stop_c1 >= STOP_LEVEL_8))
{
//=========================
MARK_TAG(SE_PURGE_L2, core)
//=========================
- // Assert L2+NCU Purges(chtm purge will be done in SGPE), and NCU tlbie quiesce
+ // Assert L2+NCU Purges(chtm purge will be done in SGPE),
+ // and NCU tlbie quiesce
PK_TRACE("SE5.1a");
out32(CME_LCL_SICR_OR, BIT32(18) | BIT32(21) | BIT32(22));
+ // todo: poll for tlbie quiesce done?
+
+ // Poll for Purged Done
+ PK_TRACE("SE5.1b");
//===========================
MARK_TRAP(SE_IS2_BEGIN)
- //===========================
- // todo: open wakeup window to abort purge
+ //===========================
+ do
+ {
+#if !SKIP_ABORT
- // Poll for Purged Done
- PK_TRACE("SE5.1b");
+ if(in32(CME_LCL_EINR) & BITS32(12, 6))
+ {
+ // abort L2+NCU purges
+ out32(CME_LCL_SICR_OR, BIT32(19) | BIT32(23));
+ }
+#endif
+ }
while((in32(CME_LCL_EISR) & BITS32(22, 2)) != BITS32(22, 2));
- // todo: close wakeup window
-
//===================
MARK_TRAP(SE_IS2_END)
//===================
- // Deassert L2+NCU Purges
+ // Deassert L2+NCU Purges, their possible aborts, NCU tlbie quiesce
PK_TRACE("SE5.1c");
- out32(CME_LCL_SICR_CLR, BIT32(18) | BIT32(22));
-
- // Raise L2-L3 quiesce???
+ out32(CME_LCL_SICR_CLR, BITS32(18, 6));
PK_TRACE("SE5.1: L2/NCU/CHTM Purged");
@@ -605,15 +722,6 @@ p9_cme_stop_entry()
//=========================
}
-
- // Recheck status in case L2 purge is aborted by wakeup
- if ((G_cme_stop_record.pm_state_c0 <= STOP_LEVEL_4) &&
- (G_cme_stop_record.pm_state_c1 <= STOP_LEVEL_4))
- {
- entry_ongoing = 0;
- break;
- }
-
//=============================
MARK_TAG(SE_SGPE_HANDOFF, core)
//=============================
@@ -628,19 +736,29 @@ p9_cme_stop_entry()
STOP_REQ_DISABLE,
STOP_ACT_ENABLE);
+ if (core & CME_MASK_C0)
+ {
+ G_cme_stop_record.act_stop_c0 = STOP_LEVEL_5;
+ }
+
+ if (core & CME_MASK_C1)
+ {
+ G_cme_stop_record.act_stop_c1 = STOP_LEVEL_5;
+ }
+
// Send PCB Interrupt per core
PK_TRACE("SE5.2b");
pig.fields.req_intr_type = 2; //0b010: STOP State Change
if (core & CME_MASK_C0)
{
- pig.fields.req_intr_payload = G_cme_stop_record.pm_state_c0;
+ pig.fields.req_intr_payload = G_cme_stop_record.req_stop_c0;
CME_PUTSCOM(PPM_PIG, CME_MASK_C0, pig.value);
}
if (core & CME_MASK_C1)
{
- pig.fields.req_intr_payload = G_cme_stop_record.pm_state_c1;
+ pig.fields.req_intr_payload = G_cme_stop_record.req_stop_c1;
CME_PUTSCOM(PPM_PIG, CME_MASK_C1, pig.value);
}
@@ -660,16 +778,20 @@ p9_cme_stop_entry()
// Release PPM Write Protection
CME_PUTSCOM(CPPM_CPMMR_CLR, core, BIT64(0));
- // Enable fired Stop and corresponding Wakeup Interrupts
- // if no handoff to SGPE
- //this exit is umasked, this entry remains masked
- //other entry is umasked only if it's waken up
+ // Enable Wakeup Interrupts of this entry core if no handoff to SGPE
+ // Otherwise enable Doorbell interrupts of this entry core
+ out32(CME_LCL_EIMR_CLR,
+ ((~core & G_cme_stop_record.active_core & CME_MASK_BC) << SHIFT32(21)));
+
if (!entry_ongoing)
out32(CME_LCL_EIMR_CLR,
- ((~core & CME_MASK_BC & G_cme_stop_record.cme_wakenup) << SHIFT32(21)) |
- (core << SHIFT32(13)) |
- (core << SHIFT32(15)) |
- (core << SHIFT32(17)));
+ /*TODO((core & ~core_aborted & CME_MASK_BC) << SHIFT32(13)) |*/
+ ((core & ~core_aborted & CME_MASK_BC) << SHIFT32(15)) |
+ ((core & ~core_aborted & CME_MASK_BC) << SHIFT32(17)));
+ else
+ {
+ out32_sh(CME_LCL_EIMR_CLR, (core << SHIFT32((41 - 32))));
+ }
//============================
MARK_TRAP(ENDSCOPE_STOP_ENTRY)
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c
index 5490507d..49d34942 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit.c
@@ -38,6 +38,10 @@ p9_cme_stop_exit()
uint32_t deeper_core = 0;
uint32_t wakeup;
uint32_t core;
+#if !SKIP_CATCHUP
+ uint8_t core_catchup;
+#endif
+ uint8_t catchup_ongoing = 0;
uint8_t pcwu, spwu, rgwu;
//uint8_t grant;
ppm_sshsrc_t hist;
@@ -48,7 +52,7 @@ p9_cme_stop_exit()
// extract wakeup signals, clear status, and mask wakeup interrupts
wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F;
- out32(CME_LCL_EISR_CLR, wakeup << SHIFT32(17));
+ out32(CME_LCL_EISR_CLR, (wakeup << SHIFT32(17)) | BITS32(24, 2));
// build the core select for wakeup
pcwu = (wakeup >> 4) & CME_MASK_BC;
@@ -57,9 +61,7 @@ p9_cme_stop_exit()
core = pcwu | spwu | rgwu;
// mask wake up interrupts
- out32(CME_LCL_EIMR_OR, (core << SHIFT32(13)) |
- (core << SHIFT32(15)) |
- (core << SHIFT32(17)));
+ out32(CME_LCL_EIMR_OR, BITS32(12, 6));
PK_TRACE("X0: Core Select[%d], pcwu[%d], spwu[%d], rgwu[%d]",
core, pcwu, spwu, rgwu);
@@ -74,14 +76,14 @@ p9_cme_stop_exit()
MARK_TAG(BEGINSCOPE_STOP_EXIT, core)
//==================================
- PK_TRACE("X0: Stop Levels[%d %d]",
- G_cme_stop_record.pm_state_c0, G_cme_stop_record.pm_state_c1);
+ PK_TRACE("X0: Actual Stop Levels[%d %d]",
+ G_cme_stop_record.act_stop_c0, G_cme_stop_record.act_stop_c1);
// Code Error: by default stop 1 auto wakeup should be enabled
- if ((core == CME_MASK_C0 && G_cme_stop_record.pm_state_c0 < 2) ||
- (core == CME_MASK_C1 && G_cme_stop_record.pm_state_c1 < 2) ||
- (core == CME_MASK_BC && (G_cme_stop_record.pm_state_c0 < 2 ||
- G_cme_stop_record.pm_state_c1 < 2)))
+ if ((core == CME_MASK_C0 && G_cme_stop_record.act_stop_c0 < 2) ||
+ (core == CME_MASK_C1 && G_cme_stop_record.act_stop_c1 < 2) ||
+ (core == CME_MASK_BC && (G_cme_stop_record.act_stop_c0 < 2 ||
+ G_cme_stop_record.act_stop_c1 < 2)))
{
return CME_STOP_EXIT_WAKEUP_FROM_STOP1;
}
@@ -89,23 +91,23 @@ p9_cme_stop_exit()
// set target_level to STOP level for c0
// unless c1(also or only) wants to wakeup
target_level = deeper_level =
- (core == CME_MASK_C0) ? G_cme_stop_record.pm_state_c0 :
- G_cme_stop_record.pm_state_c1;
+ (core == CME_MASK_C0) ? G_cme_stop_record.act_stop_c0 :
+ G_cme_stop_record.act_stop_c1;
// If both cores want to wakeup but are in different STOP levels,
// set deeper_level to the deeper level targeted by deeper core
if ((core == CME_MASK_BC) &&
- (G_cme_stop_record.pm_state_c0 != G_cme_stop_record.pm_state_c1))
+ (G_cme_stop_record.act_stop_c0 != G_cme_stop_record.act_stop_c1))
{
// Assume C0 is deeper, target_level is already set to C1
- deeper_level = G_cme_stop_record.pm_state_c0;
+ deeper_level = G_cme_stop_record.act_stop_c0;
deeper_core = CME_MASK_C0;
// Otherwise correct assumption on which one is in lighter level
- if (G_cme_stop_record.pm_state_c0 < G_cme_stop_record.pm_state_c1)
+ if (G_cme_stop_record.act_stop_c0 < G_cme_stop_record.act_stop_c1)
{
- target_level = G_cme_stop_record.pm_state_c0;
- deeper_level = G_cme_stop_record.pm_state_c1;
+ target_level = G_cme_stop_record.act_stop_c0;
+ deeper_level = G_cme_stop_record.act_stop_c1;
deeper_core = CME_MASK_C1;
}
}
@@ -154,71 +156,159 @@ p9_cme_stop_exit()
core = deeper_core;
}
-#if !STOP_PRIME
- // todo PK_TRACE("BCE Runtime Kickoff");
-
- // todo for catch up case
- //PK_TRACE("X1: Request PCB Arbiter");
- //p9_hcd_core_pcb_arb(core, 1);
-
- PK_TRACE("X1: Core Poweron");
- MARK_TRAP(SX_POWERON)
-
- if(p9_hcd_core_poweron(core))
+ do //catchup loop
{
- pk_halt();
- }
- MARK_TRAP(SX_POWERON_END)
+#if !STOP_PRIME
+ // todo PK_TRACE("BCE Runtime Kickoff");
+
+ // todo for catch up case
+ //PK_TRACE("X1: Request PCB Arbiter");
+ //p9_hcd_core_pcb_arb(core, 1);
+
+ PK_TRACE("X1: Core Poweron");
+ MARK_TRAP(SX_POWERON)
+ p9_hcd_core_poweron(core);
+ MARK_TRAP(SX_POWERON_END)
+
+ PK_TRACE("X2: Core Chiplet Reset");
+ MARK_TRAP(SX_CHIPLET_RESET)
+ p9_hcd_core_chiplet_reset(core);
+ MARK_TRAP(SX_CHIPLET_RESET_END)
+
+#if !SKIP_CATCHUP
+
+ //catchup
+ if (catchup_ongoing)
+ {
+ core = CME_MASK_BC;
+ catchup_ongoing = 0;
+ }
+ else
+ {
+ wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F;
+ out32(CME_LCL_EISR_CLR, wakeup << SHIFT32(17));
+ core_catchup = ((wakeup >> 4) | (wakeup >> 2) | (wakeup >> 0)) &
+ CME_MASK_BC;
+
+ if (core_catchup && (core_catchup + core) == CME_MASK_BC)
+ {
+ out32(CME_LCL_SICR_OR, core_catchup << SHIFT32(11));
+
+ if(((core_catchup & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_2) ||
+ ((core_catchup & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_2))
+ {
+ deeper_core = core;
+ d2u4_flag = 1;
+ }
+ else if(((core_catchup & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_4) ||
+ ((core_catchup & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_4))
+ {
+ core = core_catchup;
+ catchup_ongoing = 1;
+ continue;
+ }
+
+ while((core_catchup & (in32(CME_LCL_SISR) >> SHIFT32(11))) !=
+ core_catchup);
+ }
+ }
- PK_TRACE("X2: Core Chiplet Reset");
- MARK_TRAP(SX_CHIPLET_RESET)
- p9_hcd_core_chiplet_reset(core);
- MARK_TRAP(SX_CHIPLET_RESET_END)
+#endif
#if !SKIP_INITF
- PK_TRACE("X3: Core GPTR Time Initf");
- MARK_TRAP(SX_GPTR_TIME_INITF)
- p9_hcd_core_gptr_time_initf(core);
- MARK_TRAP(SX_GPTR_TIME_INITF_END)
+ PK_TRACE("X3: Core GPTR Time Initf");
+ MARK_TRAP(SX_GPTR_TIME_INITF)
+ p9_hcd_core_gptr_time_initf(core);
+ MARK_TRAP(SX_GPTR_TIME_INITF_END)
#endif
- PK_TRACE("X4: Switch glsmux to DPLL output");
- CME_PUTSCOM(PPM_CGCR_OR, core, BIT64(3));
-
- PK_TRACE("X5: Core Chiplet Init");
- MARK_TRAP(SX_CHIPLET_INIT)
- p9_hcd_core_chiplet_init(core);
- MARK_TRAP(SX_CHIPLET_INIT_END)
+ PK_TRACE("X5: Core Chiplet Init");
+ MARK_TRAP(SX_CHIPLET_INIT)
+ p9_hcd_core_chiplet_init(core);
+ MARK_TRAP(SX_CHIPLET_INIT_END)
#if !SKIP_INITF
- PK_TRACE("X6: Core Repair Initf");
- MARK_TRAP(SX_REPAIR_INITF)
- p9_hcd_core_repair_initf(core);
- MARK_TRAP(SX_REPAIR_INITF_END)
+ PK_TRACE("X6: Core Repair Initf");
+ MARK_TRAP(SX_REPAIR_INITF)
+ p9_hcd_core_repair_initf(core);
+ MARK_TRAP(SX_REPAIR_INITF_END)
+#endif
+
+#if !SKIP_CATCHUP
+
+ //catchup
+ if (catchup_ongoing)
+ {
+ core = CME_MASK_BC;
+ catchup_ongoing = 0;
+ }
+ else
+ {
+ wakeup = (in32(CME_LCL_EISR) >> SHIFT32(17)) & 0x3F;
+ out32(CME_LCL_EISR_CLR, wakeup << SHIFT32(17));
+ core_catchup = ((wakeup >> 4) | (wakeup >> 2) | (wakeup >> 0)) &
+ CME_MASK_BC;
+
+ if (core_catchup && (core_catchup + core) == CME_MASK_BC)
+ {
+ out32(CME_LCL_SICR_OR, core_catchup << SHIFT32(11));
+
+ if(((core_catchup & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_2) ||
+ ((core_catchup & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_2))
+ {
+ deeper_core = core;
+ d2u4_flag = 1;
+ }
+ else if(((core_catchup & CME_MASK_C0) &&
+ G_cme_stop_record.act_stop_c0 == STOP_LEVEL_4) ||
+ ((core_catchup & CME_MASK_C1) &&
+ G_cme_stop_record.act_stop_c1 == STOP_LEVEL_4))
+ {
+ core = core_catchup;
+ catchup_ongoing = 1;
+ continue;
+ }
+
+ while((core_catchup & (in32(CME_LCL_SISR) >> SHIFT32(11))) !=
+ core_catchup);
+ }
+ }
+
#endif
#if !SKIP_ARY_INIT
- PK_TRACE("X7: Core Array Init");
- MARK_TRAP(SX_ARRAY_INIT)
- p9_hcd_core_arrayinit(core);
- MARK_TRAP(SX_ARRAY_INIT_END)
+ PK_TRACE("X7: Core Array Init");
+ MARK_TRAP(SX_ARRAY_INIT)
+ p9_hcd_core_arrayinit(core);
+ MARK_TRAP(SX_ARRAY_INIT_END)
#endif
#if !SKIP_INITF
- PK_TRACE("X8: Core Func Scan");
- MARK_TRAP(SX_INITF)
- p9_hcd_core_initf(core);
- MARK_TRAP(SX_INITF_END)
+ PK_TRACE("X8: Core Func Scan");
+ MARK_TRAP(SX_INITF)
+ p9_hcd_core_initf(core);
+ MARK_TRAP(SX_INITF_END)
#endif
#endif
+ }
+ while(catchup_ongoing);
+
if (d2u4_flag)
{
core = CME_MASK_BC;
}
}
+ // todo STOP LEVEL 3
+
//--------------------------------------------------------------------------
// STOP LEVEL 2
//--------------------------------------------------------------------------
@@ -298,7 +388,7 @@ p9_cme_stop_exit()
PK_TRACE("Poll for Core stop again(pm_active=1)");
- while(~(in32(CME_LCL_EINR)) & (core << SHIFT32(21)));
+ while((~(in32(CME_LCL_EINR))) & (core << SHIFT32(21)));
MARK_TRAP(SX_STOP15_THREADS)
@@ -341,9 +431,17 @@ p9_cme_stop_exit()
STOP_REQ_DISABLE,
STOP_ACT_DISABLE)
- // unmask stop interrupts
- G_cme_stop_record.cme_wakenup |= core;
- out32(CME_LCL_EIMR_CLR, (core << SHIFT32(21)));
+ G_cme_stop_record.active_core |= core;
+
+ if (core & CME_MASK_C0)
+ {
+ G_cme_stop_record.act_stop_c0 = 0;
+ }
+
+ if (core & CME_MASK_C1)
+ {
+ G_cme_stop_record.act_stop_c1 = 0;
+ }
// If not special wakeup, allow core to go back into STOP in the future
if (!spwu)
@@ -352,6 +450,12 @@ p9_cme_stop_exit()
out32(CME_LCL_SICR_CLR, core << SHIFT32(5));
}
+ // unmask stop interrupts
+ out32(CME_LCL_EIMR_CLR, ((core << SHIFT32(21)) |
+ /* ((~core & ~G_cme_stop_record.active_core & CME_MASK_BC)<<SHIFT32(13))| */
+ ((~core & ~G_cme_stop_record.active_core & CME_MASK_BC) << SHIFT32(15)) |
+ ((~core & ~G_cme_stop_record.active_core & CME_MASK_BC) << SHIFT32(17))));
+
//===========================
MARK_TRAP(ENDSCOPE_STOP_EXIT)
//===========================
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h
index 5e8399ab..59c59d5b 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_exit_marks.h
@@ -66,16 +66,16 @@ enum CME_SX_MARKS
SX_SCOMCUST = 0x168,
SX_SCOMCUST_END = 0x1e0,
SX_RAS_RUNTIME_SCOM = 0x1e8,
- SX_RAS_RUNTIME_SCOM_END = 0x1f0,
- SX_OCC_RUNTIME_SCOM = 0x1f8,
+ SX_RAS_RUNTIME_SCOM_END = 0x230,
+ SX_OCC_RUNTIME_SCOM = 0x238,
SX_OCC_RUNTIME_SCOM_END = 0x200,
SX_SELFRESTORE = 0x208,
SX_RAM_HRMOR = 0x210,
SX_SRESET_THREADS = 0x218,
SX_STOP15_THREADS = 0x220,
SX_SELFRESTORE_END = 0x228,
- BEGINSCOPE_STOP_EXIT = 0x1f10,
- ENDSCOPE_STOP_EXIT = 0x1f18
+ BEGINSCOPE_STOP_EXIT = 0x1f28,
+ ENDSCOPE_STOP_EXIT = 0x1f30
};
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c
index b4447019..732b6a26 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_cme_stop_irq_handlers.c
@@ -24,49 +24,51 @@
/* IBM_PROLOG_END_TAG */
#include "p9_cme_stop.h"
+#include "p9_cme_stop_enter_marks.h"
-void
-p9_cme_stop_enter_handler(void* arg, PkIrqId irq)
-{
- // Disable Fired IRQ First
- out32(CME_LCL_EIMR_OR, BIT32(irq));
-
- // If any are asserted, post cme_stop_entry_thread semaphore
- //if (irq == IRQ_STOP_C0 || irq == IRQ_STOP_C1) {
- PK_TRACE("SE-IRQ: %d", irq);
- pk_semaphore_post((PkSemaphore*)arg);
- //}
-}
+extern CmeStopRecord G_cme_stop_record;
void
-p9_cme_stop_exit_handler(void* arg, PkIrqId irq)
+p9_cme_stop_event_handler(void* arg, PkIrqId irq)
{
- // Disable Fired IRQ First
- out32(CME_LCL_EIMR_OR, BIT32(irq));
+ MARK_TRAP(STOP_EVENT_HANDLER)
+ PK_TRACE("SE-IRQ: %d", irq);
- // If any are asserted, call cme_stop_exit() aka core_runinit()
- //if (irq >= IRQ_PC_C0 && irq <= IRQ_SWU_C1) {
- PK_TRACE("SX-IRQ: %d", irq);
+ if (irq == IRQ_STOP_C0 || irq == IRQ_STOP_C1)
+ {
+ out32(CME_LCL_EIMR_OR, BITS32(20, 2));
+ }
- if (p9_cme_stop_exit())
+ if (irq >= IRQ_PC_C0 && irq <= IRQ_SWU_C1)
{
- pk_halt();
+ out32(CME_LCL_EIMR_OR, BITS32(12, 6));
}
- //}
+ pk_semaphore_post((PkSemaphore*)arg);
}
void
p9_cme_stop_doorbell_handler(void* arg, PkIrqId irq)
{
- // Unmask Stop and Wakeup Interrupts
+ int rc = 0;
+ MARK_TRAP(STOP_DOORBELL_HANDLER)
+ PK_TRACE("DB-IRQ: %d", irq);
+
+ out32_sh(CME_LCL_EIMR_OR, BIT32(irq - 32));
+ out32_sh(CME_LCL_EISR_CLR, BIT32(irq - 32));
+
if (irq == IRQ_DB1_C0)
{
- out32(CME_LCL_EIMR_CLR, BIT32(12) | BIT32(14) | BIT32(16) | BIT32(20));
+ CME_PUTSCOM(CPPM_CMEDB1, CME_MASK_C0, 0);
+ out32(CME_LCL_EIMR_CLR, BIT32(12) | BIT32(14) | BIT32(16));
}
if (irq == IRQ_DB1_C1)
{
- out32(CME_LCL_EIMR_CLR, BIT32(13) | BIT32(15) | BIT32(17) | BIT32(21));
+ CME_PUTSCOM(CPPM_CMEDB1, CME_MASK_C1, 0);
+ out32(CME_LCL_EIMR_CLR, BIT32(13) | BIT32(15) | BIT32(17));
}
+
+ // TODO mask pc_itr_pending as workaround for double interrupts of pc and rwu
+ out32(CME_LCL_EIMR_OR, BITS32(12, 2));
}
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c
index 23defe4c..c4fdc9b1 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_chiplet_reset.c
@@ -30,33 +30,32 @@ int
p9_hcd_core_chiplet_reset(uint32_t core)
{
int rc = CME_STOP_SUCCESS;
+ uint64_t data, loop;
PK_TRACE("Init NETWORK_CONTROL0, step needed for hotplug");
- //CME_PUTSCOM(CPPM_NC0INDIR_CLR, core, ~NET_CTRL0_INIT_VECTOR);
- CME_PUTSCOM(CPPM_NC0INDIR_OR, core, NET_CTRL0_INIT_VECTOR);
+ CME_PUTSCOM(CPPM_NC0INDIR_OR, core, NET_CTRL0_INIT_VECTOR);
- PK_TRACE("Init Core Glitchless Mux Reset/Select via CLOCK_GRID_CTRL[0:3]");
- CME_PUTSCOM(PPM_CGCR_OR, core, BIT64(0));
- CME_PUTSCOM(PPM_CGCR_CLR, core, BIT64(3));
+ PK_TRACE("ONLY till TP030: SET VITL_PHASE=1");
+ CME_PUTSCOM(CPPM_NC0INDIR_OR, core, BIT64(8));
+ PPE_WAIT_CORE_CYCLES(loop, 50);
MARK_TRAP(SX_CHIPLET_RESET_GLSMUX_RESET)
- PK_TRACE("Clear Core Glitchless Mux Async Reset via CLOCK_GRID_CTRL[0]");
- CME_PUTSCOM(PPM_CGCR_CLR, core, BIT64(0));
+ PK_TRACE("Init Core Glitchless Mux Reset/Select via CLOCK_GRID_CTRL[0:3]");
+ CME_PUTSCOM(C_PPM_CGCR, core, BIT64(3));
PK_TRACE("Clear PCB Endpoint Reset via NET_CTRL0[1]");
CME_PUTSCOM(CPPM_NC0INDIR_CLR, core, BIT64(1));
-
- // needed by sbe
- //PK_TRACE("Reset PCB Slave Error Register");
- //CME_PUTSCOM(C_ERROR_REG, core, BITS64(0,64));
+ PPE_WAIT_CORE_CYCLES(loop, 50);
PK_TRACE("Remove chiplet electrical fence via NET_CTRL0[26]");
CME_PUTSCOM(CPPM_NC0INDIR_CLR, core, BIT64(26));
- // needed by sbe
- //PK_TRACE("Configure HANG_PULSE1 for chiplet hang counters");
- //CME_PUTSCOM(C_HANG_PULSE_1_REG, core, HANG_PULSE1_INIT_VECTOR);
+ PK_TRACE("ONLY till TP030: SET SYNC_PULSE_DELAY=0b0011");
+ CME_GETSCOM(C_SYNC_CONFIG, core, CME_SCOM_AND, data);
+ data = data | 0x3000000000000000;
+ data = data & 0x3FFFFFFFFFFFFFFF;
+ CME_PUTSCOM(C_SYNC_CONFIG, core, data);
#if !SKIP_SCAN0
// Marker for scan0
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c
index e96b9a3c..1bc415b2 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_poweron.c
@@ -32,6 +32,10 @@ p9_hcd_core_poweron(uint32_t core)
int rc = CME_STOP_SUCCESS;
uint64_t scom_data;
+ PK_TRACE("Set core glsmux reset");
+ CME_PUTSCOM(C_PPM_CGCR, core, BIT64(0));
+
+#if !EPM_P9_TUNNING
// vdd_pfet_force_state == 00 (Nop)
PK_TRACE("Make sure we are not forcing PFET for VDD off");
CME_GETSCOM(PPM_PFCS, core, CME_SCOM_AND, scom_data);
@@ -45,6 +49,7 @@ p9_hcd_core_poweron(uint32_t core)
// vdd_pfet_regulation_finger_en = 0 (controled by FSM)
PK_TRACE("Prepare PFET Controls");
CME_PUTSCOM(PPM_PFCS_CLR, core, BIT64(4) | BIT64(5) | BIT64(8));
+#endif
// vdd_pfet_force_state = 11 (Force Von)
PK_TRACE("Power Off Core VDD");
@@ -70,11 +75,11 @@ p9_hcd_core_poweron(uint32_t core)
while(scom_data & BIT64(46));
MARK_TRAP(SX_POWERON_PG_SEL)
-#endif
// vdd_pfet_force_state = 00 (Nop)
PK_TRACE("Turn Off Force Von");
CME_PUTSCOM(PPM_PFCS_CLR, core, BITS64(0, 2));
+#endif
return rc;
}
diff --git a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_startclocks.c b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_startclocks.c
index 4c3f8f46..5ef8c995 100644
--- a/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_startclocks.c
+++ b/import/chips/p9/procedures/ppe_closed/cme/stop_cme/p9_hcd_core_startclocks.c
@@ -30,23 +30,41 @@ int
p9_hcd_core_startclocks(uint32_t core)
{
int rc = CME_STOP_SUCCESS;
- uint64_t data;
+ uint64_t data, loop;
- //PK_TRACE("Drop the Pervasive THOLD via SLAVE_CONFIG[0]");
+ PK_TRACE("Setup OPCG_ALIGN Register");
+ CME_GETSCOM(C_OPCG_ALIGN, core, CME_SCOM_AND, data);
+ data = data & (BITS64(0, 4) & BITS64(12, 8) & BITS64(52, 12));
+ data = data | (BIT64(1) | BIT64(3) | BIT64(59));
+ CME_PUTSCOM(C_OPCG_ALIGN, core, data);
- PK_TRACE("Drop Vital Fence via CPLT_CTRL1[3]");
+ PK_TRACE("Drop partial good fences via CPLT_CTRL1");
+ CME_PUTSCOM(C_CPLT_CTRL1_CLEAR, core, 0xFFFF700000000000);
+
+ PK_TRACE("Drop vital fences via CPLT_CTRL1");
CME_PUTSCOM(C_CPLT_CTRL1_CLEAR, core, BIT64(3));
PK_TRACE("Reset abstclk & syncclk muxsel(io_clk_sel) via CPLT_CTRL0[0:1]");
CME_PUTSCOM(C_CPLT_CTRL0_CLEAR, core, BITS64(0, 2));
- PK_TRACE("Set abist_mode_dc for core chiplet(core recovery) via BIST[1]");
- CME_GETSCOM(C_BIST, core, CME_SCOM_OR, data);
- data = data | BIT64(1);
- CME_PUTSCOM(C_BIST, core, data);
+ PK_TRACE("Set flushmode_inhibit via CPLT_CTRL0[2]");
+ CME_PUTSCOM(C_CPLT_CTRL0_OR, core, BIT64(2));
+
+ PK_TRACE("Set force_align via CPLT_CTRL0[3]");
+ CME_PUTSCOM(C_CPLT_CTRL0_OR, core, BIT64(3));
+
+ PK_TRACE("Set/Unset clear_chiplet_is_aligned via SYNC_CONFIG[7]");
+ CME_GETSCOM(C_SYNC_CONFIG, core, CME_SCOM_AND, data);
+ data = data | BIT64(7);
+ CME_PUTSCOM(C_SYNC_CONFIG, core, data);
+ data = data & BIT64(7);
+ CME_PUTSCOM(C_SYNC_CONFIG, core, data);
- PK_TRACE("Switch core glsmux to DPLL output");
- CME_PUTSCOM(PPM_CGCR_OR, core, BIT64(3));
+ // align chiplets
+
+ PK_TRACE("Clear force_align via CPLT_CTRL0[3]");
+ CME_PUTSCOM(C_CPLT_CTRL0_CLEAR, core, BIT64(3));
+ PPE_WAIT_CORE_CYCLES(loop, 450);
PK_TRACE("Raise core clock sync enable");
CME_PUTSCOM(CPPM_CACCR_OR, core, BIT64(15));
@@ -85,21 +103,19 @@ p9_hcd_core_startclocks(uint32_t core)
MARK_TRAP(SX_STARTCLOCKS_DONE)
- PK_TRACE("Drop remaining fences via CPLT_CTRL1");
- CME_PUTSCOM(C_CPLT_CTRL1_CLEAR, core, 0xEFFF700000000000);
-
PK_TRACE("Drop chiplet fence via NC0INDIR[18]");
CME_PUTSCOM(CPPM_NC0INDIR_CLR, core, BIT64(18));
PK_TRACE("Drop fence to allow PCB operations to chiplet via NC0INDIR[26]");
CME_PUTSCOM(CPPM_NC0INDIR_CLR, core, BIT64(25));
- PK_TRACE("Clear force_align via CPLT_CTRL0[3]");
- CME_PUTSCOM(C_CPLT_CTRL0_CLEAR, core, BIT64(3));
+ // checkstop
PK_TRACE("Clear flushmode_inhibit via CPLT_CTRL0[2]");
CME_PUTSCOM(C_CPLT_CTRL0_CLEAR, core, BIT64(2));
+ // check align
+
// needed by cme
PK_TRACE("Drop Core-L2 + Core-CC Quiesces");
out32(CME_LCL_SICR_CLR, (core << SHIFT32(7)) | (core << SHIFT32(9)));
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c
index f6f9ba27..a942ea41 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_chiplet_reset.c
@@ -32,30 +32,21 @@ p9_hcd_cache_chiplet_reset(uint8_t quad)
int rc = SGPE_STOP_SUCCESS;
PK_TRACE("Init NETWORK_CONTROL0, step needed for hotplug");
- GPE_PUTSCOM(EQ_NET_CTRL0_WOR, QUAD_ADDR_BASE, quad, NET_CTRL0_INIT_VECTOR);
-
- PK_TRACE("Init Cache Glitchless Mux Reset/Select via CLOCK_GRID_CTRL[0:3]");
- GPE_PUTSCOM(PPM_CGCR_OR, QUAD_ADDR_BASE, quad, BIT64(0));
- GPE_PUTSCOM(PPM_CGCR_CLR, QUAD_ADDR_BASE, quad, BIT64(3));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, quad), NET_CTRL0_INIT_VECTOR);
MARK_TRAP(SX_CHIPLET_RESET_GLSMUX_RESET)
- PK_TRACE("Clear Cache Glitchless Mux Async Reset via CLOCK_GRID_CTRL[0]");
- GPE_PUTSCOM(PPM_CGCR_CLR, QUAD_ADDR_BASE, quad, BIT64(0));
+ PK_TRACE("Init Cache Glitchless Mux Reset/Select via CLOCK_GRID_CTRL[0:3]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_PPM_CGCR, quad), 0);
+
+ PK_TRACE("Init L2 Glitchless Mux Reset/Select via EXCLK_GRID_CTRL[32:33]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_CLR, quad), BITS64(32, 4));
PK_TRACE("Clear PCB Endpoint Reset via NET_CTRL0[1]");
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BIT64(1));
-
- // needed by sbe
- //PK_TRACE("Reset PCB Slave Error Register");
- //CME_PUTSCOM(C_ERROR_REG, core, BITS64(0,64));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, quad), ~BIT64(1));
PK_TRACE("Remove chiplet electrical fence via NET_CTRL0[26]");
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BIT64(26));
-
- // needed by sbe
- //PK_TRACE("Configure HANG_PULSE1 for chiplet hang counters");
- //CME_PUTSCOM(C_HANG_PULSE_1_REG, core, HANG_PULSE1_INIT_VECTOR);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, quad), ~BIT64(26));
#if !SKIP_SCAN0
// Marker for scan0
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c
index 6d61a020..24e35bf4 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_dpll_setup.c
@@ -36,34 +36,10 @@ p9_hcd_cache_dpll_setup(uint8_t quad)
// PRE-SCAN
// --------------
- PK_TRACE("Drop DPLL Test Mode and Reset");
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BITS64(3, 2));
-
- PK_TRACE("Put DPLL into bypass");
- GPE_PUTSCOM(EQ_NET_CTRL0_WOR, QUAD_ADDR_BASE, quad, BIT64(5));
-
- PK_TRACE("Put DPLL into Mode 1 by asserting ff_bypass");
- GPE_PUTSCOM(EQ_QPPM_DPLL_CTRL_OR, QUAD_ADDR_BASE, quad, BIT64(2));
-
- /// @todo Is there a dpllclk_muxsel in p9?
- PK_TRACE("Set syncclk_muxsel and dpllclk_muxsel");
- GPE_PUTSCOM(EQ_CPLT_CTRL0_OR, QUAD_ADDR_BASE, quad, BIT64(1));
-
// --------------
// DPLL SCAN
// --------------
/// @todo scan dpll here
- /// @todo start dpll clock here?
- PK_TRACE("Set all bits to zero prior clock start via SCAN_REGION_TYPE");
- GPE_PUTSCOM(EQ_SCAN_REGION_TYPE, QUAD_ADDR_BASE, quad, 0);
-
- PK_TRACE("Start clock(arrays+nsl clock region) via CLK_REGION");
- data = 0x5002000000006000;
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, quad, data);
-
- PK_TRACE("Start clock(sl+refresh clock region) via CLK_REGION");
- data = 0x500200000000E000;
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, quad, data);
// --------------
// DPLL SETUP
@@ -72,42 +48,56 @@ p9_hcd_cache_dpll_setup(uint8_t quad)
// This is necessary to ensure that the DPLL is in Mode 1.
// If not, the lock times will go from ~30us to 3-5ms
PK_TRACE("Ensure DPLL in Mode 1, and set slew rate to a modest value");
- GPE_PUTSCOM(EQ_QPPM_DPLL_CTRL_OR, QUAD_ADDR_BASE, quad, BIT64(2) | BIT64(8));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_DPLL_CTRL_OR, quad), BIT64(2) | BIT64(8));
- /// @todo Is there a dpllclk_muxsel in p9?
- PK_TRACE("Clear syncclk_muxsel and dpllclk_muxsel");
- GPE_PUTSCOM(EQ_CPLT_CTRL0_CLEAR, QUAD_ADDR_BASE, quad, BIT64(1));
+ PK_TRACE("Drop DPLL Test Mode and Reset");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, quad), ~BITS64(3, 2));
- /// @todo Already done in chiplet_reset?
- PK_TRACE("Drop glitchless mux async reset");
+ PK_TRACE("Set all bits to zero prior clock start via SCAN_REGION_TYPE");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, quad), 0);
- PK_TRACE("Take DPLL out of bypass");
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BIT64(5));
+ PK_TRACE("Start clock(arrays+nsl clock region) via CLK_REGION");
+ data = 0x5002000000006000;
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), data);
+
+ PK_TRACE("Start clock(sl+refresh clock region) via CLK_REGION");
+ data = 0x500200000000E000;
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), data);
- /// @todo Is there a dpll_thold in p9?
- PK_TRACE("Drop internal DPLL THOLD");
+ PK_TRACE("Polling for clocks starting via CLOCK_STAT_SL");
+
+ do
+ {
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), data);
+ }
+ while((~data & BIT64(14)) != BIT64(14));
+
+ PK_TRACE("DPLL clock is now running");
+
+ MARK_TRAP(SX_DPLL_START_DONE)
PK_TRACE("Poll for dpll lock");
do
{
- GPE_GETSCOM(EQ_QPPM_DPLL_STAT, QUAD_ADDR_BASE, quad, data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_DPLL_STAT, quad), data);
break; /// @todo Skipping the lock checking until model is ready
}
while (!(data & BIT64(63)));
- PK_TRACE("Recycle DPLL in and out of bypass");
- GPE_PUTSCOM(EQ_NET_CTRL0_WOR, QUAD_ADDR_BASE, quad, BIT64(5));
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BIT64(5));
-
PK_TRACE("DPLL is locked");
- /// @todo Later done in startclocks?
- PK_TRACE("Set glitchless mux select to dpll");
- GPE_PUTSCOM(EQ_PPM_CGCR_OR, QUAD_ADDR_BASE, quad, BIT64(3));
+ PK_TRACE("Take DPLL out of bypass");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, quad), ~BIT64(5));
+
+ PK_TRACE("Switch L3 glsmux select to DPLL output");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_PPM_CGCR, quad), BIT64(3));
+
+ PK_TRACE("Switch L2 glsmux select to DPLL output");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, quad), BITS64(34, 2));
PK_TRACE("Drop ff_bypass to switch into slew-controlled mode");
- GPE_PUTSCOM(EQ_QPPM_DPLL_CTRL_CLEAR, QUAD_ADDR_BASE, quad, BIT64(2));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_DPLL_CTRL_CLEAR, quad), BIT64(2));
return rc;
}
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c
index e3287ae5..bbc3909e 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_l2_startclocks.c
@@ -32,60 +32,78 @@ p9_hcd_cache_l2_startclocks(uint8_t ex, uint8_t quad)
int rc = SGPE_STOP_SUCCESS;
uint64_t scom_data;
- PK_TRACE("Switch glsmux to DPLL output");
- GPE_PUTSCOM(EQ_QPPM_EXCGCR_OR, QUAD_ADDR_BASE, quad, (ex << SHIFT64(35)));
+ PK_TRACE("Switch L2 glsmux select to DPLL output");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, quad), BITS64(34, 2));
+
+ PK_TRACE("Setup OPCG_ALIGN Register");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), scom_data);
+ scom_data = scom_data & (BITS64(0, 4) & BITS64(12, 8) & BITS64(52, 12));
+ scom_data = scom_data | (BIT64(1) | BIT64(3) | BIT64(59));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), scom_data);
+
+ PK_TRACE("Set flushmode_inhibit via CPLT_CTRL0[2]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_OR, quad), BIT64(2));
+
+ PK_TRACE("Set force_align via CPLT_CTRL0[3]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_OR, quad), BIT64(3));
+
+ PK_TRACE("Clear force_align via CPLT_CTRL0[3]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(3));
PK_TRACE("Raise clock sync enable before switch to dpll");
- GPE_PUTSCOM(EQ_QPPM_EXCGCR_OR, QUAD_ADDR_BASE, quad, (ex << SHIFT64(37)));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, quad), (ex << SHIFT64(37)));
#if !EPM_P9_TUNING
PK_TRACE("Poll for clock sync done to raise");
do
{
- GPE_GETSCOM(QPPM_QACSR, QUAD_ADDR_BASE, quad, scom_data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACSR, quad), scom_data);
}
while(!(scom_data & (ex << SHIFT64(37))));
#endif
PK_TRACE("Set all bits to zero prior clock start via SCAN_REGION_TYPE");
- GPE_PUTSCOM(EQ_SCAN_REGION_TYPE, QUAD_ADDR_BASE, quad, 0);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, quad), 0);
PK_TRACE("Start clock(arrays+nsl clock region) via CLK_REGION");
scom_data = 0x5000000000006000 | ((uint64_t)ex << SHIFT64(9));
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, quad, scom_data);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data);
PK_TRACE("Start clock(sl+refresh clock region) via CLK_REGION");
scom_data = 0x500000000000E000 | ((uint64_t)ex << SHIFT64(9));
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, quad, scom_data);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), scom_data);
PK_TRACE("Polling for clocks starting via CLOCK_STAT_SL");
do
{
- GPE_GETSCOM(EQ_CLOCK_STAT_SL, QUAD_ADDR_BASE, quad, scom_data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), scom_data);
}
while(((~scom_data >> SHIFT64(9)) & ex) != ex);
PK_TRACE("L2 clock is now running");
- PK_TRACE("Drop remaining fences via CPLT_CTRL1");
- GPE_PUTSCOM(EQ_CPLT_CTRL1_CLEAR, QUAD_ADDR_BASE, quad,
- 0xEFFF700000000000);
+ MARK_TRAP(SX_L2_STARTCLOCKS_DONE)
- PK_TRACE("Drop chiplet fence via NET_CTRL0[18]");
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BIT64(18));
+ PK_TRACE("Drop TLBIE Quiesce");
- PK_TRACE("Drop fence to allow PCB operations to chiplet via NET_CTRL0[25]");
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BIT64(25));
+ if (ex & FST_EX_IN_QUAD)
+ {
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_CLR, quad, 1), BIT64(21));
+ }
- PK_TRACE("Clear force_align via CPLT_CTRL0[3]");
- GPE_PUTSCOM(EQ_CPLT_CTRL0_CLEAR, QUAD_ADDR_BASE, quad, BIT64(3));
+ if (ex & SND_EX_IN_QUAD)
+ {
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CME(CME_SCOM_SICR_CLR, quad, 2), BIT64(21));
+ }
PK_TRACE("Clear flushmode_inhibit via CPLT_CTRL0[2]");
- GPE_PUTSCOM(EQ_CPLT_CTRL0_CLEAR, QUAD_ADDR_BASE, quad, BIT64(2));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(2));
+
+ PK_TRACE("Drop L2 Snoop Disable");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_L2_RCMD_DIS_REG, quad, ex), 0);
- // Drop Quiesce
return rc;
}
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c
index c3d9b1d3..f3a60650 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_poweron.c
@@ -32,9 +32,19 @@ p9_hcd_cache_poweron(uint8_t quad)
int rc = SGPE_STOP_SUCCESS;
uint64_t scom_data;
+ PK_TRACE("Set L3 glsmux reset via CLOCK_GRID_CTRL[0]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_PPM_CGCR, quad), BIT64(0));
+
+ PK_TRACE("Set L2 glsmux reset via EXCLK_GRID_CTRL[32:33]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_OR, quad), BITS64(32, 2));
+
+ PK_TRACE("Set DPLL ff_bypass via EQ_QPPM_DPLL_CTRL[2]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(QPPM_DPLL_CTRL_OR, quad), BIT64(2));
+
+#if !EPM_P9_TUNNING
// vdd_pfet_force_state == 00 (Nop)
PK_TRACE("Make sure we are not forcing PFET for VDD off");
- GPE_GETSCOM(PPM_PFCS, QUAD_ADDR_BASE, quad, scom_data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS, quad), scom_data);
if (scom_data & BITS64(0, 2))
{
@@ -44,17 +54,19 @@ p9_hcd_cache_poweron(uint8_t quad)
// vdd_pfet_val/sel_override = 0 (disbaled)
// vdd_pfet_regulation_finger_en = 0 (controled by FSM)
PK_TRACE("Prepare PFET Controls");
- GPE_PUTSCOM(PPM_PFCS_CLR, QUAD_ADDR_BASE, quad, BIT64(4) | BIT64(5) | BIT64(8));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, quad),
+ BIT64(4) | BIT64(5) | BIT64(8));
+#endif
// vdd_pfet_force_state = 11 (Force Von)
PK_TRACE("Power Off Core VDD");
- GPE_PUTSCOM(PPM_PFCS_OR, QUAD_ADDR_BASE, quad, BITS64(0, 2));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_OR, quad), BITS64(0, 2));
PK_TRACE("Poll for power gate sequencer state: 0x8 (FSM Idle)");
do
{
- GPE_GETSCOM(PPM_PFCS, QUAD_ADDR_BASE, quad, scom_data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS, quad), scom_data);
}
while(!(scom_data & BIT64(42)));
@@ -65,16 +77,16 @@ p9_hcd_cache_poweron(uint8_t quad)
do
{
- GPE_GETSCOM(PPM_PFCS, QUAD_ADDR_BASE, quad, scom_data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS, quad), scom_data);
}
while(scom_data & BIT64(46));
MARK_TRAP(SX_POWERON_PG_SEL)
-#endif
// vdd_pfet_force_state = 00 (Nop)
PK_TRACE("Turn Off Force Von");
- GPE_PUTSCOM(PPM_PFCS_CLR, QUAD_ADDR_BASE, quad, BITS64(0, 2));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, quad), BITS64(0, 2));
+#endif
return rc;
}
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c
index 9b1fb115..5cf05ee3 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_hcd_cache_startclocks.c
@@ -30,55 +30,77 @@ int
p9_hcd_cache_startclocks(uint8_t quad)
{
int rc = SGPE_STOP_SUCCESS;
- uint64_t data;
+ uint64_t data, loop;
// -------------------------------
// Prepare to cache startclocks
// -------------------------------
- /// @todo Drop the Pervasive THOLD, was in p8 code, where in p9?
-
PK_TRACE("Enable L3 EDRAM/LCO setup on both EXs");
- GPE_PUTSCOM(EQ_NET_CTRL0_WOR, QUAD_ADDR_BASE, quad, BIT64(23) | BIT64(24));
- // 0x0 -> 0x8 -> 0xC -> 0xE -> 0xF to turn on edram
- GPE_PUTSCOM(EQ_QPPM_QCCR_WOR, QUAD_ADDR_BASE, quad, BIT64(0) | BIT64(4));
- GPE_PUTSCOM(EQ_QPPM_QCCR_WOR, QUAD_ADDR_BASE, quad, BIT64(1) | BIT64(5));
- GPE_PUTSCOM(EQ_QPPM_QCCR_WOR, QUAD_ADDR_BASE, quad, BIT64(2) | BIT64(6));
- GPE_PUTSCOM(EQ_QPPM_QCCR_WOR, QUAD_ADDR_BASE, quad, BIT64(3) | BIT64(7));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, quad), BIT64(23) | BIT64(24));
- /// @todo get next step from perv, but not in p8 code, necessary?
- PK_TRACE("Drop Vital Fence via CPLT_CTRL1[3]");
- GPE_PUTSCOM(EQ_CPLT_CTRL1_CLEAR, QUAD_ADDR_BASE, quad, BIT64(3));
+ // 0x0 -> 0x8 -> 0xC -> 0xE -> 0xF to turn on edram
+ // stagger EDRAM turn-on per EX (not both at same time)
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(0));
+ PPE_WAIT_CORE_CYCLES(loop, 100);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(1));
+ PPE_WAIT_CORE_CYCLES(loop, 100);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(2));
+ PPE_WAIT_CORE_CYCLES(loop, 100);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(3));
+ PPE_WAIT_CORE_CYCLES(loop, 100);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(4));
+ PPE_WAIT_CORE_CYCLES(loop, 100);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(5));
+ PPE_WAIT_CORE_CYCLES(loop, 100);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(6));
+ PPE_WAIT_CORE_CYCLES(loop, 100);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, quad), BIT64(7));
+ PPE_WAIT_CORE_CYCLES(loop, 100);
+
+ PK_TRACE("Setup OPCG_ALIGN Register");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), data);
+ data = data & (BITS64(0, 4) & BITS64(12, 8) & BITS64(52, 12));
+ data = data | (BIT64(1) | BIT64(3) | BIT64(59));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_OPCG_ALIGN, quad), data);
+
+ PK_TRACE("Drop partial good fences via CPLT_CTRL1");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_CLEAR, quad),
+ 0xFFFF700000000000);
+
+ PK_TRACE("Drop vital fence via CPLT_CTRL1[4]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL1_CLEAR, quad), BIT64(3));
PK_TRACE("Reset abstclk & syncclk muxsel(io_clk_sel) via CPLT_CTRL0[0:1]");
- GPE_PUTSCOM(EQ_CPLT_CTRL0_CLEAR, QUAD_ADDR_BASE, quad, BIT64(0) | BIT64(1));
-
- PK_TRACE("Set abist_mode_dc for cache chiplet(cache recovery) via BIST[1]");
- GPE_GETSCOM(EQ_BIST, QUAD_ADDR_BASE, quad, data);
- data |= BIT64(1);
- GPE_PUTSCOM(EQ_BIST, QUAD_ADDR_BASE, quad, data);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(0) | BIT64(1));
/// @todo set fabric node/chip ID values(read from nest chiplet) still need?
- /// @todo force chiplet out of flush?
+
+ PK_TRACE("Set flushmode_inhibit via CPLT_CTRL0[2]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_OR, quad), BIT64(2));
+
+ PK_TRACE("Set force_align via CPLT_CTRL0[3]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_OR, quad), BIT64(3));
+
+ /// align chiplets
+
+ PK_TRACE("Clear force_align via CPLT_CTRL0[3]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(3));
// -------------------------------
// Start L3 Clock
// -------------------------------
- // @todo put this into dpll_setup?
- //PK_TRACE("Switch L3 glsmux to DPLL output");
- //GPE_PUTSCOM(EQ_PPM_CGCR_OR, BIT64(3)));
-
PK_TRACE("Set all bits to zero prior clock start via SCAN_REGION_TYPE");
- GPE_PUTSCOM(EQ_SCAN_REGION_TYPE, QUAD_ADDR_BASE, quad, 0);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, quad), 0);
PK_TRACE("Start clock(arrays+nsl clock region) via CLK_REGION");
data = 0x5F3C000000006000;
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, quad, data);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), data);
PK_TRACE("Start clock(sl+refresh clock region) via CLK_REGION");
data = 0x5F3C00000000E000;
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, quad, data);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, quad), data);
// Read Clock Status Register (Cache chiplet)
// check for bits 4:14 eq. zero, no tholds on
@@ -86,72 +108,39 @@ p9_hcd_cache_startclocks(uint8_t quad)
do
{
- GPE_GETSCOM(EQ_CLOCK_STAT_SL, QUAD_ADDR_BASE, quad, data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, quad), data);
}
- while(!(data & BITS64(4, 11)));
+ while((~data & (BITS64(4, 4) | BITS64(10, 4))) != (BITS64(4, 4) | BITS64(10, 4)));
PK_TRACE("L3 clock running now");
// @todo
// deskew_init()
-///// put everything below in l2_startclocks /////
- /*
- // -------------------------------
- // Start L2 Clock
- // -------------------------------
-
- PK_TRACE("Switch L2 glsmux to DPLL output");
- GPE_PUTSCOM(EQ_QPPM_QACCR_SCOM2, QUAD_ADDR_BASE, quad, BIT64(19));
- GPE_PUTSCOM(EQ_QPPM_QACCR_SCOM2, QUAD_ADDR_BASE, quad, BIT64(39));
-
- PK_TRACE("Raise L2 clock sync enable");
- GPE_PUTSCOM(EQ_QPPM_QACCR_SCOM2, QUAD_ADDR_BASE, quad, BIT64(13));
- GPE_PUTSCOM(EQ_QPPM_QACCR_SCOM2, QUAD_ADDR_BASE, quad, BIT64(33));
-
- PK_TRACE("Poll for clock sync done to raise on EX L2s");
- do {
- GPE_GETSCOM(EQ_QPPM_QACSR, QUAD_ADDR_BASE, quad, data);
- } while(((data & 0x3) != 3));
- PK_TRACE("EX L2s clock sync done");
-
- PK_TRACE("Start clock(arrays+nsl clock region) via CLK_REGION");
- data = 0x50C0000000006000;
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, quad, data);
-
- PK_TRACE("Start clock(sl+refresh clock region) via CLK_REGION");
- data = 0x50C000000000E000;
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, quad, data);
-
- // Read Clock Status Register (Cache chiplet)
- // check for bits 4:14 eq. zero, no tholds on
- PK_TRACE("Poll for L2 clock running");
- do {
- GPE_GETSCOM(EQ_CLOCK_STAT_SL, QUAD_ADDR_BASE, quad, data);
- } while(!(data & BITS64(4, 11)));
- PK_TRACE("L2 clock running now");
-
- // -------------------------------
- // Cleaning up
- // -------------------------------
-
- /// @todo Check the Global Checkstop FIR of dedicated EX chiplet
- /// @todo Ben's workaround at model e9025, move clear align/flush to end
-
- /// @todo what are the remaining fences to drop?
- PK_TRACE("Drop remaining fences via CPLT_CTRL1");
- GPE_PUTSCOM(EQ_CPLT_CTRL1_CLEAR, QUAD_ADDR_BASE, quad, 0xEFFF700000000000);
-
- PK_TRACE("Drop chiplet fence via NET_CTRL0[18]");
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BIT64(18));
-
- PK_TRACE("Drop fence to allow PCB operations to chiplet via NET_CTRL0[25]");
- GPE_PUTSCOM(EQ_NET_CTRL0_WAND, QUAD_ADDR_BASE, quad, ~BIT64(25));
-
- PK_TRACE("Clear force_align via CPLT_CTRL0[3]");
- GPE_PUTSCOM(EQ_CPLT_CTRL0_CLEAR, QUAD_ADDR_BASE, quad, BIT64(3));
-
- PK_TRACE("Clear flushmode_inhibit via CPLT_CTRL0[2]");
- GPE_PUTSCOM(EQ_CPLT_CTRL0_CLEAR, QUAD_ADDR_BASE, quad, BIT64(2));
- */
+
+ // -------------------------------
+ // Cleaning up
+ // -------------------------------
+
+ PK_TRACE("Drop chiplet fence via NET_CTRL0[18]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, quad), ~BIT64(18));
+
+ PK_TRACE("Drop fence to allow PCB operations to chiplet via NET_CTRL0[25]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WAND, quad), ~BIT64(25));
+
+ /// @todo Check the Global Checkstop FIR of dedicated EX chiplet
+
+ PK_TRACE("Clear flushmode_inhibit via CPLT_CTRL0[2]");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CPLT_CTRL0_CLEAR, quad), BIT64(2));
+
+ uint32_t ex = 2;
+
+ PK_TRACE("Drop refresh quiesce");
+ GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_DRAM_REF_REG, quad, ex), data);
+ data &= ~BIT64(7);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_DRAM_REF_REG, quad, ex), data);
+
+ PK_TRACE("Drop LCO Disable");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_LCO_DIS_REG, quad, ex), 0);
+
return rc;
}
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h
index 813a87b1..43373e80 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop.h
@@ -49,39 +49,42 @@
#include "p9_stop_common.h"
+#define EQ_OPCG_ALIGN 0x10030001
#define EQ_SCAN_REGION_TYPE 0x10030005
#define EQ_CLK_REGION 0x10030006
#define EQ_CLOCK_STAT_SL 0x10030008
+
+#define EQ_BIST 0x100F000B
#define EQ_NET_CTRL0_WAND 0x100F0041
#define EQ_NET_CTRL0_WOR 0x100F0042
-#define EQ_CPLT_CTRL0_CLEAR 0x10000020
+
#define EQ_CPLT_CTRL0_OR 0x10000010
-#define EQ_CPLT_CTRL1_CLEAR 0x10000021
+#define EQ_CPLT_CTRL0_CLEAR 0x10000020
#define EQ_CPLT_CTRL1_OR 0x10000011
-#define EQ_BIST 0x100F000B
-#define PM_PURGE_REG 0x10011C13
-#define DRAM_REF_REG 0x10011C0F
-#define EQ_QPPM_EDRAM_CTRL_CLEAR 0x100F01BE
-#define EQ_QPPM_EDRAM_CTRL_OR 0x100F01BF
+#define EQ_CPLT_CTRL1_CLEAR 0x10000021
+
#define EQ_QPPM_DPLL_CTRL_CLEAR 0x100F0153
#define EQ_QPPM_DPLL_CTRL_OR 0x100F0154
#define EQ_QPPM_DPLL_STAT 0x100F0155
-#define EQ_PPM_CGCR_CLEAR 0x100F0166
-#define EQ_PPM_CGCR_OR 0x100F0167
-#define EQ_QPPM_QCCR 0x100F01BD
-#define EQ_QPPM_QCCR_WCLEAR 0x100F01BE
-#define EQ_QPPM_QCCR_WOR 0x100F01BF
#define EQ_QPPM_QACCR_SCOM1 0x100F0161
#define EQ_QPPM_QACCR_SCOM2 0x100F0162
#define EQ_QPPM_QACSR 0x100F0163
+#define EQ_PPM_CGCR 0x100F0164
#define EQ_QPPM_EXCGCR 0x100F0165
#define EQ_QPPM_EXCGCR_CLR 0x100F0166
#define EQ_QPPM_EXCGCR_OR 0x100F0167
-#define EQ_PM_LCO_DIS_REG 0x0
-#define EQ_PM_L2_RCMD_DIS_REG 0x0
+#define EQ_QPPM_QCCR 0x100F01BD
+#define EQ_QPPM_QCCR_WCLEAR 0x100F01BE
+#define EQ_QPPM_QCCR_WOR 0x100F01BF
+
+#define EX_DRAM_REF_REG 0x1001180F
+#define EX_PM_PURGE_REG 0x10011813
+#define EX_PM_LCO_DIS_REG 0x10011816
+#define EX_PM_L2_RCMD_DIS_REG 0x10011818
#define SGPE_STOP_L2_CLOCK_REGION(ex) (ex << SHIFT64(9))
#define SGPE_STOP_L3_CLOCK_REGION(ex) (ex << SHIFT64(7))
+
/// Macro to update STOP History
#define SGPE_STOP_UPDATE_HISTORY(id,base,gated,trans,req_l,act_l,req_e,act_e) \
hist.fields.stop_gated = gated; \
@@ -90,7 +93,7 @@
hist.fields.act_stop_level = act_l; \
hist.fields.req_write_enable = req_e; \
hist.fields.act_write_enable = act_e; \
- GPE_PUTSCOM(PPM_SSHSRC, base, id, hist.value);
+ GPE_PUTSCOM_VAR(PPM_SSHSRC, base, id, 0, hist.value);
enum SGPE_STOP_RETURN_CODES
@@ -116,7 +119,7 @@ enum SGPE_STOP_IRQ_PAYLOAD_MASKS
enum SGPE_STOP_EVENT_LEVELS
{
SGPE_EX_BASE_LV = 8,
- SGPE_EQ_BASE_LV = 9
+ SGPE_EQ_BASE_LV = 11
};
enum SGPE_STOP_EVENT_FLAGS
@@ -147,11 +150,6 @@ typedef union sgpe_state
uint32_t status;
struct
{
- uint16_t target : 16;
- uint16_t actual : 16;
- } differ;
- struct
- {
uint8_t spare0 : 4;
uint8_t q_req : 4;
uint8_t x0req : 4;
@@ -168,18 +166,12 @@ typedef union sgpe_group
uint64_t vector[2];
struct
{
- uint32_t exit;
- uint32_t entry;
- uint32_t xq_in;
- uint32_t spare;
- } action;
- struct
- {
uint32_t c_out;
+ uint16_t x_out;
+ uint16_t q_out;
uint32_t c_in;
uint16_t x_in;
uint16_t q_in;
- uint32_t spare;
} member;
} sgpe_group_t;
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h
index c87123f5..6e86ea67 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_enter_marks.h
@@ -36,20 +36,22 @@ namespace SGPE_STOP_ENTRY_MARKS
enum SGPE_SE_MARKS
{
- SE_STOP_L2_CLKS = 0x0,
- SE_STOP_L2_GRID = 0x8,
- SE_STOP8_DONE = 0x10,
- SE_PURGE_L3 = 0x18,
- SE_PURGE_PB = 0x20,
- SE_WAIT_PGPE_SUSPEND = 0x28,
- SE_STOP_L3_CLKS = 0x30,
- SE_STOP9_DONE = 0x38,
- SE_PURGE_L3_ABORT = 0x40,
- SE_PURGE_L3_ABORT_DONE = 0x48,
- SE_POWER_OFF_CACHE = 0x50,
- SE_STOP11_DONE = 0x68,
- BEGINSCOPE_STOP_ENTRY = 0x1f00,
- ENDSCOPE_STOP_ENTRY = 0x1f08
+ SE_STOP_SUSPEND_PSTATE = 0x0,
+ SE_STOP_L2_CLKS = 0x8,
+ SE_STOP_L2_GRID = 0x10,
+ SE_STOP8_DONE = 0x18,
+ SE_PURGE_L3 = 0x20,
+ SE_PURGE_L3_ABORT = 0x28,
+ SE_PURGE_L3_ABORT_DONE = 0x30,
+ SE_PURGE_PB = 0x38,
+ SE_WAIT_PGPE_SUSPEND = 0x40,
+ SE_STOP_CACHE_CLKS = 0x48,
+ SE_STOP_CACHE_CLKS_DONE = 0x50,
+ SE_POWER_OFF_CACHE = 0x68,
+ SE_STOP11_DONE = 0xe0,
+ BEGINSCOPE_STOP_ENTRY = 0x1f08,
+ ENDSCOPE_STOP_ENTRY = 0x1f10,
+ STOP_TYPE2_HANDLER = 0x1f18
};
@@ -57,20 +59,22 @@ enum SGPE_SE_MARKS
const std::vector<SGPE_SE_MARKS> MARKS =
{
+ SE_STOP_SUSPEND_PSTATE,
SE_STOP_L2_CLKS,
SE_STOP_L2_GRID,
SE_STOP8_DONE,
SE_PURGE_L3,
- SE_PURGE_PB,
- SE_WAIT_PGPE_SUSPEND,
- SE_STOP_L3_CLKS,
- SE_STOP9_DONE,
SE_PURGE_L3_ABORT,
SE_PURGE_L3_ABORT_DONE,
+ SE_PURGE_PB,
+ SE_WAIT_PGPE_SUSPEND,
+ SE_STOP_CACHE_CLKS,
+ SE_STOP_CACHE_CLKS_DONE,
SE_POWER_OFF_CACHE,
SE_STOP11_DONE,
BEGINSCOPE_STOP_ENTRY,
- ENDSCOPE_STOP_ENTRY
+ ENDSCOPE_STOP_ENTRY,
+ STOP_TYPE2_HANDLER
};
}
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c
index 64115f4f..b3586d13 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_entry.c
@@ -36,160 +36,168 @@ p9_sgpe_stop_entry()
uint8_t qloop;
uint8_t cloop;
uint8_t climit;
- uint8_t qentry;
+ uint16_t qentry;
uint16_t xentry;
- uint64_t scom_data;
uint8_t entry_ongoing[2] = {0, 0};
+ uint8_t l3_purge_aborted = 0;
+ uint32_t loop;
+ uint64_t scom_data;
ppm_sshsrc_t hist;
//===================================================================
- MARK_TAG(BEGINSCOPE_STOP_ENTRY, G_sgpe_stop_record.group.member.c_in)
+ MARK_TAG(BEGINSCOPE_STOP_ENTRY, (G_sgpe_stop_record.group.member.q_in >> 10))
//===================================================================
- // ------------------------------------------------------------------------
- // EX STOP ENTRY
- // ------------------------------------------------------------------------
+ if (G_sgpe_stop_record.group.member.q_in)
+ MARK_TRAP(SE_STOP_SUSPEND_PSTATE)
- for(xentry = G_sgpe_stop_record.group.member.x_in, qloop = 0;
- xentry > 0;
- xentry = xentry << 2, qloop++)
- {
- // if this ex is not up to entry, skip
- if (!(ex = ((xentry & BITS16(0, 2)) >> SHIFT16(1))))
- {
- continue;
- }
-
- PK_TRACE("q[%d]exmask[%d] starts entry", qloop, ex);
-
- //-------------------------------------------------------------------------
- // STOP LEVEL 8
- //-------------------------------------------------------------------------
-
- // Update QSSR: stop_entry_ongoing
- out32(OCB_QSSR_OR, BIT32(qloop + 20));
+ //TODO: message pgpe to suspend Pstate
- // Update History for ongoing stop 8 entry
- cloop = (ex & FST_EX_IN_QUAD) ? 0 : CORES_PER_EX;
- climit = (ex & SND_EX_IN_QUAD) ? CORES_PER_QUAD : CORES_PER_EX;
-
- for(; cloop < climit; cloop++)
- {
- SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop),
- CORE_ADDR_BASE,
- STOP_CORE_IS_GATED,
- STOP_TRANS_ENTRY,
- STOP_LEVEL_8,
- STOP_LEVEL_8,
- STOP_REQ_DISABLE,
- STOP_ACT_DISABLE);
- }
-
- //========================
- MARK_TRAP(SE_STOP_L2_CLKS)
- //========================
-
- PK_TRACE("SE8.a");
- // Disable L2 Snoop(quiesce L2-L3 interface, what about NCU?)
- GPE_PUTSCOM(EQ_PM_L2_RCMD_DIS_REG, QUAD_ADDR_BASE, qloop, BIT64(0));
-
- PK_TRACE("SE8.b");
- // Set all bits to zero prior stop core clocks
- GPE_PUTSCOM(EQ_SCAN_REGION_TYPE, QUAD_ADDR_BASE, qloop, 0);
-
- PK_TRACE("SE8.c");
- // Stop L2 Clocks
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, qloop,
- (0x900000000000E000 | ((uint64_t)ex << SHIFT64(9))));
-
- PK_TRACE("SE8.d");
+ // ------------------------------------------------------------------------
+ // EX STOP ENTRY
+ // ------------------------------------------------------------------------
- // Poll for L2 clocks stopped
- do
+ for(xentry = G_sgpe_stop_record.group.member.x_in, qloop = 0;
+ xentry > 0;
+ xentry = xentry << 2, qloop++)
{
- GPE_GETSCOM(EQ_CLOCK_STAT_SL, QUAD_ADDR_BASE, qloop, scom_data);
- }
- while(((scom_data >> SHIFT64(9)) & ex) != ex);
-
- // MF: verify compiler generate single rlwmni
- // MF: delay may be needed for stage latch to propagate thold
-
- PK_TRACE("SE8: L2 Clock Stopped");
-
- //========================
- MARK_TRAP(SE_STOP_L2_GRID)
- //========================
+ // if this ex is not up to entry, skip
+ if (!(ex = ((xentry & BITS16(0, 2)) >> SHIFT16(1))))
+ {
+ continue;
+ }
+
+ PK_TRACE("q[%d]exmask[%d] starts entry", qloop, ex);
+
+ //-------------------------------------------------------------------------
+ // STOP LEVEL 8
+ //-------------------------------------------------------------------------
+
+ // Update QSSR: stop_entry_ongoing
+ out32(OCB_QSSR_OR, BIT32(qloop + 20));
+
+ // Update History for ongoing stop 8 entry
+ cloop = (ex & FST_EX_IN_QUAD) ? 0 : CORES_PER_EX;
+ climit = (ex & SND_EX_IN_QUAD) ? CORES_PER_QUAD : CORES_PER_EX;
+
+ for(; cloop < climit; cloop++)
+ {
+ SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop),
+ CORE_ADDR_BASE,
+ STOP_CORE_IS_GATED,
+ STOP_TRANS_ENTRY,
+ STOP_LEVEL_8,
+ STOP_LEVEL_8,
+ STOP_REQ_DISABLE,
+ STOP_ACT_DISABLE);
+ }
+
+ //========================
+ MARK_TRAP(SE_STOP_L2_CLKS)
+ //========================
+
+ PK_TRACE("SE8.a");
+ // Disable L2 Snoop(quiesce L2-L3 interface, what about NCU?)
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_L2_RCMD_DIS_REG, qloop, ex), BIT64(0));
+ PPE_WAIT_CORE_CYCLES(loop, 256)
+
+ PK_TRACE("SE8.b");
+ // Set all bits to zero prior stop core clocks
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, qloop), 0);
+
+ PK_TRACE("SE8.c");
+ // Stop L2 Clocks
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, qloop),
+ (0x900000000000E000 | ((uint64_t)ex << SHIFT64(9))));
+
+ PK_TRACE("SE8.d");
+
+ // Poll for L2 clocks stopped
+ do
+ {
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, qloop), scom_data);
+ }
+ while(((scom_data >> SHIFT64(9)) & ex) != ex);
+
+ // MF: verify compiler generate single rlwmni
+ // MF: delay may be needed for stage latch to propagate thold
+
+ PK_TRACE("SE8: L2 Clock Stopped");
+
+ //========================
+ MARK_TRAP(SE_STOP_L2_GRID)
+ //========================
+
+ PK_TRACE("SE8.e");
+ // Drop clock sync enable before switch to refclk
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_CLR, qloop),
+ (ex << SHIFT64(37)));
#if !EPM_P9_TUNING
- PK_TRACE("SE8.e");
- // Drop clock sync enable before switch to refclk
- GPE_PUTSCOM(EQ_QPPM_EXCGCR_CLR, QUAD_ADDR_BASE, qloop,
- (ex << SHIFT64(37)));
+ PK_TRACE("SE8.f");
- PK_TRACE("SE8.f");
-
- // Poll for clock sync done to drop
- do
- {
- GPE_GETSCOM(QPPM_QACSR, QUAD_ADDR_BASE, qloop, scom_data);
- }
- while((~scom_data >> SHIFT64(37)) & ex != ex);
+ // Poll for clock sync done to drop
+ do
+ {
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(QPPM_QACSR, qloop), scom_data);
+ }
+ while((~scom_data >> SHIFT64(37)) & ex != ex);
#endif
- PK_TRACE("SE8.g");
- // Switch glsmux to refclk to save clock grid power
- GPE_PUTSCOM(EQ_QPPM_EXCGCR_CLR, QUAD_ADDR_BASE, qloop,
- (ex << SHIFT64(35)));
-
- PK_TRACE("SE8.h");
-
- if (ex & FST_EX_IN_QUAD)
- {
- cloop = 0;
- G_sgpe_stop_record.state[qloop].detail.x0act = STOP_LEVEL_8;
- entry_ongoing[0] =
- G_sgpe_stop_record.state[qloop].detail.x0req == STOP_LEVEL_8 ?
- STOP_TRANS_COMPLETE : STOP_TRANS_ENTRY;
- }
- else
- {
- cloop = CORES_PER_EX;
- }
-
- if (ex & SND_EX_IN_QUAD)
- {
- climit = CORES_PER_QUAD;
- G_sgpe_stop_record.state[qloop].detail.x1act = STOP_LEVEL_8;
- entry_ongoing[1] =
- G_sgpe_stop_record.state[qloop].detail.x0req == STOP_LEVEL_8 ?
- STOP_TRANS_COMPLETE : STOP_TRANS_ENTRY;
- }
- else
- {
- climit = CORES_PER_EX;
- }
-
- for(; cloop < climit; cloop++)
- {
- SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop),
- CORE_ADDR_BASE,
- STOP_CORE_IS_GATED,
- entry_ongoing[cloop >> 1],
- STOP_LEVEL_8,
- STOP_LEVEL_8,
- STOP_REQ_DISABLE,
- STOP_ACT_ENABLE);
- }
-
- // Update QSSR: l2_stopped, drop stop_entry_ongoing
- out32(OCB_QSSR_OR, (ex << SHIFT32((qloop << 1) + 1)) | BIT32(qloop + 20));
-
- //=================================================
- MARK_TAG(SE_STOP8_DONE, ((ex << 6) | (1 << qloop)))
- //=================================================
-
- };
+ PK_TRACE("SE8.g");
+ // Switch glsmux to refclk to save clock grid power
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_EXCGCR_CLR, qloop),
+ (ex << SHIFT64(35)));
+
+ PK_TRACE("SE8.h");
+
+ if (ex & FST_EX_IN_QUAD)
+ {
+ cloop = 0;
+ G_sgpe_stop_record.state[qloop].detail.x0act = STOP_LEVEL_8;
+ entry_ongoing[0] =
+ G_sgpe_stop_record.state[qloop].detail.x0req == STOP_LEVEL_8 ?
+ STOP_TRANS_COMPLETE : STOP_TRANS_ENTRY;
+ }
+ else
+ {
+ cloop = CORES_PER_EX;
+ }
+
+ if (ex & SND_EX_IN_QUAD)
+ {
+ climit = CORES_PER_QUAD;
+ G_sgpe_stop_record.state[qloop].detail.x1act = STOP_LEVEL_8;
+ entry_ongoing[1] =
+ G_sgpe_stop_record.state[qloop].detail.x0req == STOP_LEVEL_8 ?
+ STOP_TRANS_COMPLETE : STOP_TRANS_ENTRY;
+ }
+ else
+ {
+ climit = CORES_PER_EX;
+ }
+
+ for(; cloop < climit; cloop++)
+ {
+ SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop),
+ CORE_ADDR_BASE,
+ STOP_CORE_IS_GATED,
+ entry_ongoing[cloop >> 1],
+ STOP_LEVEL_8,
+ STOP_LEVEL_8,
+ STOP_REQ_DISABLE,
+ STOP_ACT_ENABLE);
+ }
+
+ // Update QSSR: l2_stopped, drop stop_entry_ongoing
+ out32(OCB_QSSR_OR, (ex << SHIFT32((qloop << 1) + 1)) | BIT32(qloop + 20));
+
+ //=================================================
+ MARK_TAG(SE_STOP8_DONE, ((ex << 6) | (32 >> qloop)))
+ //=================================================
+
+ };
// ------------------------------------------------------------------------
// QUAD STOP ENTRY
@@ -199,6 +207,8 @@ p9_sgpe_stop_entry()
qentry > 0;
qentry = qentry << 1, qloop++)
{
+ PK_TRACE("q[%x] starts entry", qentry);
+
// if this quad is not up to entry, skip
if (!(qentry & BIT16(0)))
{
@@ -211,179 +221,220 @@ p9_sgpe_stop_entry()
out32(OCB_QSSR_OR, BIT32(qloop + 20));
// Update STOP History
- for(cloop = 0; cloop < CORES_PER_QUAD; cloop++)
- {
- SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop),
- CORE_ADDR_BASE,
- STOP_CORE_IS_GATED,
- STOP_TRANS_ENTRY,
- G_sgpe_stop_record.state[qloop].detail.q_req,
- STOP_LEVEL_9,
- STOP_REQ_ENABLE,
- STOP_ACT_DISABLE);
- }
+ SGPE_STOP_UPDATE_HISTORY(qloop,
+ QUAD_ADDR_BASE,
+ STOP_CORE_IS_GATED,
+ STOP_TRANS_ENTRY,
+ G_sgpe_stop_record.state[qloop].detail.q_req,
+ STOP_LEVEL_11,
+ STOP_REQ_ENABLE,
+ STOP_ACT_DISABLE);
// ------------------------------------------------------------------------
- // STOP LEVEL 9
+ // STOP LEVEL 11.A
//-------------------------------------------------------------------------
//=================================
- MARK_TAG(SE_PURGE_L3, (1 << qloop))
+ MARK_TAG(SE_PURGE_L3, (32 >> qloop))
//=================================
- // Assert chtm purges
- GPE_PUTSCOM(CME_SCOM_SICR_OR, QUAD_ADDR_BASE | CME_ADDR_OFFSET_EX0,
- qloop, BIT64(24) | BIT64(25));
- GPE_PUTSCOM(CME_SCOM_SICR_OR, QUAD_ADDR_BASE | CME_ADDR_OFFSET_EX1,
- qloop, BIT64(24) | BIT64(25));
+ ex = 2;
- PK_TRACE("SE9.a");
+ PK_TRACE("SE11.a");
// Disable LCO prior to purge
- GPE_PUTSCOM(EQ_PM_LCO_DIS_REG, QUAD_ADDR_BASE, qloop, BIT64(0));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_LCO_DIS_REG, qloop, ex), BIT64(0));
- PK_TRACE("SE9.b");
+#if !SKIP_L3_PURGE
+ PK_TRACE("SE11.b");
// Assert Purge L3
- GPE_PUTSCOM(PM_PURGE_REG, QUAD_ADDR_BASE, qloop, BIT64(0));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, ex), BIT64(0));
- PK_TRACE("SE9.b");
+ // PK_TRACE("SE11.c");
+ // No need: Assert chtm purges
+ // todo: stop debug trace, attribute may be needed
+ //GPE_PUTSCOM(CME_SCOM_SICR_OR, QUAD_ADDR_BASE|CME_ADDR_OFFSET_EX0,
+ // qloop, BIT64(24)|BIT64(25));
+ //GPE_PUTSCOM(CME_SCOM_SICR_OR, QUAD_ADDR_BASE|CME_ADDR_OFFSET_EX1,
+ // qloop, BIT64(24)|BIT64(25));
+
+ PK_TRACE("SE11.d");
// Poll for purge done on the same request bit thus no need to deassert
do
{
- GPE_GETSCOM(PM_PURGE_REG, QUAD_ADDR_BASE, qloop, scom_data);
+#if !SKIP_L3_PURGE_ABORT
+
+ if (in32(OCB_OISR1) & BIT32(15))
+ {
+ if (in32(OCB_OPITNPRA(2)) & (BITS32((qloop << 2), 4)))
+ {
+ for(cloop = 0; cloop < CORES_PER_QUAD; cloop++)
+ {
+ if (in32(OCB_OPIT2CN(((qloop << 2) + cloop))) &
+ TYPE2_PAYLOAD_STOP_EVENT)
+ {
+ // Assert Purge L3 Abort
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG,
+ qloop, ex), BIT64(2));
+
+ // Poll for Abort Done
+ do
+ {
+ GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG,
+ qloop, ex), scom_data);
+ }
+ while(scom_data & (BIT64(0) | BIT64(2)));
+
+ // Deassert LCO Disable
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_PM_LCO_DIS_REG,
+ qloop, ex), 0);
+ // Notify PGPE to resume
+ l3_purge_aborted = 1;
+ break;
+ }
+ }
+ }
+ }
+
+#endif
+ GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_PM_PURGE_REG, qloop, ex), scom_data);
}
while(scom_data & BIT64(0));
+ if (l3_purge_aborted)
+ {
+ continue;
+ }
+
+#endif
+
//====================
MARK_TRAP(SE_PURGE_PB)
//====================
- PK_TRACE("SE9.b");
- // Purge PowerBus
- GPE_PUTSCOM(EQ_QPPM_QCCR_WOR, QUAD_ADDR_BASE, qloop, BIT64(30));
+#if EPM_P9_TUNING
+ // PK_TRACE("SE11.e");
+ // No need: Poll for chtm purge done
+ // do {
+ // GPE_GETSCOM(CME_SCOM_EISR, QUAD_ADDR_BASE|CME_ADDR_OFFSET_EX0,
+ // qloop, scom_data);
+ // } while((scom_data & BITS64(24,2)) != BITS64(22,2));
+ // do {
+ // GPE_GETSCOM(CME_SCOM_EISR, QUAD_ADDR_BASE|CME_ADDR_OFFSET_EX1,
+ // qloop, scom_data);
+ // } while((scom_data & BITS64(24,2)) != BITS64(22,2));
+ // cme scom eisr is read-only, cannot clear the eisr here, clear in cme
+#endif
+
+ // PK_TRACE("SE11.f");
+ // No need: Deassert chtm purges
+ //GPE_PUTSCOM(CME_SCOM_SICR_CLR, QUAD_ADDR_BASE|CME_ADDR_OFFSET_EX0,
+ // qloop, BIT64(24)|BIT64(25));
+ //GPE_PUTSCOM(CME_SCOM_SICR_CLR, QUAD_ADDR_BASE|CME_ADDR_OFFSET_EX1,
+ // qloop, BIT64(24)|BIT64(25));
+
+ PK_TRACE("SE11.g");
+ // Assert PowerBus purge
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WOR, qloop), BIT64(30));
- PK_TRACE("SE9.b");
+ PK_TRACE("SE11.h");
- // Poll purge PowerBus done
+ // Poll PowerBus purge done
do
{
- GPE_GETSCOM(EQ_QPPM_QCCR, QUAD_ADDR_BASE, qloop, scom_data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR, qloop), scom_data);
}
while(!(scom_data & BIT64(31)));
+ PK_TRACE("SE11.i");
+ // Deassert PowerBus purge
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(30));
+
//==========================================
- MARK_TAG(SE_WAIT_PGPE_SUSPEND, (1 << qloop))
+ MARK_TAG(SE_WAIT_PGPE_SUSPEND, (32 >> qloop))
//==========================================
- // Poll PGPE Suspend Ack
+ // TODO: Poll PGPE Suspend Ack
//=====================================
- MARK_TAG(SE_STOP_L3_CLKS, (1 << qloop))
+ MARK_TAG(SE_STOP_CACHE_CLKS, (32 >> qloop))
//=====================================
- PK_TRACE("SE9.d");
+ PK_TRACE("SE11.j");
// Assert refresh quiesce prior to L3 (refresh domain) stop clk
// Edram quiesce is asserted by hardware when l3 thold is asserted in cc
- GPE_PUTSCOM(DRAM_REF_REG, qloop, QUAD_ADDR_BASE, BIT64(7));
+ GPE_GETSCOM(GPE_SCOM_ADDR_EX(EX_DRAM_REF_REG, qloop, ex), scom_data);
+ scom_data |= BIT64(7);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_EX(EX_DRAM_REF_REG, qloop, ex), scom_data);
+
+ // todo: check NCU_SATUS_REG[0:3] for all zeros
- PK_TRACE("SE9.c");
+ PK_TRACE("SE11.k");
// Raise Cache Logical fence
- GPE_PUTSCOM(EQ_NET_CTRL0_WOR, QUAD_ADDR_BASE, qloop, BIT64(18));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, qloop), BIT64(18));
// clock off cache chiplet
- PK_TRACE("SE9.e");
+ PK_TRACE("SE11.l");
// Set all bits to zero prior stop core clocks
- GPE_PUTSCOM(EQ_SCAN_REGION_TYPE, QUAD_ADDR_BASE, qloop, 0);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_SCAN_REGION_TYPE, qloop), 0);
- PK_TRACE("SE9.f");
+ PK_TRACE("SE11.m");
// Stop Cache Clocks
- GPE_PUTSCOM(EQ_CLK_REGION, QUAD_ADDR_BASE, qloop, 0x9FFC00000000E000);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLK_REGION, qloop), 0x9F3E00000000E000);
- PK_TRACE("SE9.g");
+ PK_TRACE("SE11.n");
// Poll for Cache clocks stopped
do
{
- GPE_GETSCOM(EQ_CLOCK_STAT_SL, QUAD_ADDR_BASE, qloop, scom_data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(EQ_CLOCK_STAT_SL, qloop), scom_data);
}
while((scom_data & BITS64(4, 10)) != BITS64(4, 10));
// MF: verify compiler generate single rlwmni
// MF: delay may be needed for stage latch to propagate thold
- PK_TRACE("SE9: Cache Clock Stopped");
+ PK_TRACE("SE11: Cache Clock Stopped");
- PK_TRACE("SE9.h");
+ PK_TRACE("SE11.o");
// Switch glsmux to refclk to save clock grid power
- GPE_PUTSCOM(PPM_CGCR_CLR, QUAD_ADDR_BASE, qloop, BIT64(3));
-
- PK_TRACE("SE9.i");
- // Update Stop History
- G_sgpe_stop_record.state[qloop].detail.q_act = STOP_LEVEL_9;
- entry_ongoing[0] =
- G_sgpe_stop_record.state[qloop].detail.q_req == STOP_LEVEL_9 ?
- STOP_TRANS_COMPLETE : STOP_TRANS_ENTRY;
- /*
- for(cloop=0;cloop<CORES_PER_QUAD;cloop++) {
- SGPE_STOP_UPDATE_HISTORY(((qloop<<2)+cloop),
- CORE_ADDR_BASE,
- STOP_CORE_IS_GATED,
- entry_ongoing[0],
- STOP_LEVEL_9,
- STOP_LEVEL_9,
- STOP_REQ_DISABLE,
- STOP_ACT_ENABLE);
- }*/
- SGPE_STOP_UPDATE_HISTORY(qloop,
- QUAD_ADDR_BASE,
- STOP_CORE_IS_GATED,
- entry_ongoing[0],
- STOP_LEVEL_9,
- STOP_LEVEL_9,
- STOP_REQ_DISABLE,
- STOP_ACT_ENABLE);
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_PPM_CGCR, qloop), BIT64(3));
// Update QSSR: quad_stopped
out32(OCB_QSSR_OR, BIT32(qloop + 14));
//===================================
- MARK_TAG(SE_STOP9_DONE, (1 << qloop))
+ MARK_TAG(SE_STOP_CACHE_CLKS_DONE, (32 >> qloop))
//===================================
- if (!entry_ongoing[0])
- {
- // Update QSSR: drop stop_entry_ongoing
- out32(OCB_QSSR_CLR, BIT32(qloop + 20));
- continue;
- }
-
//-------------------------------------------------------------------------
- // STOP LEVEL 11
+ // STOP LEVEL 11.B
//-------------------------------------------------------------------------
//========================================
- MARK_TAG(SE_POWER_OFF_CACHE, (1 << qloop))
+ MARK_TAG(SE_POWER_OFF_CACHE, (32 >> qloop))
//========================================
// Assert Cache Electrical Fence
- PK_TRACE("SE11.a");
- GPE_PUTSCOM(EQ_NET_CTRL0_WOR, QUAD_ADDR_BASE, qloop, BIT64(26));
+ PK_TRACE("SE11.q");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_NET_CTRL0_WOR, qloop), BIT64(26));
+#if !STOP_PRIME
// L3 edram shutdown
- PK_TRACE("SE11.b");
- GPE_PUTSCOM(EQ_QPPM_EDRAM_CTRL_CLEAR, QUAD_ADDR_BASE, qloop,
- BIT64(3) | BIT64(7));
- GPE_PUTSCOM(EQ_QPPM_EDRAM_CTRL_CLEAR, QUAD_ADDR_BASE, qloop,
- BIT64(2) | BIT64(6));
- GPE_PUTSCOM(EQ_QPPM_EDRAM_CTRL_CLEAR, QUAD_ADDR_BASE, qloop,
- BIT64(1) | BIT64(5));
- GPE_PUTSCOM(EQ_QPPM_EDRAM_CTRL_CLEAR, QUAD_ADDR_BASE, qloop,
- BIT64(0) | BIT64(4));
+ PK_TRACE("SE11.r");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(7));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(6));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(5));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(4));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(3));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(2));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(1));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(EQ_QPPM_QCCR_WCLEAR, qloop), BIT64(0));
// Make sure we are not forcing PFET for VDD or VCS off
// vdd_pfet_force_state == 00 (Nop)
// vcs_pfet_force_state == 00 (Nop)
- PK_TRACE("SE11.c");
- GPE_GETSCOM(PPM_PFCS, QUAD_ADDR_BASE, qloop, scom_data);
+ PK_TRACE("SE11.s");
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS, qloop), scom_data);
if (scom_data & BITS64(0, 4))
{
@@ -394,31 +445,31 @@ p9_sgpe_stop_entry()
// vdd_pfet_val/sel_override = 0 (disbaled)
// vcs_pfet_val/sel_override = 0 (disbaled)
// vdd_pfet_regulation_finger_en = 0 (controled by FSM)
- PK_TRACE("SE11.d");
- GPE_PUTSCOM(PPM_PFCS_CLR, QUAD_ADDR_BASE, qloop, BITS64(4, 4) | BIT64(8));
+ PK_TRACE("SE11.t");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, qloop), BITS64(4, 4) | BIT64(8));
// Power Off Core VDD
// vdd_pfet_force_state = 01 (Force Voff)
// vcs_pfet_force_state = 01 (Force Voff)
- PK_TRACE("SE11.e");
- GPE_PUTSCOM(PPM_PFCS_OR, QUAD_ADDR_BASE, qloop, BIT64(1) | BIT64(3));
+ PK_TRACE("SE11.u");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_OR, qloop), BIT64(1) | BIT64(3));
// Poll for power gate sequencer state: 0x8 (FSM Idle)
- PK_TRACE("SE11.f");
+ PK_TRACE("SE11.v");
do
{
- GPE_GETSCOM(PPM_PFCS, QUAD_ADDR_BASE, qloop, scom_data);
+ GPE_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS, qloop), scom_data);
}
while(!(scom_data & (BIT64(42) | BIT64(50))));
#if !EPM_P9_TUNING
// Optional: Poll for vdd_pg_sel/vcs_pg_sel being: 0x8
- PK_TRACE("SE11.g");
+ PK_TRACE("SE11.w");
do
{
- CME_GETSCOM(PPM_PFCS, QUAD_ADDR_BASE, qloop, scom_data);
+ CME_GETSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS, qloop), scom_data);
}
while(!(scom_data & BIT64(46) | BIT64(54)));
@@ -426,10 +477,11 @@ p9_sgpe_stop_entry()
// Turn Off Force Voff
// vdd_pfet_force_state = 00 (Nop)
- PK_TRACE("SE11.h");
- GPE_PUTSCOM(PPM_PFCS_CLR, QUAD_ADDR_BASE, qloop, BITS64(0, 4));
+ PK_TRACE("SE11.x");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_QUAD(PPM_PFCS_CLR, qloop), BITS64(0, 4));
+#endif
- PK_TRACE("SE11.i");
+ PK_TRACE("SE11.y");
G_sgpe_stop_record.state[qloop].detail.q_act = STOP_LEVEL_11;
for(cloop = 0; cloop < CORES_PER_QUAD; cloop++)
@@ -457,13 +509,12 @@ p9_sgpe_stop_entry()
out32(OCB_QSSR_CLR, BIT32(qloop + 20));
//====================================
- MARK_TAG(SE_STOP11_DONE, (1 << qloop))
+ MARK_TAG(SE_STOP11_DONE, (32 >> qloop))
//====================================
- };
+ }
// Enable Type2 Interrupt
out32(OCB_OIMR1_CLR, BIT32(15));
-
//============================
MARK_TRAP(ENDSCOPE_STOP_ENTRY)
//============================
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c
index f4745d6e..aa6e200a 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit.c
@@ -35,23 +35,18 @@ p9_sgpe_stop_exit()
uint8_t ex;
uint8_t cloop;
uint8_t qloop;
- uint8_t qexit;
uint32_t cexit;
//uint64_t scom_data;
ppm_sshsrc_t hist;
- MARK_TAG(BEGINSCOPE_STOP_EXIT, 0)
+ MARK_TAG(BEGINSCOPE_STOP_EXIT, (G_sgpe_stop_record.group.member.q_out >> 10))
- //-------------------------------------------------------------------------
- // STOP LEVEL 8
- //-------------------------------------------------------------------------
-
- for(cexit = G_sgpe_stop_record.group.member.c_out, qloop = 0, ex = 0, qexit = 0;
+ for(cexit = G_sgpe_stop_record.group.member.c_out, qloop = 0, ex = 0;
cexit > 0;
- cexit = cexit << 4, qloop++, ex = 0, qexit = 0)
+ cexit = cexit << 4, qloop++, ex = 0)
{
- ex |= (cexit & BITS32(0, 2)) ? 0 : FST_EX_IN_QUAD;
- ex |= (cexit & BITS32(2, 2)) ? 0 : SND_EX_IN_QUAD;
+ ex |= ((cexit & BITS32(0, 2)) ? FST_EX_IN_QUAD : 0);
+ ex |= ((cexit & BITS32(2, 2)) ? SND_EX_IN_QUAD : 0);
if(!ex)
{
@@ -60,9 +55,17 @@ p9_sgpe_stop_exit()
if(G_sgpe_stop_record.state[qloop].detail.q_act >= STOP_LEVEL_11)
{
- qexit = 1;
+ SGPE_STOP_UPDATE_HISTORY(qloop,
+ QUAD_ADDR_BASE,
+ STOP_CORE_IS_GATED,
+ STOP_TRANS_EXIT,
+ STOP_LEVEL_0,
+ STOP_LEVEL_0,
+ STOP_REQ_DISABLE,
+ STOP_ACT_DISABLE);
MARK_TRAP(SX_LV11_WAKEUP_START)
+#if !STOP_PRIME
PK_TRACE("Cache Poweron");
p9_hcd_cache_poweron(qloop);
MARK_TRAP(SX_POWERON_END)
@@ -94,12 +97,7 @@ p9_sgpe_stop_exit()
PK_TRACE("Cache Initf");
p9_hcd_cache_initf(qloop);
MARK_TRAP(SX_INITF_END)
- }
-
- if(G_sgpe_stop_record.state[qloop].detail.q_act >= STOP_LEVEL_9)
- {
- qexit = 1;
- MARK_TRAP(SX_LV9_WAKEUP_START)
+#endif
PK_TRACE("Cache Startclocks");
p9_hcd_cache_startclocks(qloop);
@@ -108,9 +106,28 @@ p9_sgpe_stop_exit()
G_sgpe_stop_record.state[qloop].detail.q_act = 0;
}
- if(G_sgpe_stop_record.state[qloop].detail.x0act >= STOP_LEVEL_8 ||
- G_sgpe_stop_record.state[qloop].detail.x1act >= STOP_LEVEL_8)
+ if((G_sgpe_stop_record.state[qloop].detail.x0act >= STOP_LEVEL_8 &&
+ ex == FST_EX_IN_QUAD) ||
+ (G_sgpe_stop_record.state[qloop].detail.x1act >= STOP_LEVEL_8 &&
+ ex == SND_EX_IN_QUAD) )
{
+ for(cloop = 0; cloop < CORES_PER_QUAD; cloop++)
+ {
+ if(!(cexit & BIT32(cloop)))
+ {
+ continue;
+ }
+
+ SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop),
+ CORE_ADDR_BASE,
+ STOP_CORE_IS_GATED,
+ STOP_TRANS_EXIT,
+ STOP_LEVEL_0,
+ STOP_LEVEL_0,
+ STOP_REQ_DISABLE,
+ STOP_ACT_DISABLE);
+ }
+
MARK_TRAP(SX_LV8_WAKEUP_START)
PK_TRACE("Cache L2 Startclocks");
@@ -133,6 +150,7 @@ p9_sgpe_stop_exit()
{
MARK_TRAP(SX_LV11_WAKEUP_CONTINUE)
+#if !STOP_PRIME
PK_TRACE("Cache Scom Init");
p9_hcd_cache_scominit(qloop);
MARK_TRAP(SX_SCOMINIT_END)
@@ -152,18 +170,7 @@ p9_sgpe_stop_exit()
PK_TRACE("Cache OCC Runtime Scom");
p9_hcd_cache_occ_runtime_scom(qloop);
MARK_TRAP(SX_OCC_RUNTIME_SCOM_END)
- }
-
- if (qexit)
- {
- SGPE_STOP_UPDATE_HISTORY(qloop,
- QUAD_ADDR_BASE,
- STOP_CORE_IS_GATED,
- STOP_TRANS_EXIT,
- STOP_LEVEL_0,
- STOP_LEVEL_0,
- STOP_REQ_DISABLE,
- STOP_ACT_DISABLE);
+#endif
}
for(cloop = 0; cloop < CORES_PER_QUAD; cloop++)
@@ -173,28 +180,24 @@ p9_sgpe_stop_exit()
continue;
}
- SGPE_STOP_UPDATE_HISTORY(((qloop << 2) + cloop),
- CORE_ADDR_BASE,
- STOP_CORE_IS_GATED,
- STOP_TRANS_EXIT,
- STOP_LEVEL_0,
- STOP_LEVEL_0,
- STOP_REQ_DISABLE,
- STOP_ACT_DISABLE);
// reset clevel to 0 if core is going to wake up
G_sgpe_stop_record.level[qloop].qlevel &= ~BITS16((cloop << 2), 4);
- PK_TRACE("Doorbell1 the CME");
- GPE_PUTSCOM(CPPM_CMEDB1_OR, CORE_ADDR_BASE,
- ((qloop << 2) + cloop), BIT64(7));
+ /*do {
+ GPE_GETSCOM(CME_SCOM_FLAGS, QUAD_ADDR_BASE|CME_ADDR_OFFSET_EX0,
+ ((qloop<<2)+cloop), scom_data);
+ } while(!(scom_data & BIT64(0)));*/
// Change PPM Wakeup to CME
- GPE_PUTSCOM(CPPM_CPMMR_CLR, CORE_ADDR_BASE,
- ((qloop << 2) + cloop), BIT64(13));
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CPMMR_CLR, ((qloop << 2) + cloop)),
+ BIT64(13));
+ PK_TRACE("Doorbell1 the CME");
+ GPE_PUTSCOM(GPE_SCOM_ADDR_CORE(CPPM_CMEDB1_OR, ((qloop << 2) + cloop)),
+ BIT64(7));
}
}
// Enable Type2 Interrupt
out32(OCB_OIMR1_CLR, BIT32(15));
- MARK_TAG(BEGINSCOPE_STOP_EXIT, 0)
+ MARK_TRAP(ENDSCOPE_STOP_EXIT)
return SGPE_STOP_SUCCESS;
}
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h
index db97e52b..beb48b20 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_exit_marks.h
@@ -44,27 +44,29 @@ enum SGPE_SX_MARKS
SX_CHIPLET_RESET_SCAN0 = 0x28,
SX_CHIPLET_RESET_END = 0x30,
SX_GPTR_TIME_INITF_END = 0x38,
- SX_DPLL_SETUP_END = 0x40,
- SX_CHIPLET_INIT_SCAN0 = 0x48,
- SX_CHIPLET_INIT_END = 0x50,
- SX_REPAIR_INITF_END = 0x68,
- SX_ARRAYINIT_SUBMODULE = 0xe0,
- SX_ARRAYINIT_SCAN0 = 0xe8,
- SX_ARRAYINIT_END = 0xf0,
- SX_INITF_END = 0xf8,
- SX_LV9_WAKEUP_START = 0x100,
- SX_STARTCLOCKS_DONE = 0x108,
- SX_STARTCLOCKS_END = 0x110,
- SX_LV8_WAKEUP_START = 0x118,
- SX_L2_STARTCLOCKS_END = 0x120,
- SX_LV11_WAKEUP_CONTINUE = 0x128,
- SX_SCOMINIT_END = 0x130,
- SX_SCOMCUST_END = 0x138,
- SX_CME_BOOT_END = 0x140,
- SX_RAS_RUNTIME_SCOM_END = 0x148,
- SX_OCC_RUNTIME_SCOM_END = 0x150,
- BEGINSCOPE_STOP_EXIT = 0x1f00,
- ENDSCOPE_STOP_EXIT = 0x1f08
+ SX_DPLL_START_DONE = 0x40,
+ SX_DPLL_SETUP_END = 0x48,
+ SX_CHIPLET_INIT_SCAN0 = 0x50,
+ SX_CHIPLET_INIT_END = 0x68,
+ SX_REPAIR_INITF_END = 0xe0,
+ SX_ARRAYINIT_SUBMODULE = 0xe8,
+ SX_ARRAYINIT_SCAN0 = 0xf0,
+ SX_ARRAYINIT_END = 0xf8,
+ SX_INITF_END = 0x100,
+ SX_LV9_WAKEUP_START = 0x108,
+ SX_STARTCLOCKS_DONE = 0x110,
+ SX_STARTCLOCKS_END = 0x118,
+ SX_LV8_WAKEUP_START = 0x120,
+ SX_L2_STARTCLOCKS_DONE = 0x128,
+ SX_L2_STARTCLOCKS_END = 0x130,
+ SX_LV11_WAKEUP_CONTINUE = 0x138,
+ SX_SCOMINIT_END = 0x140,
+ SX_SCOMCUST_END = 0x148,
+ SX_CME_BOOT_END = 0x150,
+ SX_RAS_RUNTIME_SCOM_END = 0x168,
+ SX_OCC_RUNTIME_SCOM_END = 0x1e0,
+ BEGINSCOPE_STOP_EXIT = 0x1f20,
+ ENDSCOPE_STOP_EXIT = 0x1f28
};
@@ -80,6 +82,7 @@ const std::vector<SGPE_SX_MARKS> MARKS =
SX_CHIPLET_RESET_SCAN0,
SX_CHIPLET_RESET_END,
SX_GPTR_TIME_INITF_END,
+ SX_DPLL_START_DONE,
SX_DPLL_SETUP_END,
SX_CHIPLET_INIT_SCAN0,
SX_CHIPLET_INIT_END,
@@ -92,6 +95,7 @@ const std::vector<SGPE_SX_MARKS> MARKS =
SX_STARTCLOCKS_DONE,
SX_STARTCLOCKS_END,
SX_LV8_WAKEUP_START,
+ SX_L2_STARTCLOCKS_DONE,
SX_L2_STARTCLOCKS_END,
SX_LV11_WAKEUP_CONTINUE,
SX_SCOMINIT_END,
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
index ff616734..0cdb575c 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/p9_sgpe_stop_irq_handlers.c
@@ -24,6 +24,7 @@
/* IBM_PROLOG_END_TAG */
#include "p9_sgpe_stop.h"
+#include "p9_sgpe_stop_enter_marks.h"
SgpeStopRecord G_sgpe_stop_record;
@@ -58,6 +59,7 @@ p9_sgpe_stop_pig_type2_handler(void* arg, PkIrqId irq)
uint32_t pending;
uint32_t payload;
+ MARK_TRAP(STOP_TYPE2_HANDLER)
// Disable Type2 Interrupt
out32(OCB_OIMR1_OR, BIT32(15));
// Cleart Type2 Interrupt
@@ -104,6 +106,10 @@ p9_sgpe_stop_pig_type2_handler(void* arg, PkIrqId irq)
event |= SGPE_EXIT_FLAG;
G_sgpe_stop_record.group.member.c_out |=
BIT32(((qloop << 2) + cloop));
+ G_sgpe_stop_record.group.member.x_out |=
+ BIT16(((qloop << 1) + (cloop >> 1)));
+ G_sgpe_stop_record.group.member.q_out |=
+ BIT16(qloop);
// otherwise it is entry request with stop level in payload
}
else
@@ -167,19 +173,22 @@ p9_sgpe_stop_pig_type2_handler(void* arg, PkIrqId irq)
PK_TRACE("q[%d]st: %x", qloop, G_sgpe_stop_record.state[qloop].status);
}
- PK_TRACE("Entry: %x, Exit: %x, Q_Entry: %x, EX_Entry: %x",
- G_sgpe_stop_record.group.action.entry,
- G_sgpe_stop_record.group.action.exit,
- G_sgpe_stop_record.group.member.q_in,
- G_sgpe_stop_record.group.member.x_in);
+ PK_TRACE("Entry: C%x, X%x, Q%x",
+ G_sgpe_stop_record.group.member.c_in,
+ G_sgpe_stop_record.group.member.x_in,
+ G_sgpe_stop_record.group.member.q_in);
+ PK_TRACE("Exit: C%x, X%x, Q%x",
+ G_sgpe_stop_record.group.member.c_out,
+ G_sgpe_stop_record.group.member.x_out,
+ G_sgpe_stop_record.group.member.q_out);
- if (G_sgpe_stop_record.group.action.entry)
+ if (G_sgpe_stop_record.group.member.c_in)
{
PK_TRACE("unblock entry");
pk_semaphore_post(&(G_sgpe_stop_record.sem[0]));
}
- if (G_sgpe_stop_record.group.action.exit)
+ if (G_sgpe_stop_record.group.member.c_out)
{
PK_TRACE("unblock exit");
pk_semaphore_post(&(G_sgpe_stop_record.sem[1]));
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h
index bc3a0be7..178185bb 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/pk_app_cfg.h
@@ -34,16 +34,17 @@
/// \brief Application specific overrides go here.
///
-//#include "occ_app_cfg.h"
-//GPE3 is the SGPE and is the route owner for now.
-// (Change this to #4 for the 405 when we pull that in.)
-#define OCCHW_IRQ_ROUTE_OWNER 3
+#define STOP_PRIME 0
+#define SKIP_L3_PURGE 0
+#define SKIP_L3_PURGE_ABORT 0
+
+// --------------------
-//#include "global_app_cfg.h"
#define USE_SIMICS_IO 0
#define EPM_P9_TUNING 1
#define DEV_DEBUG 1
+// --------------------
// This application will use the external timebase register
// (comment this line out to use the decrementer as timebase)
@@ -61,8 +62,11 @@
#define PPE_TIMEBASE_HZ 600000000
#endif /* APPCFG_USE_EXT_TIMEBASE */
+// --------------------
-#define LAB_MODE 1
+// GPE3 is the SGPE and is the route owner for now.
+// (Change this to #4 for the 405 when we pull that in.)
+#define OCCHW_IRQ_ROUTE_OWNER 3
/// The Instance ID of the OCC processor that this application is intended to run on
///// 0-3 -> GPE, 4 -> 405
diff --git a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk
index 57a0aed5..190e0540 100644
--- a/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk
+++ b/import/chips/p9/procedures/ppe_closed/sgpe/stop_gpe/topfiles.mk
@@ -41,8 +41,7 @@ TOP-C-SOURCES = p9_sgpe_main.c \
p9_hcd_cache_scominit.c \
p9_hcd_cache_scomcust.c \
p9_hcd_cache_occ_runtime_scom.c \
- p9_hcd_cache_ras_runtime_scom.c \
- pk_app_irq_table.c
+ p9_hcd_cache_ras_runtime_scom.c
TOP-S-SOURCES =
TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-S-SOURCES:.S=.o)
OpenPOWER on IntegriCloud