Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
14 changes: 9 additions & 5 deletions drivers/firmware/scmi/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ static int scmi_core_setup_chan(const struct device *transport,
return 0;
}

/* no support for RX channels ATM */
if (!tx) {
return -ENOTSUP;
}

k_mutex_init(&chan->lock);
k_sem_init(&chan->sem, 0, 1);

Expand Down Expand Up @@ -226,6 +221,7 @@ static int scmi_core_protocol_setup(const struct device *transport)
#ifndef CONFIG_ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS
/* no static channel allocation, attempt dynamic binding */
it->tx = scmi_transport_request_channel(transport, it->id, true);
it->rx = scmi_transport_request_channel(transport, it->id, false);
#endif /* CONFIG_ARM_SCMI_TRANSPORT_HAS_STATIC_CHANNELS */

if (!it->tx) {
Expand All @@ -236,6 +232,14 @@ static int scmi_core_protocol_setup(const struct device *transport)
if (ret < 0) {
return ret;
}

/* notification/delayed reply channel is optional */
if (it->rx) {
ret = scmi_core_setup_chan(transport, it->rx, false);
if (ret < 0) {
return ret;
}
}
}

return 0;
Expand Down
57 changes: 37 additions & 20 deletions drivers/firmware/scmi/mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,22 @@

LOG_MODULE_REGISTER(scmi_mbox);
Copy link
Contributor

Choose a reason for hiding this comment

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

s/callbak/callback/ in the commit subject.


static void scmi_mbox_cb(const struct device *mbox,
mbox_channel_id_t channel_id,
void *user_data,
struct mbox_msg *data)
static void scmi_mbox_tx_reply_cb(const struct device *mbox,
mbox_channel_id_t channel_id,
Copy link
Contributor

Choose a reason for hiding this comment

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

Please split this into 2 patches:

  1. Preparation for introducing the RX channel. Here you rename scmi_mbox_cb -> scmi_mbox_tx_reply_cb and implement scmi_mbox_cb with the logic for supporting tx/rx direction but only TX implemented so far.
  2. Add the RX channel.

Much easier to review the transition like this.

void *user_data,
struct mbox_msg *data)
{
struct scmi_channel *scmi_chan = user_data;

if (scmi_chan->cb) {
scmi_chan->cb(scmi_chan);
}
}

