Skip to content

espi/it8xxx2: waiting till completion of VW send to host #89703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 55 additions & 34 deletions drivers/espi/espi_it8xxx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,12 @@ IT8XXX2_ESPI_REG_SIZE_CHECK(espi_queue1_regs, 0xc0);
IT8XXX2_ESPI_REG_OFFSET_CHECK(espi_queue1_regs, UPSTREAM_DATA, 0x00);
IT8XXX2_ESPI_REG_OFFSET_CHECK(espi_queue1_regs, PUT_FLASH_NP_DATA, 0x80);

/* Register used to record VWx data transmitted to the eSPI host. */
#define IT8XXX2_ESPI_VW_REC_VW4 0xe1
#define IT8XXX2_ESPI_VW_REC_VW5 0xe2
#define IT8XXX2_ESPI_VW_REC_VW6 0xe3
#define IT8XXX2_ESPI_VW_REC_VW40 0xe4

struct espi_it8xxx2_wuc {
/* WUC control device structure */
const struct device *wucs;
Expand Down Expand Up @@ -682,9 +688,10 @@ struct espi_it8xxx2_data {
};

struct vw_channel_t {
uint8_t vw_index; /* VW index of signal */
uint8_t level_mask; /* level bit of signal */
uint8_t valid_mask; /* valid bit of signal */
uint8_t vw_index; /* VW index of signal */
uint8_t level_mask; /* level bit of signal */
uint8_t valid_mask; /* valid bit of signal */
uint8_t vw_sent_reg; /* vw signal sent to host */
};

struct vwidx_isr_t {
Expand Down Expand Up @@ -1171,41 +1178,44 @@ static void pmc2_it8xxx2_init(const struct device *dev)
}
#endif

#define IT8XXX2_ESPI_VW_SEND_TIMEOUT_US (USEC_PER_MSEC * 10)

/* eSPI api functions */
#define VW_CHAN(signal, index, level, valid) \
[signal] = {.vw_index = index, .level_mask = level, .valid_mask = valid}
#define VW_CHAN(signal, index, level, valid, reg) \
[signal] = {.vw_index = index, .level_mask = level, \
.valid_mask = valid, .vw_sent_reg = reg}

/* VW signals used in eSPI */
static const struct vw_channel_t vw_channel_list[] = {
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_S3, 0x02, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_S4, 0x02, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_S5, 0x02, BIT(2), BIT(6)),
VW_CHAN(ESPI_VWIRE_SIGNAL_OOB_RST_WARN, 0x03, BIT(2), BIT(6)),
VW_CHAN(ESPI_VWIRE_SIGNAL_PLTRST, 0x03, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SUS_STAT, 0x03, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_NMIOUT, 0x07, BIT(2), BIT(6)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SMIOUT, 0x07, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_HOST_RST_WARN, 0x07, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_A, 0x41, BIT(3), BIT(7)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SUS_PWRDN_ACK, 0x41, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SUS_WARN, 0x41, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_WLAN, 0x42, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_LAN, 0x42, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_HOST_C10, 0x47, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_DNX_WARN, 0x4a, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_PME, 0x04, BIT(3), BIT(7)),
VW_CHAN(ESPI_VWIRE_SIGNAL_WAKE, 0x04, BIT(2), BIT(6)),
VW_CHAN(ESPI_VWIRE_SIGNAL_OOB_RST_ACK, 0x04, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_TARGET_BOOT_STS, 0x05, BIT(3), BIT(7)),
VW_CHAN(ESPI_VWIRE_SIGNAL_ERR_NON_FATAL, 0x05, BIT(2), BIT(6)),
VW_CHAN(ESPI_VWIRE_SIGNAL_ERR_FATAL, 0x05, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_TARGET_BOOT_DONE, 0x05, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_HOST_RST_ACK, 0x06, BIT(3), BIT(7)),
VW_CHAN(ESPI_VWIRE_SIGNAL_RST_CPU_INIT, 0x06, BIT(2), BIT(6)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SMI, 0x06, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SCI, 0x06, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_DNX_ACK, 0x40, BIT(1), BIT(5)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SUS_ACK, 0x40, BIT(0), BIT(4)),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_S3, 0x02, BIT(0), BIT(4), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_S4, 0x02, BIT(1), BIT(5), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_S5, 0x02, BIT(2), BIT(6), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_OOB_RST_WARN, 0x03, BIT(2), BIT(6), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_PLTRST, 0x03, BIT(1), BIT(5), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SUS_STAT, 0x03, BIT(0), BIT(4), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_NMIOUT, 0x07, BIT(2), BIT(6), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SMIOUT, 0x07, BIT(1), BIT(5), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_HOST_RST_WARN, 0x07, BIT(0), BIT(4), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_A, 0x41, BIT(3), BIT(7), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SUS_PWRDN_ACK, 0x41, BIT(1), BIT(5), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SUS_WARN, 0x41, BIT(0), BIT(4), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_WLAN, 0x42, BIT(1), BIT(5), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_SLP_LAN, 0x42, BIT(0), BIT(4), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_HOST_C10, 0x47, BIT(0), BIT(4), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_DNX_WARN, 0x4a, BIT(1), BIT(5), 0),
VW_CHAN(ESPI_VWIRE_SIGNAL_PME, 0x04, BIT(3), BIT(7), IT8XXX2_ESPI_VW_REC_VW4),
VW_CHAN(ESPI_VWIRE_SIGNAL_WAKE, 0x04, BIT(2), BIT(6), IT8XXX2_ESPI_VW_REC_VW4),
VW_CHAN(ESPI_VWIRE_SIGNAL_OOB_RST_ACK, 0x04, BIT(0), BIT(4), IT8XXX2_ESPI_VW_REC_VW4),
VW_CHAN(ESPI_VWIRE_SIGNAL_TARGET_BOOT_STS, 0x05, BIT(3), BIT(7), IT8XXX2_ESPI_VW_REC_VW5),
VW_CHAN(ESPI_VWIRE_SIGNAL_ERR_NON_FATAL, 0x05, BIT(2), BIT(6), IT8XXX2_ESPI_VW_REC_VW5),
VW_CHAN(ESPI_VWIRE_SIGNAL_ERR_FATAL, 0x05, BIT(1), BIT(5), IT8XXX2_ESPI_VW_REC_VW5),
VW_CHAN(ESPI_VWIRE_SIGNAL_TARGET_BOOT_DONE, 0x05, BIT(0), BIT(4), IT8XXX2_ESPI_VW_REC_VW5),
VW_CHAN(ESPI_VWIRE_SIGNAL_HOST_RST_ACK, 0x06, BIT(3), BIT(7), IT8XXX2_ESPI_VW_REC_VW6),
VW_CHAN(ESPI_VWIRE_SIGNAL_RST_CPU_INIT, 0x06, BIT(2), BIT(6), IT8XXX2_ESPI_VW_REC_VW6),
VW_CHAN(ESPI_VWIRE_SIGNAL_SMI, 0x06, BIT(1), BIT(5), IT8XXX2_ESPI_VW_REC_VW6),
VW_CHAN(ESPI_VWIRE_SIGNAL_SCI, 0x06, BIT(0), BIT(4), IT8XXX2_ESPI_VW_REC_VW6),
VW_CHAN(ESPI_VWIRE_SIGNAL_DNX_ACK, 0x40, BIT(1), BIT(5), IT8XXX2_ESPI_VW_REC_VW40),
VW_CHAN(ESPI_VWIRE_SIGNAL_SUS_ACK, 0x40, BIT(0), BIT(4), IT8XXX2_ESPI_VW_REC_VW40),
};

