Skip to content

Commit 4e9f725

Browse files
nordic-seglrlubos
authored andcommitted
[nrf fromtree] drivers: mbox: add initial driver for nRF VEVIF event
Add a mailbox driver for VEVIF events (VPR irq). The driver can be built in either 'rx' or 'tx' configuration. The VPR sends the event, so it uses the 'tx' configuration, while the master core uses the 'rx' configuration of the driver to receive the VPR events. Signed-off-by: Jakub Zymelka <[email protected]> (cherry picked from commit bace4a1) Signed-off-by: Sebastian Głąb <[email protected]>
1 parent 3845240 commit 4e9f725

File tree

7 files changed

+329
-0
lines changed

7 files changed

+329
-0
lines changed

drivers/mbox/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ zephyr_library_sources_ifdef(CONFIG_MBOX_NXP_MAILBOX mbox_nxp_mailbox.c)
1212
zephyr_library_sources_ifdef(CONFIG_MBOX_ANDES_PLIC_SW mbox_andes_plic_sw.c)
1313
zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_VEVIF_LOCAL mbox_nrf_vevif_local.c)
1414
zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_VEVIF_REMOTE mbox_nrf_vevif_remote.c)
15+
zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_VEVIF_EVENT_RX mbox_nrf_vevif_event_rx.c)
16+
zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_VEVIF_EVENT_TX mbox_nrf_vevif_event_tx.c)
1517
zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_BELLBOARD_LOCAL mbox_nrf_bellboard_local.c)
1618
zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_BELLBOARD_REMOTE mbox_nrf_bellboard_remote.c)

drivers/mbox/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ source "drivers/mbox/Kconfig.nxp_imx"
1818
source "drivers/mbox/Kconfig.nxp_mailbox"
1919
source "drivers/mbox/Kconfig.andes"
2020
source "drivers/mbox/Kconfig.nrf_vevif"
21+
source "drivers/mbox/Kconfig.nrf_vevif_event"
2122
source "drivers/mbox/Kconfig.nrf_bellboard"
2223

