From 2c3cf4d1a9d6ed732985ea495e8ebfe1d09a916b Mon Sep 17 00:00:00 2001 From: Dino Li Date: Fri, 20 Mar 2015 17:14:45 +0800 Subject: it8380dev: add KBC/KMSC module 1. DLM 16KB. 2. Add KBC/KMSC module for emulation board. Signed-off-by: Dino Li 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 Tested-by: Dino Li Commit-Queue: Dino Li --- board/it8380dev/board.c | 21 +++++- board/it8380dev/board.h | 14 +++- board/it8380dev/ec.tasklist | 7 +- board/it8380dev/gpio.inc | 47 ++++++------ chip/it83xx/build.mk | 4 +- chip/it83xx/config_chip.h | 6 +- chip/it83xx/gpio.c | 8 ++ chip/it83xx/intc.c | 36 +++++++++ chip/it83xx/intc.h | 14 ++++ chip/it83xx/keyboard_raw.c | 138 +++++++++++++++++++++++++++++++++ chip/it83xx/kmsc_chip.h | 13 ++++ chip/it83xx/lpc.c | 180 ++++++++++++++++++++++++++++++++++++++++++++ chip/it83xx/registers.h | 178 +++++++++++++++++++++++++++++++++++-------- core/nds32/init.S | 6 ++ 14 files changed, 610 insertions(+), 62 deletions(-) create mode 100644 chip/it83xx/intc.c create mode 100644 chip/it83xx/intc.h create mode 100644 chip/it83xx/keyboard_raw.c create mode 100644 chip/it83xx/kmsc_chip.h create mode 100644 chip/it83xx/lpc.c 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] -- cgit v1.2.1