Subrata Banik has uploaded this change for review.

View Change

soc/intel/common/../cse: Perform D0I3 bit reset/set prior sending EOP

Prior to coreboot sending EOP messages during post, it's important to
ensure that CSE is not in Idle state. Incase CSE is in Dev Idle state
meaning D0I3 bit is set then ensures resetting this bit, prior to sending
EOP command.

This patch ensures coreboot has provision to send CSE EOP messages even
after the FSP Notify phase without any evitable problem.

BUG=b:BUG=b:200644229
TEST=Able to send CSE EOP message even after FSP Notify phase.

Attempting CSE EOP msg sending post FSP notify without this code change
causes `timeout` issue as below:

BS: BS_PAYLOAD_LOAD exit times (exec / console): 171 / 0 ms
Finalizing chipset.
apm_control: Finalizing SMM.
APMC done.
HECI: Sending End-of-Post
HECI: timed out reading answer!
HECI: Failed to receive!
HECI: receive Failed
HECI: EOP send/receive fail
ERROR: Failed to send EOP to CSE, 2
cse: CSE status registers: HFSTS1: 0x90000255, HFSTS2: 0xf10516 HFSTS3: 0x20
VB2:vb2api_fail() Need recovery, reason: 0x31 / 0xc
Saving nvdata
board_reset() called!
full_reset() called!

Attempting CSE EOP msg sending post FSP notify with this code change
is `successful` as below:

BS: BS_PAYLOAD_LOAD exit times (exec / console): 170 / 0 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

Change-Id: Iae1bc52e94b08f97004424ea0c147d6da8aca6e2
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
---
M src/soc/intel/common/block/cse/cse_eop.c
1 file changed, 70 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/05/57805/1
diff --git a/src/soc/intel/common/block/cse/cse_eop.c b/src/soc/intel/common/block/cse/cse_eop.c
index d8c6430..63e62c7 100644
--- a/src/soc/intel/common/block/cse/cse_eop.c
+++ b/src/soc/intel/common/block/cse/cse_eop.c
@@ -2,6 +2,8 @@

#include <bootstate.h>
#include <console/console.h>
+#include <delay.h>
+#include <device/pci.h>
#include <intelblocks/cse.h>
#include <intelblocks/pmc_ipc.h>
#include <security/vboot/vboot_common.h>
@@ -13,6 +15,17 @@
#define PMC_IPC_MEI_DISABLE_SUBID_ENABLE 0
#define PMC_IPC_MEI_DISABLE_SUBID_DISABLE 1

+#define DEV_IDLE_CONTROL 0x800
+#define DEV_IDLE (1 << 2)
+#define DEV_CIP (1 << 0)
+/* Wait up to 1 ms for CSE CIP */
+#define HECI_CIP_TIMEOUT 1000
+
+enum cse_config_status {
+ CSE_MMIO_ENABLE,
+ CSE_MMIO_DISABLE
+};
+
enum cse_eop_result {
CSE_EOP_RESULT_GLOBAL_RESET_REQUESTED,
CSE_EOP_RESULT_SUCCESS,
@@ -172,11 +185,68 @@
}
}

+static void set_cse_to_active_state(void)
+{
+ uint32_t dev_idle_ctrl = read_bar(DEV_IDLE_CONTROL);
+ dev_idle_ctrl &= ~DEV_IDLE;
+ write_bar(DEV_IDLE_CONTROL, dev_idle_ctrl);
+
+ dev_idle_ctrl = read_bar(DEV_IDLE_CONTROL);
+ while ((dev_idle_ctrl & DEV_CIP) == DEV_CIP) {
+ udelay(HECI_CIP_TIMEOUT);
+ dev_idle_ctrl = read_bar(DEV_IDLE_CONTROL);
+ }
+}
+
+static void set_cse_to_idle_state(void)
+{
+ uint32_t dev_idle_ctrl = read_bar(DEV_IDLE_CONTROL);
+ dev_idle_ctrl |= DEV_IDLE;
+ write_bar(DEV_IDLE_CONTROL, dev_idle_ctrl);
+}
+
+static bool is_cse_at_idle_state(void)
+{
+ uint32_t dev_idle_ctrl = read_bar(DEV_IDLE_CONTROL);
+ if ((dev_idle_ctrl & DEV_IDLE) == DEV_IDLE)
+ return true;
+
+ return false;
+}
+
+static void cse_config_mmio( enum cse_config_status status)
+{
+ uint32_t cmd;
+
+ if (status == CSE_MMIO_ENABLE) {
+ cmd = me_read_config32(PCI_COMMAND) | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER;
+ } else {
+ cmd = me_read_config32(PCI_COMMAND) | ~PCI_COMMAND_MEMORY |
+ ~PCI_COMMAND_MASTER;
+ }
+
+ me_write_config32(PCI_COMMAND, cmd);
+}
+
static void set_cse_end_of_post(void *unused)
{
+ bool idle_state = true;
+
+ if (is_cse_at_idle_state()) {
+ cse_config_mmio(CSE_MMIO_ENABLE);
+ set_cse_to_active_state();
+ idle_state = false;
+ }
+
timestamp_add_now(TS_ME_BEFORE_END_OF_POST);
handle_cse_eop_result(cse_send_eop());
timestamp_add_now(TS_ME_AFTER_END_OF_POST);
+
+ if (!idle_state) {
+ cse_config_mmio(CSE_MMIO_DISABLE);
+ set_cse_to_idle_state();
+ }
}

/*

To view, visit change 57805. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Iae1bc52e94b08f97004424ea0c147d6da8aca6e2
Gerrit-Change-Number: 57805
Gerrit-PatchSet: 1
Gerrit-Owner: Subrata Banik <subrata.banik@intel.com>
Gerrit-MessageType: newchange