diff --git a/drivers/espi/Kconfig.it8xxx2 b/drivers/espi/Kconfig.it8xxx2 index 6c19eb2514c..f9a57f34738 100644 --- a/drivers/espi/Kconfig.it8xxx2 +++ b/drivers/espi/Kconfig.it8xxx2 @@ -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. diff --git a/drivers/espi/espi_it8xxx2.c b/drivers/espi/espi_it8xxx2.c index 8e904cd1943..02bf92828ee 100644 --- a/drivers/espi/espi_it8xxx2.c +++ b/drivers/espi/espi_it8xxx2.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -21,8 +22,7 @@ #include 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. diff --git a/dts/riscv/ite/it51xxx.dtsi b/dts/riscv/ite/it51xxx.dtsi index 9144b85945f..7ad32212967 100644 --- a/dts/riscv/ite/it51xxx.dtsi +++ b/dts/riscv/ite/it51xxx.dtsi @@ -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 = ; + interrupt-parent = <&intc>; + wucctrl = <&wuc_wu42>; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + }; + twd0: watchdog@f04780 { compatible = "ite,it51xxx-watchdog"; reg = <0x00f04780 0x20>; diff --git a/soc/ite/ec/it51xxx/chip_chipregs.h b/soc/ite/ec/it51xxx/chip_chipregs.h index a60e959bf7e..d550ceaf7b3 100644 --- a/soc/ite/ec/it51xxx/chip_chipregs.h +++ b/soc/ite/ec/it51xxx/chip_chipregs.h @@ -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 */ diff --git a/soc/ite/ec/it51xxx/linker.ld b/soc/ite/ec/it51xxx/linker.ld index 219f6118db8..4884157116a 100644 --- a/soc/ite/ec/it51xxx/linker.ld +++ b/soc/ite/ec/it51xxx/linker.ld @@ -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; diff --git a/soc/ite/ec/it51xxx/soc.c b/soc/ite/ec/it51xxx/soc.c index 657c31131ed..79eca7e5c28 100644 --- a/soc/ite/ec/it51xxx/soc.c +++ b/soc/ite/ec/it51xxx/soc.c @@ -7,6 +7,8 @@ #include #include +#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