2324
config MBOX_INIT_PRIORITY
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config MBOX_NRF_VEVIF_EVENT_RX
5+
bool "nRF VEVIF event RX driver"
6+
depends on DT_HAS_NORDIC_NRF_VEVIF_EVENT_RX_ENABLED
7+
default y
8+
help
9+
Mailbox driver for receiving events triggered by VPR
10+
11+
config MBOX_NRF_VEVIF_EVENT_TX
12+
bool "nRF VEVIF event TX driver"
13+
depends on DT_HAS_NORDIC_NRF_VEVIF_EVENT_TX_ENABLED
14+
default y
15+
help
16+
Mailbox driver for transmitting events from VPR to a remote core
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#define DT_DRV_COMPAT nordic_nrf_vevif_event_rx
7+
8+
#include <zephyr/devicetree.h>
9+
#include <zephyr/drivers/mbox.h>
10+
11+
#include <haly/nrfy_vpr.h>
12+
13+
#if defined(CONFIG_SOC_NRF54L15_ENGA_CPUAPP)
14+
#define EVENTS_IDX_MIN 11U
15+
#define EVENTS_IDX_MAX 17U
16+
#else
17+
#define EVENTS_IDX_MIN NRF_VPR_EVENTS_TRIGGERED_MIN
18+
#define EVENTS_IDX_MAX NRF_VPR_EVENTS_TRIGGERED_MAX
19+
#endif
20+
21+
/* callbacks */
22+
struct mbox_vevif_event_rx_cbs {
23+
mbox_callback_t cb[EVENTS_IDX_MAX - EVENTS_IDX_MIN + 1U];
24+
void *user_data[EVENTS_IDX_MAX - EVENTS_IDX_MIN + 1U];
25+
uint32_t enabled_mask;
26+
};
27+
28+
struct mbox_vevif_event_rx_conf {
29+
NRF_VPR_Type *vpr;
30+
uint32_t events_mask;
31+
uint8_t events;
32+
void (*irq_connect)(void);
33+
};
34+
35+
static void vevif_event_rx_isr(const void *device)
36+
{
37+
const struct device *dev = (struct device *)device;
38+
const struct mbox_vevif_event_rx_conf *config = dev->config;
39+
struct mbox_vevif_event_rx_cbs *cbs = dev->data;
40+
41+
for (uint8_t id = EVENTS_IDX_MIN; id < EVENTS_IDX_MAX + 1U; id++) {
42+
nrf_vpr_event_t event = nrfy_vpr_triggered_event_get(id);
43+
44+
if (nrfy_vpr_event_check(config->vpr, event)) {
45+
nrfy_vpr_event_clear(config->vpr, event);
46+
uint8_t idx = id - EVENTS_IDX_MIN;
47+
48+
if ((cbs->enabled_mask & BIT(id)) && (cbs->cb[idx] != NULL)) {
49+
cbs->cb[idx](dev, id, cbs->user_data[idx], NULL);
50+
}
51+
}
52+
}
53+
}
54+
55+
static inline bool vevif_event_rx_event_is_valid(uint32_t events_mask, uint32_t id)
56+
{
57+
return ((id <= EVENTS_IDX_MAX) && ((events_mask & BIT(id)) != 0U));
58+
}
59+
60+
static uint32_t vevif_event_rx_max_channels_get(const struct device *dev)
61+
{
62+
const struct mbox_vevif_event_rx_conf *config = dev->config;
63+
64+
return config->events;
65+
}
66+
67+
static int vevif_event_rx_register_callback(const struct device *dev, uint32_t id,
68+
mbox_callback_t cb, void *user_data)
69+
{
70+
const struct mbox_vevif_event_rx_conf *config = dev->config;
71+
struct mbox_vevif_event_rx_cbs *cbs = dev->data;
72+
uint8_t idx = id - EVENTS_IDX_MIN;
73+
74+
if (!vevif_event_rx_event_is_valid(config->events_mask, id)) {
75+
return -EINVAL;
76+
}
77+
78+
cbs->cb[idx] = cb;
79+
cbs->user_data[idx] = user_data;
80+
81+
return 0;
82+
}
83+
84+
static int vevif_event_rx_set_enabled(const struct device *dev, uint32_t id, bool enable)
85+
{
86+
const struct mbox_vevif_event_rx_conf *config = dev->config;
87+
struct mbox_vevif_event_rx_cbs *cbs = dev->data;
88+
89+
if (!vevif_event_rx_event_is_valid(config->events_mask, id)) {
90+
return -EINVAL;
91+
}
92+
93+
if (enable) {
94+
if ((cbs->enabled_mask & BIT(id)) != 0U) {
95+
return -EALREADY;
96+
}
97+
98+
cbs->enabled_mask |= BIT(id);
99+
nrfy_vpr_int_enable(config->vpr, BIT(id));
100+
} else {
101+
if ((cbs->enabled_mask & BIT(id)) == 0U) {
102+
return -EALREADY;
103+
}
104+
105+
cbs->enabled_mask &= ~BIT(id);
106+
nrfy_vpr_int_disable(config->vpr, BIT(id));
107+
}
108+
109+
return 0;
110+
}
111+
112+
static const struct mbox_driver_api vevif_event_rx_driver_api = {
113+
.max_channels_get = vevif_event_rx_max_channels_get,
114+
.register_callback = vevif_event_rx_register_callback,
115+
.set_enabled = vevif_event_rx_set_enabled,
116+
};
117+
118+
static int vevif_event_rx_init(const struct device *dev)
119+
{
120+
const struct mbox_vevif_event_rx_conf *config = dev->config;
121+
122+
config->irq_connect();
123+
124+
return 0;
125+
}
126+
127+
#define VEVIF_EVENT_RX_DEFINE(inst) \
128+
BUILD_ASSERT(DT_INST_PROP(inst, nordic_events) <= NRF_VPR_EVENTS_TRIGGERED_COUNT, \
129+
"Number of events exceeds maximum"); \
130+
\
131+
static void irq_connect##inst(void) \
132+
{ \
133+
IRQ_CONNECT(DT_IRQN(DT_DRV_INST(inst)), DT_IRQ(DT_DRV_INST(inst), priority), \
134+
vevif_event_rx_isr, (const void *)DEVICE_DT_GET(DT_DRV_INST(inst)), \
135+
0); \
136+
irq_enable(DT_IRQN(DT_DRV_INST(inst))); \
137+
}; \
138+
\
139+
static struct mbox_vevif_event_rx_cbs data##inst = { \
140+
.enabled_mask = 0, \
141+
}; \
142+
static const struct mbox_vevif_event_rx_conf conf##inst = { \
143+
.vpr = (NRF_VPR_Type *)DT_INST_REG_ADDR(inst), \
144+
.events = DT_INST_PROP(inst, nordic_events), \
145+
.events_mask = DT_INST_PROP(inst, nordic_events_mask), \
146+
.irq_connect = irq_connect##inst, \
147+
}; \
148+
\
149+
DEVICE_DT_INST_DEFINE(inst, vevif_event_rx_init, NULL, &data##inst, &conf##inst, \
150+
POST_KERNEL, CONFIG_MBOX_INIT_PRIORITY, &vevif_event_rx_driver_api);
151+
152+
DT_INST_FOREACH_STATUS_OKAY(VEVIF_EVENT_RX_DEFINE)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#define DT_DRV_COMPAT nordic_nrf_vevif_event_tx
7+
8+
#include <zephyr/devicetree.h>
9+
#include <zephyr/drivers/mbox.h>
10+
11+
#include <hal/nrf_vpr.h>
12+
#include <hal/nrf_vpr_csr.h>
13+
#include <hal/nrf_vpr_csr_vevif.h>
14+
15+
#if defined(CONFIG_SOC_NRF54L15_ENGA_CPUFLPR)
16+
#define EVENTS_IDX_MAX 17U
17+
#else
18+
#define EVENTS_IDX_MAX NRF_VPR_EVENTS_TRIGGERED_MAX
19+
#endif
20+
21+
#define VEVIF_EVENTS_NUM DT_INST_PROP(0, nordic_events)
22+
#define VEVIF_EVENTS_MASK DT_INST_PROP(0, nordic_events_mask)
23+
24+
BUILD_ASSERT(DT_INST_PROP(0, nordic_events) <= NRF_VPR_EVENTS_TRIGGERED_COUNT,
25+
"Number of events exceeds maximum");
26+
27+
static inline bool vevif_event_tx_is_valid(uint32_t id)
28+
{
29+
return (id < EVENTS_IDX_MAX) && ((VEVIF_EVENTS_MASK & BIT(id)) != 0U);
30+
}
31+
32+
static int vevif_event_tx_send(const struct device *dev, uint32_t id, const struct mbox_msg *msg)
33+
{
34+
ARG_UNUSED(dev);
35+
36+
if (!vevif_event_tx_is_valid(id)) {
37+
return -EINVAL;
38+
}
39+
40+
if (msg != NULL) {
41+
return -ENOTSUP;
42+
}
43+
44+
nrf_vpr_csr_vevif_events_trigger(BIT(id));
45+
46+
return 0;
47+
}
48+
49+
static int vevif_event_tx_mtu_get(const struct device *dev)
50+
{
51+
ARG_UNUSED(dev);
52+
53+
return 0;
54+
}
55+
56+
static uint32_t vevif_event_tx_max_channels_get(const struct device *dev)
57+
{
58+
ARG_UNUSED(dev);
59+
60+
return VEVIF_EVENTS_NUM;
61+
}
62+
63+
static const struct mbox_driver_api vevif_event_tx_driver_api = {
64+
.send = vevif_event_tx_send,
65+
.mtu_get = vevif_event_tx_mtu_get,
66+
.max_channels_get = vevif_event_tx_max_channels_get,
67+
};
68+
69+
DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, POST_KERNEL, CONFIG_MBOX_INIT_PRIORITY,
70+
&vevif_event_tx_driver_api);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
Nordic VEVIF (VPR Event Interface) - EVENT RX MODE
6+
7+
VEVIF provides support for inter-domain software signaling. It implements a set of events
8+
intended for signaling within the interprocessor communication (IPC) framework.
9+
When used in the event rx mode, the VEVIF events are used to receive IRQs that are
10+
triggered by the VPR core.
11+
12+
Example definition:
13+
14+
cpuppr_vpr: vpr@deadbeef {
15+
...
16+
cpuflpr_vevif_event_rx: mailbox@0 {
17+
compatible = "nordic,nrf-vevif-event-rx";
18+
reg = <0x0 0x1000>;
19+
interrupts = <76 NRF_DEFAULT_IRQ_PRIORITY>;
20+
#mbox-cells = <1>;
21+
nordic,events = <1>;
22+
nordic,events-mask = <0x00008000>;
23+
};
24+
};
25+
26+
compatible: "nordic,nrf-vevif-event-rx"
27+
28+
include: [base.yaml, mailbox-controller.yaml]
29+
30+
properties:
31+
nordic,events:
32+
type: int
33+
required: true
34+
description: Number of events supported by the VEVIF instance.
35+
36+
nordic,events-mask:
37+
type: int
38+
required: true
39+
description: Mask of events supported by the VEVIF instance.
40+
41+
interrupts:
42+
required: true
43+
44+
reg:
45+
required: true
46+
47+
mbox-cells:
48+
- channel
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
Nordic VEVIF (VPR Event Interface) - EVENT TX MODE
6+
7+
VEVIF provides support for inter-domain software signaling. It implements a set of events
8+
intended for signaling within the interprocessor communication (IPC) framework.
9+
When used in the event tx mode, the VEVIF events are used to trigger IRQs from VPR
10+
to a remote core.
11+
12+
Example definition:
13+
14+
cpuppr_vpr: vpr@deadbeef{
15+
...
16+
cpuflpr_vevif_event_tx: mailbox {
17+
compatible = "nordic,nrf-vevif-event-tx";
18+
#mbox-cells = <1>;
19+
nordic,events = <1>;
20+
nordic,events-mask = <0x00008000>;
21+
};
22+
};
23+
24+
compatible: "nordic,nrf-vevif-event-tx"
25+
26+
include: [base.yaml, mailbox-controller.yaml]
27+
28+
properties:
29+
nordic,events:
30+
type: int
31+
required: true
32+
description: Number of events supported by the VEVIF instance.
33+
34+
nordic,events-mask:
35+
type: int
36+
required: true
37+
description: Mask of events supported by the VEVIF instance.
38+
39+
mbox-cells:
40+
- channel

0 commit comments

Comments
 (0)