drivers/espi: ite: Add it51xxx compatibility with it8xxx2 support retained
The driver originally supported only it8xxx2 series. This updates introduces compatibility allow it to also support it51xxx series with minimal changes. Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
This commit is contained in:
parent
b12717bee1
commit
a62f157118
6 changed files with 95 additions and 13 deletions
|
@ -5,7 +5,7 @@ config ESPI_IT8XXX2
|
|||
bool "ITE IT8XXX2 embedded controller ESPI driver"
|
||||
default y
|
||||
depends on DT_HAS_ITE_IT8XXX2_ESPI_ENABLED
|
||||
depends on SOC_IT8XXX2
|
||||
depends on SOC_IT8XXX2 || SOC_IT51XXX
|
||||
help
|
||||
Enable ITE IT8XXX2 ESPI driver.
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <assert.h>
|
||||
#include <zephyr/drivers/espi.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/interrupt_controller/wuc_ite_it51xxx.h>
|
||||
#include <zephyr/drivers/interrupt_controller/wuc_ite_it8xxx2.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
@ -21,8 +22,7 @@
|
|||
#include <zephyr/irq.h>
|
||||
LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
|
||||
|
||||
#define ESPI_IT8XXX2_GET_GCTRL_BASE \
|
||||
((struct gctrl_it8xxx2_regs *)DT_REG_ADDR(DT_NODELABEL(gctrl)))
|
||||
#define ESPI_ITE_GET_GCTRL_BASE ((struct gctrl_ite_ec_regs *)DT_REG_ADDR(DT_NODELABEL(gctrl)))
|
||||
|
||||
#define IT8XXX2_ESPI_IRQ DT_INST_IRQ_BY_IDX(0, 0, irq)
|
||||
#define IT8XXX2_ESPI_VW_IRQ DT_INST_IRQ_BY_IDX(0, 1, irq)
|
||||
|
@ -827,9 +827,10 @@ static const struct ec2i_t smfi_settings[] = {
|
|||
static void smfi_it8xxx2_init(const struct device *dev)
|
||||
{
|
||||
const struct espi_it8xxx2_config *const config = dev->config;
|
||||
struct smfi_it8xxx2_regs *const smfi_reg =
|
||||
(struct smfi_it8xxx2_regs *)config->base_smfi;
|
||||
struct gctrl_it8xxx2_regs *const gctrl = ESPI_IT8XXX2_GET_GCTRL_BASE;
|
||||
struct smfi_ite_ec_regs *const smfi_reg = (struct smfi_ite_ec_regs *)config->base_smfi;
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_IT8XXX2
|
||||
struct gctrl_ite_ec_regs *const gctrl = ESPI_ITE_GET_GCTRL_BASE;
|
||||
uint8_t h2ram_offset;
|
||||
|
||||
/* Set the host to RAM cycle address offset */
|
||||
|
@ -838,6 +839,7 @@ static void smfi_it8xxx2_init(const struct device *dev)
|
|||
gctrl->GCTRL_H2ROFSR =
|
||||
(gctrl->GCTRL_H2ROFSR & ~IT8XXX2_ESPI_H2RAM_OFFSET_MASK) |
|
||||
h2ram_offset;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD
|
||||
memset(&h2ram_pool[CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM], 0,
|
||||
|
@ -929,12 +931,13 @@ static void pnpcfg_it8xxx2_configure(const struct device *dev,
|
|||
|
||||
#define PNPCFG(_s) \
|
||||
pnpcfg_it8xxx2_configure(dev, _s##_settings, ARRAY_SIZE(_s##_settings))
|
||||
extern uint8_t _h2ram_pool_start[];
|
||||
|
||||
static void pnpcfg_it8xxx2_init(const struct device *dev)
|
||||
{
|
||||
const struct espi_it8xxx2_config *const config = dev->config;
|
||||
struct ec2i_regs *const ec2i = (struct ec2i_regs *)config->base_ec2i;
|
||||
struct gctrl_it8xxx2_regs *const gctrl = ESPI_IT8XXX2_GET_GCTRL_BASE;
|
||||
struct gctrl_ite_ec_regs *const gctrl = ESPI_ITE_GET_GCTRL_BASE;
|
||||
|
||||
/* The register pair to access PNPCFG is 004Eh and 004Fh */
|
||||
gctrl->GCTRL_BADRSEL = 0x1;
|
||||
|
@ -953,6 +956,15 @@ static void pnpcfg_it8xxx2_init(const struct device *dev)
|
|||
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) || \
|
||||
defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
|
||||
PNPCFG(smfi);
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_IT51XXX
|
||||
uint8_t h2ram_pool_idx;
|
||||
|
||||
h2ram_pool_idx = ((uint32_t)_h2ram_pool_start & IT8XXX2_ESPI_H2RAM_BASEADDR_MASK) /
|
||||
IT8XXX2_ESPI_H2RAM_POOL_SIZE_MAX;
|
||||
/* H2RAM 4K page select */
|
||||
ec2i_it8xxx2_write(dev, HOST_INDEX_DSLDC13, h2ram_pool_idx);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1086,7 +1098,7 @@ static void pmc1_it8xxx2_init(const struct device *dev)
|
|||
static void port80_it8xxx2_isr(const struct device *dev)
|
||||
{
|
||||
struct espi_it8xxx2_data *const data = dev->data;
|
||||
struct gctrl_it8xxx2_regs *const gctrl = ESPI_IT8XXX2_GET_GCTRL_BASE;
|
||||
struct gctrl_ite_ec_regs *const gctrl = ESPI_ITE_GET_GCTRL_BASE;
|
||||
struct espi_event evt = {
|
||||
ESPI_BUS_PERIPHERAL_NOTIFICATION,
|
||||
(ESPI_PERIPHERAL_INDEX_0 << 16) | ESPI_PERIPHERAL_DEBUG_PORT80,
|
||||
|
@ -1107,7 +1119,7 @@ static void port80_it8xxx2_isr(const struct device *dev)
|
|||
static void port80_it8xxx2_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
struct gctrl_it8xxx2_regs *const gctrl = ESPI_IT8XXX2_GET_GCTRL_BASE;
|
||||
struct gctrl_ite_ec_regs *const gctrl = ESPI_ITE_GET_GCTRL_BASE;
|
||||
|
||||
/* Accept Port 80h (and 81h) Cycle */
|
||||
if (IS_ENABLED(CONFIG_ESPI_IT8XXX2_PORT_81_CYCLE)) {
|
||||
|
@ -2395,7 +2407,11 @@ void espi_it8xxx2_enable_trans_irq(const struct device *dev, bool enable)
|
|||
} else {
|
||||
irq_disable(IT8XXX2_TRANS_IRQ);
|
||||
/* Clear pending interrupt */
|
||||
#ifdef CONFIG_SOC_SERIES_IT51XXX
|
||||
it51xxx_wuc_clear_status(config->wuc.wucs, config->wuc.mask);
|
||||
#else
|
||||
it8xxx2_wuc_clear_status(config->wuc.wucs, config->wuc.mask);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2431,7 +2447,7 @@ void espi_it8xxx2_espi_reset_isr(const struct device *port,
|
|||
#define ESPI_IT8XXX2_ESPI_RESET_PIN 2
|
||||
static void espi_it8xxx2_enable_reset(void)
|
||||
{
|
||||
struct gpio_it8xxx2_regs *const gpio_regs = GPIO_IT8XXX2_REG_BASE;
|
||||
struct gpio_ite_ec_regs *const gpio_regs = GPIO_ITE_EC_REGS_BASE;
|
||||
static struct gpio_callback espi_reset_cb;
|
||||
|
||||
/* eSPI reset is enabled on GPD2 */
|
||||
|
@ -2472,7 +2488,7 @@ static int espi_it8xxx2_init(const struct device *dev)
|
|||
(struct espi_vw_regs *)config->base_espi_vw;
|
||||
struct espi_slave_regs *const slave_reg =
|
||||
(struct espi_slave_regs *)config->base_espi_slave;
|
||||
struct gctrl_it8xxx2_regs *const gctrl = ESPI_IT8XXX2_GET_GCTRL_BASE;
|
||||
struct gctrl_ite_ec_regs *const gctrl = ESPI_ITE_GET_GCTRL_BASE;
|
||||
|
||||
/* configure VCC detector */
|
||||
gctrl->GCTRL_RSTS = (gctrl->GCTRL_RSTS &
|
||||
|
@ -2539,8 +2555,13 @@ static int espi_it8xxx2_init(const struct device *dev)
|
|||
slave_reg->ESGCTRL2 |= IT8XXX2_ESPI_TO_WUC_ENABLE;
|
||||
|
||||
/* Enable WU42 of WUI */
|
||||
#ifdef CONFIG_SOC_SERIES_IT51XXX
|
||||
it51xxx_wuc_clear_status(config->wuc.wucs, config->wuc.mask);
|
||||
it51xxx_wuc_enable(config->wuc.wucs, config->wuc.mask);
|
||||
#else
|
||||
it8xxx2_wuc_clear_status(config->wuc.wucs, config->wuc.mask);
|
||||
it8xxx2_wuc_enable(config->wuc.wucs, config->wuc.mask);
|
||||
#endif
|
||||
/*
|
||||
* Only register isr here, the interrupt only need to be enabled
|
||||
* before CPU and RAM clocks gated in the idle function.
|
||||
|
|
|
@ -1189,6 +1189,31 @@
|
|||
kso17-gpios = <&gpioc 5 (GPIO_OPEN_DRAIN | GPIO_PULL_UP)>;
|
||||
};
|
||||
|
||||
espi0: espi@f03100 {
|
||||
compatible = "ite,it8xxx2-espi";
|
||||
reg = <0x00f03100 0xd8 /* eSPI slave */
|
||||
0x00f03200 0x9a /* eSPI VW */
|
||||
0x00f03300 0xd0 /* eSPI Queue 0 */
|
||||
0x00f03400 0xc0 /* eSPI Queue 1 */
|
||||
0x00f01200 6 /* EC2I bridge */
|
||||
0x00f01300 11 /* Host KBC */
|
||||
0x00f01500 0x100 /* Host PMC */
|
||||
0x00f01000 0xd1>; /* SMFI */
|
||||
interrupts = <IT51XXX_IRQ_ESPI IRQ_TYPE_LEVEL_HIGH
|
||||
IT51XXX_IRQ_ESPI_VW IRQ_TYPE_LEVEL_HIGH
|
||||
IT51XXX_IRQ_KBC_IBF IRQ_TYPE_LEVEL_HIGH
|
||||
IT51XXX_IRQ_KBC_OBE IRQ_TYPE_LEVEL_HIGH
|
||||
IT51XXX_IRQ_PMC1_IBF IRQ_TYPE_LEVEL_HIGH
|
||||
IT51XXX_IRQ_PCH_P80 IRQ_TYPE_LEVEL_HIGH
|
||||
IT51XXX_IRQ_PMC2_IBF IRQ_TYPE_LEVEL_HIGH
|
||||
IT51XXX_IRQ_WKINTD IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-parent = <&intc>;
|
||||
wucctrl = <&wuc_wu42>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
twd0: watchdog@f04780 {
|
||||
compatible = "ite,it51xxx-watchdog";
|
||||
reg = <0x00f04780 0x20>;
|
||||
|
|
|
@ -267,8 +267,16 @@ struct gctrl_it51xxx_regs {
|
|||
volatile uint8_t reserved_1d_1f[3];
|
||||
/* 0x20: Reset Control 5 */
|
||||
volatile uint8_t GCTRL_RSTC5;
|
||||
/* 0x21-0x37: reserved_21_37 */
|
||||
volatile uint8_t reserved_21_37[23];
|
||||
/* 0x21-0x2f: reserved_21_2f */
|
||||
volatile uint8_t reserved_21_2f[15];
|
||||
/* 0x30: Port 80h/81h Status Register */
|
||||
volatile uint8_t GCTRL_P80H81HSR;
|
||||
/* 0x31: Port 80h Data Register */
|
||||
volatile uint8_t GCTRL_P80HDR;
|
||||
/* 0x32: Port 81h Data Register */
|
||||
volatile uint8_t GCTRL_P81HDR;
|
||||
/* 0x33-0x37: reserved_33_37 */
|
||||
volatile uint8_t reserved_33_37[5];
|
||||
/* 0x38: Special Control 9 */
|
||||
volatile uint8_t GCTRL_SPCTRL9;
|
||||
/* 0x39-0x46: reserved_39_46 */
|
||||
|
|
|
@ -377,6 +377,19 @@ SECTIONS
|
|||
|
||||
__data_region_end = .;
|
||||
|
||||
SECTION_DATA_PROLOGUE(.h2ram_pool,(NOLOAD),)
|
||||
{
|
||||
/*
|
||||
* Append h2ram_pool section at the end of used memory, so gap
|
||||
* due to alignment is still available for newly added variables
|
||||
*/
|
||||
. = ALIGN(0x1000);
|
||||
_h2ram_pool_start = .;
|
||||
KEEP(*(.h2ram_pool))
|
||||
_h2ram_pool_end = .;
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)
|
||||
_h2ram_pool_size = ABSOLUTE(_h2ram_pool_end - _h2ram_pool_start);
|
||||
|
||||
__kernel_ram_end = .;
|
||||
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <soc_common.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include "soc_espi.h"
|
||||
|
||||
static mm_reg_t ecpm_base = DT_REG_ADDR(DT_NODELABEL(ecpm));
|
||||
/* it51xxx ECPM registers definition */
|
||||
/* 0x03: PLL Control */
|
||||
|
@ -57,12 +59,25 @@ void riscv_idle(enum chip_pll_mode mode, unsigned int key)
|
|||
csr_clear(mie, MIP_MEIP);
|
||||
sys_trace_idle();
|
||||
|
||||
#ifdef CONFIG_ESPI
|
||||
/*
|
||||
* H2RAM feature requires RAM clock to be active. Since the below doze
|
||||
* mode will disable CPU and RAM clocks, enable eSPI transaction
|
||||
* interrupt to restore clocks. With this interrupt, EC will not defer
|
||||
* eSPI bus while transaction is accepted.
|
||||
*/
|
||||
espi_ite_ec_enable_trans_irq(ESPI_ITE_SOC_DEV, true);
|
||||
#endif
|
||||
/* Chip doze after wfi instruction */
|
||||
chip_pll_ctrl(mode);
|
||||
|
||||
/* Wait for interrupt */
|
||||
__asm__ volatile("wfi");
|
||||
|
||||
#ifdef CONFIG_ESPI
|
||||
/* CPU has been woken up, the interrupt is no longer needed */
|
||||
espi_ite_ec_enable_trans_irq(ESPI_ITE_SOC_DEV, false);
|
||||
#endif
|
||||
/*
|
||||
* Enable M-mode external interrupt
|
||||
* An interrupt can not be fired yet until we enable global interrupt
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue