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"
|
bool "ITE IT8XXX2 embedded controller ESPI driver"
|
||||||
default y
|
default y
|
||||||
depends on DT_HAS_ITE_IT8XXX2_ESPI_ENABLED
|
depends on DT_HAS_ITE_IT8XXX2_ESPI_ENABLED
|
||||||
depends on SOC_IT8XXX2
|
depends on SOC_IT8XXX2 || SOC_IT51XXX
|
||||||
help
|
help
|
||||||
Enable ITE IT8XXX2 ESPI driver.
|
Enable ITE IT8XXX2 ESPI driver.
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <zephyr/drivers/espi.h>
|
#include <zephyr/drivers/espi.h>
|
||||||
#include <zephyr/drivers/gpio.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/drivers/interrupt_controller/wuc_ite_it8xxx2.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/sys/util.h>
|
#include <zephyr/sys/util.h>
|
||||||
|
@ -21,8 +22,7 @@
|
||||||
#include <zephyr/irq.h>
|
#include <zephyr/irq.h>
|
||||||
LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
|
LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
|
||||||
|
|
||||||
#define ESPI_IT8XXX2_GET_GCTRL_BASE \
|
#define ESPI_ITE_GET_GCTRL_BASE ((struct gctrl_ite_ec_regs *)DT_REG_ADDR(DT_NODELABEL(gctrl)))
|
||||||
((struct gctrl_it8xxx2_regs *)DT_REG_ADDR(DT_NODELABEL(gctrl)))
|
|
||||||
|
|
||||||
#define IT8XXX2_ESPI_IRQ DT_INST_IRQ_BY_IDX(0, 0, irq)
|
#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)
|
#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)
|
static void smfi_it8xxx2_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct espi_it8xxx2_config *const config = dev->config;
|
const struct espi_it8xxx2_config *const config = dev->config;
|
||||||
struct smfi_it8xxx2_regs *const smfi_reg =
|
struct smfi_ite_ec_regs *const smfi_reg = (struct smfi_ite_ec_regs *)config->base_smfi;
|
||||||
(struct smfi_it8xxx2_regs *)config->base_smfi;
|
|
||||||
struct gctrl_it8xxx2_regs *const gctrl = ESPI_IT8XXX2_GET_GCTRL_BASE;
|
#ifdef CONFIG_SOC_SERIES_IT8XXX2
|
||||||
|
struct gctrl_ite_ec_regs *const gctrl = ESPI_ITE_GET_GCTRL_BASE;
|
||||||
uint8_t h2ram_offset;
|
uint8_t h2ram_offset;
|
||||||
|
|
||||||
/* Set the host to RAM cycle address 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 =
|
||||||
(gctrl->GCTRL_H2ROFSR & ~IT8XXX2_ESPI_H2RAM_OFFSET_MASK) |
|
(gctrl->GCTRL_H2ROFSR & ~IT8XXX2_ESPI_H2RAM_OFFSET_MASK) |
|
||||||
h2ram_offset;
|
h2ram_offset;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD
|
#ifdef CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD
|
||||||
memset(&h2ram_pool[CONFIG_ESPI_PERIPHERAL_HOST_CMD_PARAM_PORT_NUM], 0,
|
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) \
|
#define PNPCFG(_s) \
|
||||||
pnpcfg_it8xxx2_configure(dev, _s##_settings, ARRAY_SIZE(_s##_settings))
|
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)
|
static void pnpcfg_it8xxx2_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct espi_it8xxx2_config *const config = dev->config;
|
const struct espi_it8xxx2_config *const config = dev->config;
|
||||||
struct ec2i_regs *const ec2i = (struct ec2i_regs *)config->base_ec2i;
|
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 */
|
/* The register pair to access PNPCFG is 004Eh and 004Fh */
|
||||||
gctrl->GCTRL_BADRSEL = 0x1;
|
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) || \
|
#if defined(CONFIG_ESPI_PERIPHERAL_EC_HOST_CMD) || \
|
||||||
defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
|
defined(CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION)
|
||||||
PNPCFG(smfi);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1086,7 +1098,7 @@ static void pmc1_it8xxx2_init(const struct device *dev)
|
||||||
static void port80_it8xxx2_isr(const struct device *dev)
|
static void port80_it8xxx2_isr(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct espi_it8xxx2_data *const data = dev->data;
|
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 = {
|
struct espi_event evt = {
|
||||||
ESPI_BUS_PERIPHERAL_NOTIFICATION,
|
ESPI_BUS_PERIPHERAL_NOTIFICATION,
|
||||||
(ESPI_PERIPHERAL_INDEX_0 << 16) | ESPI_PERIPHERAL_DEBUG_PORT80,
|
(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)
|
static void port80_it8xxx2_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(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 */
|
/* Accept Port 80h (and 81h) Cycle */
|
||||||
if (IS_ENABLED(CONFIG_ESPI_IT8XXX2_PORT_81_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 {
|
} else {
|
||||||
irq_disable(IT8XXX2_TRANS_IRQ);
|
irq_disable(IT8XXX2_TRANS_IRQ);
|
||||||
/* Clear pending interrupt */
|
/* 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);
|
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
|
#define ESPI_IT8XXX2_ESPI_RESET_PIN 2
|
||||||
static void espi_it8xxx2_enable_reset(void)
|
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;
|
static struct gpio_callback espi_reset_cb;
|
||||||
|
|
||||||
/* eSPI reset is enabled on GPD2 */
|
/* 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_vw_regs *)config->base_espi_vw;
|
||||||
struct espi_slave_regs *const slave_reg =
|
struct espi_slave_regs *const slave_reg =
|
||||||
(struct espi_slave_regs *)config->base_espi_slave;
|
(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 */
|
/* configure VCC detector */
|
||||||
gctrl->GCTRL_RSTS = (gctrl->GCTRL_RSTS &
|
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;
|
slave_reg->ESGCTRL2 |= IT8XXX2_ESPI_TO_WUC_ENABLE;
|
||||||
|
|
||||||
/* Enable WU42 of WUI */
|
/* 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_clear_status(config->wuc.wucs, config->wuc.mask);
|
||||||
it8xxx2_wuc_enable(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
|
* Only register isr here, the interrupt only need to be enabled
|
||||||
* before CPU and RAM clocks gated in the idle function.
|
* before CPU and RAM clocks gated in the idle function.
|
||||||
|
|
|
@ -1189,6 +1189,31 @@
|
||||||
kso17-gpios = <&gpioc 5 (GPIO_OPEN_DRAIN | GPIO_PULL_UP)>;
|
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 {
|
twd0: watchdog@f04780 {
|
||||||
compatible = "ite,it51xxx-watchdog";
|
compatible = "ite,it51xxx-watchdog";
|
||||||
reg = <0x00f04780 0x20>;
|
reg = <0x00f04780 0x20>;
|
||||||
|
|
|
@ -267,8 +267,16 @@ struct gctrl_it51xxx_regs {
|
||||||
volatile uint8_t reserved_1d_1f[3];
|
volatile uint8_t reserved_1d_1f[3];
|
||||||
/* 0x20: Reset Control 5 */
|
/* 0x20: Reset Control 5 */
|
||||||
volatile uint8_t GCTRL_RSTC5;
|
volatile uint8_t GCTRL_RSTC5;
|
||||||
/* 0x21-0x37: reserved_21_37 */
|
/* 0x21-0x2f: reserved_21_2f */
|
||||||
volatile uint8_t reserved_21_37[23];
|
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 */
|
/* 0x38: Special Control 9 */
|
||||||
volatile uint8_t GCTRL_SPCTRL9;
|
volatile uint8_t GCTRL_SPCTRL9;
|
||||||
/* 0x39-0x46: reserved_39_46 */
|
/* 0x39-0x46: reserved_39_46 */
|
||||||
|
|
|
@ -377,6 +377,19 @@ SECTIONS
|
||||||
|
|
||||||
__data_region_end = .;
|
__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_end = .;
|
||||||
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
|
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <soc_common.h>
|
#include <soc_common.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
|
|
||||||
|
#include "soc_espi.h"
|
||||||
|
|
||||||
static mm_reg_t ecpm_base = DT_REG_ADDR(DT_NODELABEL(ecpm));
|
static mm_reg_t ecpm_base = DT_REG_ADDR(DT_NODELABEL(ecpm));
|
||||||
/* it51xxx ECPM registers definition */
|
/* it51xxx ECPM registers definition */
|
||||||
/* 0x03: PLL Control */
|
/* 0x03: PLL Control */
|
||||||
|
@ -57,12 +59,25 @@ void riscv_idle(enum chip_pll_mode mode, unsigned int key)
|
||||||
csr_clear(mie, MIP_MEIP);
|
csr_clear(mie, MIP_MEIP);
|
||||||
sys_trace_idle();
|
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 doze after wfi instruction */
|
||||||
chip_pll_ctrl(mode);
|
chip_pll_ctrl(mode);
|
||||||
|
|
||||||
/* Wait for interrupt */
|
/* Wait for interrupt */
|
||||||
__asm__ volatile("wfi");
|
__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
|
* Enable M-mode external interrupt
|
||||||
* An interrupt can not be fired yet until we enable global interrupt
|
* An interrupt can not be fired yet until we enable global interrupt
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue