drivers: espi: xec: Extend automatic warning VWire ack mechanism.

Expand configuration mechanism for additional eSPI host warnings.
Notify client driver when sleep A virtual wire is received.
Simplify virtual wire interrupt enabling.

Signed-off-by: Jose Alberto Meza <jose.a.meza.arellano@intel.com>
This commit is contained in:
Jose Alberto Meza 2020-02-10 18:05:04 -08:00 committed by Anas Nashif
commit 150eee0fb6

View file

@ -771,6 +771,43 @@ static void notify_system_state(struct device *dev,
espi_send_callbacks(&data->callbacks, dev, evt);
}
static void notify_host_warning(struct device *dev,
enum espi_vwire_signal signal)
{
u8_t status;
espi_xec_receive_vwire(dev, signal, &status);
if (!IS_ENABLED(CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE)) {
struct espi_xec_data *data =
(struct espi_xec_data *)(dev->driver_data);
struct espi_event evt = {ESPI_BUS_EVENT_VWIRE_RECEIVED, 0, 0 };
evt.evt_details = signal;
evt.evt_data = status;
espi_send_callbacks(&data->callbacks, dev, evt);
} else {
k_busy_wait(ESPI_XEC_VWIRE_ACK_DELAY);
switch (signal) {
case ESPI_VWIRE_SIGNAL_HOST_RST_WARN:
espi_xec_send_vwire(dev,
ESPI_VWIRE_SIGNAL_HOST_RST_ACK,
status);
break;
case ESPI_VWIRE_SIGNAL_SUS_WARN:
espi_xec_send_vwire(dev, ESPI_VWIRE_SIGNAL_SUS_ACK,
status);
break;
case ESPI_VWIRE_SIGNAL_OOB_RST_WARN:
espi_xec_send_vwire(dev, ESPI_VWIRE_SIGNAL_OOB_RST_ACK,
status);
break;
default:
break;
}
}
}
static void vw_slp3_isr(struct device *dev)
{
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SLP_S3);
@ -788,45 +825,22 @@ static void vw_slp5_isr(struct device *dev)
static void vw_host_rst_warn_isr(struct device *dev)
{
u8_t status;
#ifndef CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE
struct espi_xec_data *data = (struct espi_xec_data *)(dev->driver_data);
struct espi_event evt = { ESPI_BUS_EVENT_VWIRE_RECEIVED, 0, 0 };
#endif
espi_xec_receive_vwire(dev, ESPI_VWIRE_SIGNAL_HOST_RST_WARN, &status);
#ifndef CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE
evt.evt_details = ESPI_VWIRE_SIGNAL_HOST_RST_WARN;
evt.evt_details = ESPI_BUS_EVENT_VWIRE_RECEIVED;
espi_send_callbacks(&data->callbacks, dev, evt);
#else
k_busy_wait(ESPI_XEC_VWIRE_ACK_DELAY);
espi_xec_send_vwire(dev, ESPI_VWIRE_SIGNAL_HOST_RST_ACK, status);
#endif
notify_host_warning(dev, ESPI_VWIRE_SIGNAL_HOST_RST_WARN);
}
static void vw_sus_warn_isr(struct device *dev)
{
u8_t status;
notify_host_warning(dev, ESPI_VWIRE_SIGNAL_SUS_WARN);
}
#ifndef CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE
struct espi_xec_data *data = (struct espi_xec_data *)(dev->driver_data);
struct espi_event evt = { ESPI_BUS_EVENT_VWIRE_RECEIVED, 0, 0 };
#endif
static void vw_oob_rst_isr(struct device *dev)
{
notify_host_warning(dev, ESPI_VWIRE_SIGNAL_OOB_RST_WARN);
}
espi_xec_receive_vwire(dev, ESPI_VWIRE_SIGNAL_SUS_WARN, &status);
#ifndef CONFIG_ESPI_AUTOMATIC_WARNING_ACKNOWLEDGE
evt.evt_details = ESPI_BUS_EVENT_VWIRE_RECEIVED;
evt.evt_data = status;
espi_send_callbacks(&data->callbacks, dev, evt);
#else
k_busy_wait(ESPI_XEC_VWIRE_ACK_DELAY);
espi_xec_send_vwire(dev, ESPI_VWIRE_SIGNAL_SUS_ACK, status);
#endif
static void vw_sus_slp_a_isr(struct device *dev)
{
notify_system_state(dev, ESPI_VWIRE_SIGNAL_SLP_A);
}
static void ibf_isr(struct device *dev)
@ -897,13 +911,26 @@ const struct espi_isr espi_bus_isr[] = {
{MCHP_ESPI_VW_EN_GIRQ_VAL, espi_vwire_chanel_isr},
};
u8_t vw_wires_int_en[] = {
ESPI_VWIRE_SIGNAL_SLP_S3,
ESPI_VWIRE_SIGNAL_SLP_S4,
ESPI_VWIRE_SIGNAL_SLP_S5,
ESPI_VWIRE_SIGNAL_PLTRST,
ESPI_VWIRE_SIGNAL_OOB_RST_WARN,
ESPI_VWIRE_SIGNAL_HOST_RST_WARN,
ESPI_VWIRE_SIGNAL_SUS_WARN,
ESPI_VWIRE_SIGNAL_SUS_PWRDN_ACK,
};
const struct espi_isr m2s_vwires_isr[] = {
{MEC_ESPI_MSVW00_SRC0_VAL, vw_slp3_isr},
{MEC_ESPI_MSVW00_SRC1_VAL, vw_slp4_isr},
{MEC_ESPI_MSVW00_SRC2_VAL, vw_slp5_isr},
{MEC_ESPI_MSVW01_SRC1_VAL, vw_pltrst_isr},
{MEC_ESPI_MSVW01_SRC2_VAL, vw_oob_rst_isr},
{MEC_ESPI_MSVW02_SRC0_VAL, vw_host_rst_warn_isr},
{MEC_ESPI_MSVW03_SRC0_VAL, vw_sus_warn_isr},
{MEC_ESPI_MSVW03_SRC3_VAL, vw_sus_slp_a_isr},
};
const struct espi_isr peripherals_isr[] = {
@ -1054,26 +1081,15 @@ static int espi_xec_init(struct device *dev)
ESPI_PC_REGS->PC_IEN |= MCHP_ESPI_PC_IEN_EN_CHG;
/* Enable VWires interrupts */
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW00,
ESPI_VWIRE_SRC_ID0, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW00,
ESPI_VWIRE_SRC_ID1, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW00,
ESPI_VWIRE_SRC_ID2, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW01,
ESPI_VWIRE_SRC_ID0, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW01,
ESPI_VWIRE_SRC_ID1, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW01,
ESPI_VWIRE_SRC_ID2, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW02,
ESPI_VWIRE_SRC_ID0, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW03,
ESPI_VWIRE_SRC_ID0, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW03,
ESPI_VWIRE_SRC_ID1, MSVW_IRQ_SEL_EDGE_BOTH);
mec_espi_msvw_irq_sel_set(&ESPI_M2S_VW_REGS->MSVW03,
ESPI_VWIRE_SRC_ID3, MSVW_IRQ_SEL_EDGE_BOTH);
for (int i = 0; i < sizeof(vw_wires_int_en); i++) {
u8_t signal = vw_wires_int_en[i];
struct xec_signal signal_info = vw_tbl[signal];
u8_t xec_id = signal_info.xec_reg_idx;
ESPI_MSVW_REG *reg = &(ESPI_M2S_VW_REGS->MSVW00) + xec_id;
mec_espi_msvw_irq_sel_set(reg, signal_info.bit,
MSVW_IRQ_SEL_EDGE_BOTH);
}
/* Enable interrupts for each logical channel enable assertion */
MCHP_GIRQ_ENSET(config->bus_girq_id) = MCHP_ESPI_ESPI_RST_GIRQ_VAL |