soc/intel/cmn/block/cse: Support sending EOP from payload

Skip sending EOP from coreboot when payload is sending it.

BUG=b:279184514
TEST=Verify sending EOP from depthcharge on google/rex

Signed-off-by: Kapil Porwal <kapilporwal@google.com>
Change-Id: I0fbb9fd0f8522eefad39960ca3167c2ba764f523
Reviewed-on: https://review.coreboot.org/c/coreboot/+/74765
Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Subrata Banik <subratabanik@google.com>
diff --git a/src/soc/intel/common/block/cse/Kconfig b/src/soc/intel/common/block/cse/Kconfig
index 581cecd..ca806fd 100644
--- a/src/soc/intel/common/block/cse/Kconfig
+++ b/src/soc/intel/common/block/cse/Kconfig
@@ -134,6 +134,20 @@
 	  request is posted (at CSE .final device operation) and the
 	  time coreboot check for its completion (BS_PAYLOAD_LOAD).
 
+config SOC_INTEL_CSE_SEND_EOP_BY_PAYLOAD
+	bool
+	depends on SOC_INTEL_COMMON_BLOCK_CSE
+	depends on !SOC_INTEL_CSE_SEND_EOP_LATE
+	depends on !SOC_INTEL_CSE_SEND_EOP_EARLY
+	depends on !SOC_INTEL_CSE_SEND_EOP_ASYNC
+	depends on !DISABLE_HECI1_AT_PRE_BOOT
+	help
+	  Use this config to specify that the payload will send the End Of Post (EOP) instead
+	  of coreboot.
+
+	  In this case, the HECI interface needs to stay visible and the payload must support
+	  sending commands to CSE.
+
 config SOC_INTEL_CSE_LITE_SKU
 	bool
 	default n
diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c
index af1ca92..8a92332 100644
--- a/src/soc/intel/common/block/cse/cse.c
+++ b/src/soc/intel/common/block/cse/cse.c
@@ -1441,15 +1441,17 @@
 	if (CONFIG(SOC_INTEL_STORE_CSE_FW_VERSION))
 		intel_cse_get_rw_version();
 	/*
-	 * SoC user can have two options for sending EOP:
+	 * SoC user can have three options for sending EOP:
 	 * 1. Choose to send EOP late
 	 * 2. Choose to send EOP cmd asynchronously
+	 * 3. Choose to send EOP cmd from payload i.e. skip here
 	 *
 	 * In case of sending EOP in asynchronous mode, the EOP command
 	 * has most likely not been completed yet. The finalization steps
 	 * will be run once the EOP command has successfully been completed.
 	 */
 	if (CONFIG(SOC_INTEL_CSE_SEND_EOP_LATE) ||
+	    CONFIG(SOC_INTEL_CSE_SEND_EOP_BY_PAYLOAD) ||
 	    CONFIG(SOC_INTEL_CSE_SEND_EOP_ASYNC))
 		return;
 
diff --git a/src/soc/intel/common/block/cse/cse_eop.c b/src/soc/intel/common/block/cse/cse_eop.c
index 135bcb7..265fe04 100644
--- a/src/soc/intel/common/block/cse/cse_eop.c
+++ b/src/soc/intel/common/block/cse/cse_eop.c
@@ -309,6 +309,11 @@
 
 static void send_cse_eop_with_late_finalize(void *unused)
 {
+	if (CONFIG(SOC_INTEL_CSE_SEND_EOP_BY_PAYLOAD)) {
+		printk(BIOS_INFO, "Deferring CSE EOP to payload\n");
+		return;
+	}
+
 	if (is_cse_eop_supported())
 		do_send_end_of_post(true);