1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022 MediaTek Inc. 4 * Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com> 5 */ 6 7 #include <linux/remoteproc.h> 8 #include <linux/remoteproc/mtk_scp.h> 9 #include "mtk-mdp3-vpu.h" 10 #include "mtk-mdp3-core.h" 11 12 #define MDP_VPU_MESSAGE_TIMEOUT 500U 13 14 static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu) 15 { 16 return container_of(vpu, struct mdp_dev, vpu); 17 } 18 19 static int mdp_vpu_shared_mem_alloc(struct mdp_vpu_dev *vpu) 20 { 21 struct device *dev; 22 23 if (IS_ERR_OR_NULL(vpu)) 24 goto err_return; 25 26 dev = scp_get_device(vpu->scp); 27 28 if (!vpu->param) { 29 vpu->param = dma_alloc_wc(dev, vpu->param_size, 30 &vpu->param_addr, GFP_KERNEL); 31 if (!vpu->param) 32 goto err_return; 33 } 34 35 if (!vpu->work) { 36 vpu->work = dma_alloc_wc(dev, vpu->work_size, 37 &vpu->work_addr, GFP_KERNEL); 38 if (!vpu->work) 39 goto err_free_param; 40 } 41 42 if (!vpu->config) { 43 vpu->config = dma_alloc_wc(dev, vpu->config_size, 44 &vpu->config_addr, GFP_KERNEL); 45 if (!vpu->config) 46 goto err_free_work; 47 } 48 49 return 0; 50 51 err_free_work: 52 dma_free_wc(dev, vpu->work_size, vpu->work, vpu->work_addr); 53 vpu->work = NULL; 54 err_free_param: 55 dma_free_wc(dev, vpu->param_size, vpu->param, vpu->param_addr); 56 vpu->param = NULL; 57 err_return: 58 return -ENOMEM; 59 } 60 61 void mdp_vpu_shared_mem_free(struct mdp_vpu_dev *vpu) 62 { 63 struct device *dev; 64 65 if (IS_ERR_OR_NULL(vpu)) 66 return; 67 68 dev = scp_get_device(vpu->scp); 69 70 if (vpu->param && vpu->param_addr) 71 dma_free_wc(dev, vpu->param_size, vpu->param, vpu->param_addr); 72 73 if (vpu->work && vpu->work_addr) 74 dma_free_wc(dev, vpu->work_size, vpu->work, vpu->work_addr); 75 76 if (vpu->config && vpu->config_addr) 77 dma_free_wc(dev, vpu->config_size, vpu->config, vpu->config_addr); 78 } 79 80 static void mdp_vpu_ipi_handle_init_ack(void *data, unsigned int len, 81 void *priv) 82 { 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; 86 87 if (!vpu->work_size) 88 vpu->work_size = msg->work_size; 89 90 vpu->status = msg->status; 91 complete(&vpu->ipi_acked); 92 } 93 94 static void mdp_vpu_ipi_handle_deinit_ack(void *data, unsigned int len, 95 void *priv) 96 { 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; 100 101 vpu->status = msg->status; 102 complete(&vpu->ipi_acked); 103 } 104 105 static void mdp_vpu_ipi_handle_frame_ack(void *data, unsigned int len, 106 void *priv) 107 { 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; 113 114 if (param->state) { 115 struct mdp_dev *mdp = vpu_to_mdp(vpu); 116 117 dev_err(&mdp->pdev->dev, "VPU MDP failure:%d\n", param->state); 118 } 119 vpu->status = param->state; 120 complete(&vpu->ipi_acked); 121 } 122 123 int mdp_vpu_register(struct mdp_dev *mdp) 124 { 125 int err; 126 struct mtk_scp *scp = mdp->scp; 127 struct device *dev = &mdp->pdev->dev; 128 129 err = scp_ipi_register(scp, SCP_IPI_MDP_INIT, 130 mdp_vpu_ipi_handle_init_ack, NULL); 131 if (err) { 132 dev_err(dev, "scp_ipi_register failed %d\n", err); 133 goto err_ipi_init; 134 } 135 err = scp_ipi_register(scp, SCP_IPI_MDP_DEINIT, 136 mdp_vpu_ipi_handle_deinit_ack, NULL); 137 if (err) { 138 dev_err(dev, "scp_ipi_register failed %d\n", err); 139 goto err_ipi_deinit; 140 } 141 err = scp_ipi_register(scp, SCP_IPI_MDP_FRAME, 142 mdp_vpu_ipi_handle_frame_ack, NULL); 143 if (err) { 144 dev_err(dev, "scp_ipi_register failed %d\n", err); 145 goto err_ipi_frame; 146 } 147 return 0; 148 149 err_ipi_frame: 150 scp_ipi_unregister(scp, SCP_IPI_MDP_DEINIT); 151 err_ipi_deinit: 152 scp_ipi_unregister(scp, SCP_IPI_MDP_INIT); 153 err_ipi_init: 154 155 return err; 156 } 157 158 void mdp_vpu_unregister(struct mdp_dev *mdp) 159 { 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); 163 } 164 165 static int mdp_vpu_sendmsg(struct mdp_vpu_dev *vpu, enum scp_ipi_id id, 166 void *buf, unsigned int len) 167 { 168 struct mdp_dev *mdp = vpu_to_mdp(vpu); 169 unsigned int t = MDP_VPU_MESSAGE_TIMEOUT; 170 int ret; 171 172 if (!vpu->scp) { 173 dev_dbg(&mdp->pdev->dev, "vpu scp is NULL"); 174 return -EINVAL; 175 } 176 ret = scp_ipi_send(vpu->scp, id, buf, len, 2000); 177 178 if (ret) { 179 dev_err(&mdp->pdev->dev, "scp_ipi_send failed %d\n", ret); 180 return -EPERM; 181 } 182 ret = wait_for_completion_timeout(&vpu->ipi_acked, 183 msecs_to_jiffies(t)); 184 if (!ret) 185 ret = -ETIME; 186 else if (vpu->status) 187 ret = -EINVAL; 188 else 189 ret = 0; 190 return ret; 191 } 192 193 int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp, 194 struct mutex *lock) 195 { 196 struct mdp_ipi_init_msg msg = { 197 .drv_data = (unsigned long)vpu, 198 }; 199 struct mdp_dev *mdp = vpu_to_mdp(vpu); 200 int err; 201 202 init_completion(&vpu->ipi_acked); 203 vpu->scp = scp; 204 vpu->lock = lock; 205 vpu->work_size = 0; 206 err = mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_INIT, &msg, sizeof(msg)); 207 if (err) 208 goto err_work_size; 209 /* vpu work_size was set in mdp_vpu_ipi_handle_init_ack */ 210 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); 217 if (err) { 218 dev_err(&mdp->pdev->dev, "VPU memory alloc fail!"); 219 goto err_mem_alloc; 220 } 221 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); 227 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)); 231 if (err) 232 goto err_work_size; 233 234 return 0; 235 236 err_work_size: 237 switch (vpu->status) { 238 case -MDP_IPI_EBUSY: 239 err = -EBUSY; 240 break; 241 case -MDP_IPI_ENOMEM: 242 err = -ENOSPC; /* -ENOMEM */ 243 break; 244 } 245 return err; 246 err_mem_alloc: 247 return err; 248 } 249 250 int mdp_vpu_dev_deinit(struct mdp_vpu_dev *vpu) 251 { 252 struct mdp_ipi_deinit_msg msg = { 253 .drv_data = (unsigned long)vpu, 254 .work_addr = vpu->work_addr, 255 }; 256 257 return mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_DEINIT, &msg, sizeof(msg)); 258 } 259 260 int mdp_vpu_process(struct mdp_vpu_dev *vpu, struct img_ipi_frameparam *param) 261 { 262 struct mdp_dev *mdp = vpu_to_mdp(vpu); 263 struct img_sw_addr addr; 264 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); 269 return -ENOMEM; 270 } 271 272 memset(vpu->param, 0, vpu->param_size); 273 memset(vpu->work, 0, vpu->work_size); 274 memset(vpu->config, 0, vpu->config_size); 275 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)); 282 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)); 287 } 288