-
Notifications
You must be signed in to change notification settings - Fork 8k
NXP Add SCMI P2A workflow and BBNSM protocol #93305
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
base: main
Are you sure you want to change the base?
Changes from 6 commits
ee512b4
749274f
7ab7a84
a3233c5
bcba9ec
8821a9f
bf9d35d
e0679ec
7fb6b89
d876137
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,8 +43,55 @@ int scmi_status_to_errno(int scmi_status) | |
} | ||
} | ||
|
||
static void scmi_core_reply_cb(struct scmi_channel *chan) | ||
static int scmi_core_handle_notification(int hdr) | ||
{ | ||
uint32_t protocol_id, msg_id; | ||
struct scmi_protocol_event *events; | ||
|
||
protocol_id = SCMI_MESSAGE_HDR_EX_PROTOCOL(hdr); | ||
msg_id = SCMI_MESSAGE_HDR_EX_MSGID(hdr); | ||
|
||
STRUCT_SECTION_FOREACH(scmi_protocol, it) { | ||
events = it->events; | ||
if (!events || !events->cb) { | ||
continue; | ||
} | ||
|
||
if (protocol_id == it->id) { | ||
for (uint32_t num = 0; num < events->num_events; num++) { | ||
if (msg_id == events->evts[num]) { | ||
events->cb(msg_id); | ||
return 0; | ||
} | ||
} | ||
} | ||
} | ||
|
||
return -ENOENT; | ||
} | ||
|
||
static void scmi_core_reply_cb(struct scmi_channel *chan, int hdr) | ||
{ | ||
int msg_type; | ||
int status; | ||
|
||
msg_type = SCMI_MESSAGE_HDR_EX_TYPE(hdr); | ||
|
||
switch (msg_type) { | ||
case SCMI_COMMAND: | ||
break; | ||
case SCMI_DELAYED_REPLY: | ||
break; | ||
case SCMI_NOTIFICATION: | ||
status = scmi_core_handle_notification(hdr); | ||
if (status) { | ||
LOG_WRN("Scmi notification event not find"); | ||
} | ||
break; | ||
default: | ||
LOG_WRN("Unexpected message type %u", msg_type); | ||
} | ||
|
||
if (!k_is_pre_kernel()) { | ||
k_sem_give(&chan->sem); | ||
} | ||
|
@@ -63,11 +110,6 @@ static int scmi_core_setup_chan(const struct device *transport, | |
return 0; | ||
} | ||
|
||
dbaluta marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/* no support for RX channels ATM */ | ||
if (!tx) { | ||
return -ENOTSUP; | ||
} | ||
|
||
k_mutex_init(&chan->lock); | ||
k_sem_init(&chan->sem, 0, 1); | ||
|
||
|
@@ -216,6 +258,31 @@ int scmi_send_message(struct scmi_protocol *proto, struct scmi_message *msg, | |
} | ||
} | ||
|
||
int scmi_read_message(struct scmi_protocol *proto, struct scmi_message *msg) | ||
{ | ||
int ret; | ||
|
||
if (!proto->rx) { | ||
return -ENODEV; | ||
} | ||
|
||
if (!proto->rx->ready) { | ||
return -EINVAL; | ||
} | ||
|
||
/* read message from platform, such as notification event | ||
* | ||
* Unlike scmi_send_message, reading messages with scmi_read_message is not currently | ||
* required in the PRE_KERNEL stage. The interrupt-based logic is used here. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe add a
check here then? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, added it now |
||
*/ | ||
if (k_is_pre_kernel()) { | ||
return -EINVAL; | ||
} | ||
|
||
ret = scmi_transport_read_message(proto->transport, proto->rx, msg); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for ret here. Judt directly return scmi_transport_read_message. |
||
|
||
return ret; | ||
} | ||
static int scmi_core_protocol_setup(const struct device *transport) | ||
{ | ||
int ret; | ||
|
@@ -226,6 +293,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) { | ||
|
@@ -236,6 +304,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; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,18 +6,61 @@ | |
|
||
#include <zephyr/logging/log.h> | ||
#include "mailbox.h" | ||
#include <zephyr/drivers/firmware/scmi/protocol.h> | ||
|
||
LOG_MODULE_REGISTER(scmi_mbox); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 int scmi_mbox_get_pending_msg(struct scmi_channel *chan, | ||
struct scmi_message *msg) | ||
{ | ||
uint32_t context; | ||
int ret; | ||
struct scmi_mbox_channel *mbox_chan = chan->data; | ||
|
||
msg->hdr = 0x0; | ||
msg->len = sizeof(uint32_t); | ||
msg->content = &context; | ||
|
||
ret = scmi_shmem_read_hdr(mbox_chan->shmem, msg); | ||
if (ret < 0) { | ||
LOG_ERR("failed to read message to shmem: %d", ret); | ||
return ret; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static void scmi_mbox_tx_reply_cb(const struct device *mbox, | ||
mbox_channel_id_t channel_id, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please split this into 2 patches:
Much easier to review the transition like this. |
||
void *user_data, | ||
struct mbox_msg *data) | ||
{ | ||
struct scmi_channel *scmi_chan = user_data; | ||
struct scmi_message msg; | ||
|
||
scmi_mbox_get_pending_msg(scmi_chan, &msg); | ||
|
||
if (scmi_chan->cb) { | ||
scmi_chan->cb(scmi_chan); | ||
scmi_chan->cb(scmi_chan, msg.hdr); | ||
} | ||
} | ||
|
||
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; | ||
struct scmi_mbox_channel *mbox_chan = scmi_chan->data; | ||
const struct device *shmem = mbox_chan->shmem; | ||
bool a2p = false; | ||
struct scmi_message msg; | ||
|
||
scmi_mbox_get_pending_msg(scmi_chan, &msg); | ||
|
||
if (scmi_chan->cb) { | ||
scmi_chan->cb(scmi_chan, msg.hdr); | ||
scmi_shmem_clear_channel_status(shmem, a2p); | ||
} | ||
} | ||
|
||
|
@@ -71,29 +114,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 */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/not find/not found. Also, do you want to print the status here?