1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2022 MediaTek Inc.
4 * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
7 #include <linux/remoteproc.h>
8 #include <linux/remoteproc/mtk_scp.h>
9 #include "mtk-mdp3-vpu.h"
10 #include "mtk-mdp3-core.h"
12 #define MDP_VPU_MESSAGE_TIMEOUT 500U
14 static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu)
16 return container_of(vpu, struct mdp_dev, vpu);
19 static int mdp_vpu_shared_mem_alloc(struct mdp_vpu_dev *vpu)
23 if (IS_ERR_OR_NULL(vpu))
26 dev = scp_get_device(vpu->scp);
29 vpu->param = dma_alloc_wc(dev, vpu->param_size,
30 &vpu->param_addr, GFP_KERNEL);
36 vpu->work = dma_alloc_wc(dev, vpu->work_size,
37 &vpu->work_addr, GFP_KERNEL);
43 vpu->config = dma_alloc_wc(dev, vpu->config_size,
44 &vpu->config_addr, GFP_KERNEL);
52 dma_free_wc(dev, vpu->work_size, vpu->work, vpu->work_addr);
55 dma_free_wc(dev, vpu->param_size, vpu->param, vpu->param_addr);
61 void mdp_vpu_shared_mem_free(struct mdp_vpu_dev *vpu)
65 if (IS_ERR_OR_NULL(vpu))
68 dev = scp_get_device(vpu->scp);
70 if (vpu->param && vpu->param_addr)
71 dma_free_wc(dev, vpu->param_size, vpu->param, vpu->param_addr);
73 if (vpu->work && vpu->work_addr)
74 dma_free_wc(dev, vpu->work_size, vpu->work, vpu->work_addr);
76 if (vpu->config && vpu->config_addr)
77 dma_free_wc(dev, vpu->config_size, vpu->config, vpu->config_addr);
80 static void mdp_vpu_ipi_handle_init_ack(void *data, unsigned int len,
83 struct mdp_ipi_init_msg *msg = (struct mdp_ipi_init_msg *)data;
84 struct mdp_vpu_dev *vpu =
85 (struct mdp_vpu_dev *)(unsigned long)msg->drv_data;
88 vpu->work_size = msg->work_size;
90 vpu->status = msg->status;
91 complete(&vpu->ipi_acked);
94 static void mdp_vpu_ipi_handle_deinit_ack(void *data, unsigned int len,
97 struct mdp_ipi_deinit_msg *msg = (struct mdp_ipi_deinit_msg *)data;
98 struct mdp_vpu_dev *vpu =
99 (struct mdp_vpu_dev *)(unsigned long)msg->drv_data;
101 vpu->status = msg->status;
102 complete(&vpu->ipi_acked);
105 static void mdp_vpu_ipi_handle_frame_ack(void *data, unsigned int len,
108 struct img_sw_addr *addr = (struct img_sw_addr *)data;
109 struct img_ipi_frameparam *param =
110 (struct img_ipi_frameparam *)(unsigned long)addr->va;
111 struct mdp_vpu_dev *vpu =
112 (struct mdp_vpu_dev *)(unsigned long)param->drv_data;
115 struct mdp_dev *mdp = vpu_to_mdp(vpu);
117 dev_err(&mdp->pdev->dev, "VPU MDP failure:%d\n", param->state);
119 vpu->status = param->state;
120 complete(&vpu->ipi_acked);
123 int mdp_vpu_register(struct mdp_dev *mdp)
126 struct mtk_scp *scp = mdp->scp;
127 struct device *dev = &mdp->pdev->dev;
129 err = scp_ipi_register(scp, SCP_IPI_MDP_INIT,
130 mdp_vpu_ipi_handle_init_ack, NULL);
132 dev_err(dev, "scp_ipi_register failed %d\n", err);
135 err = scp_ipi_register(scp, SCP_IPI_MDP_DEINIT,
136 mdp_vpu_ipi_handle_deinit_ack, NULL);
138 dev_err(dev, "scp_ipi_register failed %d\n", err);
141 err = scp_ipi_register(scp, SCP_IPI_MDP_FRAME,
142 mdp_vpu_ipi_handle_frame_ack, NULL);
144 dev_err(dev, "scp_ipi_register failed %d\n", err);
150 scp_ipi_unregister(scp, SCP_IPI_MDP_DEINIT);
152 scp_ipi_unregister(scp, SCP_IPI_MDP_INIT);
158 void mdp_vpu_unregister(struct mdp_dev *mdp)
160 scp_ipi_unregister(mdp->scp, SCP_IPI_MDP_INIT);
161 scp_ipi_unregister(mdp->scp, SCP_IPI_MDP_DEINIT);
162 scp_ipi_unregister(mdp->scp, SCP_IPI_MDP_FRAME);
165 static int mdp_vpu_sendmsg(struct mdp_vpu_dev *vpu, enum scp_ipi_id id,
166 void *buf, unsigned int len)
168 struct mdp_dev *mdp = vpu_to_mdp(vpu);
169 unsigned int t = MDP_VPU_MESSAGE_TIMEOUT;
173 dev_dbg(&mdp->pdev->dev, "vpu scp is NULL");
176 ret = scp_ipi_send(vpu->scp, id, buf, len, 2000);
179 dev_err(&mdp->pdev->dev, "scp_ipi_send failed %d\n", ret);
182 ret = wait_for_completion_timeout(&vpu->ipi_acked,
183 msecs_to_jiffies(t));
186 else if (vpu->status)
193 int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
196 struct mdp_ipi_init_msg msg = {
197 .drv_data = (unsigned long)vpu,
199 struct mdp_dev *mdp = vpu_to_mdp(vpu);
202 init_completion(&vpu->ipi_acked);
206 err = mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_INIT, &msg, sizeof(msg));
209 /* vpu work_size was set in mdp_vpu_ipi_handle_init_ack */
211 mutex_lock(vpu->lock);
212 vpu->work_size = ALIGN(vpu->work_size, 64);
213 vpu->param_size = ALIGN(sizeof(struct img_ipi_frameparam), 64);
214 vpu->config_size = ALIGN(sizeof(struct img_config), 64);
215 err = mdp_vpu_shared_mem_alloc(vpu);
216 mutex_unlock(vpu->lock);
218 dev_err(&mdp->pdev->dev, "VPU memory alloc fail!");
222 dev_dbg(&mdp->pdev->dev,
223 "VPU param:%pK pa:%pad sz:%zx, work:%pK pa:%pad sz:%zx, config:%pK pa:%pad sz:%zx",
224 vpu->param, &vpu->param_addr, vpu->param_size,
225 vpu->work, &vpu->work_addr, vpu->work_size,
226 vpu->config, &vpu->config_addr, vpu->config_size);
228 msg.work_addr = vpu->work_addr;
229 msg.work_size = vpu->work_size;
230 err = mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_INIT, &msg, sizeof(msg));
237 switch (vpu->status) {
241 case -MDP_IPI_ENOMEM:
242 err = -ENOSPC; /* -ENOMEM */
250 int mdp_vpu_dev_deinit(struct mdp_vpu_dev *vpu)
252 struct mdp_ipi_deinit_msg msg = {
253 .drv_data = (unsigned long)vpu,
254 .work_addr = vpu->work_addr,
257 return mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_DEINIT, &msg, sizeof(msg));
260 int mdp_vpu_process(struct mdp_vpu_dev *vpu, struct img_ipi_frameparam *param)
262 struct mdp_dev *mdp = vpu_to_mdp(vpu);
263 struct img_sw_addr addr;
265 mutex_lock(vpu->lock);
266 if (mdp_vpu_shared_mem_alloc(vpu)) {
267 dev_err(&mdp->pdev->dev, "VPU memory alloc fail!");
268 mutex_unlock(vpu->lock);
272 memset(vpu->param, 0, vpu->param_size);
273 memset(vpu->work, 0, vpu->work_size);
274 memset(vpu->config, 0, vpu->config_size);
276 param->self_data.va = (unsigned long)vpu->work;
277 param->self_data.pa = vpu->work_addr;
278 param->config_data.va = (unsigned long)vpu->config;
279 param->config_data.pa = vpu->config_addr;
280 param->drv_data = (unsigned long)vpu;
281 memcpy(vpu->param, param, sizeof(*param));
283 addr.pa = vpu->param_addr;
284 addr.va = (unsigned long)vpu->param;
285 mutex_unlock(vpu->lock);
286 return mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_FRAME, &addr, sizeof(addr));