diff options
-rw-r--r-- | board/it8380dev/board.c | 8 | ||||
-rw-r--r-- | board/it8380dev/board.h | 4 | ||||
-rw-r--r-- | chip/it83xx/ec2i_chip.h | 5 | ||||
-rw-r--r-- | chip/it83xx/lpc.c | 81 | ||||
-rw-r--r-- | chip/it83xx/registers.h | 9 |
5 files changed, 100 insertions, 7 deletions
diff --git a/board/it8380dev/board.c b/board/it8380dev/board.c index 326ad09c9a..9808a91f97 100644 --- a/board/it8380dev/board.c +++ b/board/it8380dev/board.c @@ -146,6 +146,14 @@ const struct ec2i_t pnpcfg_settings[] = { {HOST_INDEX_IRQNUMX, 0x00}, /* Enable logical device */ {HOST_INDEX_LDA, 0x01}, + /* Select logical device 10h(RTCT) */ + {HOST_INDEX_LDN, LDN_RTCT}, + /* P80L Begin Index */ + {HOST_INDEX_DSLDC4, P80L_P80LB}, + /* P80L End Index */ + {HOST_INDEX_DSLDC5, P80L_P80LE}, + /* P80L Current Index */ + {HOST_INDEX_DSLDC6, P80L_P80LC}, }; BUILD_ASSERT(ARRAY_SIZE(pnpcfg_settings) == EC2I_SETTING_COUNT); diff --git a/board/it8380dev/board.h b/board/it8380dev/board.h index e143d9a76a..b477ed9c3d 100644 --- a/board/it8380dev/board.h +++ b/board/it8380dev/board.h @@ -90,6 +90,10 @@ enum ec2i_setting { EC2I_SET_PMC3_BASE1_LSB, EC2I_SET_PMC3_IRQ, EC2I_SET_PMC3_ENABLE, + EC2I_SET_RTCT_LDN, + EC2I_SET_RTCT_P80LB, + EC2I_SET_RTCT_P80LE, + EC2I_SET_RTCT_P80LC, /* Number of EC2I settings */ EC2I_SETTING_COUNT }; diff --git a/chip/it83xx/ec2i_chip.h b/chip/it83xx/ec2i_chip.h index 953903226b..7b9fe1cf4e 100644 --- a/chip/it83xx/ec2i_chip.h +++ b/chip/it83xx/ec2i_chip.h @@ -8,6 +8,11 @@ #ifndef __CROS_EC_EC2I_CHIP_H #define __CROS_EC_EC2I_CHIP_H +#define P80L_P80LB 0 +#define P80L_P80LE 0x3F +#define P80L_P80LC 0 +#define P80L_BRAM_BANK1_MAX_SIZE 0x3F + /* Index list of the host interface registers of PNPCFG */ enum host_pnpcfg_index { /* Logical Device Number */ diff --git a/chip/it83xx/lpc.c b/chip/it83xx/lpc.c index c8ff8d0109..1ffc82d117 100644 --- a/chip/it83xx/lpc.c +++ b/chip/it83xx/lpc.c @@ -9,9 +9,11 @@ #include "clock.h" #include "common.h" #include "console.h" +#include "ec2i_chip.h" #include "gpio.h" #include "hooks.h" #include "host_command.h" +#include "irq_chip.h" #include "keyboard_protocol.h" #include "lpc.h" #include "port80.h" @@ -22,7 +24,6 @@ #include "timer.h" #include "uart.h" #include "util.h" -#include "irq_chip.h" /* Console output macros */ #define CPUTS(outstr) cputs(CC_LPC, outstr) @@ -62,6 +63,7 @@ static uint8_t host_cmd_flags; /* Flags from host command */ /* Params must be 32-bit aligned */ static uint8_t params_copy[EC_LPC_HOST_PACKET_SIZE] __aligned(4); static int init_done; +static int p80l_index; static uint8_t * const cmd_params = (uint8_t *)host_cmd_memmap + EC_LPC_ADDR_HOST_PARAM - EC_LPC_ADDR_HOST_ARGS; @@ -99,6 +101,12 @@ static void pm_put_data_out(enum lpc_pm_ch ch, uint8_t out) IT83XX_PMC_PMDO(ch) = out; } +static void pm_clear_ibf(enum lpc_pm_ch ch) +{ + /* bit7, write-1 clear IBF */ + IT83XX_PMC_PMIE(ch) |= (1 << 7); +} + /** * Generate SMI pulse to the host chipset via GPIO. * @@ -269,7 +277,7 @@ void lpc_keyboard_put_char(uint8_t chr, int send_irq) * 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; + IT83XX_KBC_KBHICR &= 0x3C; /* * Enable the interrupt to keyboard driver in the host processor @@ -288,7 +296,12 @@ void lpc_keyboard_put_char(uint8_t chr, int send_irq) void lpc_keyboard_clear_buffer(void) { - /* --- (not implemented yet) --- */ + uint32_t int_mask = get_int_mask(); + interrupt_disable(); + /* bit6, write-1 clear OBF */ + IT83XX_KBC_KBHICR |= (1 << 6); + IT83XX_KBC_KBHICR &= ~(1 << 6); + set_int_mask(int_mask); } void lpc_keyboard_resume_irq(void) @@ -378,6 +391,9 @@ void lpc_kbc_ibf_interrupt(void) if (lpc_keyboard_input_pending()) { keyboard_host_write(IT83XX_KBC_KBHIDIR, (IT83XX_KBC_KBHISR & 0x08) ? 1 : 0); + /* bit7, write-1 clear IBF */ + IT83XX_KBC_KBHICR |= (1 << 7); + IT83XX_KBC_KBHICR &= ~(1 << 7); } task_clear_pending_irq(IT83XX_IRQ_KBC_IN); @@ -423,6 +439,8 @@ void pm1_ibf_interrupt(void) if (acpi_ap_to_ec(is_cmd, value, &result)) pm_put_data_out(LPC_ACPI_CMD, result); + pm_clear_ibf(LPC_ACPI_CMD); + /* Clear the busy bit */ pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_PROCESSING, 0); @@ -452,6 +470,7 @@ void pm2_ibf_interrupt(void) if (!(status & EC_LPC_STATUS_LAST_CMD)) { /* R/C IBF*/ value = pm_get_data_in(LPC_HOST_CMD); + pm_clear_ibf(LPC_HOST_CMD); task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); return; } @@ -487,6 +506,7 @@ void pm2_ibf_interrupt(void) lpc_packet.driver_result = EC_RES_SUCCESS; host_packet_receive(&lpc_packet); + pm_clear_ibf(LPC_HOST_CMD); task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); return; } else { @@ -497,29 +517,55 @@ void pm2_ibf_interrupt(void) /* Hand off to host command handler */ host_command_received(&host_cmd_args); + pm_clear_ibf(LPC_HOST_CMD); task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); } void pm3_ibf_interrupt(void) { - if (pm_get_status(LPC_HOST_PORT_80H) & EC_LPC_STATUS_FROM_HOST) - port_80_write(pm_get_data_in(LPC_HOST_PORT_80H)); + int new_p80_idx, i; + enum ec2i_message ec2i_r; + + /* set LDN */ + if (ec2i_write(HOST_INDEX_LDN, LDN_RTCT) == EC2I_WRITE_SUCCESS) { + /* get P80L current index */ + ec2i_r = ec2i_read(HOST_INDEX_DSLDC6); + /* clear IBF */ + pm_clear_ibf(LPC_HOST_PORT_80H); + /* read OK */ + if ((ec2i_r & 0xff00) == EC2I_READ_SUCCESS) { + new_p80_idx = ec2i_r & P80L_BRAM_BANK1_MAX_SIZE; + for (i = 0; i < P80L_BRAM_BANK1_MAX_SIZE; i++) { + if (++p80l_index > P80L_P80LE) + p80l_index = P80L_P80LB; + port_80_write(IT83XX_BRAM_BANK1(p80l_index)); + if (p80l_index == new_p80_idx) + break; + } + } + } else { + pm_clear_ibf(LPC_HOST_PORT_80H); + } task_clear_pending_irq(IT83XX_IRQ_PMC3_IN); } void pm4_ibf_interrupt(void) { + pm_clear_ibf(LPC_PM4); task_clear_pending_irq(IT83XX_IRQ_PMC4_IN); } void pm5_ibf_interrupt(void) { + pm_clear_ibf(LPC_PM5); task_clear_pending_irq(IT83XX_IRQ_PMC5_IN); } static void lpc_init(void) { + enum ec2i_message ec2i_r; + /* * DLM 52k~56k size select enable. * For mapping LPC I/O cycle 800h ~ 9FFh to DLM 8D800 ~ 8D9FF. @@ -537,8 +583,15 @@ static void lpc_init(void) /* * bit2, Output Buffer Empty CPU Interrupt Enable. * bit3, Input Buffer Full CPU Interrupt Enable. + * bit5, IBF/OBF EC clear mode. + * 0b: IBF cleared if EC read data register, EC reset, or host reset. + * OBF cleared if host read data register, or EC reset. + * 1b: IBF cleared if EC write-1 to bit7 at related registers, + * EC reset, or host reset. + * OBF cleared if host read data register, EC write-1 to bit6 at + * related registers, or EC reset. */ - IT83XX_KBC_KBHICR |= 0x0C; + IT83XX_KBC_KBHICR |= 0x2C; /* PM1 Input Buffer Full Interrupt Enable for 62h/66 port */ pm_set_ctrl(LPC_ACPI_CMD, PM_CTRL_IBFIE, 1); @@ -609,6 +662,22 @@ static void lpc_init(void) /* PM3 Input Buffer Full Interrupt Enable for 80h port */ pm_set_ctrl(LPC_HOST_PORT_80H, PM_CTRL_IBFIE, 1); + p80l_index = P80L_P80LC; + if (ec2i_write(HOST_INDEX_LDN, LDN_RTCT) == EC2I_WRITE_SUCCESS) { + /* get P80L current index */ + ec2i_r = ec2i_read(HOST_INDEX_DSLDC6); + /* read OK */ + if ((ec2i_r & 0xff00) == EC2I_READ_SUCCESS) + p80l_index = ec2i_r & P80L_BRAM_BANK1_MAX_SIZE; + } + + /* + * bit[7], enable P80L function. + * bit[6], accept port 80h cycle. + * bit[1-0], 10b: I2EC is read-only. + */ + IT83XX_GCTRL_SPCTRL1 |= 0xC2; + gpio_enable_interrupt(GPIO_PCH_PLTRST_L); task_clear_pending_irq(IT83XX_IRQ_KBC_OUT); diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h index 3cfeede2cf..2d2cd14ccf 100644 --- a/chip/it83xx/registers.h +++ b/chip/it83xx/registers.h @@ -642,6 +642,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) +#define IT83XX_GCTRL_SPCTRL1 REG8(IT83XX_GCTRL_BASE+0x0D) #define IT83XX_GCTRL_RSTC4 REG8(IT83XX_GCTRL_BASE+0x11) #define IT83XX_GCTRL_SPCTRL4 REG8(IT83XX_GCTRL_BASE+0x1C) #define IT83XX_GCTRL_MCCR REG8(IT83XX_GCTRL_BASE+0x30) @@ -817,6 +818,8 @@ enum clock_gate_offsets { REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 2 : 4) + (ch << 4)) #define IT83XX_PMC_PMCTL(ch) \ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 3 : 6) + (ch << 4)) +#define IT83XX_PMC_PMIE(ch) \ +REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 5 : 8) + (ch << 4)) /* Keyboard Matrix Scan control (KBS) */ #define IT83XX_KBS_BASE 0x00F01D00 @@ -936,13 +939,17 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 3 : 6) + (ch << 4)) #define IT83XX_SMB_SMBPCTL(ch) REG8(IT83XX_SMB_BASE+0x4A+(ch << 6)) #define IT83XX_SMB_HOCTL2(ch) REG8(IT83XX_SMB_BASE+0x50+(ch << 6)) +/* BRAM */ +#define IT83XX_BRAM_BASE 0x00F02200 + +#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_BRAM_BASE 0x00F02200 #define IT83XX_CIR_BASE 0x00F02300 #define IT83XX_DBGR_BASE 0x00F02500 #define IT83XX_OW_BASE 0x00F02A00 |