Skip to content

Commit

Permalink
rpmsg: add rpmsg support for mt8183 SCP.
Browse files Browse the repository at this point in the history
Add a simple rpmsg support for mt8183 SCP, that use IPI / IPC directly.

Signed-off-by: Pi-Hsun Shih <pihsun@chromium.org>
Link: https://lore.kernel.org/r/20191112110330.179649-4-pihsun@chromium.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
  • Loading branch information
peter50216 authored and andersson committed Jan 20, 2020
1 parent 63c13d6 commit 7017996
Show file tree
Hide file tree
Showing 9 changed files with 525 additions and 5 deletions.
1 change: 1 addition & 0 deletions drivers/remoteproc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions drivers/remoteproc/mtk_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/**
Expand Down
61 changes: 57 additions & 4 deletions drivers/remoteproc/mtk_scp.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/remoteproc.h>
#include <linux/remoteproc/mtk_scp.h>
#include <linux/rpmsg/mtk_rpmsg.h>

#include "mtk_common.h"
#include "remoteproc_internal.h"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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++)
Expand Down
1 change: 1 addition & 0 deletions drivers/remoteproc/mtk_scp_ipi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
9 changes: 9 additions & 0 deletions drivers/rpmsg/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ config RPMSG_CHAR
in /dev. They make it possible for user-space programs to send and
receive rpmsg packets.

config RPMSG_MTK_SCP
tristate "MediaTek SCP"
depends on MTK_SCP
select RPMSG
help
Say y here to enable support providing communication channels to
remote processors in MediaTek platforms.
This use IPI and IPC to communicate with remote processors.

config RPMSG_QCOM_GLINK_NATIVE
tristate
select RPMSG
Expand Down
1 change: 1 addition & 0 deletions drivers/rpmsg/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_RPMSG) += rpmsg_core.o
obj-$(CONFIG_RPMSG_CHAR) += rpmsg_char.o
obj-$(CONFIG_RPMSG_MTK_SCP) += mtk_rpmsg.o
obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o
obj-$(CONFIG_RPMSG_QCOM_GLINK_NATIVE) += qcom_glink_native.o
obj-$(CONFIG_RPMSG_QCOM_GLINK_SMEM) += qcom_glink_smem.o
Expand Down
Loading

0 comments on commit 7017996

Please sign in to comment.