summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDino Li <dino.li@ite.com.tw>2015-03-20 17:14:45 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-03-22 03:13:58 +0000
commit2c3cf4d1a9d6ed732985ea495e8ebfe1d09a916b (patch)
tree8903dec2bb649fdccfe7af9edcf6cb4c6275f3a6
parentc12181d9af8fbe0b61ac522e813bec463571dda5 (diff)
downloadchrome-ec-2c3cf4d1a9d6ed732985ea495e8ebfe1d09a916b.tar.gz
it8380dev: add KBC/KMSC module
1. DLM 16KB. 2. Add KBC/KMSC module for emulation board. Signed-off-by: Dino Li <dino.li@ite.com.tw> BRANCH=none BUG=none TEST=EVB + x86 MB can boot into DOS and keyboard works. Change-Id: Ia5cc2d4f1733ce07879d410b0447b2d48e50cd95 Reviewed-on: https://chromium-review.googlesource.com/259923 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Tested-by: Dino Li <dino.li@ite.com.tw> Commit-Queue: Dino Li <dino.li@ite.com.tw>
-rw-r--r--board/it8380dev/board.c21
-rw-r--r--board/it8380dev/board.h14
-rw-r--r--board/it8380dev/ec.tasklist7
-rw-r--r--board/it8380dev/gpio.inc47
-rw-r--r--chip/it83xx/build.mk4
-rw-r--r--chip/it83xx/config_chip.h6
-rw-r--r--chip/it83xx/gpio.c8
-rw-r--r--chip/it83xx/intc.c36
-rw-r--r--chip/it83xx/intc.h14
-rw-r--r--chip/it83xx/keyboard_raw.c138
-rw-r--r--chip/it83xx/kmsc_chip.h13
-rw-r--r--chip/it83xx/lpc.c180
-rw-r--r--chip/it83xx/registers.h178
-rw-r--r--core/nds32/init.S6
14 files changed, 610 insertions, 62 deletions
diff --git a/board/it8380dev/board.c b/board/it8380dev/board.c
index c18aa58d41..8448c98e30 100644
--- a/board/it8380dev/board.c
+++ b/board/it8380dev/board.c
@@ -16,6 +16,11 @@
#include "adc.h"
#include "adc_chip.h"
#include "ec2i_chip.h"
+#include "power_button.h"
+#include "lid_switch.h"
+#include "keyboard_scan.h"
+#include "timer.h"
+#include "lpc.h"
/* Test GPIO interrupt function that toggles one LED. */
void test_interrupt(enum gpio_signal signal)
@@ -71,7 +76,7 @@ BUILD_ASSERT(ARRAY_SIZE(pnpcfg_settings) == EC2I_SETTING_COUNT);
/* Initialize board. */
static void board_init(void)
{
- gpio_enable_interrupt(GPIO_START_SW);
+
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
@@ -89,6 +94,20 @@ const struct adc_t adc_channels[] = {
};
BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT);
+/* Keyboard scan setting */
+struct keyboard_scan_config keyscan_config = {
+ .output_settle_us = 35,
+ .debounce_down_us = 5 * MSEC,
+ .debounce_up_us = 40 * MSEC,
+ .scan_period_us = 3 * MSEC,
+ .min_post_scan_delay_us = 1000,
+ .poll_timeout_us = 100 * MSEC,
+ .actual_key_mask = {
+ 0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff,
+ 0xa4, 0xff, 0xfe, 0x55, 0xfa, 0xca /* full set */
+ },
+};
+
/*****************************************************************************/
/* Console commands */
diff --git a/board/it8380dev/board.h b/board/it8380dev/board.h
index a1852d46a6..14523d4a1a 100644
--- a/board/it8380dev/board.h
+++ b/board/it8380dev/board.h
@@ -8,10 +8,18 @@
#ifndef __BOARD_H
#define __BOARD_H
-#ifndef __ASSEMBLER__
+/* Optional features */
+#define CONFIG_POWER_BUTTON
+#define CONFIG_KEYBOARD_PROTOCOL_8042
+#define CONFIG_KEYBOARD_BOARD_CONFIG
+#undef CONFIG_KEYBOARD_KSI_WUC_INT
+
+/* Debug */
+#undef CONFIG_KEYBOARD_DEBUG
+#undef CONFIG_UART_TX_BUF_SIZE
+#define CONFIG_UART_TX_BUF_SIZE 4096
-/* stubbed features */
-#undef CONFIG_LID_SWITCH
+#ifndef __ASSEMBLER__
#include "gpio_signal.h"
diff --git a/board/it8380dev/ec.tasklist b/board/it8380dev/ec.tasklist
index d3ac489b42..6db02cfa8a 100644
--- a/board/it8380dev/ec.tasklist
+++ b/board/it8380dev/ec.tasklist
@@ -17,5 +17,8 @@
* 's' is the stack size in bytes; must be a multiple of 8
*/
#define CONFIG_TASK_LIST \
- TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \
- TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE)
+ TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(CONSOLE, console_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(HOSTCMD, host_command_task, NULL, TASK_STACK_SIZE) \
+ TASK_NOTEST(KEYPROTO, keyboard_protocol_task, NULL, TASK_STACK_SIZE) \
+ TASK_NOTEST(KEYSCAN, keyboard_scan_task, NULL, TASK_STACK_SIZE)
diff --git a/board/it8380dev/gpio.inc b/board/it8380dev/gpio.inc
index 444ae4c15d..7fc5d09ef6 100644
--- a/board/it8380dev/gpio.inc
+++ b/board/it8380dev/gpio.inc
@@ -5,28 +5,31 @@
* found in the LICENSE file.
*/
-GPIO(H_LED0, A, 0, GPIO_ODR_HIGH, NULL)
-GPIO(H_LED1, A, 1, GPIO_ODR_HIGH, NULL)
-GPIO(H_LED2, A, 2, GPIO_ODR_HIGH, NULL)
-GPIO(H_LED3, A, 3, GPIO_ODR_HIGH, NULL)
-GPIO(H_LED4, A, 4, GPIO_ODR_HIGH, NULL)
-GPIO(H_LED5, A, 5, GPIO_ODR_HIGH, NULL)
-GPIO(H_LED6, A, 6, GPIO_ODR_HIGH, NULL)
-GPIO(L_LED0, I, 0, GPIO_ODR_HIGH, NULL)
-GPIO(L_LED1, I, 1, GPIO_ODR_HIGH, NULL)
-GPIO(L_LED2, I, 2, GPIO_ODR_HIGH, NULL)
-GPIO(L_LED3, I, 3, GPIO_ODR_HIGH, NULL)
-GPIO(L_LED4, I, 4, GPIO_ODR_HIGH, NULL)
-GPIO(L_LED5, I, 5, GPIO_ODR_HIGH, NULL)
-GPIO(L_LED6, I, 6, GPIO_ODR_HIGH, NULL)
-GPIO(BUSY_LED, J, 0, GPIO_OUT_LOW, NULL)
-GPIO(GOOD_LED, J, 1, GPIO_OUT_HIGH, NULL)
-GPIO(FAIL_LED, J, 2, GPIO_OUT_LOW, NULL)
-GPIO(SW1, E, 0, GPIO_INPUT, NULL)
-GPIO(SW2, E, 1, GPIO_INPUT | GPIO_PULL_DOWN, NULL)
-GPIO(SW3, E, 2, GPIO_INPUT | GPIO_PULL_DOWN, NULL)
-GPIO(SW4, E, 3, GPIO_INPUT | GPIO_PULL_DOWN, NULL)
-GPIO(START_SW, E, 4, GPIO_INT_FALLING, test_interrupt)
+GPIO(H_LED0, A, 0, GPIO_ODR_HIGH, NULL)
+GPIO(H_LED1, A, 1, GPIO_ODR_HIGH, NULL)
+GPIO(H_LED2, A, 2, GPIO_ODR_HIGH, NULL)
+GPIO(H_LED3, A, 3, GPIO_ODR_HIGH, NULL)
+GPIO(H_LED4, A, 4, GPIO_ODR_HIGH, NULL)
+GPIO(H_LED5, A, 5, GPIO_ODR_HIGH, NULL)
+GPIO(H_LED6, A, 6, GPIO_ODR_HIGH, NULL)
+GPIO(L_LED0, I, 0, GPIO_ODR_HIGH, NULL)
+GPIO(L_LED1, I, 1, GPIO_ODR_HIGH, NULL)
+GPIO(L_LED2, I, 2, GPIO_ODR_HIGH, NULL)
+GPIO(L_LED3, I, 3, GPIO_ODR_HIGH, NULL)
+GPIO(L_LED4, I, 4, GPIO_ODR_HIGH, NULL)
+GPIO(L_LED5, I, 5, GPIO_ODR_HIGH, NULL)
+GPIO(L_LED6, I, 6, GPIO_ODR_HIGH, NULL)
+GPIO(BUSY_LED, J, 0, GPIO_OUT_LOW, NULL)
+GPIO(GOOD_LED, J, 1, GPIO_OUT_HIGH, NULL)
+GPIO(FAIL_LED, J, 2, GPIO_OUT_LOW, NULL)
+GPIO(POWER_BUTTON_L, E, 4, GPIO_INT_BOTH | GPIO_PULL_UP, power_button_interrupt)
+GPIO(LID_OPEN, E, 2, GPIO_INT_BOTH | GPIO_PULL_DOWN, lid_interrupt)
+GPIO(PCH_PLTRST_L, E, 3, GPIO_INPUT, NULL)
+GPIO(PCH_SMI_L, D, 3, GPIO_OUT_HIGH, NULL)
+GPIO(PCH_SCI_L, D, 4, GPIO_OUT_HIGH, NULL)
+GPIO(GATE_A20_H, B, 5, GPIO_OUT_HIGH, NULL)
+GPIO(PCH_RCIN_L, B, 6, GPIO_OUT_HIGH, NULL)
+GPIO(LPC_CLKRUN_L, H, 0, GPIO_OUT_LOW, NULL)
/* Unimplemented signals which we need to emulate for now */
UNIMPLEMENTED(ENTERING_RW)
diff --git a/chip/it83xx/build.mk b/chip/it83xx/build.mk
index 615e7832f9..f94257fb0e 100644
--- a/chip/it83xx/build.mk
+++ b/chip/it83xx/build.mk
@@ -10,10 +10,12 @@
CORE:=nds32
# Required chip modules
-chip-y=hwtimer.o uart.o gpio.o system.o jtag.o clock.o irq.o
+chip-y=hwtimer.o uart.o gpio.o system.o jtag.o clock.o irq.o intc.o
# Optional chip modules
chip-$(CONFIG_WATCHDOG)+=watchdog.o
chip-$(CONFIG_PWM)+=pwm.o
chip-$(CONFIG_ADC)+=adc.o
chip-$(CONFIG_EC2I)+=ec2i.o
+chip-$(CONFIG_LPC)+=lpc.o
+chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
diff --git a/chip/it83xx/config_chip.h b/chip/it83xx/config_chip.h
index a282933faa..d7b13d1480 100644
--- a/chip/it83xx/config_chip.h
+++ b/chip/it83xx/config_chip.h
@@ -26,14 +26,15 @@
/* Memory mapping */
#define CONFIG_RAM_BASE 0x00080000
-#define CONFIG_RAM_SIZE 0x00002000
+#define CONFIG_RAM_SIZE 0x00004000
/* System stack size */
#define CONFIG_STACK_SIZE 1024
/* non-standard task stack sizes */
#define IDLE_TASK_STACK_SIZE 512
-#define LARGER_TASK_STACK_SIZE 640
+#define LARGER_TASK_STACK_SIZE 768
+#define SMALLER_TASK_STACK_SIZE 384
/* Default task stack size */
#define TASK_STACK_SIZE 512
@@ -96,5 +97,6 @@
#define CONFIG_PWM
#define CONFIG_ADC
#define CONFIG_EC2I
+#define CONFIG_LPC
#endif /* __CROS_EC_CONFIG_CHIP_H */
diff --git a/chip/it83xx/gpio.c b/chip/it83xx/gpio.c
index 8f5f83acdd..7bdc41682c 100644
--- a/chip/it83xx/gpio.c
+++ b/chip/it83xx/gpio.c
@@ -14,6 +14,7 @@
#include "task.h"
#include "timer.h"
#include "util.h"
+#include "kmsc_chip.h"
/*
* Converts port (ie GPIO A) to base address offset of the control register
@@ -361,6 +362,13 @@ static void __gpio_irq(void)
/* Determine interrupt number. */
int irq = IT83XX_INTC_IVCT2 - 16;
+#if defined(HAS_TASK_KEYSCAN) && defined(CONFIG_KEYBOARD_KSI_WUC_INT)
+ if (irq == IT83XX_IRQ_WKINTC) {
+ keyboard_raw_interrupt();
+ return;
+ }
+#endif
+
/* Run the GPIO master handler above with corresponding port/mask. */
gpio_interrupt(gpio_irqs[irq].gpio_port, gpio_irqs[irq].gpio_mask);
diff --git a/chip/it83xx/intc.c b/chip/it83xx/intc.c
new file mode 100644
index 0000000000..f4ddd86ac1
--- /dev/null
+++ b/chip/it83xx/intc.c
@@ -0,0 +1,36 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "registers.h"
+#include "task.h"
+#include "kmsc_chip.h"
+#include "intc.h"
+
+void intc_cpu_int_group_5(void)
+{
+ /* Determine interrupt number. */
+ int intc_group_5 = IT83XX_INTC_IVCT5 - 16;
+
+ switch (intc_group_5) {
+#ifdef CONFIG_LPC
+ case IT83XX_IRQ_KBC_OUT:
+ lpc_kbc_obe_interrupt();
+ break;
+
+ case IT83XX_IRQ_KBC_IN:
+ lpc_kbc_ibf_interrupt();
+ break;
+#endif
+#if defined(HAS_TASK_KEYSCAN) && !defined(CONFIG_KEYBOARD_KSI_WUC_INT)
+ case IT83XX_IRQ_KB_MATRIX:
+ keyboard_raw_interrupt();
+ break;
+#endif
+ default:
+ break;
+ }
+}
+DECLARE_IRQ(CPU_INT_GROUP_5, intc_cpu_int_group_5, 2);
diff --git a/chip/it83xx/intc.h b/chip/it83xx/intc.h
new file mode 100644
index 0000000000..488331f2a9
--- /dev/null
+++ b/chip/it83xx/intc.h
@@ -0,0 +1,14 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* INTC control module for IT83xx. */
+
+#ifndef __CROS_EC_IT83XX_INTC_H
+#define __CROS_EC_IT83XX_INTC_H
+
+void lpc_kbc_ibf_interrupt(void);
+void lpc_kbc_obe_interrupt(void);
+
+#endif /* __CROS_EC_IT83XX_INTC_H */
diff --git a/chip/it83xx/keyboard_raw.c b/chip/it83xx/keyboard_raw.c
new file mode 100644
index 0000000000..48749008d2
--- /dev/null
+++ b/chip/it83xx/keyboard_raw.c
@@ -0,0 +1,138 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "keyboard_raw.h"
+#include "keyboard_scan.h"
+#include "registers.h"
+#include "task.h"
+#include "irq_chip.h"
+
+/*
+ * Initialize the raw keyboard interface.
+ */
+void keyboard_raw_init(void)
+{
+ /* Ensure top-level interrupt is disabled */
+ keyboard_raw_enable_interrupt(0);
+
+ /*
+ * bit2, Setting 1 enables the internal pull-up of the KSO[15:0] pins.
+ * To pull up KSO[17:16], set the GPCR registers of their
+ * corresponding GPIO ports.
+ * bit0, Setting 1 enables the open-drain mode of the KSO[17:0] pins.
+ */
+ IT83XX_KBS_KSOCTRL = 0x05;
+
+ /* bit2, 1 enables the internal pull-up of the KSI[7:0] pins. */
+ IT83XX_KBS_KSICTRL = 0x04;
+
+ /* KSO[7:0] pins low. */
+ IT83XX_KBS_KSOL = 0x00;
+
+ /* KSO[15:8] pins low. */
+ IT83XX_KBS_KSOH1 = 0x00;
+
+#ifdef CONFIG_KEYBOARD_KSI_WUC_INT
+ /* KSI[0-7] falling-edge triggered is selected */
+ IT83XX_WUC_WUEMR3 = 0xFF;
+
+ /* W/C */
+ IT83XX_WUC_WUESR3 = 0xFF;
+
+ task_clear_pending_irq(IT83XX_IRQ_WKINTC);
+
+ /* Enable WUC for KSI[0-7] */
+ IT83XX_WUC_WUENR3 = 0xFF;
+#else
+ task_clear_pending_irq(IT83XX_IRQ_KB_MATRIX);
+#endif
+
+ keyboard_raw_enable_interrupt(1);
+}
+
+/*
+ * Finish initialization after task scheduling has started.
+ */
+void keyboard_raw_task_start(void)
+{
+#ifdef CONFIG_KEYBOARD_KSI_WUC_INT
+ IT83XX_WUC_WUESR3 = 0xFF;
+ task_clear_pending_irq(IT83XX_IRQ_WKINTC);
+ task_enable_irq(IT83XX_IRQ_WKINTC);
+#else
+ task_clear_pending_irq(IT83XX_IRQ_KB_MATRIX);
+ task_enable_irq(IT83XX_IRQ_KB_MATRIX);
+#endif
+}
+
+/*
+ * Drive the specified column low.
+ */
+test_mockable void keyboard_raw_drive_column(int col)
+{
+ int mask;
+
+ /* Tri-state all outputs */
+ if (col == KEYBOARD_COLUMN_NONE)
+ mask = 0xffff;
+ /* Assert all outputs */
+ else if (col == KEYBOARD_COLUMN_ALL)
+ mask = 0;
+ /* Assert a single output */
+ else
+ mask = 0xffff ^ (1 << col);
+
+ IT83XX_KBS_KSOL = mask & 0xff;
+ IT83XX_KBS_KSOH1 = (mask >> 8) & 0xff;
+}
+
+/*
+ * Read raw row state.
+ * Bits are 1 if signal is present, 0 if not present.
+ */
+test_mockable int keyboard_raw_read_rows(void)
+{
+ /* Bits are active-low, so invert returned levels */
+ return IT83XX_KBS_KSI ^ 0xff;
+}
+
+/*
+ * Enable or disable keyboard matrix scan interrupts.
+ */
+void keyboard_raw_enable_interrupt(int enable)
+{
+ if (enable) {
+#ifdef CONFIG_KEYBOARD_KSI_WUC_INT
+ IT83XX_WUC_WUESR3 = 0xFF;
+ task_clear_pending_irq(IT83XX_IRQ_WKINTC);
+ task_enable_irq(IT83XX_IRQ_WKINTC);
+#else
+ task_clear_pending_irq(IT83XX_IRQ_KB_MATRIX);
+ task_enable_irq(IT83XX_IRQ_KB_MATRIX);
+#endif
+ } else {
+#ifdef CONFIG_KEYBOARD_KSI_WUC_INT
+ task_disable_irq(IT83XX_IRQ_WKINTC);
+#else
+ task_disable_irq(IT83XX_IRQ_KB_MATRIX);
+#endif
+ }
+}
+
+/*
+ * Interrupt handler for keyboard matrix scan interrupt.
+ */
+void keyboard_raw_interrupt(void)
+{
+#ifdef CONFIG_KEYBOARD_KSI_WUC_INT
+ task_disable_irq(IT83XX_IRQ_WKINTC);
+#else
+ task_disable_irq(IT83XX_IRQ_KB_MATRIX);
+#endif
+
+ /* Wake the scan task */
+ task_wake(TASK_ID_KEYSCAN);
+}
diff --git a/chip/it83xx/kmsc_chip.h b/chip/it83xx/kmsc_chip.h
new file mode 100644
index 0000000000..348cf34204
--- /dev/null
+++ b/chip/it83xx/kmsc_chip.h
@@ -0,0 +1,13 @@
+/* Copyright 2015 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Keyboard matrix scan control module for IT83xx. */
+
+#ifndef __CROS_EC_IT83XX_KMSC_H
+#define __CROS_EC_IT83XX_KMSC_H
+
+void keyboard_raw_interrupt(void);
+
+#endif /* __CROS_EC_IT83XX_KMSC_H */
diff --git a/chip/it83xx/lpc.c b/chip/it83xx/lpc.c
new file mode 100644
index 0000000000..1968761fbf
--- /dev/null
+++ b/chip/it83xx/lpc.c
@@ -0,0 +1,180 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* LPC module for Chrome EC */
+
+#include "acpi.h"
+#include "clock.h"
+#include "common.h"
+#include "console.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "host_command.h"
+#include "keyboard_protocol.h"
+#include "lpc.h"
+#include "port80.h"
+#include "pwm.h"
+#include "registers.h"
+#include "system.h"
+#include "task.h"
+#include "timer.h"
+#include "uart.h"
+#include "util.h"
+#include "irq_chip.h"
+
+static uint8_t acpi_ec_memmap[EC_MEMMAP_SIZE] __aligned(4);
+
+uint8_t *lpc_get_memmap_range(void)
+{
+ return (uint8_t *)acpi_ec_memmap;
+}
+
+int lpc_keyboard_has_char(void)
+{
+ /* OBE or OBF */
+ return IT83XX_KBC_KBHISR & 0x01;
+}
+
+int lpc_keyboard_input_pending(void)
+{
+ /* IBE or IBF */
+ return IT83XX_KBC_KBHISR & 0x02;
+}
+
+void lpc_keyboard_put_char(uint8_t chr, int send_irq)
+{
+ /* Clear programming data bit 7-4 */
+ IT83XX_KBC_KBHISR &= 0x0F;
+
+ /* keyboard */
+ IT83XX_KBC_KBHISR |= 0x10;
+
+ /*
+ * bit0 = 0, The IRQ1 is controlled by the IRQ1B bit in KBIRQR.
+ * bit1 = 0, The IRQ12 is controlled by the IRQ12B bit in KBIRQR.
+ */
+ IT83XX_KBC_KBHICR &= 0xFC;
+
+ /*
+ * Enable the interrupt to keyboard driver in the host processor
+ * via SERIRQ when the output buffer is full.
+ */
+ if (send_irq)
+ IT83XX_KBC_KBHICR |= 0x01;
+
+ udelay(16);
+
+ /* The data output to the KBC Data Output Register. */
+ IT83XX_KBC_KBHIKDOR = chr;
+}
+
+void lpc_keyboard_clear_buffer(void)
+{
+ /* --- (not implemented yet) --- */
+}
+
+void lpc_keyboard_resume_irq(void)
+{
+ if (lpc_keyboard_has_char()) {
+ /* The IRQ1 is controlled by the IRQ1B bit in KBIRQR. */
+ IT83XX_KBC_KBHICR &= ~0x01;
+
+ /*
+ * When the OBFKIE bit in KBC Host Interface Control Register
+ * (KBHICR) is 0, the bit directly controls the IRQ1 signal.
+ */
+ IT83XX_KBC_KBIRQR |= 0x01;
+
+ task_clear_pending_irq(IT83XX_IRQ_KBC_OUT);
+
+ task_enable_irq(IT83XX_IRQ_KBC_OUT);
+ }
+}
+
+void lpc_set_host_event_state(uint32_t mask)
+{
+ /* --- (not implemented yet) --- */
+}
+
+int lpc_query_host_event_state(void)
+{
+ /* --- (not implemented yet) --- */
+ return -1;
+}
+
+void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask)
+{
+ /* --- (not implemented yet) --- */
+}
+
+uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type)
+{
+ /* --- (not implemented yet) --- */
+ return 0;
+}
+
+int lpc_get_pltrst_asserted(void)
+{
+ return !gpio_get_level(GPIO_PCH_PLTRST_L);
+}
+
+/* KBC and PMC control modules */
+void lpc_kbc_ibf_interrupt(void)
+{
+ if (lpc_keyboard_input_pending()) {
+ keyboard_host_write(IT83XX_KBC_KBHIDIR,
+ (IT83XX_KBC_KBHISR & 0x08) ? 1 : 0);
+ }
+
+ task_clear_pending_irq(IT83XX_IRQ_KBC_IN);
+}
+
+void lpc_kbc_obe_interrupt(void)
+{
+ task_disable_irq(IT83XX_IRQ_KBC_OUT);
+
+ task_clear_pending_irq(IT83XX_IRQ_KBC_OUT);
+
+ if (!(IT83XX_KBC_KBHICR & 0x01)) {
+ IT83XX_KBC_KBIRQR &= ~0x01;
+
+ IT83XX_KBC_KBHICR |= 0x01;
+ }
+}
+
+static void lpc_init(void)
+{
+ IT83XX_GPIO_GCR = 0x06;
+
+ /* The register pair to access PNPCFG is 002Eh and 002Fh */
+ IT83XX_GCTRL_BADRSEL = 0x00;
+
+ /* Disable KBC IRQ */
+ IT83XX_KBC_KBIRQR = 0x00;
+
+ /*
+ * bit2, Output Buffer Empty CPU Interrupt Enable.
+ * bit3, Input Buffer Full CPU Interrupt Enable.
+ */
+ IT83XX_KBC_KBHICR |= 0x0C;
+
+ /* Input Buffer Full Interrupt Enable */
+ IT83XX_PMC_PM1CTL |= 0x01;
+
+ memset(lpc_get_memmap_range(), 0, EC_MEMMAP_SIZE);
+
+ task_clear_pending_irq(IT83XX_IRQ_KBC_OUT);
+
+ task_disable_irq(IT83XX_IRQ_KBC_OUT);
+
+ task_clear_pending_irq(IT83XX_IRQ_KBC_IN);
+
+ task_enable_irq(IT83XX_IRQ_KBC_IN);
+}
+/*
+ * Set prio to higher than default; this way LPC memory mapped data is ready
+ * before other inits try to initialize their memmap data.
+ */
+DECLARE_HOOK(HOOK_INIT, lpc_init, HOOK_PRIO_INIT_LPC);
diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h
index 473f696a6c..9e5d115f81 100644
--- a/chip/it83xx/registers.h
+++ b/chip/it83xx/registers.h
@@ -292,6 +292,9 @@
#define CPU_INT_2_ALL_GPIOS 255
#define IT83XX_CPU_INT_IRQ_255 2
+#define CPU_INT_GROUP_5 254
+#define IT83XX_CPU_INT_IRQ_254 5
+
#define CPU_INT(irq) CONCAT2(IT83XX_CPU_INT_IRQ_, irq)
/* --- INTC --- */
@@ -408,6 +411,10 @@
#define IT83XX_WUC_WUESR10 REG8(IT83XX_WUC_BASE+0x21)
#define IT83XX_WUC_WUESR11 REG8(IT83XX_WUC_BASE+0x25)
+#define IT83XX_WUC_WUEMR3 REG8(IT83XX_WUC_BASE+0x02)
+#define IT83XX_WUC_WUESR3 REG8(IT83XX_WUC_BASE+0x06)
+#define IT83XX_WUC_WUENR3 REG8(IT83XX_WUC_BASE+0x0A)
+
/* --- UART --- */
#define IT83XX_UART0_BASE 0x00F02700
#define IT83XX_UART1_BASE 0x00F02800
@@ -434,34 +441,36 @@
#define IT83XX_GPIO_BASE 0x00F01600
-#define IT83XX_GPIO_GPCRA0 REG8(IT83XX_GPIO_BASE+0x10)
-#define IT83XX_GPIO_GPCRA1 REG8(IT83XX_GPIO_BASE+0x11)
-#define IT83XX_GPIO_GPCRA2 REG8(IT83XX_GPIO_BASE+0x12)
-#define IT83XX_GPIO_GPCRA3 REG8(IT83XX_GPIO_BASE+0x13)
-#define IT83XX_GPIO_GPCRA4 REG8(IT83XX_GPIO_BASE+0x14)
-#define IT83XX_GPIO_GPCRA5 REG8(IT83XX_GPIO_BASE+0x15)
-#define IT83XX_GPIO_GPCRA6 REG8(IT83XX_GPIO_BASE+0x16)
-#define IT83XX_GPIO_GPCRA7 REG8(IT83XX_GPIO_BASE+0x17)
-
-#define IT83XX_GPIO_GPCRF0 REG8(IT83XX_GPIO_BASE+0x38)
-
-#define IT83XX_GPIO_GPCRI0 REG8(IT83XX_GPIO_BASE+0x50)
-#define IT83XX_GPIO_GPCRI1 REG8(IT83XX_GPIO_BASE+0x51)
-#define IT83XX_GPIO_GPCRI2 REG8(IT83XX_GPIO_BASE+0x52)
-#define IT83XX_GPIO_GPCRI3 REG8(IT83XX_GPIO_BASE+0x53)
-#define IT83XX_GPIO_GPCRI4 REG8(IT83XX_GPIO_BASE+0x54)
-#define IT83XX_GPIO_GPCRI5 REG8(IT83XX_GPIO_BASE+0x55)
-#define IT83XX_GPIO_GPCRI6 REG8(IT83XX_GPIO_BASE+0x56)
-#define IT83XX_GPIO_GPCRI7 REG8(IT83XX_GPIO_BASE+0x57)
-
-#define IT83XX_GPIO_GRC1 REG8(IT83XX_GPIO_BASE+0xF0)
-#define IT83XX_GPIO_GRC2 REG8(IT83XX_GPIO_BASE+0xF1)
-#define IT83XX_GPIO_GRC3 REG8(IT83XX_GPIO_BASE+0xF2)
-#define IT83XX_GPIO_GRC4 REG8(IT83XX_GPIO_BASE+0xF3)
-#define IT83XX_GPIO_GRC5 REG8(IT83XX_GPIO_BASE+0xF4)
-#define IT83XX_GPIO_GRC6 REG8(IT83XX_GPIO_BASE+0xF5)
-#define IT83XX_GPIO_GRC7 REG8(IT83XX_GPIO_BASE+0xF6)
-#define IT83XX_GPIO_GRC8 REG8(IT83XX_GPIO_BASE+0xF7)
+#define IT83XX_GPIO_GCR REG8(IT83XX_GPIO_BASE+0x00)
+
+#define IT83XX_GPIO_GPCRA0 REG8(IT83XX_GPIO_BASE+0x10)
+#define IT83XX_GPIO_GPCRA1 REG8(IT83XX_GPIO_BASE+0x11)
+#define IT83XX_GPIO_GPCRA2 REG8(IT83XX_GPIO_BASE+0x12)
+#define IT83XX_GPIO_GPCRA3 REG8(IT83XX_GPIO_BASE+0x13)
+#define IT83XX_GPIO_GPCRA4 REG8(IT83XX_GPIO_BASE+0x14)
+#define IT83XX_GPIO_GPCRA5 REG8(IT83XX_GPIO_BASE+0x15)
+#define IT83XX_GPIO_GPCRA6 REG8(IT83XX_GPIO_BASE+0x16)
+#define IT83XX_GPIO_GPCRA7 REG8(IT83XX_GPIO_BASE+0x17)
+
+#define IT83XX_GPIO_GPCRF0 REG8(IT83XX_GPIO_BASE+0x38)
+
+#define IT83XX_GPIO_GPCRI0 REG8(IT83XX_GPIO_BASE+0x50)
+#define IT83XX_GPIO_GPCRI1 REG8(IT83XX_GPIO_BASE+0x51)
+#define IT83XX_GPIO_GPCRI2 REG8(IT83XX_GPIO_BASE+0x52)
+#define IT83XX_GPIO_GPCRI3 REG8(IT83XX_GPIO_BASE+0x53)
+#define IT83XX_GPIO_GPCRI4 REG8(IT83XX_GPIO_BASE+0x54)
+#define IT83XX_GPIO_GPCRI5 REG8(IT83XX_GPIO_BASE+0x55)
+#define IT83XX_GPIO_GPCRI6 REG8(IT83XX_GPIO_BASE+0x56)
+#define IT83XX_GPIO_GPCRI7 REG8(IT83XX_GPIO_BASE+0x57)
+
+#define IT83XX_GPIO_GRC1 REG8(IT83XX_GPIO_BASE+0xF0)
+#define IT83XX_GPIO_GRC2 REG8(IT83XX_GPIO_BASE+0xF1)
+#define IT83XX_GPIO_GRC3 REG8(IT83XX_GPIO_BASE+0xF2)
+#define IT83XX_GPIO_GRC4 REG8(IT83XX_GPIO_BASE+0xF3)
+#define IT83XX_GPIO_GRC5 REG8(IT83XX_GPIO_BASE+0xF4)
+#define IT83XX_GPIO_GRC6 REG8(IT83XX_GPIO_BASE+0xF5)
+#define IT83XX_GPIO_GRC7 REG8(IT83XX_GPIO_BASE+0xF6)
+#define IT83XX_GPIO_GRC8 REG8(IT83XX_GPIO_BASE+0xF7)
#define IT83XX_GPIO_DATA_BASE (IT83XX_GPIO_BASE + 0x00)
#define IT83XX_GPIO_OUTPUT_TYPE_BASE (IT83XX_GPIO_BASE + 0x70)
@@ -561,6 +570,7 @@ enum clock_gate_offsets {
#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)
/* --- Pulse Width Modulation (PWM) --- */
#define IT83XX_PWM_BASE 0x00F01800
@@ -655,16 +665,122 @@ enum clock_gate_offsets {
#define IT83XX_ADC_CMP2THRDATM REG8(IT83XX_ADC_BASE+0x4D)
#define IT83XX_ADC_CMP2THRDATL REG8(IT83XX_ADC_BASE+0x4E)
+/* Keyboard Controller (KBC) */
+#define IT83XX_KBC_BASE 0x00F01300
+
+#define IT83XX_KBC_KBHICR REG8(IT83XX_KBC_BASE+0x00)
+#define IT83XX_KBC_KBIRQR REG8(IT83XX_KBC_BASE+0x02)
+#define IT83XX_KBC_KBHISR REG8(IT83XX_KBC_BASE+0x04)
+#define IT83XX_KBC_KBHIKDOR REG8(IT83XX_KBC_BASE+0x06)
+#define IT83XX_KBC_KBHIMDOR REG8(IT83XX_KBC_BASE+0x08)
+#define IT83XX_KBC_KBHIDIR REG8(IT83XX_KBC_BASE+0x0A)
+
+/* Power Management Channel (PMC) */
+#define IT83XX_PMC_BASE 0x00F01500
+
+#define IT83XX_PMC_PM1STS REG8(IT83XX_PMC_BASE+0x00)
+#define IT83XX_PMC_PM1DO REG8(IT83XX_PMC_BASE+0x01)
+#define IT83XX_PMC_PM1DOSCI REG8(IT83XX_PMC_BASE+0x02)
+#define IT83XX_PMC_PM1DOSMI REG8(IT83XX_PMC_BASE+0x03)
+#define IT83XX_PMC_PM1DI REG8(IT83XX_PMC_BASE+0x04)
+#define IT83XX_PMC_PM1DISCI REG8(IT83XX_PMC_BASE+0x05)
+#define IT83XX_PMC_PM1CTL REG8(IT83XX_PMC_BASE+0x06)
+#define IT83XX_PMC_PM1IC REG8(IT83XX_PMC_BASE+0x07)
+#define IT83XX_PMC_PM1IE REG8(IT83XX_PMC_BASE+0x08)
+#define IT83XX_PMC_PM2STS REG8(IT83XX_PMC_BASE+0x10)
+#define IT83XX_PMC_PM2DO REG8(IT83XX_PMC_BASE+0x11)
+#define IT83XX_PMC_PM2DOSCI REG8(IT83XX_PMC_BASE+0x12)
+#define IT83XX_PMC_PM2DOSMI REG8(IT83XX_PMC_BASE+0x13)
+#define IT83XX_PMC_PM2DI REG8(IT83XX_PMC_BASE+0x14)
+#define IT83XX_PMC_PM2DISCI REG8(IT83XX_PMC_BASE+0x15)
+#define IT83XX_PMC_PM2CTL REG8(IT83XX_PMC_BASE+0x16)
+#define IT83XX_PMC_PM2IC REG8(IT83XX_PMC_BASE+0x17)
+#define IT83XX_PMC_PM2IE REG8(IT83XX_PMC_BASE+0x18)
+#define IT83XX_PMC_PM3STS REG8(IT83XX_PMC_BASE+0x20)
+#define IT83XX_PMC_PM3DO REG8(IT83XX_PMC_BASE+0x21)
+#define IT83XX_PMC_PM3DI REG8(IT83XX_PMC_BASE+0x22)
+#define IT83XX_PMC_PM3CTL REG8(IT83XX_PMC_BASE+0x23)
+#define IT83XX_PMC_PM3IC REG8(IT83XX_PMC_BASE+0x24)
+#define IT83XX_PMC_PM3IE REG8(IT83XX_PMC_BASE+0x25)
+#define IT83XX_PMC_PM4STS REG8(IT83XX_PMC_BASE+0x30)
+#define IT83XX_PMC_PM4DO REG8(IT83XX_PMC_BASE+0x31)
+#define IT83XX_PMC_PM4DI REG8(IT83XX_PMC_BASE+0x32)
+#define IT83XX_PMC_PM4CTL REG8(IT83XX_PMC_BASE+0x33)
+#define IT83XX_PMC_PM4IC REG8(IT83XX_PMC_BASE+0x34)
+#define IT83XX_PMC_PM4IE REG8(IT83XX_PMC_BASE+0x35)
+#define IT83XX_PMC_PM5STS REG8(IT83XX_PMC_BASE+0x40)
+#define IT83XX_PMC_PM5DO REG8(IT83XX_PMC_BASE+0x41)
+#define IT83XX_PMC_PM5DI REG8(IT83XX_PMC_BASE+0x42)
+#define IT83XX_PMC_PM5CTL REG8(IT83XX_PMC_BASE+0x43)
+#define IT83XX_PMC_PM5IC REG8(IT83XX_PMC_BASE+0x44)
+#define IT83XX_PMC_PM5IE REG8(IT83XX_PMC_BASE+0x45)
+#define IT83XX_PMC_MBXCTRL REG8(IT83XX_PMC_BASE+0x19)
+#define IT83XX_PMC_MBXEC_00 REG8(IT83XX_PMC_BASE+0xF0)
+#define IT83XX_PMC_MBXEC_01 REG8(IT83XX_PMC_BASE+0xF1)
+#define IT83XX_PMC_MBXEC_02 REG8(IT83XX_PMC_BASE+0xF2)
+#define IT83XX_PMC_MBXEC_03 REG8(IT83XX_PMC_BASE+0xF3)
+#define IT83XX_PMC_MBXEC_04 REG8(IT83XX_PMC_BASE+0xF4)
+#define IT83XX_PMC_MBXEC_05 REG8(IT83XX_PMC_BASE+0xF5)
+#define IT83XX_PMC_MBXEC_06 REG8(IT83XX_PMC_BASE+0xF6)
+#define IT83XX_PMC_MBXEC_07 REG8(IT83XX_PMC_BASE+0xF7)
+#define IT83XX_PMC_MBXEC_08 REG8(IT83XX_PMC_BASE+0xF8)
+#define IT83XX_PMC_MBXEC_09 REG8(IT83XX_PMC_BASE+0xF9)
+#define IT83XX_PMC_MBXEC_10 REG8(IT83XX_PMC_BASE+0xFA)
+#define IT83XX_PMC_MBXEC_11 REG8(IT83XX_PMC_BASE+0xFB)
+#define IT83XX_PMC_MBXEC_12 REG8(IT83XX_PMC_BASE+0xFC)
+#define IT83XX_PMC_MBXEC_13 REG8(IT83XX_PMC_BASE+0xFD)
+#define IT83XX_PMC_MBXEC_14 REG8(IT83XX_PMC_BASE+0xFE)
+#define IT83XX_PMC_MBXEC_15 REG8(IT83XX_PMC_BASE+0xFF)
+
+/* Keyboard Matrix Scan control (KBS) */
+#define IT83XX_KBS_BASE 0x00F01D00
+
+#define IT83XX_KBS_KSOL REG8(IT83XX_KBS_BASE+0x00)
+#define IT83XX_KBS_KSOH1 REG8(IT83XX_KBS_BASE+0x01)
+#define IT83XX_KBS_KSOCTRL REG8(IT83XX_KBS_BASE+0x02)
+#define IT83XX_KBS_KSOH2 REG8(IT83XX_KBS_BASE+0x03)
+#define IT83XX_KBS_KSI REG8(IT83XX_KBS_BASE+0x04)
+#define IT83XX_KBS_KSICTRL REG8(IT83XX_KBS_BASE+0x05)
+#define IT83XX_KBS_KSIGCTRL REG8(IT83XX_KBS_BASE+0x06)
+#define IT83XX_KBS_KSIGOEN REG8(IT83XX_KBS_BASE+0x07)
+#define IT83XX_KBS_KSIGDAT REG8(IT83XX_KBS_BASE+0x08)
+#define IT83XX_KBS_KSIGDMRR REG8(IT83XX_KBS_BASE+0x09)
+#define IT83XX_KBS_KSOHGCTRL REG8(IT83XX_KBS_BASE+0x0A)
+#define IT83XX_KBS_KSOHGOEN REG8(IT83XX_KBS_BASE+0x0B)
+#define IT83XX_KBS_KSOHGDMRR REG8(IT83XX_KBS_BASE+0x0C)
+#define IT83XX_KBS_KSOLGCTRL REG8(IT83XX_KBS_BASE+0x0D)
+#define IT83XX_KBS_KSOLGOEN REG8(IT83XX_KBS_BASE+0x0E)
+#define IT83XX_KBS_KSOLGDMRR REG8(IT83XX_KBS_BASE+0x0F)
+#define IT83XX_KBS_KSO0LSDR REG8(IT83XX_KBS_BASE+0x10)
+#define IT83XX_KBS_KSO1LSDR REG8(IT83XX_KBS_BASE+0x11)
+#define IT83XX_KBS_KSO2LSDR REG8(IT83XX_KBS_BASE+0x12)
+#define IT83XX_KBS_KSO3LSDR REG8(IT83XX_KBS_BASE+0x13)
+#define IT83XX_KBS_KSO4LSDR REG8(IT83XX_KBS_BASE+0x14)
+#define IT83XX_KBS_KSO5LSDR REG8(IT83XX_KBS_BASE+0x15)
+#define IT83XX_KBS_KSO6LSDR REG8(IT83XX_KBS_BASE+0x16)
+#define IT83XX_KBS_KSO7LSDR REG8(IT83XX_KBS_BASE+0x17)
+#define IT83XX_KBS_KSO8LSDR REG8(IT83XX_KBS_BASE+0x18)
+#define IT83XX_KBS_KSO9LSDR REG8(IT83XX_KBS_BASE+0x19)
+#define IT83XX_KBS_KSO10LSDR REG8(IT83XX_KBS_BASE+0x1A)
+#define IT83XX_KBS_KSO11LSDR REG8(IT83XX_KBS_BASE+0x1B)
+#define IT83XX_KBS_KSO12LSDR REG8(IT83XX_KBS_BASE+0x1C)
+#define IT83XX_KBS_KSO13LSDR REG8(IT83XX_KBS_BASE+0x1D)
+#define IT83XX_KBS_KSO14LSDR REG8(IT83XX_KBS_BASE+0x1E)
+#define IT83XX_KBS_KSO15LSDR REG8(IT83XX_KBS_BASE+0x1F)
+#define IT83XX_KBS_KSO16LSDR REG8(IT83XX_KBS_BASE+0x20)
+#define IT83XX_KBS_KSO17LSDR REG8(IT83XX_KBS_BASE+0x21)
+#define IT83XX_KBS_SDC1R REG8(IT83XX_KBS_BASE+0x22)
+#define IT83XX_KBS_SDC2R REG8(IT83XX_KBS_BASE+0x23)
+#define IT83XX_KBS_SDC3R REG8(IT83XX_KBS_BASE+0x24)
+#define IT83XX_KBS_SDSR REG8(IT83XX_KBS_BASE+0x25)
+
/* --- MISC (not implemented yet) --- */
#define IT83XX_SMFI_BASE 0x00F01000
-#define IT83XX_KBC_BASE 0x00F01300
-#define IT83XX_PMC_BASE 0x00F01500
#define IT83XX_PS2_BASE 0x00F01700
#define IT83XX_DAC_BASE 0x00F01A00
#define IT83XX_WUC_BASE 0x00F01B00
#define IT83XX_SMB_BASE 0x00F01C00
-#define IT83XX_KBS_BASE 0x00F01D00
#define IT83XX_EGPIO_BASE 0x00F02100
#define IT83XX_BRAM_BASE 0x00F02200
#define IT83XX_CIR_BASE 0x00F02300
diff --git a/core/nds32/init.S b/core/nds32/init.S
index 0f2c0710d6..23483e59b0 100644
--- a/core/nds32/init.S
+++ b/core/nds32/init.S
@@ -95,6 +95,12 @@ reset:
li $r0, 0x00080005
mtsr $r0, $mr7
+ /* Enable DLM 8k~12K(bit2) and DLM 12k~16k(bit3) */
+ la $r1, 0x00F02030
+ lbi $r0, [$r1]
+ ori $r0, $r0, 0x0C
+ sbi $r0, [$r1]
+
/* Clear BSS */
la $r0, _bss_start
lwi $r1, [$r0]