it83xx: add espi module

Add espi control module for it83xx.

Signed-off-by: Dino Li <dino.li@ite.com.tw>

BRANCH=none
BUG=none
TEST=1. it8390+Intel SKL-Y RVP3 and boot to shell.
     2. console command "kbpress 1 4" to test keyboard data.
     (board code for espi module test on CL:392587)

Change-Id: I1b32bd16f7e01abf07b9c9a68ebef2399cc9828d
Reviewed-on: https://chromium-review.googlesource.com/394471
Commit-Ready: Dino Li <Dino.Li@ite.com.tw>
Tested-by: Dino Li <Dino.Li@ite.com.tw>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
Dino Li
2017-11-14 10:55:55 +08:00
committed by chrome-bot
parent 385c276e4b
commit 2bb1811f07
11 changed files with 514 additions and 2 deletions

View File

@@ -9,7 +9,9 @@
* Note: Those with interrupt handlers must be declared first. */
GPIO_INT(POWER_BUTTON_L, PIN(E, 4), GPIO_INT_BOTH | GPIO_PULL_UP, power_button_interrupt)
#ifndef CONFIG_ESPI_VW_SIGNALS
GPIO_INT(PCH_PLTRST_L, PIN(E, 3), GPIO_INT_BOTH | GPIO_PULL_UP, lpcrst_interrupt)
#endif
GPIO_INT(LID_OPEN, PIN(E, 2), GPIO_INT_BOTH | GPIO_PULL_DOWN, lid_interrupt)
GPIO_INT(WP_L, PIN(E, 1), GPIO_INT_BOTH, switch_interrupt) /* Write protect input */
#ifdef CONFIG_LOW_POWER_IDLE

View File

@@ -20,7 +20,9 @@ GPIO_INT(PCH_SLP_S0_L, PIN(B, 7), GPIO_INT_BOTH, power_signal_interrupt) /*
#endif
GPIO_INT(SUSPWRNACK, PIN(E, 1), GPIO_INT_BOTH, power_signal_interrupt) /* SUSPWRNACK */
GPIO_INT(LID_OPEN, PIN(E, 2), GPIO_INT_BOTH, lid_interrupt) /* LID_OPEN */
#ifndef CONFIG_ESPI_VW_SIGNALS
GPIO_INT(PCH_PLTRST_L, PIN(E, 3), GPIO_INT_BOTH | GPIO_PULL_UP, lpcrst_interrupt) /* PLT_RST_L */
#endif
GPIO_INT(POWER_BUTTON_L, PIN(E, 4), GPIO_INT_BOTH, power_button_interrupt) /* MECH_PWR_BTN_ODL */
GPIO_INT(ALL_SYS_PGOOD, PIN(F, 0), GPIO_INT_BOTH, power_signal_interrupt) /* PMIC_EC_PWROK_OD */
GPIO_INT(RSMRST_L_PGOOD, PIN(F, 1), GPIO_INT_BOTH, power_signal_interrupt) /* PMIC_EC_RSMRST_ODL */

View File

@@ -21,6 +21,7 @@ chip-$(CONFIG_PWM)+=pwm.o
chip-$(CONFIG_ADC)+=adc.o
chip-$(CONFIG_EC2I)+=ec2i.o
chip-$(CONFIG_LPC)+=lpc.o
chip-$(CONFIG_ESPI)+=espi.o
chip-$(CONFIG_SPI)+=spi.o
chip-$(CONFIG_PECI)+=peci.o
chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o

387
chip/it83xx/espi.c Normal file
View File