static void scmi_mbox_notify_cb(const struct device *mbox,
mbox_channel_id_t channel_id,
void *user_data,
struct mbox_msg *data)
{
struct scmi_channel *scmi_chan = user_data;

Expand Down Expand Up @@ -71,29 +83,34 @@ static int scmi_mbox_setup_chan(const struct device *transport,
{
int ret;
struct scmi_mbox_channel *mbox_chan;
struct mbox_dt_spec *tx_reply;
struct mbox_dt_spec *mbox_spec;

mbox_chan = chan->data;

if (!tx) {
return -ENOTSUP;
}

if (mbox_chan->tx_reply.dev) {
tx_reply = &mbox_chan->tx_reply;
if (tx) {
mbox_spec = mbox_chan->tx_reply.dev ? &mbox_chan->tx_reply : &mbox_chan->tx;
ret = mbox_register_callback_dt(mbox_spec, scmi_mbox_tx_reply_cb, chan);
if (ret < 0) {
LOG_ERR("failed to register reply cb on %s",
mbox_chan->tx_reply.dev ? "tx_reply" : "tx");
return ret;
}
} else {
tx_reply = &mbox_chan->tx;
}

ret = mbox_register_callback_dt(tx_reply, scmi_mbox_cb, chan);
if (ret < 0) {
LOG_ERR("failed to register tx reply cb");
return ret;
if (!mbox_chan->rx.dev) {
LOG_ERR("RX channel not defined");
return -ENOTSUP;
}
mbox_spec = &mbox_chan->rx;
ret = mbox_register_callback_dt(&mbox_chan->rx, scmi_mbox_notify_cb, chan);
if (ret < 0) {
LOG_ERR("failed to register notify cb on rx");
return ret;
}
}

ret = mbox_set_enabled_dt(tx_reply, true);
ret = mbox_set_enabled_dt(mbox_spec, true);
if (ret < 0) {
LOG_ERR("failed to enable tx reply dbell");
LOG_ERR("failed to enable %s dbell", tx ? "tx" : "rx");
}

/* enable interrupt-based communication */
Expand Down
59 changes: 40 additions & 19 deletions drivers/firmware/scmi/mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,34 @@
.tx_reply = _SCMI_MBOX_CHAN_DBELL(node_id, tx_reply), \
}

/* define private data for a protocol RX channel */
#define _SCMI_MBOX_CHAN_DEFINE_PRIV_RX(node_id, proto) \
static struct scmi_mbox_channel _SCMI_MBOX_CHAN_NAME(proto, 1) =\
{ \
.shmem = _SCMI_MBOX_SHMEM_BY_IDX(node_id, 1), \
.rx = _SCMI_MBOX_CHAN_DBELL(node_id, rx), \
}

/*
* Define a mailbox channel. This does two things:
* 1) Define the mandatory `struct scmi_channel` structure
* 2) Define the mailbox-specific private data for said
* channel (i.e: a struct scmi_mbox_channel)
*/
#define _SCMI_MBOX_CHAN_DEFINE(node_id, proto, idx) \
#define _SCMI_MBOX_CHAN_DEFINE_TX(node_id, proto, idx) \
_SCMI_MBOX_CHAN_DEFINE_PRIV_TX(node_id, proto); \
DT_SCMI_TRANSPORT_CHAN_DEFINE(node_id, idx, proto, \
&(_SCMI_MBOX_CHAN_NAME(proto, idx))); \

#define _SCMI_MBOX_CHAN_DEFINE_RX(node_id, proto, idx) \
_SCMI_MBOX_CHAN_DEFINE_PRIV_RX(node_id, proto); \
DT_SCMI_TRANSPORT_CHAN_DEFINE(node_id, idx, proto, \
&(_SCMI_MBOX_CHAN_NAME(proto, idx))); \

#define _SCMI_MBOX_CHAN_DEFINE_RX_OPTIONAL(node_id, proto, idx) \
COND_CODE_1(DT_PROP_HAS_IDX(node_id, shmem, idx), \
(_SCMI_MBOX_CHAN_DEFINE_RX(node_id, proto, idx)), \
())
/*
* Optionally define a mailbox channel for a protocol. This is optional
* because a protocol might not have a dedicated channel.
Expand All @@ -69,24 +86,26 @@
_SCMI_MBOX_CHAN_DEFINE_OPTIONAL(node_id, DT_REG_ADDR(node_id), 0)

/* define and validate base protocol TX channel */
#define DT_INST_SCMI_MBOX_BASE_CHAN_DEFINE(inst) \
BUILD_ASSERT(DT_INST_PROP_LEN(inst, mboxes) != 1 || \
(DT_INST_PROP_HAS_IDX(inst, shmem, 0) && \
DT_INST_PROP_HAS_NAME(inst, mboxes, tx)), \
"bad bidirectional channel description"); \
\
BUILD_ASSERT(DT_INST_PROP_LEN(inst, mboxes) != 2 || \
(DT_INST_PROP_HAS_NAME(inst, mboxes, tx) && \
DT_INST_PROP_HAS_NAME(inst, mboxes, tx_reply)), \
"bad unidirectional channel description"); \
\
BUILD_ASSERT(DT_INST_PROP_LEN(inst, shmem) == 1, \
"bad SHMEM count"); \
\
BUILD_ASSERT(DT_INST_PROP_LEN(inst, mboxes) <= 2, \
"bad mbox count"); \
\
_SCMI_MBOX_CHAN_DEFINE(DT_INST(inst, DT_DRV_COMPAT), SCMI_PROTOCOL_BASE, 0)
#define DT_INST_SCMI_MBOX_BASE_CHAN_DEFINE(inst) \
BUILD_ASSERT(DT_INST_PROP_LEN(inst, mboxes) != 1 || \
(DT_INST_PROP_HAS_IDX(inst, shmem, 0) && \
DT_INST_PROP_HAS_NAME(inst, mboxes, tx)), \
"bad bidirectional channel description"); \
\
BUILD_ASSERT(DT_INST_PROP_LEN(inst, mboxes) != 2 || \
((DT_INST_PROP_HAS_NAME(inst, mboxes, tx) && \
(DT_INST_PROP_HAS_NAME(inst, mboxes, tx_reply) || \
DT_INST_PROP_HAS_NAME(inst, mboxes, rx)))), \
"bad unidirectional channel description"); \
\
BUILD_ASSERT(DT_INST_PROP_LEN(inst, shmem) <= 2, \
"bad SHMEM count"); \
\
BUILD_ASSERT(DT_INST_PROP_LEN(inst, mboxes) <= 2, \
"bad mbox count"); \
\
_SCMI_MBOX_CHAN_DEFINE_TX(DT_INST(inst, DT_DRV_COMPAT), SCMI_PROTOCOL_BASE, 0) \
_SCMI_MBOX_CHAN_DEFINE_RX_OPTIONAL(DT_INST(inst, DT_DRV_COMPAT), SCMI_PROTOCOL_BASE, 1) \

/*
* Define the mailbox-based transport layer. What this does is:
Expand All @@ -112,6 +131,8 @@ struct scmi_mbox_channel {
struct mbox_dt_spec tx;
/* TX reply dbell */
struct mbox_dt_spec tx_reply;
/* RX dbell */
struct mbox_dt_spec rx;
};

#endif /* _ZEPHYR_DRIVERS_FIRMWARE_SCMI_MAILBOX_H_ */
2 changes: 2 additions & 0 deletions include/zephyr/drivers/firmware/scmi/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ struct scmi_protocol {
uint32_t id;
/** TX channel */
struct scmi_channel *tx;
/** RX channel */
struct scmi_channel *rx;
/** transport layer device */
const struct device *transport;
/** protocol private data */
Expand Down
23 changes: 20 additions & 3 deletions include/zephyr/drivers/firmware/scmi/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
#define SCMI_TRANSPORT_CHAN_NAME(proto, idx) CONCAT(scmi_channel_, proto, _, idx)

/**
* @brief Declare a TX SCMI channel
* @brief Declare TX/RX SCMI channel
*
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't merge commments like this. Add a similar comment at the top of RX Channel declaration.

* Given a node_id for a protocol, this macro declares the SCMI
* TX channel statically bound to said protocol via the "extern"
Expand All @@ -70,6 +70,15 @@
(extern struct scmi_channel \
SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 0);)) \

#define DT_SCMI_TRANSPORT_RX_CHAN_DECLARE(node_id) \
COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 1), \
(extern struct scmi_channel \
SCMI_TRANSPORT_CHAN_NAME(DT_REG_ADDR_RAW(node_id), 1);), \
(COND_CODE_1(DT_PROP_HAS_IDX(DT_PARENT(node_id), shmem, 1),\
(extern struct scmi_channel \
SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 1);), \
(/* no decl when NULL */))))

