summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/it8380dev/board.c8
-rw-r--r--board/it8380dev/board.h4
-rw-r--r--chip/it83xx/ec2i_chip.h5
-rw-r--r--chip/it83xx/lpc.c81
-rw-r--r--chip/it83xx/registers.h9
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