@@ -0,0 +1,387 @@
/* Copyright 2017 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.
*/
/* ESPI module for Chrome EC */
#include "console.h"
#include "espi.h"
#include "hooks.h"
#include "port80.h"
#include "power.h"
#include "registers.h"
#include "system.h"
#include "task.h"
#include "uart.h"
#include "util.h"
#define CHIP_ESPI_VW_INTERRUPT_NUM 8
/* Console output macros */
#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args)
struct vw_channel_t {
uint8_t index; /* VW index of signal */
uint8_t level_mask; /* level bit of signal */
uint8_t valid_mask; /* valid bit of signal */
};
/* VW settings at initialization */
static const struct vw_channel_t vw_init_setting[] = {
{ESPI_SYSTEM_EVENT_VW_IDX_4,
VW_LEVEL_FIELD(0),
VW_VALID_FIELD(VW_IDX_4_OOB_RST_ACK)},
{ESPI_SYSTEM_EVENT_VW_IDX_5,
VW_LEVEL_FIELD(VW_IDX_5_BTLD_STATUS_DONE),
VW_VALID_FIELD(VW_IDX_5_BTLD_STATUS_DONE)},
{ESPI_SYSTEM_EVENT_VW_IDX_40,
VW_LEVEL_FIELD(0),
VW_VALID_FIELD(VW_IDX_40_SUS_ACK)},
};
/* VW settings at host startup */
static const struct vw_channel_t vw_host_startup_setting[] = {
{ESPI_SYSTEM_EVENT_VW_IDX_6,
VW_LEVEL_FIELD(VW_IDX_6_SCI | VW_IDX_6_SMI |
VW_IDX_6_RCIN | VW_IDX_6_HOST_RST_ACK),
VW_VALID_FIELD(VW_IDX_6_SCI | VW_IDX_6_SMI |
VW_IDX_6_RCIN | VW_IDX_6_HOST_RST_ACK)},
};
#define VW_CHAN(name, idx, level, valid) \
[(name - VW_SIGNAL_BASE)] = {idx, level, valid}
/* VW signals used in eSPI (NOTE: must match order of enum espi_vw_signal). */
static const struct vw_channel_t vw_channel_list[] = {
/* index 02h: master to slave. */
VW_CHAN(VW_SLP_S3_L,
ESPI_SYSTEM_EVENT_VW_IDX_2,
VW_LEVEL_FIELD(VW_IDX_2_SLP_S3),
VW_VALID_FIELD(VW_IDX_2_SLP_S3)),
VW_CHAN(VW_SLP_S4_L,
ESPI_SYSTEM_EVENT_VW_IDX_2,
VW_LEVEL_FIELD(VW_IDX_2_SLP_S4),
VW_VALID_FIELD(VW_IDX_2_SLP_S4)),
VW_CHAN(VW_SLP_S5_L,
ESPI_SYSTEM_EVENT_VW_IDX_2,
VW_LEVEL_FIELD(VW_IDX_2_SLP_S5),
VW_VALID_FIELD(VW_IDX_2_SLP_S5)),
/* index 03h: master to slave. */
VW_CHAN(VW_SUS_STAT_L,
ESPI_SYSTEM_EVENT_VW_IDX_3,
VW_LEVEL_FIELD(VW_IDX_3_SUS_STAT),
VW_VALID_FIELD(VW_IDX_3_SUS_STAT)),
VW_CHAN(VW_PLTRST_L,
ESPI_SYSTEM_EVENT_VW_IDX_3,
VW_LEVEL_FIELD(VW_IDX_3_PLTRST),
VW_VALID_FIELD(VW_IDX_3_PLTRST)),
VW_CHAN(VW_OOB_RST_WARN,
ESPI_SYSTEM_EVENT_VW_IDX_3,
VW_LEVEL_FIELD(VW_IDX_3_OOB_RST_WARN),
VW_VALID_FIELD(VW_IDX_3_OOB_RST_WARN)),
/* index 04h: slave to master. */
VW_CHAN(VW_OOB_RST_ACK,
ESPI_SYSTEM_EVENT_VW_IDX_4,
VW_LEVEL_FIELD(VW_IDX_4_OOB_RST_ACK),
VW_VALID_FIELD(VW_IDX_4_OOB_RST_ACK)),
VW_CHAN(VW_WAKE_L,
ESPI_SYSTEM_EVENT_VW_IDX_4,
VW_LEVEL_FIELD(VW_IDX_4_WAKE),
VW_VALID_FIELD(VW_IDX_4_WAKE)),
VW_CHAN(VW_PME_L,
ESPI_SYSTEM_EVENT_VW_IDX_4,
VW_LEVEL_FIELD(VW_IDX_4_PME),
VW_VALID_FIELD(VW_IDX_4_PME)),
/* index 05h: slave to master. */
VW_CHAN(VW_ERROR_FATAL,
ESPI_SYSTEM_EVENT_VW_IDX_5,
VW_LEVEL_FIELD(VW_IDX_5_FATAL),
VW_VALID_FIELD(VW_IDX_5_FATAL)),
VW_CHAN(VW_ERROR_NON_FATAL,
ESPI_SYSTEM_EVENT_VW_IDX_5,
VW_LEVEL_FIELD(VW_IDX_5_NON_FATAL),
VW_VALID_FIELD(VW_IDX_5_NON_FATAL)),
VW_CHAN(VW_SLAVE_BTLD_STATUS_DONE,
ESPI_SYSTEM_EVENT_VW_IDX_5,
VW_LEVEL_FIELD(VW_IDX_5_BTLD_STATUS_DONE),
VW_VALID_FIELD(VW_IDX_5_BTLD_STATUS_DONE)),
/* index 06h: slave to master. */
VW_CHAN(VW_SCI_L,
ESPI_SYSTEM_EVENT_VW_IDX_6,
VW_LEVEL_FIELD(VW_IDX_6_SCI),
VW_VALID_FIELD(VW_IDX_6_SCI)),
VW_CHAN(VW_SMI_L,
ESPI_SYSTEM_EVENT_VW_IDX_6,
VW_LEVEL_FIELD(VW_IDX_6_SMI),
VW_VALID_FIELD(VW_IDX_6_SMI)),
VW_CHAN(VW_RCIN_L,
ESPI_SYSTEM_EVENT_VW_IDX_6,
VW_LEVEL_FIELD(VW_IDX_6_RCIN),
VW_VALID_FIELD(VW_IDX_6_RCIN)),
VW_CHAN(VW_HOST_RST_ACK,
ESPI_SYSTEM_EVENT_VW_IDX_6,
VW_LEVEL_FIELD(VW_IDX_6_HOST_RST_ACK),
VW_VALID_FIELD(VW_IDX_6_HOST_RST_ACK)),
/* index 07h: master to slave. */
VW_CHAN(VW_HOST_RST_WARN,
ESPI_SYSTEM_EVENT_VW_IDX_7,
VW_LEVEL_FIELD(VW_IDX_7_HOST_RST_WARN),
VW_VALID_FIELD(VW_IDX_7_HOST_RST_WARN)),
/* index 40h: slave to master. */
VW_CHAN(VW_SUS_ACK,
ESPI_SYSTEM_EVENT_VW_IDX_40,
VW_LEVEL_FIELD(VW_IDX_40_SUS_ACK),
VW_VALID_FIELD(VW_IDX_40_SUS_ACK)),
/* index 41h: master to slave. */
VW_CHAN(VW_SUS_WARN_L,
ESPI_SYSTEM_EVENT_VW_IDX_41,
VW_LEVEL_FIELD(VW_IDX_41_SUS_WARN),
VW_VALID_FIELD(VW_IDX_41_SUS_WARN)),
VW_CHAN(VW_SUS_PWRDN_ACK_L,
ESPI_SYSTEM_EVENT_VW_IDX_41,
VW_LEVEL_FIELD(VW_IDX_41_SUS_PWRDN_ACK),
VW_VALID_FIELD(VW_IDX_41_SUS_PWRDN_ACK)),
VW_CHAN(VW_SLP_A_L,
ESPI_SYSTEM_EVENT_VW_IDX_41,
VW_LEVEL_FIELD(VW_IDX_41_SLP_A),
VW_VALID_FIELD(VW_IDX_41_SLP_A)),
/* index 42h: master to slave. */
VW_CHAN(VW_SLP_LAN,
ESPI_SYSTEM_EVENT_VW_IDX_42,
VW_LEVEL_FIELD(VW_IDX_42_SLP_LAN),
VW_VALID_FIELD(VW_IDX_42_SLP_LAN)),
VW_CHAN(VW_SLP_WLAN,
ESPI_SYSTEM_EVENT_VW_IDX_42,
VW_LEVEL_FIELD(VW_IDX_42_SLP_WLAN),
VW_VALID_FIELD(VW_IDX_42_SLP_WLAN)),
};
BUILD_ASSERT(ARRAY_SIZE(vw_channel_list) ==
(VW_SIGNAL_BASE_END - VW_SIGNAL_BASE));
/* Get vw index & value information by signal */
static int espi_vw_get_signal_index(enum espi_vw_signal event)
{
uint32_t i = event - VW_SIGNAL_BASE;
return (i < ARRAY_SIZE(vw_channel_list)) ? i : -1;
}
/**
* Set eSPI Virtual-Wire signal to Host
*
* @param signal vw signal needs to set
* @param level level of vw signal
* @return EC_SUCCESS, or non-zero if error.
*/
int espi_vw_set_wire(enum espi_vw_signal signal, uint8_t level)
{
/* Get index of vw signal list by signale name */
int i = espi_vw_get_signal_index(signal);
if (i < 0)
return EC_ERROR_PARAM1;
/* critical section with interrupts off */
interrupt_disable();
if (level)
IT83XX_ESPI_VWIDX(vw_channel_list[i].index) |=
vw_channel_list[i].level_mask;
else
IT83XX_ESPI_VWIDX(vw_channel_list[i].index) &=
~vw_channel_list[i].level_mask;
/* restore interrupts */
interrupt_enable();
return EC_SUCCESS;
}
/**
* Get eSPI Virtual-Wire signal from host
*
* @param signal vw signal needs to get
* @return 1: set by host, otherwise: no signal
*/
int espi_vw_get_wire(enum espi_vw_signal signal)
{
/* Get index of vw signal list by signale name */
int i = espi_vw_get_signal_index(signal);
if (i < 0)
return 0;
/* Not valid */
if (!(IT83XX_ESPI_VWIDX(vw_channel_list[i].index) &
vw_channel_list[i].valid_mask))
return 0;
return !!(IT83XX_ESPI_VWIDX(vw_channel_list[i].index) &
vw_channel_list[i].level_mask);
}
/**
* Enable VW interrupt of power sequence signal
*
* @param signal vw signal needs to enable interrupt
* @return EC_SUCCESS, or non-zero if error.
*/
int espi_vw_enable_wire_int(enum espi_vw_signal signal)
{
/*
* Common code calls this function to enable VW interrupt of power
* sequence signal.
* IT83xx only use a bit (bit7@IT83XX_ESPI_VWCTRL0) to enable VW
* interrupt.
* VW interrupt will be triggerd with any updated VW index flag
* if this control bit is set.
* So we will always return success here.
*/
return EC_SUCCESS;
}
/**
* Disable VW interrupt of power sequence signal
*
* @param signal vw signal needs to disable interrupt
* @return EC_SUCCESS, or non-zero if error.
*/
int espi_vw_disable_wire_int(enum espi_vw_signal signal)
{
/*
* We can't disable VW interrupt of power sequence signal
* individually.
*/
return EC_ERROR_UNIMPLEMENTED;
}
static void espi_vw_host_startup(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(vw_host_startup_setting); i++)
IT83XX_ESPI_VWIDX(vw_host_startup_setting[i].index) =
(vw_host_startup_setting[i].level_mask |
vw_host_startup_setting[i].valid_mask);
}
static void espi_vw_no_isr(uint8_t flag_changed)
{
}
static void espi_vw_idx41_isr(uint8_t flag_changed)
{
if (flag_changed & VW_LEVEL_FIELD(VW_IDX_41_SUS_WARN))
espi_vw_set_wire(VW_SUS_ACK, espi_vw_get_wire(VW_SUS_WARN_L));
}
static void espi_vw_idx7_isr(uint8_t flag_changed)
{
if (flag_changed & VW_LEVEL_FIELD(VW_IDX_7_HOST_RST_WARN))
espi_vw_set_wire(VW_HOST_RST_ACK,
espi_vw_get_wire(VW_HOST_RST_WARN));
}
static void espi_vw_idx3_isr(uint8_t flag_changed)
{
if (flag_changed & VW_LEVEL_FIELD(VW_IDX_3_PLTRST)) {
int pltrst = espi_vw_get_wire(VW_PLTRST_L);
if (pltrst)
espi_vw_host_startup();
else
/* Store port 80 reset event */
port_80_write(PORT_80_EVENT_RESET);
CPRINTS("PLTRST_L %sasserted", pltrst ? "de" : "");
}
if (flag_changed & VW_LEVEL_FIELD(VW_IDX_3_OOB_RST_WARN))
espi_vw_set_wire(VW_OOB_RST_ACK,
espi_vw_get_wire(VW_OOB_RST_WARN));
}
static void espi_vw_idx2_isr(uint8_t flag_changed)
{
if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S3))
power_signal_interrupt(VW_SLP_S3_L);
if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S4))
power_signal_interrupt(VW_SLP_S4_L);
if (flag_changed & VW_LEVEL_FIELD(VW_IDX_2_SLP_S5))
power_signal_interrupt(VW_SLP_S5_L);
}
struct vw_interrupt_t {
void (*vw_isr)(uint8_t flag_changed);
uint8_t vw_index;
};
static const struct vw_interrupt_t vw_isr_list[CHIP_ESPI_VW_INTERRUPT_NUM] = {
{espi_vw_idx2_isr, ESPI_SYSTEM_EVENT_VW_IDX_2},
{espi_vw_idx3_isr, ESPI_SYSTEM_EVENT_VW_IDX_3},
{espi_vw_idx7_isr, ESPI_SYSTEM_EVENT_VW_IDX_7},
{espi_vw_idx41_isr, ESPI_SYSTEM_EVENT_VW_IDX_41},
{espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_42},
{espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_43},
{espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_44},
{espi_vw_no_isr, ESPI_SYSTEM_EVENT_VW_IDX_47},
};
/*
* This is used to record the previous VW valid / level field state to discover
* changes. Then do following sequence only when state is changed.
*/
static uint8_t vw_index_flag[CHIP_ESPI_VW_INTERRUPT_NUM];
void espi_vw_interrupt(void)
{
int i;
uint8_t vwidx_updated = IT83XX_ESPI_VWCTRL1;
/*
* TODO(b:68918637): write-1 clear bug.
* for now, we have to write 0xff to clear pending bit.
*/
#if 0
IT83XX_ESPI_VWCTRL1 = vwidx_updated;
#else
IT83XX_ESPI_VWCTRL1 = 0xff;
#endif
task_clear_pending_irq(IT83XX_IRQ_ESPI_VW);
for (i = 0; i < CHIP_ESPI_VW_INTERRUPT_NUM; i++) {
if (vwidx_updated & (1 << i)) {
uint8_t idx_flag;
idx_flag = IT83XX_ESPI_VWIDX(vw_isr_list[i].vw_index);
vw_isr_list[i].vw_isr(vw_index_flag[i] ^ idx_flag);
vw_index_flag[i] = idx_flag;
}
}
}
void espi_interrupt(void)
{
}
void espi_init(void)
{
int i;
/* TODO: PLL change won't success if eSPI chip select is low. */
#if (PLL_CLOCK != 48000000)
#error "Not support PLL change if eSPI module is enabled. "
#endif
for (i = 0; i < ARRAY_SIZE(vw_init_setting); i++)
IT83XX_ESPI_VWIDX(vw_init_setting[i].index) =
(vw_init_setting[i].level_mask |
vw_init_setting[i].valid_mask);
for (i = 0; i < CHIP_ESPI_VW_INTERRUPT_NUM; i++)
vw_index_flag[i] = IT83XX_ESPI_VWIDX(vw_isr_list[i].vw_index);
task_clear_pending_irq(IT83XX_IRQ_ESPI_VW);
/* bit7: VW interrupt enable */
IT83XX_ESPI_VWCTRL0 |= (1 << 7);
task_enable_irq(IT83XX_IRQ_ESPI_VW);
}

