| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Copyright 2020-2021 NXP
- */
- #include <linux/init.h>
- #include <linux/interconnect.h>
- #include <linux/ioctl.h>
- #include <linux/list.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/platform_device.h>
- #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))
- return dev_err_probe(dev, PTR_ERR(ch),
- "Failed to request mbox chan %s\n",
- mbox->name);
- 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);
- }
|