/**
* @brief Declare SCMI TX/RX channels
*
Expand All @@ -84,6 +93,7 @@
*/
#define DT_SCMI_TRANSPORT_CHANNELS_DECLARE(node_id) \
DT_SCMI_TRANSPORT_TX_CHAN_DECLARE(node_id) \
DT_SCMI_TRANSPORT_RX_CHAN_DECLARE(node_id) \

/**
* @brief Declare SCMI TX/RX channels using node instance number
Expand All @@ -97,22 +107,28 @@
DT_SCMI_TRANSPORT_CHANNELS_DECLARE(DT_INST(inst, DT_DRV_COMPAT))

/**
* @brief Get a reference to a protocol's SCMI TX channel
* @brief Get a reference to a protocol's SCMI TX/RX channel
*
Copy link
Contributor

Choose a reason for hiding this comment

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

Dont merge the comments like this. Add a similar comment for RX channel.

* Given a node_id for a protocol, this macro returns a
* reference to an SCMI TX channel statically bound to said
* protocol.
*
* @param node_id protocol node identifier
*
* @return reference to the struct scmi_channel of the TX channel
* @return reference to the struct scmi_channel of the TX/RX channel
* bound to the protocol identifier by node_id
*/
#define DT_SCMI_TRANSPORT_TX_CHAN(node_id) \
COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 0), \
(&SCMI_TRANSPORT_CHAN_NAME(DT_REG_ADDR_RAW(node_id), 0)), \
(&SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 0)))

#define DT_SCMI_TRANSPORT_RX_CHAN(node_id) \
COND_CODE_1(DT_SCMI_TRANSPORT_PROTO_HAS_CHAN(node_id, 1), \
(&SCMI_TRANSPORT_CHAN_NAME(DT_REG_ADDR_RAW(node_id), 1)), \
(COND_CODE_1(DT_PROP_HAS_IDX(DT_PARENT(node_id), shmem, 1), \
(&SCMI_TRANSPORT_CHAN_NAME(SCMI_PROTOCOL_BASE, 1)), \
(NULL))))
/**
* @brief Define an SCMI channel for a protocol
*
Expand Down Expand Up @@ -151,6 +167,7 @@
{ \
.id = proto, \
.tx = DT_SCMI_TRANSPORT_TX_CHAN(node_id), \
.rx = DT_SCMI_TRANSPORT_RX_CHAN(node_id), \
.data = pdata, \
}

Expand Down