View File

@@ -106,6 +106,15 @@ void intc_cpu_int_group_12(void)
peci_interrupt();
break;
#endif
#ifdef CONFIG_ESPI
case IT83XX_IRQ_ESPI:
espi_interrupt();
break;
case IT83XX_IRQ_ESPI_VW:
espi_vw_interrupt();
break;
#endif
#ifdef CONFIG_USB_PD_TCPM_ITE83XX
case IT83XX_IRQ_USBPD0:
chip_pd_irq(USBPD_PORT_A);

View File

@@ -23,5 +23,8 @@ void i2c_interrupt(int port);
void clock_sleep_mode_wakeup_isr(void);
int clock_ec_wake_from_sleep(void);
void __enter_hibernate(uint32_t seconds, uint32_t microseconds);
void espi_interrupt(void);
void espi_vw_interrupt(void);
void espi_init(void);
#endif /* __CROS_EC_INTC_H */

View File

@@ -11,9 +11,11 @@
#include "common.h"
#include "console.h"
#include "ec2i_chip.h"
#include "espi.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "intc.h"
#include "irq_chip.h"
#include "keyboard_protocol.h"
#include "lpc.h"
@@ -363,10 +365,12 @@ void lpc_clear_acpi_status_mask(uint8_t mask)
pm_set_status(LPC_ACPI_CMD, mask, 0);
}
#ifndef CONFIG_ESPI_VW_SIGNALS
int lpc_get_pltrst_asserted(void)
{
return !gpio_get_level(GPIO_PCH_PLTRST_L);
}
#endif
/* KBC and PMC control modules */
void lpc_kbc_ibf_interrupt(void)
@@ -663,7 +667,9 @@ static void lpc_init(void)
*/
IT83XX_GCTRL_SPCTRL1 |= 0xC2;
#ifndef CONFIG_ESPI_VW_SIGNALS
gpio_enable_interrupt(GPIO_PCH_PLTRST_L);
#endif
task_clear_pending_irq(IT83XX_IRQ_KBC_OUT);
task_disable_irq(IT83XX_IRQ_KBC_OUT);
@@ -682,6 +688,9 @@ static void lpc_init(void)
task_clear_pending_irq(IT83XX_IRQ_PMC3_IN);
task_enable_irq(IT83XX_IRQ_PMC3_IN);
#ifdef CONFIG_ESPI
espi_init();
#endif
/* Sufficiently initialized */
init_done = 1;
@@ -694,6 +703,21 @@ static void lpc_init(void)
*/
DECLARE_HOOK(HOOK_INIT, lpc_init, HOOK_PRIO_INIT_LPC);
void lpc_host_reset(void)
{
/* Host Reset Control will assert RCIN# */
#ifdef CONFIG_ESPI_VW_SIGNALS
espi_vw_set_wire(VW_RCIN_L, 0);
udelay(10);
espi_vw_set_wire(VW_RCIN_L, 1);
#else
gpio_set_level(GPIO_PCH_RCIN_L, 0);
udelay(10);
gpio_set_level(GPIO_PCH_RCIN_L, 1);
#endif
}
#ifndef CONFIG_ESPI_VW_SIGNALS
void lpcrst_interrupt(enum gpio_signal signal)
{
if (lpc_get_pltrst_asserted())
@@ -703,6 +727,7 @@ void lpcrst_interrupt(enum gpio_signal signal)
CPRINTS("LPC RESET# %sasserted",
lpc_get_pltrst_asserted() ? "" : "de");
}
#endif
/* Enable LPC ACPI-EC interrupts */
void lpc_enable_acpi_interrupts(void)

