From e17e29b1ee453bdf49d1bd9e0672446c7f159cb2 Mon Sep 17 00:00:00 2001 From: Marcin Szymczyk Date: Mon, 16 Dec 2024 15:12:07 +0100 Subject: [PATCH] drivers: mbox: nrf_vevif_event: add workaround for nRF54L errata 16 Prevent events from being triggered again on the next CNT0 event. Signed-off-by: Marcin Szymczyk --- drivers/mbox/Kconfig.nrf_vevif_event | 4 ++++ drivers/mbox/mbox_nrf_vevif_event_rx.c | 30 ++++++++++++++++++++------ drivers/mbox/mbox_nrf_vevif_event_tx.c | 8 +++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/drivers/mbox/Kconfig.nrf_vevif_event b/drivers/mbox/Kconfig.nrf_vevif_event index c9d634dac828c06..94a9658d9a9ee0d 100644 --- a/drivers/mbox/Kconfig.nrf_vevif_event +++ b/drivers/mbox/Kconfig.nrf_vevif_event @@ -14,3 +14,7 @@ config MBOX_NRF_VEVIF_EVENT_TX default y help Mailbox driver for transmitting events from VPR to a remote core + +config MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16 + bool "Apply errata 16 for nRF54L series" + default y if SOC_SERIES_NRF54LX diff --git a/drivers/mbox/mbox_nrf_vevif_event_rx.c b/drivers/mbox/mbox_nrf_vevif_event_rx.c index 4b2760fe5a98c0d..f2fc96599f80667 100644 --- a/drivers/mbox/mbox_nrf_vevif_event_rx.c +++ b/drivers/mbox/mbox_nrf_vevif_event_rx.c @@ -13,6 +13,12 @@ #define EVENTS_IDX_MIN NRF_VPR_EVENTS_TRIGGERED_MIN #define EVENTS_IDX_MAX NRF_VPR_EVENTS_TRIGGERED_MAX +#if defined(CONFIG_MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16) +#define VEVIF_54L_EVENT_IDX 20 +BUILD_ASSERT(DT_INST_PROP(0, nordic_events) == 1); +BUILD_ASSERT(DT_INST_PROP(0, nordic_events_mask) & BIT(VEVIF_54L_EVENT_IDX)); +#endif + /* callbacks */ struct mbox_vevif_event_rx_cbs { mbox_callback_t cb[EVENTS_IDX_MAX - EVENTS_IDX_MIN + 1U]; @@ -27,24 +33,34 @@ struct mbox_vevif_event_rx_conf { void (*irq_connect)(void); }; +static void trigger_callback(const struct device *dev, struct mbox_vevif_event_rx_cbs *cbs, + uint8_t id) +{ + uint8_t idx = id - EVENTS_IDX_MIN; + + if ((cbs->enabled_mask & BIT(id)) && (cbs->cb[idx] != NULL)) { + cbs->cb[idx](dev, id, cbs->user_data[idx], NULL); + } +} + static void vevif_event_rx_isr(const void *device) { const struct device *dev = (struct device *)device; - const struct mbox_vevif_event_rx_conf *config = dev->config; struct mbox_vevif_event_rx_cbs *cbs = dev->data; +#if !defined(CONFIG_MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16) + const struct mbox_vevif_event_rx_conf *config = dev->config; + for (uint8_t id = EVENTS_IDX_MIN; id < EVENTS_IDX_MAX + 1U; id++) { nrf_vpr_event_t event = nrfy_vpr_triggered_event_get(id); - if (nrfy_vpr_event_check(config->vpr, event)) { nrfy_vpr_event_clear(config->vpr, event); - uint8_t idx = id - EVENTS_IDX_MIN; - - if ((cbs->enabled_mask & BIT(id)) && (cbs->cb[idx] != NULL)) { - cbs->cb[idx](dev, id, cbs->user_data[idx], NULL); - } + trigger_callback(dev, cbs, id); } } +#else + trigger_callback(dev, cbs, VEVIF_54L_EVENT_IDX); +#endif } static inline bool vevif_event_rx_event_is_valid(uint32_t events_mask, uint32_t id) diff --git a/drivers/mbox/mbox_nrf_vevif_event_tx.c b/drivers/mbox/mbox_nrf_vevif_event_tx.c index b0869185da7e090..f8b49c2b8000b08 100644 --- a/drivers/mbox/mbox_nrf_vevif_event_tx.c +++ b/drivers/mbox/mbox_nrf_vevif_event_tx.c @@ -39,6 +39,14 @@ static int vevif_event_tx_send(const struct device *dev, uint32_t id, const stru nrf_vpr_csr_vevif_events_trigger(BIT(id)); +#if defined(CONFIG_MBOX_NRF_VEVIF_EVENT_USE_54L_ERRATA_16) + while(!nrf_vpr_csr_vevif_events_get()) + { + ; + } + nrf_vpr_csr_vevif_events_set(0); +#endif + return 0; }