soc/intel/common/cse: Add `finalize` operation for CSE

This patch implements the required operations to perform prior to
booting to OS using coreboot native driver when platform decides
to skip FSP notify APIs i.e. Ready to Boot and End Of Firmware.

BUG=b:211954778
TEST=Able to build brya with these changes and coreboot log with this
code change as below when ADL SoC selects all required configs:

BS: BS_PAYLOAD_LOAD run times (exec / console): 135 / 62 ms
coreboot skipped calling FSP notify phase: 00000040.
coreboot skipped calling FSP notify phase: 000000f0.
BS: BS_PAYLOAD_LOAD exit times (exec / console): 0 / 11 ms
Finalizing chipset.
apm_control: Finalizing SMM.
APMC done.
HECI: Sending End-of-Post
CSE: EOP requested action: continue boot
CSE EOP successful, continuing boot
HECI: CSE device 16.1 is disabled
HECI: CSE device 16.4 is disabled
HECI: CSE device 16.5 is disabled
BS: BS_PAYLOAD_BOOT entry times (exec / console): 9 / 27 ms

Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: I70bde33f77026e8be165ff082defe3cab6686ec7
Reviewed-on: https://review.coreboot.org/c/coreboot/+/60405
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nick Vaccaro <nvaccaro@google.com>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c
index 5140369..19d7336 100644
--- a/src/soc/intel/common/block/cse/cse.c
+++ b/src/soc/intel/common/block/cse/cse.c
@@ -1184,6 +1184,68 @@
 		me_reset_with_count();
 }
 
+struct cse_notify_phase_data {
+	bool skip;
+	void (*notify_func)(void);
+};
+
+/*
+ * `cse_final_ready_to_boot` function is native implementation of equivalent events
+ * performed by FSP NotifyPhase(Ready To Boot) API invocations.
+ *
+ * Operations are:
+ * 1. Send EOP to CSE if not done.
+ * 2. Perform global reset lock.
+ * 3. Put HECI1 to D0i3 and disable the HECI1 if the user selects
+ *      DISABLE_HECI1_AT_PRE_BOOT config.
+ */
+static void cse_final_ready_to_boot(void)
+{
+	cse_send_end_of_post();
+
+	cse_control_global_reset_lock();
+
+	if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) {
+		cse_set_to_d0i3();
+		heci1_disable();
+	}
+}
+
+/*
+ * `cse_final_end_of_firmware` function is native implementation of equivalent events
+ * performed by FSP NotifyPhase(End of Firmware) API invocations.
+ *
+ * Operations are:
+ * 1. Set D0I3 for all HECI devices.
+ */
+static void cse_final_end_of_firmware(void)
+{
+	heci_set_to_d0i3();
+}
+
+static const struct cse_notify_phase_data notify_data[] = {
+	{
+		.skip         = CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT),
+		.notify_func  = cse_final_ready_to_boot,
+	},
+	{
+		.skip         = CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE),
+		.notify_func  = cse_final_end_of_firmware,
+	},
+};
+
+/*
+ * `cse_final` function is native implementation of equivalent events performed by
+ * each FSP NotifyPhase() API invocations.
+ */
+static void cse_final(struct device *dev)
+{
+	for (size_t i = 0; i < ARRAY_SIZE(notify_data); i++) {
+		if (!notify_data[i].skip)
+			return notify_data[i].notify_func();
+	}
+}
+
 static struct device_operations cse_ops = {
 	.set_resources		= pci_dev_set_resources,
 	.read_resources		= pci_dev_read_resources,
@@ -1191,6 +1253,7 @@
 	.init			= pci_dev_init,
 	.ops_pci		= &pci_dev_ops_pci,
 	.enable			= cse_set_state,
+	.final			= cse_final,
 };
 
 static const unsigned short pci_device_ids[] = {