Skip to content

Commit a41a4e5

Browse files
Dino-Licarlescufi
authored andcommitted
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 <[email protected]>
1 parent 00b5114 commit a41a4e5

File tree

7 files changed

+85
-2
lines changed

7 files changed

+85
-2
lines changed

drivers/espi/espi_it8xxx2.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
#include <assert.h>
1010
#include <zephyr/drivers/espi.h>
1111
#include <zephyr/drivers/gpio.h>
12+
#include <zephyr/drivers/interrupt_controller/wuc_ite_it8xxx2.h>
1213
#include <zephyr/kernel.h>
1314
#include <soc.h>
15+
#include <soc_dt.h>
1416
#include "soc_espi.h"
1517
#include "espi_utils.h"
1618

@@ -28,6 +30,7 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
2830
#define IT8XXX2_PMC1_IBF_IRQ DT_INST_IRQ_BY_IDX(0, 4, irq)
2931
#define IT8XXX2_PORT_80_IRQ DT_INST_IRQ_BY_IDX(0, 5, irq)
3032
#define IT8XXX2_PMC2_IBF_IRQ DT_INST_IRQ_BY_IDX(0, 6, irq)
33+
#define IT8XXX2_TRANS_IRQ DT_INST_IRQ_BY_IDX(0, 7, irq)
3134

3235
/* General Capabilities and Configuration 1 */
3336
#define IT8XXX2_ESPI_MAX_FREQ_MASK GENMASK(2, 0)
@@ -72,6 +75,13 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
7275
#define IT8XXX2_ESPI_PUT_FLASH_TAG_MASK GENMASK(7, 4)
7376
#define IT8XXX2_ESPI_PUT_FLASH_LEN_MASK GENMASK(6, 0)
7477

78+
struct espi_it8xxx2_wuc {
79+
/* WUC control device structure */
80+
const struct device *wucs;
81+
/* WUC pin mask */
82+
uint8_t mask;
83+
};
84+
7585
struct espi_it8xxx2_config {
7686
uintptr_t base_espi_slave;
7787
uintptr_t base_espi_vw;
@@ -81,6 +91,7 @@ struct espi_it8xxx2_config {
8191
uintptr_t base_kbc;
8292
uintptr_t base_pmc;
8393
uintptr_t base_smfi;
94+
const struct espi_it8xxx2_wuc wuc;
8495
};
8596

8697
struct espi_it8xxx2_data {
@@ -1755,6 +1766,28 @@ void espi_it8xxx2_enable_pad_ctrl(const struct device *dev, bool enable)
17551766
}
17561767
}
17571768