View File

@@ -761,6 +761,7 @@ enum clock_gate_offsets {
#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_RSTDMMC REG8(IT83XX_GCTRL_BASE+0x10)
#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)
@@ -1203,6 +1204,75 @@ enum usbpd_port {
#define USB_VID_ITE 0x048d
#define IT83XX_ESPI_BASE 0x00F03100
/* eSPI VW */
#define IT83XX_ESPI_VW_BASE 0x00F03200
#define IT83XX_ESPI_VWIDX(i) REG8(IT83XX_ESPI_VW_BASE+(i))
#define VW_LEVEL_FIELD(f) ((f) << 0)
#define VW_VALID_FIELD(f) ((f) << 4)
#define ESPI_SYSTEM_EVENT_VW_IDX_2 0x2
#define VW_IDX_2_SLP_S3 (1 << 0)
#define VW_IDX_2_SLP_S4 (1 << 1)
#define VW_IDX_2_SLP_S5 (1 << 2)
#define ESPI_SYSTEM_EVENT_VW_IDX_3 0x3
#define VW_IDX_3_SUS_STAT (1 << 0)
#define VW_IDX_3_PLTRST (1 << 1)
#define VW_IDX_3_OOB_RST_WARN (1 << 2)
#define ESPI_SYSTEM_EVENT_VW_IDX_4 0x4
#define VW_IDX_4_OOB_RST_ACK (1 << 0)
#define VW_IDX_4_WAKE (1 << 2)
#define VW_IDX_4_PME (1 << 3)
#define ESPI_SYSTEM_EVENT_VW_IDX_5 0x5
#define VW_IDX_5_SLAVE_BTLD_DONE (1 << 0)
#define VW_IDX_5_FATAL (1 << 1)
#define VW_IDX_5_NON_FATAL (1 << 2)
#define VW_IDX_5_SLAVE_BTLD_STATUS (1 << 3)
#define VW_IDX_5_BTLD_STATUS_DONE (VW_IDX_5_SLAVE_BTLD_DONE | \
VW_IDX_5_SLAVE_BTLD_STATUS)
#define ESPI_SYSTEM_EVENT_VW_IDX_6 0x6
#define VW_IDX_6_SCI (1 << 0)
#define VW_IDX_6_SMI (1 << 1)
#define VW_IDX_6_RCIN (1 << 2)
#define VW_IDX_6_HOST_RST_ACK (1 << 3)
#define ESPI_SYSTEM_EVENT_VW_IDX_7 0x7
#define VW_IDX_7_HOST_RST_WARN (1 << 0)
#define ESPI_SYSTEM_EVENT_VW_IDX_40 0x40
#define VW_IDX_40_SUS_ACK (1 << 0)
#define ESPI_SYSTEM_EVENT_VW_IDX_41 0x41
#define VW_IDX_41_SUS_WARN (1 << 0)
#define VW_IDX_41_SUS_PWRDN_ACK (1 << 1)
#define VW_IDX_41_SLP_A (1 << 3)
#define ESPI_SYSTEM_EVENT_VW_IDX_42 0x42
#define VW_IDX_42_SLP_LAN (1 << 0)
#define VW_IDX_42_SLP_WLAN (1 << 1)
#define ESPI_SYSTEM_EVENT_VW_IDX_43 0x43
#define ESPI_SYSTEM_EVENT_VW_IDX_44 0x44
#define ESPI_SYSTEM_EVENT_VW_IDX_47 0x47
#define IT83XX_ESPI_VWCTRL0 REG8(IT83XX_ESPI_VW_BASE+0x90)
#define IT83XX_ESPI_VWCTRL1 REG8(IT83XX_ESPI_VW_BASE+0x91)
#define IT83XX_ESPI_VWCTRL2 REG8(IT83XX_ESPI_VW_BASE+0x92)
#define IT83XX_ESPI_VWCTRL3 REG8(IT83XX_ESPI_VW_BASE+0x93)
/* eSPI Queue 0 */
#define IT83XX_ESPI_QUEUE_BASE 0x00F03300
/* PUT_PC data byte 0 - 63 */
#define IT83XX_ESPI_QUEUE_PUT_PC(i) REG8(IT83XX_ESPI_QUEUE_BASE+(i))
/* PUT_OOB data byte 0 - 79 */
#define IT83XX_ESPI_QUEUE_PUT_OOB(i) REG8(IT83XX_ESPI_QUEUE_BASE+0x80+(i))
/* Wake pin definitions, defined at board-level */
extern const enum gpio_signal hibernate_wake_pins[];
extern const int hibernate_wake_pins_used;

View File

@@ -205,6 +205,12 @@ void uart_deepsleep_interrupt(enum gpio_signal signal)
void uart_init(void)
{
/*
* bit3: uart1 belongs to the EC side.
* This is necessary for enabling eSPI module.
*/
IT83XX_GCTRL_RSTDMMC |= (1 << 3);
/* reset uart before config it */
IT83XX_GCTRL_RSTC4 |= (1 << 1);

View File

@@ -84,7 +84,13 @@ vector irq_15, 15 /* HW 15 */
.balign 16
.global eflash_sig
eflash_sig:
.byte 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xB4
.byte 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5
#ifdef CONFIG_ESPI
.byte 0xA4 /* eSPI */
#else
.byte 0xA5 /* LPC */
#endif
.byte 0xB4 /* flag of signature */
.byte 0x85, 0x12, 0x5A, 0x5A, 0xAA, 0xAA, 0x55, 0x55
/* flags: internal oscillator + implicit location */

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2016 The Chromium OS Authors. All rights reserved.
/* Copyright 2016 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.
*/
@@ -37,6 +37,7 @@ enum espi_vw_signal {
VW_SLP_A_L,
VW_SLP_LAN, /* index 42h (In) */
VW_SLP_WLAN,
VW_SIGNAL_BASE_END,
};
/**