aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block/cse
diff options
context:
space:
mode:
authorSridhar Siricilla <sridhar.siricilla@intel.com>2019-08-31 11:38:33 +0530
committerPatrick Georgi <pgeorgi@google.com>2019-09-12 13:14:39 +0000
commitb9d075b0fc12c26316eaaca2de6bfa659f0cb6c1 (patch)
treebd2eb747d26da36f66cca594462d3ef4c8212ad0 /src/soc/intel/common/block/cse
parentbc553e6a5beee3db02cfd27e3a5e410857e78897 (diff)
src/soc/intel/common/block/cse: Make hfsts1 common & add helper functions
Host FW status 1 (FWSTS1/HFSTS1) register definition is common across SoCs, hence move it to common. Also add below helper function, * wait_cse_sec_override_mode() - Polls ME status for "HECI_OP_MODE_SEC_OVERRIDE". It's a special CSE mode, the mode ensures CSE does not trigger any spi cycles to CSE region. * set_host_ready() - Clears reset state from host CSR. TEST=Verified CSE recover mode on CML RVP & Hatch board Change-Id: Id5c12b7abdb27c38af74ea6ee568b42ec74bcb3c Signed-off-by: Rizwan Qureshi <rizwan.qureshi@intel.com> Signed-off-by: Sridhar Siricilla <sridhar.siricilla@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/35226 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aamir Bohra <aamir.bohra@intel.com>
Diffstat (limited to 'src/soc/intel/common/block/cse')
-rw-r--r--src/soc/intel/common/block/cse/cse.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c
index 1671970a19..223eab5fb2 100644
--- a/src/soc/intel/common/block/cse/cse.c
+++ b/src/soc/intel/common/block/cse/cse.c
@@ -67,6 +67,7 @@
#define MEI_HDR_CSE_ADDR_START 0
#define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START)
+#define HECI_OP_MODE_SEC_OVERRIDE 5
static struct cse_device {
uintptr_t sec_bar;
@@ -239,6 +240,43 @@ static int cse_ready(void)
return csr & CSR_READY;
}
+/*
+ * Checks if CSE is in SEC_OVERRIDE operation mode. This is the mode where
+ * CSE will allow reflashing of CSE region.
+ */
+static uint8_t check_cse_sec_override_mode(void)
+{
+ union me_hfsts1 hfs1;
+ hfs1.data = me_read_config32(PCI_ME_HFSTS1);
+ if (hfs1.fields.operation_mode == HECI_OP_MODE_SEC_OVERRIDE)
+ return 1;
+ return 0;
+}
+
+/* Makes the host ready to communicate with CSE */
+void set_host_ready(void)
+{
+ uint32_t csr;
+ csr = read_host_csr();
+ csr &= ~CSR_RESET;
+ csr |= (CSR_IG | CSR_READY);
+ write_host_csr(csr);
+}
+
+/* Polls for ME state 'HECI_OP_MODE_SEC_OVERRIDE' for 15 seconds */
+uint8_t wait_cse_sec_override_mode(void)
+{
+ struct stopwatch sw;
+ stopwatch_init_msecs_expire(&sw, HECI_DELAY_READY);
+ while (!check_cse_sec_override_mode()) {
+ udelay(HECI_DELAY);
+ if (stopwatch_expired(&sw))
+ return 0;
+ }
+
+ return 1;
+}
+
static int wait_heci_ready(void)
{
struct stopwatch sw;
@@ -484,17 +522,12 @@ int heci_reset(void)
/* Send reset request */
csr = read_host_csr();
- csr |= CSR_RESET;
- csr |= CSR_IG;
+ csr |= (CSR_RESET | CSR_IG);
write_host_csr(csr);
if (wait_heci_ready()) {
/* Device is back on its imaginary feet, clear reset */
- csr = read_host_csr();
- csr &= ~CSR_RESET;
- csr |= CSR_IG;
- csr |= CSR_READY;
- write_host_csr(csr);
+ set_host_ready();
return 1;
}