static int espi_it8xxx2_configure(const struct device *dev,
Expand Down Expand Up @@ -1288,6 +1298,7 @@ static int espi_it8xxx2_send_vwire(const struct device *dev,
uint8_t vw_index = vw_channel_list[signal].vw_index;
uint8_t level_mask = vw_channel_list[signal].level_mask;
uint8_t valid_mask = vw_channel_list[signal].valid_mask;
uint8_t vw_sent = vw_channel_list[signal].vw_sent_reg;

if (signal > ARRAY_SIZE(vw_channel_list)) {
return -EIO;
Expand All @@ -1301,6 +1312,16 @@ static int espi_it8xxx2_send_vwire(const struct device *dev,

vw_reg->VW_INDEX[vw_index] |= valid_mask;

if (espi_it8xxx2_channel_ready(dev, ESPI_CHANNEL_VWIRE) && vw_sent) {
if (!WAIT_FOR(vw_reg->VW_INDEX[vw_index] ==
sys_read8(config->base_espi_vw + vw_sent),
IT8XXX2_ESPI_VW_SEND_TIMEOUT_US, k_busy_wait(10))) {
LOG_WRN("VW send to host has timed out vw[0x%x] = 0x%x",
vw_index, vw_reg->VW_INDEX[vw_index]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please return -ETIMEDOUT upon failure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Dino-Li this is still relevant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

return -ETIMEDOUT;
}
}

return 0;
}

Expand Down