espi: it8xxx2: enable espi transaction interrupt
The interrupt is used to wake up EC from low power mode. So EC does not defer eSPI bus while transaction is accepted. Fixes EC host commands slow issue. Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
This commit is contained in:
parent
00b5114344
commit
a41a4e5e24
7 changed files with 85 additions and 2 deletions
|
@ -9,8 +9,10 @@
|
|||
#include <assert.h>
|
||||
#include <zephyr/drivers/espi.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/interrupt_controller/wuc_ite_it8xxx2.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <soc.h>
|
||||
#include <soc_dt.h>
|
||||
#include "soc_espi.h"
|
||||
#include "espi_utils.h"
|
||||
|
||||
|
@ -28,6 +30,7 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
|
|||
#define IT8XXX2_PMC1_IBF_IRQ DT_INST_IRQ_BY_IDX(0, 4, irq)
|
||||
#define IT8XXX2_PORT_80_IRQ DT_INST_IRQ_BY_IDX(0, 5, irq)
|
||||
#define IT8XXX2_PMC2_IBF_IRQ DT_INST_IRQ_BY_IDX(0, 6, irq)
|
||||
#define IT8XXX2_TRANS_IRQ DT_INST_IRQ_BY_IDX(0, 7, irq)
|
||||
|
||||
/* General Capabilities and Configuration 1 */
|
||||
#define IT8XXX2_ESPI_MAX_FREQ_MASK GENMASK(2, 0)
|
||||
|
@ -72,6 +75,13 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
|
|||
#define IT8XXX2_ESPI_PUT_FLASH_TAG_MASK GENMASK(7, 4)
|
||||
#define IT8XXX2_ESPI_PUT_FLASH_LEN_MASK GENMASK(6, 0)
|
||||
|
||||
struct espi_it8xxx2_wuc {
|
||||
/* WUC control device structure */
|
||||
const struct device *wucs;
|
||||
/* WUC pin mask */
|
||||
uint8_t mask;
|
||||
};
|
||||
|
||||
struct espi_it8xxx2_config {
|
||||
uintptr_t base_espi_slave;
|
||||
uintptr_t base_espi_vw;
|
||||
|
@ -81,6 +91,7 @@ struct espi_it8xxx2_config {
|
|||
uintptr_t base_kbc;
|
||||
uintptr_t base_pmc;
|
||||
uintptr_t base_smfi;
|
||||
const struct espi_it8xxx2_wuc wuc;
|
||||
};
|
||||
|
||||
struct espi_it8xxx2_data {
|
||||
|
@ -1755,6 +1766,28 @@ void espi_it8xxx2_enable_pad_ctrl(const struct device *dev, bool enable)
|
|||
}
|
||||
}
|
||||
|
||||
void espi_it8xxx2_enable_trans_irq(const struct device *dev, bool enable)
|
||||
{
|
||||
const struct espi_it8xxx2_config *const config = dev->config;
|
||||
|
||||
if (enable) {
|
||||
irq_enable(IT8XXX2_TRANS_IRQ);
|
||||
} else {
|
||||
irq_disable(IT8XXX2_TRANS_IRQ);
|
||||
/* Clear pending interrupt */
|
||||
it8xxx2_wuc_clear_status(config->wuc.wucs, config->wuc.mask);
|
||||
}
|
||||
}
|
||||
|
||||
static void espi_it8xxx2_trans_isr(const struct device *dev)
|
||||
{
|
||||
/*
|
||||
* This interrupt is only used to wake up CPU, there is no need to do
|
||||
* anything in the isr in addition to disable interrupt.
|
||||
*/
|
||||
espi_it8xxx2_enable_trans_irq(dev, false);
|
||||
}
|
||||
|
||||
void espi_it8xxx2_espi_reset_isr(const struct device *port,
|
||||
struct gpio_callback *cb, uint32_t pins)
|
||||
{
|
||||
|
@ -1804,6 +1837,7 @@ static const struct espi_it8xxx2_config espi_it8xxx2_config_0 = {
|
|||
.base_kbc = DT_INST_REG_ADDR_BY_IDX(0, 5),
|
||||
.base_pmc = DT_INST_REG_ADDR_BY_IDX(0, 6),
|
||||
.base_smfi = DT_INST_REG_ADDR_BY_IDX(0, 7),
|
||||
.wuc = IT8XXX2_DT_WUC_ITEMS_FUNC(0, 0),
|
||||
};
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, &espi_it8xxx2_init, NULL,
|
||||
|
@ -1884,7 +1918,15 @@ static int espi_it8xxx2_init(const struct device *dev)
|
|||
*/
|
||||
slave_reg->ESGCTRL2 |= IT8XXX2_ESPI_TO_WUC_ENABLE;
|
||||
|
||||
/* TODO: enable WU42 of WUI */
|
||||
/* Enable WU42 of WUI */
|
||||
it8xxx2_wuc_clear_status(config->wuc.wucs, config->wuc.mask);
|
||||
it8xxx2_wuc_enable(config->wuc.wucs, config->wuc.mask);
|
||||
/*
|
||||
* Only register isr here, the interrupt only need to be enabled
|
||||
* before CPU and RAM clocks gated in the idle function.
|
||||
*/
|
||||
IRQ_CONNECT(IT8XXX2_TRANS_IRQ, 0, espi_it8xxx2_trans_isr,
|
||||
DEVICE_DT_INST_GET(0), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
14
dts/bindings/espi/ite,it8xxx2-espi.yaml
Normal file
14
dts/bindings/espi/ite,it8xxx2-espi.yaml
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Copyright (c) 2023 ITE Corporation. All Rights Reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: ITE IT8XXX2 ESPI controller
|
||||
|
||||
compatible: "ite,it8xxx2-espi"
|
||||
|
||||
include: espi-controller.yaml
|
||||
|
||||
properties:
|
||||
wucctrl:
|
||||
type: phandles
|
||||
description: |
|
||||
eSPI node WUC interrupt.
|
|
@ -61,6 +61,9 @@
|
|||
wuc_wu40: wu40 {
|
||||
wucs = <&wuc4 BIT(0)>; /* GPE5 */
|
||||
};
|
||||
wuc_wu42: wu42 {
|
||||
wucs = <&wuc4 BIT(2)>; /* eSPI transaction */
|
||||
};
|
||||
wuc_wu45: wu45 {
|
||||
wucs = <&wuc4 BIT(5)>; /* GPE6 */
|
||||
};
|
||||
|
|
|
@ -430,8 +430,10 @@
|
|||
IT8XXX2_IRQ_KBC_OBE IRQ_TYPE_LEVEL_HIGH
|
||||
IT8XXX2_IRQ_PMC1_IBF IRQ_TYPE_LEVEL_HIGH
|
||||
IT8XXX2_IRQ_PCH_P80 IRQ_TYPE_LEVEL_HIGH
|
||||
IT8XXX2_IRQ_PMC2_IBF IRQ_TYPE_LEVEL_HIGH>;
|
||||
IT8XXX2_IRQ_PMC2_IBF IRQ_TYPE_LEVEL_HIGH
|
||||
IT8XXX2_IRQ_WKINTD IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-parent = <&intc>;
|
||||
wucctrl = <&wuc_wu42>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
status = "disabled";
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define IT8XXX2_IRQ_WU20 1
|
||||
#define IT8XXX2_IRQ_KBC_OBE 2
|
||||
#define IT8XXX2_IRQ_SMB_D 4
|
||||
#define IT8XXX2_IRQ_WKINTD 5
|
||||
#define IT8XXX2_IRQ_WU23 6
|
||||
/* Group 1 */
|
||||
#define IT8XXX2_IRQ_SMB_A 9
|
||||
|
|
|
@ -24,6 +24,14 @@ extern "C" {
|
|||
*/
|
||||
void espi_it8xxx2_enable_pad_ctrl(const struct device *dev, bool enable);
|
||||
|
||||
/**
|
||||
* @brief eSPI transaction interrupt control
|
||||
*
|
||||
* @param dev pointer to eSPI device
|
||||
* @param enable/disable eSPI transaction interrupt
|
||||
*/
|
||||
void espi_it8xxx2_enable_trans_irq(const struct device *dev, bool enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -207,6 +207,15 @@ 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_it8xxx2_enable_trans_irq(ESPI_IT8XXX2_SOC_DEV, true);
|
||||
#endif
|
||||
/* Chip doze after wfi instruction */
|
||||
chip_pll_ctrl(mode);
|
||||
|
||||
|
@ -223,6 +232,10 @@ void riscv_idle(enum chip_pll_mode mode, unsigned int key)
|
|||
*/
|
||||
} while (ite_intc_no_irq());
|
||||
|
||||
#ifdef CONFIG_ESPI
|
||||
/* CPU has been woken up, the interrupt is no longer needed */
|
||||
espi_it8xxx2_enable_trans_irq(ESPI_IT8XXX2_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