diff options
author | Yue Du <daviddu@us.ibm.com> | 2016-01-13 17:11:37 -0600 |
---|---|---|
committer | Joshua Hunsberger <jahunsbe@us.ibm.com> | 2017-10-23 15:56:59 -0500 |
commit | 35cebfb7ba9d37a3fc65665d4ea9c0196afdffd7 (patch) | |
tree | 293c0aa38b4f3b71ace1819ccab17b045a243f20 /import/chips/p9 | |
parent | d0a5117fe30d2e231e9cf96e8c1f0a63c2348aae (diff) | |
download | talos-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')
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) |