diff options
-rw-r--r-- | board/it8380dev/board.h | 1 | ||||
-rw-r--r-- | chip/it83xx/gpio.c | 12 | ||||
-rw-r--r-- | chip/it83xx/registers.h | 28 | ||||
-rw-r--r-- | chip/it83xx/system.c | 74 | ||||
-rw-r--r-- | core/nds32/task.c | 24 | ||||
-rw-r--r-- | include/config.h | 3 |
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 |