From 7017996951fde84698ddfe7fd47f92bd9d9eb85d Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih Date: Tue, 12 Nov 2019 19:03:26 +0800 Subject: rpmsg: add rpmsg support for mt8183 SCP. Add a simple rpmsg support for mt8183 SCP, that use IPI / IPC directly. Signed-off-by: Pi-Hsun Shih Link: https://lore.kernel.org/r/20191112110330.179649-4-pihsun@chromium.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/Kconfig | 1 + drivers/remoteproc/mtk_common.h | 2 ++ drivers/remoteproc/mtk_scp.c | 61 +++++++++++++++++++++++++++++++++++++--- drivers/remoteproc/mtk_scp_ipi.c | 1 + 4 files changed, 61 insertions(+), 4 deletions(-) (limited to 'drivers/remoteproc') diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 85d594df12e3..de3862c15fcc 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -26,6 +26,7 @@ config IMX_REMOTEPROC config MTK_SCP tristate "Mediatek SCP support" depends on ARCH_MEDIATEK + select RPMSG_MTK_SCP help Say y here to support Mediatek's System Companion Processor (SCP) via the remote processor framework. diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h index 4afcec19c34c..deb20096146a 100644 --- a/drivers/remoteproc/mtk_common.h +++ b/drivers/remoteproc/mtk_common.h @@ -70,6 +70,8 @@ struct mtk_scp { void __iomem *cpu_addr; phys_addr_t phys_addr; size_t dram_size; + + struct rproc_subdev *rpmsg_subdev; }; /** diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c index dc5babb3af59..7ccdf64ff3ea 100644 --- a/drivers/remoteproc/mtk_scp.c +++ b/drivers/remoteproc/mtk_scp.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "mtk_common.h" #include "remoteproc_internal.h" @@ -464,6 +465,54 @@ static void scp_unmap_memory_region(struct mtk_scp *scp) of_reserved_mem_device_release(scp->dev); } +static int scp_register_ipi(struct platform_device *pdev, u32 id, + ipi_handler_t handler, void *priv) +{ + struct mtk_scp *scp = platform_get_drvdata(pdev); + + return scp_ipi_register(scp, id, handler, priv); +} + +static void scp_unregister_ipi(struct platform_device *pdev, u32 id) +{ + struct mtk_scp *scp = platform_get_drvdata(pdev); + + scp_ipi_unregister(scp, id); +} + +static int scp_send_ipi(struct platform_device *pdev, u32 id, void *buf, + unsigned int len, unsigned int wait) +{ + struct mtk_scp *scp = platform_get_drvdata(pdev); + + return scp_ipi_send(scp, id, buf, len, wait); +} + +static struct mtk_rpmsg_info mtk_scp_rpmsg_info = { + .send_ipi = scp_send_ipi, + .register_ipi = scp_register_ipi, + .unregister_ipi = scp_unregister_ipi, + .ns_ipi_id = SCP_IPI_NS_SERVICE, +}; + +static void scp_add_rpmsg_subdev(struct mtk_scp *scp) +{ + scp->rpmsg_subdev = + mtk_rpmsg_create_rproc_subdev(to_platform_device(scp->dev), + &mtk_scp_rpmsg_info); + if (scp->rpmsg_subdev) + rproc_add_subdev(scp->rproc, scp->rpmsg_subdev); +} + +static void scp_remove_rpmsg_subdev(struct mtk_scp *scp) +{ + if (scp->rpmsg_subdev) { + rproc_remove_subdev(scp->rproc, scp->rpmsg_subdev); + mtk_rpmsg_destroy_rproc_subdev(scp->rpmsg_subdev); + scp->rpmsg_subdev = NULL; + } +} + static int scp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -544,22 +593,25 @@ static int scp_probe(struct platform_device *pdev) init_waitqueue_head(&scp->run.wq); init_waitqueue_head(&scp->ack_wq); + scp_add_rpmsg_subdev(scp); + ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0), NULL, scp_irq_handler, IRQF_ONESHOT, pdev->name, scp); if (ret) { dev_err(dev, "failed to request irq\n"); - goto unregister_ipi; + goto remove_subdev; } ret = rproc_add(rproc); if (ret) - goto unregister_ipi; + goto remove_subdev; - return ret; + return 0; -unregister_ipi: +remove_subdev: + scp_remove_rpmsg_subdev(scp); scp_ipi_unregister(scp, SCP_IPI_INIT); release_dev_mem: scp_unmap_memory_region(scp); @@ -579,6 +631,7 @@ static int scp_remove(struct platform_device *pdev) int i; rproc_del(scp->rproc); + scp_remove_rpmsg_subdev(scp); scp_ipi_unregister(scp, SCP_IPI_INIT); scp_unmap_memory_region(scp); for (i = 0; i < SCP_IPI_MAX; i++) diff --git a/drivers/remoteproc/mtk_scp_ipi.c b/drivers/remoteproc/mtk_scp_ipi.c index abdb7944368a..3d3d87210ef2 100644 --- a/drivers/remoteproc/mtk_scp_ipi.c +++ b/drivers/remoteproc/mtk_scp_ipi.c @@ -162,6 +162,7 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, int ret; if (WARN_ON(id <= SCP_IPI_INIT) || WARN_ON(id >= SCP_IPI_MAX) || + WARN_ON(id == SCP_IPI_NS_SERVICE) || WARN_ON(len > sizeof(send_obj->share_buf)) || WARN_ON(!buf)) return -EINVAL; -- cgit