blob: 2f18ce89cdce746035488a945dd99d78fb77681c [file] [log] [blame]
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
#include "mailbox.h"
LOG_MODULE_REGISTER(scmi_mbox);
static void scmi_mbox_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;
if (scmi_chan->cb) {
scmi_chan->cb(scmi_chan);
}
}
static int scmi_mbox_send_message(const struct device *transport,
struct scmi_channel *chan,
struct scmi_message *msg)
{
struct scmi_mbox_channel *mbox_chan;
int ret;
mbox_chan = chan->data;
ret = scmi_shmem_write_message(mbox_chan->shmem, msg);
if (ret < 0) {
LOG_ERR("failed to write message to shmem: %d", ret);
return ret;
}
ret = mbox_send_dt(&mbox_chan->tx, NULL);
if (ret < 0) {
LOG_ERR("failed to ring doorbell: %d", ret);
return ret;
}
return 0;
}
static int scmi_mbox_read_message(const struct device *transport,
struct scmi_channel *chan,
struct scmi_message *msg)
{
struct scmi_mbox_channel *mbox_chan;
mbox_chan = chan->data;
return scmi_shmem_read_message(mbox_chan->shmem, msg);
}
static bool scmi_mbox_channel_is_free(const struct device *transport,
struct scmi_channel *chan)
{
struct scmi_mbox_channel *mbox_chan = chan->data;
return scmi_shmem_channel_status(mbox_chan->shmem) &
SCMI_SHMEM_CHAN_STATUS_BUSY_BIT;
}
static int scmi_mbox_setup_chan(const struct device *transport,
struct scmi_channel *chan,
bool tx)
{
int ret;
struct scmi_mbox_channel *mbox_chan;
struct mbox_dt_spec *tx_reply;
mbox_chan = chan->data;
if (!tx) {
return -ENOTSUP;
}
if (mbox_chan->tx_reply.dev) {
tx_reply = &mbox_chan->tx_reply;
} 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;
}
ret = mbox_set_enabled_dt(tx_reply, true);
if (ret < 0) {
LOG_ERR("failed to enable tx reply dbell");
}
/* enable interrupt-based communication */
scmi_shmem_update_flags(mbox_chan->shmem,
SCMI_SHMEM_CHAN_FLAG_IRQ_BIT,
SCMI_SHMEM_CHAN_FLAG_IRQ_BIT);
return 0;
}
static struct scmi_transport_api scmi_mbox_api = {
.setup_chan = scmi_mbox_setup_chan,
.send_message = scmi_mbox_send_message,
.read_message = scmi_mbox_read_message,
.channel_is_free = scmi_mbox_channel_is_free,
};
DT_INST_SCMI_MAILBOX_DEFINE(0, PRE_KERNEL_1,
CONFIG_ARM_SCMI_TRANSPORT_INIT_PRIORITY,
&scmi_mbox_api);