@@ -10,7 +10,7 @@ remoteproc-y += remoteproc_sysfs.o
remoteproc-y += remoteproc_virtio.o
remoteproc-y += remoteproc_elf_loader.o
obj-$(CONFIG_IMX_REMOTEPROC) += imx_rproc.o
-obj-$(CONFIG_MTK_SCP) += mtk_scp.o
+obj-$(CONFIG_MTK_SCP) += mtk_scp.o mtk_scp_ipi.o
obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o
obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o
obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o
new file mode 100644
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#ifndef __RPROC_MTK_COMMON_H
+#define __RPROC_MTK_COMMON_H
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+
+#define MT8183_SW_RSTN 0x0
+#define MT8183_SW_RSTN_BIT BIT(0)
+#define MT8183_SCP_TO_HOST 0x1C
+#define MT8183_SCP_IPC_INT_BIT BIT(0)
+#define MT8183_SCP_WDT_INT_BIT BIT(8)
+#define MT8183_HOST_TO_SCP 0x28
+#define MT8183_HOST_IPC_INT_BIT BIT(0)
+#define MT8183_SCP_SRAM_PDN 0x402C
+
+#define SCP_FW_VER_LEN 32
+
+struct scp_run {
+ u32 signaled;
+ s8 fw_ver[SCP_FW_VER_LEN];
+ u32 dec_capability;
+ u32 enc_capability;
+ wait_queue_head_t wq;
+};
+
+struct scp_ipi_desc {
+ ipi_handler_t handler;
+ const char *name;
+ void *priv;
+};
+
+struct mtk_scp {
+ struct device *dev;
+ struct rproc *rproc;
+ struct clk *clk;
+ void __iomem *reg_base;
+ void __iomem *sram_base;
+ size_t sram_size;
+
+ struct share_obj *recv_buf;
+ struct share_obj *send_buf;
+ struct scp_run run;
+ struct mutex scp_mutex; /* for protecting mtk_scp data structure */
+ struct scp_ipi_desc ipi_desc[IPI_MAX];
+ bool ipi_id_ack[IPI_MAX];
+ wait_queue_head_t ack_wq;
+
+ void __iomem *cpu_addr;
+ phys_addr_t phys_addr;
+ size_t dram_size;
+};
+
+/**
+ * struct share_obj - SRAM buffer shared with
+ * AP and SCP
+ *
+ * @id: IPI id
+ * @len: share buffer length
+ * @share_buf: share buffer data
+ */
+struct share_obj {
+ s32 id;
+ u32 len;
+ u8 share_buf[288];
+};
+
+#endif
@@ -14,163 +14,12 @@
#include <linux/remoteproc.h>
#include "remoteproc_internal.h"
-
-#define MT8183_SW_RSTN 0x0
-#define MT8183_SW_RSTN_BIT BIT(0)
-#define MT8183_SCP_TO_HOST 0x1C
-#define MT8183_SCP_IPC_INT_BIT BIT(0)
-#define MT8183_SCP_WDT_INT_BIT BIT(8)
-#define MT8183_HOST_TO_SCP 0x28
-#define MT8183_HOST_IPC_INT_BIT BIT(0)
-#define MT8183_SCP_SRAM_PDN 0x402C
+#include "mtk_common.h"
#define INIT_TIMEOUT_MS 2000
-#define IPI_TIMEOUT_MS 2000
-#define SCP_FW_VER_LEN 32
#define MAX_CODE_SIZE 0x500000
-struct scp_run {
- u32 signaled;
- s8 fw_ver[SCP_FW_VER_LEN];
- u32 dec_capability;
- u32 enc_capability;
- wait_queue_head_t wq;
-};
-
-struct scp_ipi_desc {
- ipi_handler_t handler;
- const char *name;
- void *priv;
-};
-
-struct mtk_scp {
- struct device *dev;
- struct rproc *rproc;
- struct clk *clk;
- void __iomem *reg_base;
- void __iomem *sram_base;
- size_t sram_size;
-
- struct share_obj *recv_buf;
- struct share_obj *send_buf;
- struct scp_run run;
- struct mutex scp_mutex; /* for protecting mtk_scp data structure */
- struct scp_ipi_desc ipi_desc[IPI_MAX];
- bool ipi_id_ack[IPI_MAX];
- wait_queue_head_t ack_wq;
-
- void __iomem *cpu_addr;
- phys_addr_t phys_addr;
- size_t dram_size;
-};
-
-/**
- * struct share_obj - SRAM buffer shared with
- * AP and SCP
- *
- * @id: IPI id
- * @len: share buffer length
- * @share_buf: share buffer data
- */
-struct share_obj {
- s32 id;
- u32 len;
- u8 share_buf[288];
-};
-
-int scp_ipi_register(struct platform_device *pdev,
- enum ipi_id id,
- ipi_handler_t handler,
- const char *name,
- void *priv)
-{
- struct mtk_scp *scp = platform_get_drvdata(pdev);
- struct scp_ipi_desc *ipi_desc;
-
- if (!scp) {
- dev_err(&pdev->dev, "scp device is not ready\n");
- return -EPROBE_DEFER;
- }
-
- if (WARN(id < 0 || id >= IPI_MAX || handler == NULL,
- "register scp ipi id %d with invalid arguments\n", id))
- return -EINVAL;
-
- ipi_desc = scp->ipi_desc;
- ipi_desc[id].name = name;
- ipi_desc[id].handler = handler;
- ipi_desc[id].priv = priv;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(scp_ipi_register);
-
-int scp_ipi_send(struct platform_device *pdev,
- enum ipi_id id, void *buf,
- unsigned int len,
- unsigned int wait)
-{
- struct mtk_scp *scp = platform_get_drvdata(pdev);
- struct share_obj *send_obj = scp->send_buf;
- unsigned long timeout;
- int ret;
-
- if (WARN(id <= IPI_SCP_INIT || id >= IPI_MAX ||
- len > sizeof(send_obj->share_buf) || !buf,
- "failed to send ipi message\n"))
- return -EINVAL;
-
- ret = clk_prepare_enable(scp->clk);
- if (ret) {
- dev_err(scp->dev, "failed to enable clock\n");
- return ret;
- }
-
- mutex_lock(&scp->scp_mutex);
-
- /* Wait until SCP receives the last command */
- timeout = jiffies + msecs_to_jiffies(IPI_TIMEOUT_MS);
- do {
- if (time_after(jiffies, timeout)) {
- dev_err(scp->dev, "scp_ipi_send: IPI timeout!\n");
- ret = -EIO;
- mutex_unlock(&scp->scp_mutex);
- goto clock_disable;
- }
- } while (readl(scp->reg_base + MT8183_HOST_TO_SCP));
-
- memcpy(send_obj->share_buf, buf, len);
- send_obj->len = len;
- send_obj->id = id;
-
- scp->ipi_id_ack[id] = false;
- /* send the command to SCP */
- writel(MT8183_HOST_IPC_INT_BIT, scp->reg_base + MT8183_HOST_TO_SCP);
-
- mutex_unlock(&scp->scp_mutex);
-
- if (wait) {
- /* wait for SCP's ACK */
- timeout = msecs_to_jiffies(wait);
- ret = wait_event_timeout(scp->ack_wq,
- scp->ipi_id_ack[id],
- timeout);
- scp->ipi_id_ack[id] = false;
- if (WARN(!ret,
- "scp ipi %d ack time out !", id))
- ret = -EIO;
- else
- ret = 0;
- }
-
-clock_disable:
- clk_disable_unprepare(scp->clk);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(scp_ipi_send);
-
struct platform_device *scp_get_plat_device(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
new file mode 100644
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_data/mtk_scp.h>
+#include <linux/platform_device.h>
+
+#include "mtk_common.h"
+
+#define IPI_TIMEOUT_MS 2000
+
+int scp_ipi_register(struct platform_device *pdev,
+ enum ipi_id id,
+ ipi_handler_t handler,
+ const char *name,
+ void *priv)
+{
+ struct mtk_scp *scp = platform_get_drvdata(pdev);
+ struct scp_ipi_desc *ipi_desc;
+
+ if (!scp) {
+ dev_err(&pdev->dev, "scp device is not ready\n");
+ return -EPROBE_DEFER;
+ }
+
+ if (WARN(id < 0 || id >= IPI_MAX || handler == NULL,
+ "register scp ipi id %d with invalid arguments\n", id))
+ return -EINVAL;
+
+ ipi_desc = scp->ipi_desc;
+ ipi_desc[id].name = name;
+ ipi_desc[id].handler = handler;
+ ipi_desc[id].priv = priv;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(scp_ipi_register);
+
+int scp_ipi_send(struct platform_device *pdev,
+ enum ipi_id id, void *buf,
+ unsigned int len,
+ unsigned int wait)
+{
+ struct mtk_scp *scp = platform_get_drvdata(pdev);
+ struct share_obj *send_obj = scp->send_buf;
+ unsigned long timeout;
+ int ret;
+
+ if (WARN(id <= IPI_SCP_INIT || id >= IPI_MAX ||
+ len > sizeof(send_obj->share_buf) || !buf,
+ "failed to send ipi message\n"))
+ return -EINVAL;
+
+ ret = clk_prepare_enable(scp->clk);
+ if (ret) {
+ dev_err(scp->dev, "failed to enable clock\n");
+ return ret;
+ }
+
+ mutex_lock(&scp->scp_mutex);
+
+ /* Wait until SCP receives the last command */
+ timeout = jiffies + msecs_to_jiffies(IPI_TIMEOUT_MS);
+ do {
+ if (time_after(jiffies, timeout)) {
+ dev_err(scp->dev, "scp_ipi_send: IPI timeout!\n");
+ ret = -EIO;
+ mutex_unlock(&scp->scp_mutex);
+ goto clock_disable;
+ }
+ } while (readl(scp->reg_base + MT8183_HOST_TO_SCP));
+
+ memcpy(send_obj->share_buf, buf, len);
+ send_obj->len = len;
+ send_obj->id = id;
+
+ scp->ipi_id_ack[id] = false;
+ /* send the command to SCP */
+ writel(MT8183_HOST_IPC_INT_BIT, scp->reg_base + MT8183_HOST_TO_SCP);
+
+ mutex_unlock(&scp->scp_mutex);
+
+ if (wait) {
+ /* wait for SCP's ACK */
+ timeout = msecs_to_jiffies(wait);
+ ret = wait_event_timeout(scp->ack_wq,
+ scp->ipi_id_ack[id],
+ timeout);
+ scp->ipi_id_ack[id] = false;
+ if (WARN(!ret,
+ "scp ipi %d ack time out !", id))
+ ret = -EIO;
+ else
+ ret = 0;
+ }
+
+clock_disable:
+ clk_disable_unprepare(scp->clk);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(scp_ipi_send);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MediaTek scp IPI interface");
Move the IPI interface into a separate file mtk_scp_ipi.c, so the things that use the interface only can depend on the module only. Signed-off-by: Pi-Hsun Shih <pihsun@chromium.org> --- drivers/remoteproc/Makefile | 2 +- drivers/remoteproc/mtk_common.h | 73 +++++++++++++++ drivers/remoteproc/mtk_scp.c | 153 +------------------------------ drivers/remoteproc/mtk_scp_ipi.c | 109 ++++++++++++++++++++++ 4 files changed, 184 insertions(+), 153 deletions(-) create mode 100644 drivers/remoteproc/mtk_common.h create mode 100644 drivers/remoteproc/mtk_scp_ipi.c