1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2020-2021 NXP 4 */ 5 6 #include <linux/init.h> 7 #include <linux/interconnect.h> 8 #include <linux/ioctl.h> 9 #include <linux/list.h> 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include "vpu.h" 13 #include "vpu_core.h" 14 #include "vpu_rpc.h" 15 #include "vpu_mbox.h" 16 #include "vpu_defs.h" 17 #include "vpu_cmds.h" 18 #include "vpu_msgs.h" 19 #include "vpu_v4l2.h" 20 21 #define VPU_PKT_HEADER_LENGTH 3 22 23 struct vpu_msg_handler { 24 u32 id; 25 void (*done)(struct vpu_inst *inst, struct vpu_rpc_event *pkt); 26 }; 27 28 static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 29 { 30 vpu_trace(inst->dev, "[%d]\n", inst->id); 31 } 32 33 static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 34 { 35 struct vpu_pkt_mem_req_data req_data; 36 37 vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data); 38 vpu_trace(inst->dev, "[%d] %d:%d %d:%d %d:%d\n", 39 inst->id, 40 req_data.enc_frame_size, 41 req_data.enc_frame_num, 42 req_data.ref_frame_size, 43 req_data.ref_frame_num, 44 req_data.act_buf_size, 45 req_data.act_buf_num); 46 call_void_vop(inst, mem_request, 47 req_data.enc_frame_size, 48 req_data.enc_frame_num, 49 req_data.ref_frame_size, 50 req_data.ref_frame_num, 51 req_data.act_buf_size, 52 req_data.act_buf_num); 53 } 54 55 static void vpu_session_handle_stop_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 56 { 57 vpu_trace(inst->dev, "[%d]\n", inst->id); 58 59 call_void_vop(inst, stop_done); 60 } 61 62 static void vpu_session_handle_seq_hdr(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 63 { 64 struct vpu_dec_codec_info info; 65 const struct vpu_core_resources *res; 66 67 memset(&info, 0, sizeof(info)); 68 res = vpu_get_resource(inst); 69 info.stride = res ? res->stride : 1; 70 vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); 71 call_void_vop(inst, event_notify, VPU_MSG_ID_SEQ_HDR_FOUND, &info); 72 } 73 74 static void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 75 { 76 call_void_vop(inst, event_notify, VPU_MSG_ID_RES_CHANGE, NULL); 77 } 78 79 static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 80 { 81 struct vpu_enc_pic_info info; 82 83 vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); 84 dev_dbg(inst->dev, "[%d] frame id = %d, wptr = 0x%x, size = %d\n", 85 inst->id, info.frame_id, info.wptr, info.frame_size); 86 call_void_vop(inst, get_one_frame, &info); 87 } 88 89 static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 90 { 91 struct vpu_fs_info fs; 92 93 vpu_iface_unpack_msg_data(inst->core, pkt, &fs); 94 call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs); 95 } 96 97 static void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 98 { 99 if (inst->core->type == VPU_CORE_TYPE_ENC) { 100 struct vpu_frame_info info; 101 102 memset(&info, 0, sizeof(info)); 103 vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info.sequence); 104 dev_dbg(inst->dev, "[%d] %d\n", inst->id, info.sequence); 105 info.type = inst->out_format.type; 106 call_void_vop(inst, buf_done, &info); 107 } else if (inst->core->type == VPU_CORE_TYPE_DEC) { 108 struct vpu_fs_info fs; 109 110 vpu_iface_unpack_msg_data(inst->core, pkt, &fs); 111 call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs); 112 } 113 } 114 115 static void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 116 { 117 dev_dbg(inst->dev, "[%d]\n", inst->id); 118 call_void_vop(inst, input_done); 119 } 120 121 static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 122 { 123 struct vpu_dec_pic_info info; 124 125 vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); 126 call_void_vop(inst, get_one_frame, &info); 127 } 128 129 static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 130 { 131 struct vpu_dec_pic_info info; 132 struct vpu_frame_info frame; 133 134 memset(&frame, 0, sizeof(frame)); 135 vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); 136 if (inst->core->type == VPU_CORE_TYPE_DEC) 137 frame.type = inst->cap_format.type; 138 frame.id = info.id; 139 frame.luma = info.luma; 140 frame.skipped = info.skipped; 141 frame.timestamp = info.timestamp; 142 143 call_void_vop(inst, buf_done, &frame); 144 } 145 146 static void vpu_session_handle_eos(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 147 { 148 call_void_vop(inst, event_notify, VPU_MSG_ID_PIC_EOS, NULL); 149 } 150 151 static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 152 { 153 char *str = (char *)pkt->data; 154 155 if (strlen(str)) 156 dev_err(inst->dev, "instance %d firmware error : %s\n", inst->id, str); 157 else 158 dev_err(inst->dev, "instance %d is unsupported stream\n", inst->id); 159 call_void_vop(inst, event_notify, VPU_MSG_ID_UNSUPPORTED, NULL); 160 vpu_v4l2_set_error(inst); 161 } 162 163 static void vpu_session_handle_firmware_xcpt(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 164 { 165 char *str = (char *)pkt->data; 166 167 dev_err(inst->dev, "%s firmware xcpt: %s\n", 168 vpu_core_type_desc(inst->core->type), str); 169 call_void_vop(inst, event_notify, VPU_MSG_ID_FIRMWARE_XCPT, NULL); 170 set_bit(inst->id, &inst->core->hang_mask); 171 vpu_v4l2_set_error(inst); 172 } 173 174 static void vpu_session_handle_pic_skipped(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 175 { 176 vpu_inst_lock(inst); 177 vpu_skip_frame(inst, 1); 178 vpu_inst_unlock(inst); 179 } 180 181 static struct vpu_msg_handler handlers[] = { 182 {VPU_MSG_ID_START_DONE, vpu_session_handle_start_done}, 183 {VPU_MSG_ID_STOP_DONE, vpu_session_handle_stop_done}, 184 {VPU_MSG_ID_MEM_REQUEST, vpu_session_handle_mem_request}, 185 {VPU_MSG_ID_SEQ_HDR_FOUND, vpu_session_handle_seq_hdr}, 186 {VPU_MSG_ID_RES_CHANGE, vpu_session_handle_resolution_change}, 187 {VPU_MSG_ID_FRAME_INPUT_DONE, vpu_session_handle_input_done}, 188 {VPU_MSG_ID_FRAME_REQ, vpu_session_handle_frame_request}, 189 {VPU_MSG_ID_FRAME_RELEASE, vpu_session_handle_frame_release}, 190 {VPU_MSG_ID_ENC_DONE, vpu_session_handle_enc_frame_done}, 191 {VPU_MSG_ID_PIC_DECODED, vpu_session_handle_pic_decoded}, 192 {VPU_MSG_ID_DEC_DONE, vpu_session_handle_pic_done}, 193 {VPU_MSG_ID_PIC_EOS, vpu_session_handle_eos}, 194 {VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error}, 195 {VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt}, 196 {VPU_MSG_ID_PIC_SKIPPED, vpu_session_handle_pic_skipped}, 197 }; 198 199 static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *msg) 200 { 201 int ret; 202 u32 msg_id; 203 struct vpu_msg_handler *handler = NULL; 204 unsigned int i; 205 206 ret = vpu_iface_convert_msg_id(inst->core, msg->hdr.id); 207 if (ret < 0) 208 return -EINVAL; 209 210 msg_id = ret; 211 dev_dbg(inst->dev, "[%d] receive event(0x%x)\n", inst->id, msg_id); 212 213 for (i = 0; i < ARRAY_SIZE(handlers); i++) { 214 if (handlers[i].id == msg_id) { 215 handler = &handlers[i]; 216 break; 217 } 218 } 219 220 if (handler && handler->done) 221 handler->done(inst, msg); 222 223 vpu_response_cmd(inst, msg_id, 1); 224 225 return 0; 226 } 227 228 static bool vpu_inst_receive_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 229 { 230 unsigned long bytes = sizeof(struct vpu_rpc_event_header); 231 u32 ret; 232 233 memset(pkt, 0, sizeof(*pkt)); 234 if (kfifo_len(&inst->msg_fifo) < bytes) 235 return false; 236 237 ret = kfifo_out(&inst->msg_fifo, pkt, bytes); 238 if (ret != bytes) 239 return false; 240 241 if (pkt->hdr.num > 0) { 242 bytes = pkt->hdr.num * sizeof(u32); 243 ret = kfifo_out(&inst->msg_fifo, pkt->data, bytes); 244 if (ret != bytes) 245 return false; 246 } 247 248 return true; 249 } 250 251 void vpu_inst_run_work(struct work_struct *work) 252 { 253 struct vpu_inst *inst = container_of(work, struct vpu_inst, msg_work); 254 struct vpu_rpc_event pkt; 255 256 while (vpu_inst_receive_msg(inst, &pkt)) 257 vpu_session_handle_msg(inst, &pkt); 258 } 259 260 static void vpu_inst_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt) 261 { 262 unsigned long bytes; 263 u32 id = pkt->hdr.id; 264 int ret; 265 266 if (!inst->workqueue) 267 return; 268 269 bytes = sizeof(pkt->hdr) + pkt->hdr.num * sizeof(u32); 270 ret = kfifo_in(&inst->msg_fifo, pkt, bytes); 271 if (ret != bytes) 272 dev_err(inst->dev, "[%d:%d]overflow: %d\n", inst->core->id, inst->id, id); 273 queue_work(inst->workqueue, &inst->msg_work); 274 } 275 276 static int vpu_handle_msg(struct vpu_core *core) 277 { 278 struct vpu_rpc_event pkt; 279 struct vpu_inst *inst; 280 int ret; 281 282 memset(&pkt, 0, sizeof(pkt)); 283 while (!vpu_iface_receive_msg(core, &pkt)) { 284 dev_dbg(core->dev, "event index = %d, id = %d, num = %d\n", 285 pkt.hdr.index, pkt.hdr.id, pkt.hdr.num); 286 287 ret = vpu_iface_convert_msg_id(core, pkt.hdr.id); 288 if (ret < 0) 289 continue; 290 291 inst = vpu_core_find_instance(core, pkt.hdr.index); 292 if (inst) { 293 vpu_response_cmd(inst, ret, 0); 294 mutex_lock(&core->cmd_lock); 295 vpu_inst_record_flow(inst, ret); 296 mutex_unlock(&core->cmd_lock); 297 298 vpu_inst_handle_msg(inst, &pkt); 299 vpu_inst_put(inst); 300 } 301 memset(&pkt, 0, sizeof(pkt)); 302 } 303 304 return 0; 305 } 306 307 static int vpu_isr_thread(struct vpu_core *core, u32 irq_code) 308 { 309 dev_dbg(core->dev, "irq code = 0x%x\n", irq_code); 310 switch (irq_code) { 311 case VPU_IRQ_CODE_SYNC: 312 vpu_mbox_send_msg(core, PRC_BUF_OFFSET, core->rpc.phys - core->fw.phys); 313 vpu_mbox_send_msg(core, BOOT_ADDRESS, core->fw.phys); 314 vpu_mbox_send_msg(core, INIT_DONE, 2); 315 break; 316 case VPU_IRQ_CODE_BOOT_DONE: 317 break; 318 case VPU_IRQ_CODE_SNAPSHOT_DONE: 319 break; 320 default: 321 vpu_handle_msg(core); 322 break; 323 } 324 325 return 0; 326 } 327 328 static void vpu_core_run_msg_work(struct vpu_core *core) 329 { 330 const unsigned int SIZE = sizeof(u32); 331 332 while (kfifo_len(&core->msg_fifo) >= SIZE) { 333 u32 data = 0; 334 335 if (kfifo_out(&core->msg_fifo, &data, SIZE) == SIZE) 336 vpu_isr_thread(core, data); 337 } 338 } 339 340 void vpu_msg_run_work(struct work_struct *work) 341 { 342 struct vpu_core *core = container_of(work, struct vpu_core, msg_work); 343 unsigned long delay = msecs_to_jiffies(10); 344 345 vpu_core_run_msg_work(core); 346 queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay); 347 } 348 349 void vpu_msg_delayed_work(struct work_struct *work) 350 { 351 struct vpu_core *core; 352 struct delayed_work *dwork; 353 unsigned long bytes = sizeof(u32); 354 u32 i; 355 356 if (!work) 357 return; 358 359 dwork = to_delayed_work(work); 360 core = container_of(dwork, struct vpu_core, msg_delayed_work); 361 if (kfifo_len(&core->msg_fifo) >= bytes) 362 vpu_core_run_msg_work(core); 363 364 bytes = sizeof(struct vpu_rpc_event_header); 365 for (i = 0; i < core->supported_instance_count; i++) { 366 struct vpu_inst *inst = vpu_core_find_instance(core, i); 367 368 if (!inst) 369 continue; 370 371 if (inst->workqueue && kfifo_len(&inst->msg_fifo) >= bytes) 372 queue_work(inst->workqueue, &inst->msg_work); 373 374 vpu_inst_put(inst); 375 } 376 } 377 378 int vpu_isr(struct vpu_core *core, u32 irq) 379 { 380 switch (irq) { 381 case VPU_IRQ_CODE_SYNC: 382 break; 383 case VPU_IRQ_CODE_BOOT_DONE: 384 complete(&core->cmp); 385 break; 386 case VPU_IRQ_CODE_SNAPSHOT_DONE: 387 complete(&core->cmp); 388 break; 389 default: 390 break; 391 } 392 393 if (kfifo_in(&core->msg_fifo, &irq, sizeof(irq)) != sizeof(irq)) 394 dev_err(core->dev, "[%d]overflow: %d\n", core->id, irq); 395 queue_work(core->workqueue, &core->msg_work); 396 397 return 0; 398 } 399