diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 4d043f7dc9bb..ab3d6f693969 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -79,6 +79,12 @@ config ROCKCHIP_MBOX Please check it that the Soc you use have Mailbox hardware. Say Y here if you want to use the Rockchip Mailbox support. +config ROCKCHIP_MBOX_DEMO + tristate "Rockchip MBOX Demo" + depends on ROCKCHIP_MBOX + help + Say y here to enable Rockchip MBOX Demo. + config PCC bool "Platform Communication Channel Driver" depends on ACPI diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index 2e06e02b2e03..2a2eecd4ac46 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -19,6 +19,8 @@ obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o obj-$(CONFIG_ROCKCHIP_MBOX) += rockchip-mailbox.o +obj-$(CONFIG_ROCKCHIP_MBOX_DEMO) += rockchip-mbox-demo.o + obj-$(CONFIG_PCC) += pcc.o obj-$(CONFIG_ALTERA_MBOX) += mailbox-altera.o diff --git a/drivers/mailbox/rockchip-mbox-demo.c b/drivers/mailbox/rockchip-mbox-demo.c new file mode 100644 index 000000000000..17a313b7e0ab --- /dev/null +++ b/drivers/mailbox/rockchip-mbox-demo.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Rockchip MBOX Demo. + * + * Copyright (c) 2023 Rockchip Electronics Co. Ltd. + * Author: Jiahang Zheng + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The Linux kernel uses the mailbox framework TXDONE_BY_POLL mechanism. + * The minimum unit of the txpoll period interface is ms. + * Configure rockchip,txpoll-period-ms = <1> in dts. + * If data that is longer than MBOX_TX_QUEUE_LEN may be lost, + * each send should be at least interval txpoll-period-ms + */ +#define MSG_LIMIT (100) +#define LINUX_TEST_COMPENSATION (1) + +struct rk_mbox_dev { + struct platform_device *pdev; + struct mbox_client mbox_cl; + struct mbox_chan *mbox_rx_chan; + struct mbox_chan *mbox_tx_chan; + struct rockchip_mbox_msg tx_msg; + int rx_count; +}; + +static void rk_mbox_rx_callback(struct mbox_client *client, void *message) +{ + struct rk_mbox_dev *test_dev = container_of(client, struct rk_mbox_dev, mbox_cl); + struct platform_device *pdev = test_dev->pdev; + struct device *dev = &pdev->dev; + struct rockchip_mbox_msg *tx_msg; + struct rockchip_mbox_msg *rx_msg; + + rx_msg = message; + dev_info(dev, "mbox master: rx_count:%d cmd=0x%x data=0x%x\n", + ++test_dev->rx_count, rx_msg->cmd, rx_msg->data); + + /* test should not live forever */ + if (test_dev->rx_count >= MSG_LIMIT) { + dev_info(dev, "Rockchip mbox test exit!\n"); + return; + } + + mdelay(LINUX_TEST_COMPENSATION); + tx_msg = &test_dev->tx_msg; + mbox_send_message(test_dev->mbox_tx_chan, tx_msg); +} + +static int mbox_demo_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rk_mbox_dev *test_dev = NULL; + struct mbox_client *cl; + struct rockchip_mbox_msg *tx_msg; + int ret = 0; + + test_dev = devm_kzalloc(dev, sizeof(*test_dev), GFP_KERNEL); + if (!test_dev) + return -ENOMEM; + + /* link_id: master core 0 and remote core 3 */ + tx_msg = &test_dev->tx_msg; + tx_msg->cmd = 0x03U; + tx_msg->data = 0x524D5347U; + + dev_info(dev, "rockchip mbox demo probe.\n"); + test_dev->pdev = pdev; + test_dev->rx_count = 0; + + cl = &test_dev->mbox_cl; + cl->dev = dev; + cl->rx_callback = rk_mbox_rx_callback; + + platform_set_drvdata(pdev, test_dev); + test_dev->mbox_rx_chan = mbox_request_channel_byname(cl, "test-rx"); + if (IS_ERR(test_dev->mbox_rx_chan)) { + ret = PTR_ERR(test_dev->mbox_rx_chan); + dev_err(dev, "failed to request mbox rx chan, ret %d\n", ret); + return ret; + } + test_dev->mbox_tx_chan = mbox_request_channel_byname(cl, "test-tx"); + if (IS_ERR(test_dev->mbox_tx_chan)) { + ret = PTR_ERR(test_dev->mbox_tx_chan); + dev_err(dev, "failed to request mbox tx chan, ret %d\n", ret); + return ret; + } + + dev_info(dev, "mbox master: send cmd=0x%x data=0x%x\n", tx_msg->cmd, tx_msg->data); + mbox_send_message(test_dev->mbox_tx_chan, tx_msg); + + return ret; +} + +static int mbox_demo_remove(struct platform_device *pdev) +{ + struct rk_mbox_dev *test_dev = platform_get_drvdata(pdev); + + mbox_free_channel(test_dev->mbox_rx_chan); + mbox_free_channel(test_dev->mbox_tx_chan); + + return 0; +} + +static const struct of_device_id mbox_demo_match[] = { + { .compatible = "rockchip,mbox-demo", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, mbox_demo_match); + +static struct platform_driver mbox_demo_driver = { + .probe = mbox_demo_probe, + .remove = mbox_demo_remove, + .driver = { + .name = "mbox-demo", + .of_match_table = mbox_demo_match, + }, +}; +module_platform_driver(mbox_demo_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Rockchip MBOX Demo"); +MODULE_AUTHOR("Jiahang Zheng ");