// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2020-2021 NXP */ #include #include #include #include #include #include #include #include #include #include "vpu.h" #include "vpu_mbox.h" #include "vpu_msgs.h" static void vpu_mbox_rx_callback(struct mbox_client *cl, void *msg) { struct vpu_mbox *rx = container_of(cl, struct vpu_mbox, cl); struct vpu_core *core = container_of(rx, struct vpu_core, rx); vpu_isr(core, *(u32 *)msg); } static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox) { struct mbox_chan *ch; struct mbox_client *cl; if (!dev || !mbox) return -EINVAL; if (mbox->ch) return 0; cl = &mbox->cl; cl->dev = dev; if (mbox->block) { cl->tx_block = true; cl->tx_tout = 1000; } else { cl->tx_block = false; } cl->knows_txdone = false; cl->rx_callback = vpu_mbox_rx_callback; ch = mbox_request_channel_byname(cl, mbox->name); if (IS_ERR(ch)) { dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n", mbox->name, PTR_ERR(ch)); return PTR_ERR(ch); } mbox->ch = ch; return 0; } int vpu_mbox_init(struct vpu_core *core) { scnprintf(core->tx_type.name, sizeof(core->tx_type.name) - 1, "tx0"); core->tx_type.block = true; scnprintf(core->tx_data.name, sizeof(core->tx_data.name) - 1, "tx1"); core->tx_data.block = false; scnprintf(core->rx.name, sizeof(core->rx.name) - 1, "rx"); core->rx.block = true; return 0; } int vpu_mbox_request(struct vpu_core *core) { int ret; ret = vpu_mbox_request_channel(core->dev, &core->tx_type); if (ret) goto error; ret = vpu_mbox_request_channel(core->dev, &core->tx_data); if (ret) goto error; ret = vpu_mbox_request_channel(core->dev, &core->rx); if (ret) goto error; dev_dbg(core->dev, "%s request mbox\n", vpu_core_type_desc(core->type)); return 0; error: vpu_mbox_free(core); return ret; } void vpu_mbox_free(struct vpu_core *core) { mbox_free_channel(core->tx_type.ch); mbox_free_channel(core->tx_data.ch); mbox_free_channel(core->rx.ch); core->tx_type.ch = NULL; core->tx_data.ch = NULL; core->rx.ch = NULL; dev_dbg(core->dev, "%s free mbox\n", vpu_core_type_desc(core->type)); } void vpu_mbox_send_type(struct vpu_core *core, u32 type) { mbox_send_message(core->tx_type.ch, &type); } void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data) { mbox_send_message(core->tx_data.ch, &data); mbox_send_message(core->tx_type.ch, &type); } void vpu_mbox_enable_rx(struct vpu_dev *dev) { }