summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/it8380dev/board.h1
-rw-r--r--chip/it83xx/gpio.c12
-rw-r--r--chip/it83xx/registers.h28
-rw-r--r--chip/it83xx/system.c74
-rw-r--r--core/nds32/task.c24
-rw-r--r--include/config.h3
6 files changed, 114 insertions, 28 deletions
diff --git a/board/it8380dev/board.h b/board/it8380dev/board.h
index 13db5ed5e9..7eaa27a9aa 100644
--- a/board/it8380dev/board.h
+++ b/board/it8380dev/board.h
@@ -13,6 +13,7 @@
#define CONFIG_FANS 1
#undef CONFIG_IT83XX_KEYBOARD_KSI_WUC_INT
+#define CONFIG_IT83XX_LPC_ACCESS_INT
#define CONFIG_IT83XX_PECI_WITH_INTERRUPT
#define CONFIG_IT83XX_SMCLK2_ON_GPC7
#define CONFIG_KEYBOARD_BOARD_CONFIG
diff --git a/chip/it83xx/gpio.c b/chip/it83xx/gpio.c
index f00c954f1c..8ae7c5bbd3 100644
--- a/chip/it83xx/gpio.c
+++ b/chip/it83xx/gpio.c
@@ -440,6 +440,18 @@ static void __gpio_irq(void)
}
#endif
+ if (irq == IT83XX_IRQ_WKINTAD) {
+#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
+ if (BRAM_LPC_ACCESS == LPC_ACCESS_INT_BUSY)
+ task_disable_irq(IT83XX_IRQ_WKINTAD);
+#else
+ task_disable_irq(IT83XX_IRQ_WKINTAD);
+#endif
+ IT83XX_WUC_WUESR4 = 0xff;
+ task_clear_pending_irq(IT83XX_IRQ_WKINTAD);
+ return;
+ }
+
/*
* Clear the WUC status register. Note the external pin first goes
* to the WUC module and is always edge triggered.
diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h
index 2d2cd14ccf..fa31c11d83 100644
--- a/chip/it83xx/registers.h
+++ b/chip/it83xx/registers.h
@@ -433,6 +433,10 @@
#define IT83XX_WUC_WUESR3 REG8(IT83XX_WUC_BASE+0x06)
#define IT83XX_WUC_WUENR3 REG8(IT83XX_WUC_BASE+0x0A)
+#define IT83XX_WUC_WUEMR4 REG8(IT83XX_WUC_BASE+0x03)
+#define IT83XX_WUC_WUESR4 REG8(IT83XX_WUC_BASE+0x07)
+#define IT83XX_WUC_WUENR4 REG8(IT83XX_WUC_BASE+0x0B)
+
/* --- UART --- */
#define IT83XX_UART0_BASE 0x00F02700
#define IT83XX_UART1_BASE 0x00F02800
@@ -639,6 +643,9 @@ enum clock_gate_offsets {
/* --- General Control (GCTRL) --- */
#define IT83XX_GCTRL_BASE 0x00F02000
+#define IT83XX_GCTRL_CHIPID1 REG8(IT83XX_GCTRL_BASE+0x00)
+#define IT83XX_GCTRL_CHIPID2 REG8(IT83XX_GCTRL_BASE+0x01)
+#define IT83XX_GCTRL_CHIPVER REG8(IT83XX_GCTRL_BASE+0x02)
#define IT83XX_GCTRL_WNCKR REG8(IT83XX_GCTRL_BASE+0x0B)
#define IT83XX_GCTRL_RSTS REG8(IT83XX_GCTRL_BASE+0x06)
#define IT83XX_GCTRL_BADRSEL REG8(IT83XX_GCTRL_BASE+0x0A)
@@ -942,13 +949,32 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 5 : 8) + (ch << 4))
/* BRAM */
#define IT83XX_BRAM_BASE 0x00F02200
+/* offset 0 ~ 0x7f */
+#define IT83XX_BRAM_BANK0(i) REG8(IT83XX_BRAM_BASE + i)
+/* Battery backed RAM indices. */
+enum bram_indices {
+ /* reset flags uses 4 bytes */
+ BRAM_IDX_RESET_FLAGS = 0,
+ BRAM_IDX_RESET_FLAGS1 = 1,
+ BRAM_IDX_RESET_FLAGS2 = 2,
+ BRAM_IDX_RESET_FLAGS3 = 3,
+
+ BRAM_IDX_LPC_ACCESS = 4,
+};
+#define BRAM_RESET_FLAGS IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS)
+#define BRAM_RESET_FLAGS1 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS1)
+#define BRAM_RESET_FLAGS2 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS2)
+#define BRAM_RESET_FLAGS3 IT83XX_BRAM_BANK0(BRAM_IDX_RESET_FLAGS3)
+
+#define BRAM_LPC_ACCESS IT83XX_BRAM_BANK0(BRAM_IDX_LPC_ACCESS)
+#define LPC_ACCESS_INT_BUSY 0x33
+
#define IT83XX_BRAM_BANK1(i) REG8(IT83XX_BRAM_BASE + 0x80 + i)
/* --- MISC (not implemented yet) --- */
#define IT83XX_PS2_BASE 0x00F01700
#define IT83XX_DAC_BASE 0x00F01A00
-#define IT83XX_WUC_BASE 0x00F01B00
#define IT83XX_EGPIO_BASE 0x00F02100
#define IT83XX_CIR_BASE 0x00F02300
#define IT83XX_DBGR_BASE 0x00F02500
diff --git a/chip/it83xx/system.c b/chip/it83xx/system.c
index 21230f37f9..fe4c5d83c0 100644
--- a/chip/it83xx/system.c
+++ b/chip/it83xx/system.c
@@ -16,13 +16,6 @@
#include "version.h"
#include "watchdog.h"
-/* Battery backed RAM indices. */
-enum system_bram_indices {
- BRAM_INDEX_SAVED_RESET_FLAGS = 0, /* uses 4 bytes */
-};
-
-
-
void system_hibernate(uint32_t seconds, uint32_t microseconds)
{
/* TODO(crosbug.com/p/23575): IMPLEMENT ME ! */
@@ -53,22 +46,20 @@ static void check_reset_cause(void)
/* Restore then clear saved reset flags. */
if (!(flags & RESET_FLAG_POWER_ON)) {
- const uint32_t addr =
- IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS;
- flags |= REG8(addr + 0) << 24;
- flags |= REG8(addr + 1) << 16;
- flags |= REG8(addr + 2) << 8;
- flags |= REG8(addr + 3);
+ flags |= BRAM_RESET_FLAGS << 24;
+ flags |= BRAM_RESET_FLAGS1 << 16;
+ flags |= BRAM_RESET_FLAGS2 << 8;
+ flags |= BRAM_RESET_FLAGS3;
/* watchdog module triggers these reset */
if (flags & (RESET_FLAG_HARD | RESET_FLAG_SOFT))
flags &= ~RESET_FLAG_WATCHDOG;
}
- REG8(IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS) = 0;
- REG8(IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS+1) = 0;
- REG8(IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS+2) = 0;
- REG8(IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS+3) = 0;
+ BRAM_RESET_FLAGS = 0;
+ BRAM_RESET_FLAGS1 = 0;
+ BRAM_RESET_FLAGS2 = 0;
+ BRAM_RESET_FLAGS3 = 0;
system_set_reset_flags(flags);
}
@@ -120,13 +111,10 @@ void system_reset(int flags)
save_flags |= RESET_FLAG_SOFT;
/* Store flags to battery backed RAM. */
- REG8(IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS) = save_flags >> 24;
- REG8(IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS+1) =
- (save_flags >> 16) & 0xff;
- REG8(IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS+2) =
- (save_flags >> 8) & 0xff;
- REG8(IT83XX_BRAM_BASE+BRAM_INDEX_SAVED_RESET_FLAGS+3) =
- save_flags & 0xff;
+ BRAM_RESET_FLAGS = save_flags >> 24;
+ BRAM_RESET_FLAGS1 = (save_flags >> 16) & 0xff;
+ BRAM_RESET_FLAGS2 = (save_flags >> 8) & 0xff;
+ BRAM_RESET_FLAGS3 = save_flags & 0xff;
/*
* Writing invalid key to watchdog module triggers a soft reset. For
@@ -152,6 +140,24 @@ uint32_t system_get_scratchpad(void)
return 0;
}
+static uint16_t system_get_chip_id(void)
+{
+ return (IT83XX_GCTRL_CHIPID1 << 8) | IT83XX_GCTRL_CHIPID2;
+}
+
+static uint8_t system_get_chip_version(void)
+{
+ /* bit[3-0], chip version */
+ return IT83XX_GCTRL_CHIPVER & 0x0F;
+}
+
+static char to_hex(int x)
+{
+ if (x >= 0 && x <= 9)
+ return '0' + x;
+ return 'a' + x - 10;
+}
+
const char *system_get_chip_vendor(void)
{
return "ite";
@@ -159,12 +165,28 @@ const char *system_get_chip_vendor(void)
const char *system_get_chip_name(void)
{
- return "it83xx";
+ static char buf[7];
+ uint16_t chip_id = system_get_chip_id();
+
+ buf[0] = 'i';
+ buf[1] = 't';
+ buf[2] = to_hex((chip_id >> 12) & 0xf);
+ buf[3] = to_hex((chip_id >> 8) & 0xf);
+ buf[4] = to_hex((chip_id >> 4) & 0xf);
+ buf[5] = to_hex(chip_id & 0xf);
+ buf[6] = '\0';
+ return buf;
}
const char *system_get_chip_revision(void)
{
- return "";
+ static char buf[3];
+ uint8_t rev = system_get_chip_version();
+
+ buf[0] = to_hex(rev + 0xa);
+ buf[1] = 'x';
+ buf[2] = '\0';
+ return buf;
}
int system_get_vbnvcontext(uint8_t *block)
diff --git a/core/nds32/task.c b/core/nds32/task.c
index bb62f5a725..5543d83cb1 100644
--- a/core/nds32/task.c
+++ b/core/nds32/task.c
@@ -11,6 +11,7 @@
#include "cpu.h"
#include "irq_chip.h"
#include "link_defs.h"
+#include "registers.h"
#include "task.h"
#include "timer.h"
#include "util.h"
@@ -60,12 +61,33 @@ void __idle(void)
*/
cprints(CC_TASK, "idle task started");
+#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
+ IT83XX_WUC_WUESR4 = 0xff;
+ task_clear_pending_irq(IT83XX_IRQ_WKINTAD);
+ /* bit2, wake-up enable for LPC access */
+ IT83XX_WUC_WUENR4 |= (1 << 2);
+#endif
+
while (1) {
+#if defined(CONFIG_LPC) && defined(CONFIG_IT83XX_LPC_ACCESS_INT)
+ BRAM_LPC_ACCESS = LPC_ACCESS_INT_BUSY;
+ /* LPC access interrupt pending. */
+ if (IT83XX_WUC_WUESR4 & (1 << 2)) {
+ task_enable_irq(IT83XX_IRQ_WKINTAD);
+ continue;
+ }
+ BRAM_LPC_ACCESS = 0x00;
+ task_enable_irq(IT83XX_IRQ_WKINTAD);
+#endif
+
+ /* doze mode */
+ IT83XX_ECPM_PLLCTRL = 0x00;
+ asm volatile ("dsb");
/*
* Wait for the next irq event. This stops the CPU clock
* (sleep / deep sleep, depending on chip config).
*/
- asm("standby no_wake_grant");
+ asm("standby wake_grant");
}
}
#endif /* !CONFIG_LOW_POWER_IDLE */
diff --git a/include/config.h b/include/config.h
index 8cb9af0e79..daf2cfd110 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1055,6 +1055,9 @@
/* Enable Wake-up control interrupt from KSI */
#undef CONFIG_IT83XX_KEYBOARD_KSI_WUC_INT
+/* LPC cycle can wake-up EC from doze / deep doze mode if define it. */
+#undef CONFIG_IT83XX_LPC_ACCESS_INT
+
/* Interrupt for PECI module. (IT839X series and IT838X DX only) */
#undef CONFIG_IT83XX_PECI_WITH_INTERRUPT