1769+
void espi_it8xxx2_enable_trans_irq(const struct device *dev, bool enable)
1770+
{
1771+
const struct espi_it8xxx2_config *const config = dev->config;
1772+
1773+
if (enable) {
1774+
irq_enable(IT8XXX2_TRANS_IRQ);
1775+
} else {
1776+
irq_disable(IT8XXX2_TRANS_IRQ);
1777+
/* Clear pending interrupt */
1778+
it8xxx2_wuc_clear_status(config->wuc.wucs, config->wuc.mask);
1779+
}
1780+
}
1781+
1782+
static void espi_it8xxx2_trans_isr(const struct device *dev)
1783+
{
1784+
/*
1785+
* This interrupt is only used to wake up CPU, there is no need to do
1786+
* anything in the isr in addition to disable interrupt.
1787+
*/
1788+
espi_it8xxx2_enable_trans_irq(dev, false);
1789+
}
1790+
17581791
void espi_it8xxx2_espi_reset_isr(const struct device *port,
17591792
struct gpio_callback *cb, uint32_t pins)
17601793
{
@@ -1804,6 +1837,7 @@ static const struct espi_it8xxx2_config espi_it8xxx2_config_0 = {
18041837
.base_kbc = DT_INST_REG_ADDR_BY_IDX(0, 5),
18051838
.base_pmc = DT_INST_REG_ADDR_BY_IDX(0, 6),
18061839
.base_smfi = DT_INST_REG_ADDR_BY_IDX(0, 7),
1840+
.wuc = IT8XXX2_DT_WUC_ITEMS_FUNC(0, 0),
18071841
};
18081842

18091843
DEVICE_DT_INST_DEFINE(0, &espi_it8xxx2_init, NULL,
@@ -1884,7 +1918,15 @@ static int espi_it8xxx2_init(const struct device *dev)
18841918
*/
18851919
slave_reg->ESGCTRL2 |= IT8XXX2_ESPI_TO_WUC_ENABLE;
18861920

1887-
/* TODO: enable WU42 of WUI */
1921+
/* Enable WU42 of WUI */
1922+
it8xxx2_wuc_clear_status(config->wuc.wucs, config->wuc.mask);
1923+
it8xxx2_wuc_enable(config->wuc.wucs, config->wuc.mask);
1924+
/*
1925+
* Only register isr here, the interrupt only need to be enabled
1926+
* before CPU and RAM clocks gated in the idle function.
1927+
*/
1928+
IRQ_CONNECT(IT8XXX2_TRANS_IRQ, 0, espi_it8xxx2_trans_isr,
1929+
DEVICE_DT_INST_GET(0), 0);
18881930

18891931
return 0;
18901932
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) 2023 ITE Corporation. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: ITE IT8XXX2 ESPI controller
5+
6+
compatible: "ite,it8xxx2-espi"
7+
8+
include: espi-controller.yaml
9+
10+
properties:
11+
wucctrl:
12+
type: phandles
13+
description: |
14+
eSPI node WUC interrupt.

dts/riscv/ite/it8xxx2-wuc-map.dtsi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
wuc_wu40: wu40 {
6262
wucs = <&wuc4 BIT(0)>; /* GPE5 */
6363
};
64+
wuc_wu42: wu42 {
65+
wucs = <&wuc4 BIT(2)>; /* eSPI transaction */
66+
};
6467
wuc_wu45: wu45 {
6568
wucs = <&wuc4 BIT(5)>; /* GPE6 */
6669
};

dts/riscv/ite/it8xxx2.dtsi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,10 @@
430430
IT8XXX2_IRQ_KBC_OBE IRQ_TYPE_LEVEL_HIGH
431431
IT8XXX2_IRQ_PMC1_IBF IRQ_TYPE_LEVEL_HIGH
432432
IT8XXX2_IRQ_PCH_P80 IRQ_TYPE_LEVEL_HIGH
433-
IT8XXX2_IRQ_PMC2_IBF IRQ_TYPE_LEVEL_HIGH>;
433+
IT8XXX2_IRQ_PMC2_IBF IRQ_TYPE_LEVEL_HIGH
434+
IT8XXX2_IRQ_WKINTD IRQ_TYPE_LEVEL_HIGH>;
434435
interrupt-parent = <&intc>;
436+
wucctrl = <&wuc_wu42>;
435437
#address-cells = <1>;
436438
#size-cells = <1>;
437439
status = "disabled";

include/zephyr/dt-bindings/interrupt-controller/ite-intc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define IT8XXX2_IRQ_WU20 1
1919
#define IT8XXX2_IRQ_KBC_OBE 2
2020
#define IT8XXX2_IRQ_SMB_D 4
21+
#define IT8XXX2_IRQ_WKINTD 5
2122
#define IT8XXX2_IRQ_WU23 6
2223
/* Group 1 */
2324
#define IT8XXX2_IRQ_SMB_A 9

soc/riscv/riscv-ite/common/soc_espi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ extern "C" {
2424
*/
2525
void espi_it8xxx2_enable_pad_ctrl(const struct device *dev, bool enable);
2626

27+
/**
28+
* @brief eSPI transaction interrupt control
29+
*
30+
* @param dev pointer to eSPI device
31+
* @param enable/disable eSPI transaction interrupt
32+
*/
33+
void espi_it8xxx2_enable_trans_irq(const struct device *dev, bool enable);
34+
2735
#ifdef __cplusplus
2836
}
2937
#endif

soc/riscv/riscv-ite/it8xxx2/soc.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,15 @@ void riscv_idle(enum chip_pll_mode mode, unsigned int key)
207207
*/
208208
csr_clear(mie, MIP_MEIP);
209209
sys_trace_idle();
210+
#ifdef CONFIG_ESPI
211+
/*
212+
* H2RAM feature requires RAM clock to be active. Since the below doze
213+
* mode will disable CPU and RAM clocks, enable eSPI transaction
214+
* interrupt to restore clocks. With this interrupt, EC will not defer
215+
* eSPI bus while transaction is accepted.
216+
*/
217+
espi_it8xxx2_enable_trans_irq(ESPI_IT8XXX2_SOC_DEV, true);
218+
#endif
210219
/* Chip doze after wfi instruction */
211220
chip_pll_ctrl(mode);
212221

@@ -223,6 +232,10 @@ void riscv_idle(enum chip_pll_mode mode, unsigned int key)
223232
*/
224233
} while (ite_intc_no_irq());
225234

235+
#ifdef CONFIG_ESPI
236+
/* CPU has been woken up, the interrupt is no longer needed */
237+
espi_it8xxx2_enable_trans_irq(ESPI_IT8XXX2_SOC_DEV, false);
238+
#endif
226239
/*
227240
* Enable M-mode external interrupt
228241
* An interrupt can not be fired yet until we enable global interrupt

0 commit comments

Comments
 (0)