summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDino Li <Dino.Li@ite.com.tw>2020-12-28 13:46:10 +0800
committerCommit Bot <commit-bot@chromium.org>2020-12-29 02:57:49 +0000
commit4553e910add49fb420a855d6db9a71ea95fb030b (patch)
tree1bf2bf322af83f51cc53590ba7fb195fd62da0c9
parentcd133aa2de5782dc75d95192fd0ecdfdbd8dad4d (diff)
downloadchrome-ec-4553e910add49fb420a855d6db9a71ea95fb030b.tar.gz
it83xx/spi: add support emmc boot mode
IT81202 bx version can configure SPI module to work as eMMC boot mode to catch CMD0. Once this mode is enabled, SPI's CS# pin isn't required. HW will drop data until CMD goes low (CMD0 starts with 01b) and saving 128 bytes in RX FIFO. FW need to parse the data of FIFO and handle argument of CMD0 (GO_IDLE_STATE, GO_PRE_IDLE_STATE, and BOOT_INITIATION). Pinmux of eMMC boot mode are as following: GPM2->CLK GPM3->CMD GPM6->DATA0 BUG=b:170795623 BRANCH=none TEST=boot to kernel on Juniper (replace EC with it81202 bx). Signed-off-by: Dino Li <Dino.Li@ite.com.tw> Change-Id: I1dac1848bfd79f4a7dc02e1d90905e0cd6b8af3f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2604802 Reviewed-by: Eric Yilun Lin <yllin@chromium.org>
-rw-r--r--chip/it83xx/intc.h1
-rw-r--r--chip/it83xx/registers.h5
-rw-r--r--chip/it83xx/spi.c17
3 files changed, 23 insertions, 0 deletions
diff --git a/chip/it83xx/intc.h b/chip/it83xx/intc.h
index c407e6e155..239a46f760 100644
--- a/chip/it83xx/intc.h
+++ b/chip/it83xx/intc.h
@@ -44,6 +44,7 @@ void espi_vw_interrupt(void);
void espi_enable_pad(int enable);
void espi_init(void);
void clock_cpu_standby(void);
+void spi_emmc_cmd0_isr(uint32_t *cmd0_payload);
void spi_slv_int_handler(void);
#if defined(CONFIG_HOSTCMD_X86) && defined(HAS_TASK_KEYPROTO)
void lpc_kbc_ibf_interrupt(void);
diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h
index 83a0fb4014..483eabe346 100644
--- a/chip/it83xx/registers.h
+++ b/chip/it83xx/registers.h
@@ -991,6 +991,7 @@ enum clock_gate_offsets {
#define IT83XX_GCTRL_EPLR REG8(IT83XX_GCTRL_BASE+0x37)
#define IT83XX_GCTRL_IVTBAR REG8(IT83XX_GCTRL_BASE+0x41)
#define IT83XX_GCTRL_MCCR2 REG8(IT83XX_GCTRL_BASE+0x44)
+#define IT83XX_GCTRL_PIN_MUX0 REG8(IT83XX_GCTRL_BASE+0x46)
#define IT83XX_DLM14_ENABLE BIT(5)
#define IT83XX_GCTRL_SSCR REG8(IT83XX_GCTRL_BASE+0x4A)
#define IT83XX_GCTRL_ETWDUARTCR REG8(IT83XX_GCTRL_BASE+0x4B)
@@ -1324,9 +1325,11 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 5 : 8) + (ch << 4))
#define IT83XX_SPI_RXF1OC BIT(3)
#define IT83XX_SPI_RXFAR BIT(0)
#define IT83XX_SPI_IMR REG8(IT83XX_SPI_BASE+0x04)
+#define IT83XX_SPI_RX_FIFO_FULL BIT(7)
#define IT83XX_SPI_RX_REACH BIT(5)
#define IT83XX_SPI_EDIM BIT(2)
#define IT83XX_SPI_ISR REG8(IT83XX_SPI_BASE+0x05)
+#define IT83XX_SPI_TXFSR REG8(IT83XX_SPI_BASE+0x06)
#define IT83XX_SPI_ENDDETECTINT BIT(2)
#define IT83XX_SPI_RXFSR REG8(IT83XX_SPI_BASE+0x07)
#define IT83XX_SPI_RXFFSM (BIT(4) | BIT(3))
@@ -1348,6 +1351,8 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 5 : 8) + (ch << 4))
#define IT83XX_SPI_TCCB0 REG8(IT83XX_SPI_BASE+0x1A)
#define IT83XX_SPI_TCCB1 REG8(IT83XX_SPI_BASE+0x1B)
#define IT83XX_SPI_HPR2 REG8(IT83XX_SPI_BASE+0x1E)
+#define IT83XX_SPI_EMMCBMR REG8(IT83XX_SPI_BASE+0x21)
+#define IT83XX_SPI_EMMCABM BIT(1) /* eMMC Alternative Boot Mode */
#define IT83XX_SPI_RX_VLISMR REG8(IT83XX_SPI_BASE+0x26)
#define IT83XX_SPI_RVLIM BIT(0)
#define IT83XX_SPI_RX_VLISR REG8(IT83XX_SPI_BASE+0x27)
diff --git a/chip/it83xx/spi.c b/chip/it83xx/spi.c
index bacfe434c5..d92d98fdf2 100644
--- a/chip/it83xx/spi.c
+++ b/chip/it83xx/spi.c
@@ -12,6 +12,7 @@
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
+#include "intc.h"
#include "registers.h"
#include "spi.h"
#include "system.h"
@@ -235,6 +236,22 @@ void spi_event(enum gpio_signal signal)
void spi_slv_int_handler(void)
{
+ if (IS_ENABLED(CONFIG_BOOTBLOCK) &&
+ (IT83XX_SPI_ISR & IT83XX_SPI_RX_FIFO_FULL) &&
+ (IT83XX_SPI_EMMCBMR & IT83XX_SPI_EMMCABM)) {
+ spi_host_request_data(in_msg, 128);
+ /* End CPU access RX FIFO */
+ IT83XX_SPI_TXRXFAR = 0;
+ /* Write to clear interrupt status */
+ IT83XX_SPI_ISR = 0xff;
+ /*
+ * Handle eMMC CMD0:
+ * GO_IDLE_STATE, GO_PRE_IDLE_STATE, and BOOT_INITIATION
+ */
+ spi_emmc_cmd0_isr((uint32_t *)in_msg);
+ return;
+ }
+
/*
* The status of SPI end detection interrupt bit is set, it
* means that host command parse has been completed and AP