1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2025 Advanced Micro Devices, Inc. 4 */ 5 6 #include <linux/pm_domain.h> 7 #include <linux/units.h> 8 9 #include "isp4.h" 10 #include "isp4_fw_cmd_resp.h" 11 #include "isp4_interface.h" 12 13 #define ISP4SD_MIN_BUF_CNT_BEF_START_STREAM 4 14 15 #define ISP4SD_PERFORMANCE_STATE_LOW 0 16 #define ISP4SD_PERFORMANCE_STATE_HIGH 1 17 18 /* align 32KB */ 19 #define ISP4SD_META_BUF_SIZE ALIGN(sizeof(struct isp4fw_meta_info), 0x8000) 20 21 #define to_isp4_subdev(sd) container_of(sd, struct isp4_subdev, sdev) 22 23 static const char *isp4sd_entity_name = "amd isp4"; 24 25 static const char *isp4sd_thread_name[ISP4SD_MAX_FW_RESP_STREAM_NUM] = { 26 "amd_isp4_thread_global", 27 "amd_isp4_thread_stream1", 28 }; 29 30 static void isp4sd_module_enable(struct isp4_subdev *isp_subdev, bool enable) 31 { 32 if (isp_subdev->enable_gpio) { 33 gpiod_set_value(isp_subdev->enable_gpio, enable ? 1 : 0); 34 dev_dbg(isp_subdev->dev, "%s isp_subdev module\n", 35 enable ? "enable" : "disable"); 36 } 37 } 38 39 static int isp4sd_setup_fw_mem_pool(struct isp4_subdev *isp_subdev) 40 { 41 struct isp4_interface *ispif = &isp_subdev->ispif; 42 struct isp4fw_cmd_send_buffer buf_type; 43 struct device *dev = isp_subdev->dev; 44 int ret; 45 46 if (!ispif->fw_mem_pool) { 47 dev_err(dev, "fail to alloc mem pool\n"); 48 return -ENOMEM; 49 } 50 51 /* 52 * The struct will be shared with ISP FW, use memset() to guarantee 53 * padding bits are zeroed, since this is not guaranteed on all 54 * compilers. 55 */ 56 memset(&buf_type, 0, sizeof(buf_type)); 57 buf_type.buffer_type = ISP4FW_BUFFER_TYPE_MEM_POOL; 58 buf_type.buffer.vmid_space.bit.space = ISP4FW_ADDR_SPACE_TYPE_GPU_VA; 59 isp4if_split_addr64(ispif->fw_mem_pool->gpu_mc_addr, 60 &buf_type.buffer.buf_base_a_lo, 61 &buf_type.buffer.buf_base_a_hi); 62 buf_type.buffer.buf_size_a = ispif->fw_mem_pool->mem_size; 63 64 ret = isp4if_send_command(ispif, ISP4FW_CMD_ID_SEND_BUFFER, 65 &buf_type, sizeof(buf_type)); 66 if (ret) { 67 dev_err(dev, "send fw mem pool 0x%llx(%u) fail %d\n", 68 ispif->fw_mem_pool->gpu_mc_addr, 69 buf_type.buffer.buf_size_a, ret); 70 return ret; 71 } 72 73 dev_dbg(dev, "send fw mem pool 0x%llx(%u) suc\n", 74 ispif->fw_mem_pool->gpu_mc_addr, buf_type.buffer.buf_size_a); 75 76 return 0; 77 } 78 79 static int isp4sd_set_stream_path(struct isp4_subdev *isp_subdev) 80 { 81 struct isp4_interface *ispif = &isp_subdev->ispif; 82 struct isp4fw_cmd_set_stream_cfg cmd; 83 struct device *dev = isp_subdev->dev; 84 85 /* 86 * The struct will be shared with ISP FW, use memset() to guarantee 87 * padding bits are zeroed, since this is not guaranteed on all 88 * compilers. 89 */ 90 memset(&cmd, 0, sizeof(cmd)); 91 cmd.stream_cfg.mipi_pipe_path_cfg.isp4fw_sensor_id = 92 ISP4FW_SENSOR_ID_ON_MIPI0; 93 cmd.stream_cfg.mipi_pipe_path_cfg.b_enable = true; 94 cmd.stream_cfg.isp_pipe_path_cfg.isp_pipe_id = 95 ISP4FW_MIPI0_ISP_PIPELINE_ID; 96 97 cmd.stream_cfg.b_enable_tnr = true; 98 dev_dbg(dev, "isp4fw_sensor_id %d, pipeId 0x%x EnableTnr %u\n", 99 cmd.stream_cfg.mipi_pipe_path_cfg.isp4fw_sensor_id, 100 cmd.stream_cfg.isp_pipe_path_cfg.isp_pipe_id, 101 cmd.stream_cfg.b_enable_tnr); 102 103 return isp4if_send_command(ispif, ISP4FW_CMD_ID_SET_STREAM_CONFIG, 104 &cmd, sizeof(cmd)); 105 } 106 107 static int isp4sd_send_meta_buf(struct isp4_subdev *isp_subdev) 108 { 109 struct isp4_interface *ispif = &isp_subdev->ispif; 110 struct isp4fw_cmd_send_buffer buf_type; 111 struct device *dev = isp_subdev->dev; 112 113 /* 114 * The struct will be shared with ISP FW, use memset() to guarantee 115 * padding bits are zeroed, since this is not guaranteed on all 116 * compilers. 117 */ 118 memset(&buf_type, 0, sizeof(buf_type)); 119 for (unsigned int i = 0; i < ISP4IF_MAX_STREAM_BUF_COUNT; i++) { 120 struct isp4if_gpu_mem_info *meta_info_buf = 121 isp_subdev->ispif.meta_info_buf[i]; 122 int ret; 123 124 if (!meta_info_buf) { 125 dev_err(dev, "fail for no meta info buf(%u)\n", i); 126 return -ENOMEM; 127 } 128 129 buf_type.buffer_type = ISP4FW_BUFFER_TYPE_META_INFO; 130 buf_type.buffer.vmid_space.bit.space = 131 ISP4FW_ADDR_SPACE_TYPE_GPU_VA; 132 isp4if_split_addr64(meta_info_buf->gpu_mc_addr, 133 &buf_type.buffer.buf_base_a_lo, 134 &buf_type.buffer.buf_base_a_hi); 135 buf_type.buffer.buf_size_a = meta_info_buf->mem_size; 136 ret = isp4if_send_command(ispif, ISP4FW_CMD_ID_SEND_BUFFER, 137 &buf_type, sizeof(buf_type)); 138 if (ret) { 139 dev_err(dev, "send meta info(%u) fail\n", i); 140 return ret; 141 } 142 } 143 144 dev_dbg(dev, "send meta info suc\n"); 145 return 0; 146 } 147 148 static bool isp4sd_get_str_out_prop(struct isp4_subdev *isp_subdev, 149 struct isp4fw_image_prop *out_prop, 150 struct v4l2_subdev_state *state, u32 pad) 151 { 152 struct device *dev = isp_subdev->dev; 153 struct v4l2_mbus_framefmt *format; 154 155 format = v4l2_subdev_state_get_format(state, pad, 0); 156 if (!format) { 157 dev_err(dev, "fail get subdev state format\n"); 158 return false; 159 } 160 161 switch (format->code) { 162 case MEDIA_BUS_FMT_YUYV8_1_5X8: 163 out_prop->image_format = ISP4FW_IMAGE_FORMAT_NV12; 164 out_prop->width = format->width; 165 out_prop->height = format->height; 166 out_prop->luma_pitch = format->width; 167 out_prop->chroma_pitch = out_prop->width; 168 break; 169 case MEDIA_BUS_FMT_YUYV8_1X16: 170 out_prop->image_format = ISP4FW_IMAGE_FORMAT_YUV422INTERLEAVED; 171 out_prop->width = format->width; 172 out_prop->height = format->height; 173 out_prop->luma_pitch = format->width * 2; 174 out_prop->chroma_pitch = 0; 175 break; 176 default: 177 dev_err(dev, "fail for bad image format:0x%x\n", 178 format->code); 179 return false; 180 } 181 182 if (!out_prop->width || !out_prop->height) 183 return false; 184 185 return true; 186 } 187 188 static int isp4sd_kickoff_stream(struct isp4_subdev *isp_subdev, u32 w, u32 h) 189 { 190 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 191 struct isp4_interface *ispif = &isp_subdev->ispif; 192 struct device *dev = isp_subdev->dev; 193 194 if (sensor_info->status == ISP4SD_START_STATUS_STARTED) 195 return 0; 196 197 if (sensor_info->status == ISP4SD_START_STATUS_START_FAIL) { 198 dev_err(dev, "fail for previous start fail\n"); 199 return -EINVAL; 200 } 201 202 dev_dbg(dev, "w:%u,h:%u\n", w, h); 203 204 if (isp4sd_send_meta_buf(isp_subdev)) { 205 dev_err(dev, "fail to send meta buf\n"); 206 sensor_info->status = ISP4SD_START_STATUS_START_FAIL; 207 return -EINVAL; 208 } 209 210 sensor_info->status = ISP4SD_START_STATUS_OFF; 211 212 if (!sensor_info->start_stream_cmd_sent && 213 sensor_info->buf_sent_cnt >= ISP4SD_MIN_BUF_CNT_BEF_START_STREAM) { 214 int ret = isp4if_send_command(ispif, ISP4FW_CMD_ID_START_STREAM, 215 NULL, 0); 216 if (ret) { 217 dev_err(dev, "fail to start stream\n"); 218 return ret; 219 } 220 221 sensor_info->start_stream_cmd_sent = true; 222 } else { 223 dev_dbg(dev, 224 "no send START_STREAM, start_sent %u, buf_sent %u\n", 225 sensor_info->start_stream_cmd_sent, 226 sensor_info->buf_sent_cnt); 227 } 228 229 return 0; 230 } 231 232 static int isp4sd_setup_output(struct isp4_subdev *isp_subdev, 233 struct v4l2_subdev_state *state, u32 pad) 234 { 235 struct isp4sd_output_info *output_info = 236 &isp_subdev->sensor_info.output_info; 237 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 238 struct isp4_interface *ispif = &isp_subdev->ispif; 239 struct isp4fw_cmd_set_out_ch_prop cmd_ch_prop; 240 struct isp4fw_cmd_enable_out_ch cmd_ch_en; 241 struct device *dev = isp_subdev->dev; 242 int ret; 243 244 if (output_info->start_status == ISP4SD_START_STATUS_STARTED) 245 return 0; 246 247 if (output_info->start_status == ISP4SD_START_STATUS_START_FAIL) { 248 dev_err(dev, "fail for previous start fail\n"); 249 return -EINVAL; 250 } 251 252 /* 253 * The struct will be shared with ISP FW, use memset() to guarantee 254 * padding bits are zeroed, since this is not guaranteed on all 255 * compilers. 256 */ 257 memset(&cmd_ch_prop, 0, sizeof(cmd_ch_prop)); 258 cmd_ch_prop.ch = ISP4FW_ISP_PIPE_OUT_CH_PREVIEW; 259 260 if (!isp4sd_get_str_out_prop(isp_subdev, 261 &cmd_ch_prop.image_prop, state, pad)) { 262 dev_err(dev, "fail to get out prop\n"); 263 return -EINVAL; 264 } 265 266 dev_dbg(dev, "channel:%d,fmt %d,w:h=%u:%u,lp:%u,cp%u\n", 267 cmd_ch_prop.ch, 268 cmd_ch_prop.image_prop.image_format, 269 cmd_ch_prop.image_prop.width, cmd_ch_prop.image_prop.height, 270 cmd_ch_prop.image_prop.luma_pitch, 271 cmd_ch_prop.image_prop.chroma_pitch); 272 273 ret = isp4if_send_command(ispif, ISP4FW_CMD_ID_SET_OUT_CHAN_PROP, 274 &cmd_ch_prop, sizeof(cmd_ch_prop)); 275 if (ret) { 276 output_info->start_status = ISP4SD_START_STATUS_START_FAIL; 277 dev_err(dev, "fail to set out prop\n"); 278 return ret; 279 } 280 281 /* 282 * The struct will be shared with ISP FW, use memset() to guarantee 283 * padding bits are zeroed, since this is not guaranteed on all 284 * compilers. 285 */ 286 memset(&cmd_ch_en, 0, sizeof(cmd_ch_en)); 287 cmd_ch_en.ch = ISP4FW_ISP_PIPE_OUT_CH_PREVIEW; 288 cmd_ch_en.is_enable = true; 289 ret = isp4if_send_command(ispif, ISP4FW_CMD_ID_ENABLE_OUT_CHAN, 290 &cmd_ch_en, sizeof(cmd_ch_en)); 291 if (ret) { 292 output_info->start_status = ISP4SD_START_STATUS_START_FAIL; 293 dev_err(dev, "fail to enable channel\n"); 294 return ret; 295 } 296 297 dev_dbg(dev, "enable channel %d\n", cmd_ch_en.ch); 298 299 if (!sensor_info->start_stream_cmd_sent) { 300 ret = isp4sd_kickoff_stream(isp_subdev, 301 cmd_ch_prop.image_prop.width, 302 cmd_ch_prop.image_prop.height); 303 if (ret) { 304 dev_err(dev, "kickoff stream fail %d\n", ret); 305 return ret; 306 } 307 /* 308 * sensor_info->start_stream_cmd_sent will be set to true 309 * 1. in isp4sd_kickoff_stream, if app first send buffer then 310 * start stream 311 * 2. in isp_set_stream_buf, if app first start stream, then 312 * send buffer because ISP FW has the requirement, host needs 313 * to send buffer before send start stream cmd 314 */ 315 if (sensor_info->start_stream_cmd_sent) { 316 sensor_info->status = ISP4SD_START_STATUS_STARTED; 317 output_info->start_status = ISP4SD_START_STATUS_STARTED; 318 dev_dbg(dev, "kickoff stream suc,start cmd sent\n"); 319 } 320 } else { 321 dev_dbg(dev, "stream running, no need kickoff\n"); 322 output_info->start_status = ISP4SD_START_STATUS_STARTED; 323 } 324 325 dev_dbg(dev, "setup output suc\n"); 326 return 0; 327 } 328 329 static int isp4sd_init_stream(struct isp4_subdev *isp_subdev) 330 { 331 struct device *dev = isp_subdev->dev; 332 int ret; 333 334 ret = isp4sd_setup_fw_mem_pool(isp_subdev); 335 if (ret) { 336 dev_err(dev, "fail to setup fw mem pool\n"); 337 return ret; 338 } 339 340 ret = isp4sd_set_stream_path(isp_subdev); 341 if (ret) { 342 dev_err(dev, "fail to setup stream path\n"); 343 return ret; 344 } 345 346 return 0; 347 } 348 349 static void isp4sd_uninit_stream(struct isp4_subdev *isp_subdev, 350 struct v4l2_subdev_state *state, u32 pad) 351 { 352 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 353 struct isp4sd_output_info *output_info = &sensor_info->output_info; 354 struct isp4_interface *ispif = &isp_subdev->ispif; 355 struct v4l2_mbus_framefmt *format; 356 357 format = v4l2_subdev_state_get_format(state, pad, 0); 358 if (!format) { 359 dev_err(isp_subdev->dev, "fail to get v4l2 format\n"); 360 } else { 361 memset(format, 0, sizeof(*format)); 362 format->code = MEDIA_BUS_FMT_YUYV8_1_5X8; 363 } 364 365 isp4if_clear_bufq(ispif); 366 isp4if_clear_cmdq(ispif); 367 368 sensor_info->start_stream_cmd_sent = false; 369 sensor_info->buf_sent_cnt = 0; 370 371 sensor_info->status = ISP4SD_START_STATUS_OFF; 372 output_info->start_status = ISP4SD_START_STATUS_OFF; 373 } 374 375 static void isp4sd_fw_resp_cmd_done(struct isp4_subdev *isp_subdev, 376 enum isp4if_stream_id stream_id, 377 struct isp4fw_resp_cmd_done *para) 378 { 379 struct isp4_interface *ispif = &isp_subdev->ispif; 380 struct isp4if_cmd_element *ele = 381 isp4if_rm_cmd_from_cmdq(ispif, para->cmd_seq_num, para->cmd_id); 382 struct device *dev = isp_subdev->dev; 383 384 dev_dbg(dev, "stream %d,cmd (0x%08x)(%d),seq %u, ele %p\n", 385 stream_id, 386 para->cmd_id, para->cmd_status, para->cmd_seq_num, 387 ele); 388 389 if (ele) { 390 complete(&ele->cmd_done); 391 if (atomic_dec_and_test(&ele->refcnt)) 392 kfree(ele); 393 } 394 } 395 396 static struct isp4fw_meta_info * 397 isp4sd_get_meta_by_mc(struct isp4_subdev *isp_subdev, u64 mc) 398 { 399 for (unsigned int i = 0; i < ISP4IF_MAX_STREAM_BUF_COUNT; i++) { 400 struct isp4if_gpu_mem_info *meta_info_buf = 401 isp_subdev->ispif.meta_info_buf[i]; 402 403 if (meta_info_buf->gpu_mc_addr == mc) 404 return meta_info_buf->sys_addr; 405 } 406 407 return NULL; 408 } 409 410 static void isp4sd_send_meta_info(struct isp4_subdev *isp_subdev, 411 u64 meta_info_mc) 412 { 413 struct isp4_interface *ispif = &isp_subdev->ispif; 414 struct isp4fw_cmd_send_buffer buf_type; 415 struct device *dev = isp_subdev->dev; 416 417 if (isp_subdev->sensor_info.status != ISP4SD_START_STATUS_STARTED) { 418 dev_warn(dev, "not working status %i, meta_info 0x%llx\n", 419 isp_subdev->sensor_info.status, meta_info_mc); 420 return; 421 } 422 423 /* 424 * The struct will be shared with ISP FW, use memset() to guarantee 425 * padding bits are zeroed, since this is not guaranteed on all 426 * compilers. 427 */ 428 memset(&buf_type, 0, sizeof(buf_type)); 429 buf_type.buffer_type = ISP4FW_BUFFER_TYPE_META_INFO; 430 buf_type.buffer.vmid_space.bit.space = ISP4FW_ADDR_SPACE_TYPE_GPU_VA; 431 isp4if_split_addr64(meta_info_mc, 432 &buf_type.buffer.buf_base_a_lo, 433 &buf_type.buffer.buf_base_a_hi); 434 buf_type.buffer.buf_size_a = ISP4SD_META_BUF_SIZE; 435 436 if (isp4if_send_command(ispif, ISP4FW_CMD_ID_SEND_BUFFER, 437 &buf_type, sizeof(buf_type))) 438 dev_err(dev, "fail send meta_info 0x%llx\n", 439 meta_info_mc); 440 else 441 dev_dbg(dev, "resend meta_info 0x%llx\n", meta_info_mc); 442 } 443 444 static void isp4sd_fw_resp_frame_done(struct isp4_subdev *isp_subdev, 445 enum isp4if_stream_id stream_id, 446 struct isp4fw_resp_param_package *para) 447 { 448 struct isp4_interface *ispif = &isp_subdev->ispif; 449 struct device *dev = isp_subdev->dev; 450 struct isp4if_img_buf_node *prev; 451 struct isp4fw_meta_info *meta; 452 u64 mc; 453 454 mc = isp4if_join_addr64(para->package_addr_lo, para->package_addr_hi); 455 meta = isp4sd_get_meta_by_mc(isp_subdev, mc); 456 if (!meta) { 457 dev_err(dev, "fail to get meta from mc %llx\n", mc); 458 return; 459 } 460 461 dev_dbg(dev, "ts:%llu,streamId:%d,poc:%u,preview_en:%u,status:%i\n", 462 ktime_get_ns(), stream_id, meta->poc, meta->preview.enabled, 463 meta->preview.status); 464 465 if (meta->preview.enabled && 466 (meta->preview.status == ISP4FW_BUFFER_STATUS_SKIPPED || 467 meta->preview.status == ISP4FW_BUFFER_STATUS_DONE || 468 meta->preview.status == ISP4FW_BUFFER_STATUS_DIRTY)) { 469 prev = isp4if_dequeue_buffer(ispif); 470 if (prev) { 471 isp4vid_handle_frame_done(&isp_subdev->isp_vdev, 472 &prev->buf_info); 473 isp4if_dealloc_buffer_node(prev); 474 } else { 475 dev_err(dev, "fail null prev buf\n"); 476 } 477 } else if (meta->preview.enabled) { 478 dev_err(dev, "fail bad preview status %u\n", 479 meta->preview.status); 480 } 481 482 if (isp_subdev->sensor_info.status == ISP4SD_START_STATUS_STARTED) 483 isp4sd_send_meta_info(isp_subdev, mc); 484 485 dev_dbg(dev, "stream_id:%d, status:%d\n", stream_id, 486 isp_subdev->sensor_info.status); 487 } 488 489 static void isp4sd_fw_resp_func(struct isp4_subdev *isp_subdev, 490 enum isp4if_stream_id stream_id) 491 { 492 struct isp4_interface *ispif = &isp_subdev->ispif; 493 struct device *dev = isp_subdev->dev; 494 struct isp4fw_resp resp; 495 496 while (true) { 497 if (isp4if_f2h_resp(ispif, stream_id, &resp)) { 498 /* Re-enable the interrupt */ 499 isp4_intr_enable(isp_subdev, stream_id, true); 500 /* 501 * Recheck to see if there is a new response. 502 * To ensure that an in-flight interrupt is not lost, 503 * enabling the interrupt must occur _before_ checking 504 * for a new response, hence a memory barrier is needed. 505 * Disable the interrupt again if there was a new 506 * response. 507 */ 508 mb(); 509 if (likely(isp4if_f2h_resp(ispif, stream_id, &resp))) 510 break; 511 512 isp4_intr_enable(isp_subdev, stream_id, false); 513 } 514 515 switch (resp.resp_id) { 516 case ISP4FW_RESP_ID_CMD_DONE: 517 isp4sd_fw_resp_cmd_done(isp_subdev, stream_id, 518 &resp.param.cmd_done); 519 break; 520 case ISP4FW_RESP_ID_NOTI_FRAME_DONE: 521 isp4sd_fw_resp_frame_done(isp_subdev, stream_id, 522 &resp.param.frame_done); 523 break; 524 default: 525 dev_err(dev, "-><- fail respid (0x%x)\n", 526 resp.resp_id); 527 break; 528 } 529 } 530 } 531 532 static s32 isp4sd_fw_resp_thread(void *context) 533 { 534 struct isp4_subdev_thread_param *para = context; 535 struct isp4_subdev *isp_subdev = para->isp_subdev; 536 struct isp4sd_thread_handler *thread_ctx = 537 &isp_subdev->fw_resp_thread[para->idx]; 538 struct device *dev = isp_subdev->dev; 539 540 dev_dbg(dev, "[%u] fw resp thread started\n", para->idx); 541 while (true) { 542 wait_event_interruptible(thread_ctx->waitq, 543 thread_ctx->resp_ready); 544 thread_ctx->resp_ready = false; 545 546 if (kthread_should_stop()) { 547 dev_dbg(dev, "[%u] fw resp thread quit\n", para->idx); 548 break; 549 } 550 551 isp4sd_fw_resp_func(isp_subdev, para->idx); 552 } 553 554 return 0; 555 } 556 557 static int isp4sd_stop_resp_proc_threads(struct isp4_subdev *isp_subdev) 558 { 559 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) { 560 struct isp4sd_thread_handler *thread_ctx = 561 &isp_subdev->fw_resp_thread[i]; 562 563 if (thread_ctx->thread) { 564 kthread_stop(thread_ctx->thread); 565 thread_ctx->thread = NULL; 566 } 567 } 568 569 return 0; 570 } 571 572 static int isp4sd_start_resp_proc_threads(struct isp4_subdev *isp_subdev) 573 { 574 struct device *dev = isp_subdev->dev; 575 576 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) { 577 struct isp4sd_thread_handler *thread_ctx = 578 &isp_subdev->fw_resp_thread[i]; 579 580 isp_subdev->isp_resp_para[i].idx = i; 581 isp_subdev->isp_resp_para[i].isp_subdev = isp_subdev; 582 init_waitqueue_head(&thread_ctx->waitq); 583 thread_ctx->resp_ready = false; 584 585 thread_ctx->thread = kthread_run(isp4sd_fw_resp_thread, 586 &isp_subdev->isp_resp_para[i], 587 isp4sd_thread_name[i]); 588 if (IS_ERR(thread_ctx->thread)) { 589 dev_err(dev, "create thread [%d] fail\n", i); 590 thread_ctx->thread = NULL; 591 isp4sd_stop_resp_proc_threads(isp_subdev); 592 return -EINVAL; 593 } 594 } 595 596 return 0; 597 } 598 599 int isp4sd_pwroff_and_deinit(struct v4l2_subdev *sd) 600 { 601 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 602 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 603 unsigned int perf_state = ISP4SD_PERFORMANCE_STATE_LOW; 604 struct isp4_interface *ispif = &isp_subdev->ispif; 605 struct device *dev = isp_subdev->dev; 606 int ret; 607 608 guard(mutex)(&isp_subdev->ops_mutex); 609 if (sensor_info->status == ISP4SD_START_STATUS_STARTED) { 610 dev_err(dev, "fail for stream still running\n"); 611 return -EINVAL; 612 } 613 614 sensor_info->status = ISP4SD_START_STATUS_OFF; 615 616 if (isp_subdev->irq_enabled) { 617 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) 618 disable_irq(isp_subdev->irq[i]); 619 isp_subdev->irq_enabled = false; 620 } 621 622 isp4sd_stop_resp_proc_threads(isp_subdev); 623 dev_dbg(dev, "isp_subdev stop resp proc threads suc\n"); 624 625 isp4if_stop(ispif); 626 627 ret = dev_pm_genpd_set_performance_state(dev, perf_state); 628 if (ret) 629 dev_err(dev, 630 "fail to set isp_subdev performance state %u,ret %d\n", 631 perf_state, ret); 632 633 /* hold ccpu reset */ 634 isp4hw_wreg(isp_subdev->mmio, ISP_SOFT_RESET, 0); 635 isp4hw_wreg(isp_subdev->mmio, ISP_POWER_STATUS, 0); 636 ret = pm_runtime_put_sync(dev); 637 if (ret) 638 dev_err(dev, "power off isp_subdev fail %d\n", ret); 639 else 640 dev_dbg(dev, "power off isp_subdev suc\n"); 641 642 ispif->status = ISP4IF_STATUS_PWR_OFF; 643 isp4if_clear_cmdq(ispif); 644 isp4sd_module_enable(isp_subdev, false); 645 646 /* 647 * When opening the camera, isp4sd_module_enable(isp_subdev, true) is 648 * called. Hardware requires at least a 20ms delay between disabling 649 * and enabling the module, so a sleep is added to ensure ISP stability 650 * during quick reopen scenarios. 651 */ 652 msleep(20); 653 654 return 0; 655 } 656 657 int isp4sd_pwron_and_init(struct v4l2_subdev *sd) 658 { 659 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 660 struct isp4_interface *ispif = &isp_subdev->ispif; 661 struct device *dev = isp_subdev->dev; 662 int ret; 663 664 guard(mutex)(&isp_subdev->ops_mutex); 665 if (ispif->status == ISP4IF_STATUS_FW_RUNNING) { 666 dev_dbg(dev, "camera already opened, do nothing\n"); 667 return 0; 668 } 669 670 isp4sd_module_enable(isp_subdev, true); 671 672 if (ispif->status < ISP4IF_STATUS_PWR_ON) { 673 unsigned int perf_state = ISP4SD_PERFORMANCE_STATE_HIGH; 674 675 ret = pm_runtime_resume_and_get(dev); 676 if (ret) { 677 dev_err(dev, "fail to power on isp_subdev ret %d\n", 678 ret); 679 goto err_deinit; 680 } 681 682 /* ISPPG ISP Power Status */ 683 isp4hw_wreg(isp_subdev->mmio, ISP_POWER_STATUS, 0x7FF); 684 ret = dev_pm_genpd_set_performance_state(dev, perf_state); 685 if (ret) { 686 dev_err(dev, 687 "fail to set performance state %u, ret %d\n", 688 perf_state, ret); 689 goto err_deinit; 690 } 691 692 ispif->status = ISP4IF_STATUS_PWR_ON; 693 } 694 695 isp_subdev->sensor_info.start_stream_cmd_sent = false; 696 isp_subdev->sensor_info.buf_sent_cnt = 0; 697 698 ret = isp4if_start(ispif); 699 if (ret) { 700 dev_err(dev, "fail to start isp_subdev interface\n"); 701 goto err_deinit; 702 } 703 704 if (isp4sd_start_resp_proc_threads(isp_subdev)) { 705 dev_err(dev, "isp_start_resp_proc_threads fail\n"); 706 goto err_deinit; 707 } 708 709 dev_dbg(dev, "create resp threads ok\n"); 710 711 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) 712 enable_irq(isp_subdev->irq[i]); 713 isp_subdev->irq_enabled = true; 714 715 return 0; 716 err_deinit: 717 isp4sd_pwroff_and_deinit(sd); 718 return -EINVAL; 719 } 720 721 static int isp4sd_stop_stream(struct isp4_subdev *isp_subdev, 722 struct v4l2_subdev_state *state, u32 pad) 723 { 724 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 725 struct isp4sd_output_info *output_info = &sensor_info->output_info; 726 struct isp4_interface *ispif = &isp_subdev->ispif; 727 struct device *dev = isp_subdev->dev; 728 729 guard(mutex)(&isp_subdev->ops_mutex); 730 dev_dbg(dev, "status %i\n", output_info->start_status); 731 732 if (output_info->start_status == ISP4SD_START_STATUS_STARTED) { 733 struct isp4fw_cmd_enable_out_ch cmd_ch_disable; 734 int ret; 735 736 /* 737 * The struct will be shared with ISP FW, use memset() to 738 * guarantee padding bits are zeroed, since this is not 739 * guaranteed on all compilers. 740 */ 741 memset(&cmd_ch_disable, 0, sizeof(cmd_ch_disable)); 742 cmd_ch_disable.ch = ISP4FW_ISP_PIPE_OUT_CH_PREVIEW; 743 /* `cmd_ch_disable.is_enable` is already false */ 744 ret = isp4if_send_command_sync(ispif, 745 ISP4FW_CMD_ID_ENABLE_OUT_CHAN, 746 &cmd_ch_disable, 747 sizeof(cmd_ch_disable)); 748 if (ret) 749 dev_err(dev, "fail to disable stream\n"); 750 else 751 dev_dbg(dev, "wait disable stream suc\n"); 752 753 ret = isp4if_send_command_sync(ispif, ISP4FW_CMD_ID_STOP_STREAM, 754 NULL, 0); 755 if (ret) 756 dev_err(dev, "fail to stop stream\n"); 757 else 758 dev_dbg(dev, "wait stop stream suc\n"); 759 } 760 761 isp4sd_uninit_stream(isp_subdev, state, pad); 762 763 /* 764 * Return success to ensure the stop process proceeds, 765 * and disregard any errors since they are not fatal. 766 */ 767 return 0; 768 } 769 770 static int isp4sd_start_stream(struct isp4_subdev *isp_subdev, 771 struct v4l2_subdev_state *state, u32 pad) 772 { 773 struct isp4sd_output_info *output_info = 774 &isp_subdev->sensor_info.output_info; 775 struct isp4_interface *ispif = &isp_subdev->ispif; 776 struct device *dev = isp_subdev->dev; 777 int ret; 778 779 guard(mutex)(&isp_subdev->ops_mutex); 780 781 if (ispif->status != ISP4IF_STATUS_FW_RUNNING) { 782 dev_err(dev, "fail, bad fsm %d\n", ispif->status); 783 return -EINVAL; 784 } 785 786 switch (output_info->start_status) { 787 case ISP4SD_START_STATUS_OFF: 788 break; 789 case ISP4SD_START_STATUS_STARTED: 790 dev_dbg(dev, "stream already started, do nothing\n"); 791 return 0; 792 case ISP4SD_START_STATUS_START_FAIL: 793 dev_err(dev, "stream previously failed to start\n"); 794 return -EINVAL; 795 } 796 797 ret = isp4sd_init_stream(isp_subdev); 798 if (ret) { 799 dev_err(dev, "fail to init isp_subdev stream\n"); 800 goto err_stop_stream; 801 } 802 803 ret = isp4sd_setup_output(isp_subdev, state, pad); 804 if (ret) { 805 dev_err(dev, "fail to setup output\n"); 806 goto err_stop_stream; 807 } 808 809 return 0; 810 811 err_stop_stream: 812 isp4sd_stop_stream(isp_subdev, state, pad); 813 return ret; 814 } 815 816 int isp4sd_ioc_send_img_buf(struct v4l2_subdev *sd, 817 struct isp4if_img_buf_info *buf_info) 818 { 819 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 820 struct isp4_interface *ispif = &isp_subdev->ispif; 821 struct isp4if_img_buf_node *buf_node; 822 struct device *dev = isp_subdev->dev; 823 int ret; 824 825 guard(mutex)(&isp_subdev->ops_mutex); 826 827 if (ispif->status != ISP4IF_STATUS_FW_RUNNING) { 828 dev_err(dev, "fail send img buf for bad fsm %d\n", 829 ispif->status); 830 return -EINVAL; 831 } 832 833 buf_node = isp4if_alloc_buffer_node(buf_info); 834 if (!buf_node) { 835 dev_err(dev, "fail alloc sys img buf info node\n"); 836 return -ENOMEM; 837 } 838 839 ret = isp4if_queue_buffer(ispif, buf_node); 840 if (ret) { 841 dev_err(dev, "fail to queue image buf, %d\n", ret); 842 goto error_release_buf_node; 843 } 844 845 if (!isp_subdev->sensor_info.start_stream_cmd_sent) { 846 isp_subdev->sensor_info.buf_sent_cnt++; 847 848 if (isp_subdev->sensor_info.buf_sent_cnt >= 849 ISP4SD_MIN_BUF_CNT_BEF_START_STREAM) { 850 ret = isp4if_send_command(ispif, 851 ISP4FW_CMD_ID_START_STREAM, 852 NULL, 0); 853 if (ret) { 854 dev_err(dev, "fail to START_STREAM"); 855 goto error_release_buf_node; 856 } 857 isp_subdev->sensor_info.start_stream_cmd_sent = true; 858 isp_subdev->sensor_info.output_info.start_status = 859 ISP4SD_START_STATUS_STARTED; 860 isp_subdev->sensor_info.status = 861 ISP4SD_START_STATUS_STARTED; 862 } else { 863 dev_dbg(dev, 864 "no send start, required %u, buf sent %u\n", 865 ISP4SD_MIN_BUF_CNT_BEF_START_STREAM, 866 isp_subdev->sensor_info.buf_sent_cnt); 867 } 868 } 869 870 return 0; 871 872 error_release_buf_node: 873 isp4if_dealloc_buffer_node(buf_node); 874 return ret; 875 } 876 877 static const struct v4l2_subdev_video_ops isp4sd_video_ops = { 878 .s_stream = v4l2_subdev_s_stream_helper, 879 }; 880 881 static int isp4sd_set_pad_format(struct v4l2_subdev *sd, 882 struct v4l2_subdev_state *sd_state, 883 struct v4l2_subdev_format *format) 884 { 885 struct isp4sd_output_info *stream_info = 886 &(to_isp4_subdev(sd)->sensor_info.output_info); 887 struct v4l2_mbus_framefmt *fmt; 888 889 fmt = v4l2_subdev_state_get_format(sd_state, format->pad); 890 891 if (!fmt) { 892 dev_err(sd->dev, "fail to get state format\n"); 893 return -EINVAL; 894 } 895 896 *fmt = format->format; 897 switch (fmt->code) { 898 case MEDIA_BUS_FMT_YUYV8_1X16: 899 stream_info->image_size = fmt->width * fmt->height * 2; 900 break; 901 case MEDIA_BUS_FMT_YUYV8_1_5X8: 902 default: 903 stream_info->image_size = fmt->width * fmt->height * 3 / 2; 904 break; 905 } 906 907 if (!stream_info->image_size) { 908 dev_err(sd->dev, 909 "fail set pad format,code 0x%x,width %u, height %u\n", 910 fmt->code, fmt->width, fmt->height); 911 return -EINVAL; 912 } 913 914 dev_dbg(sd->dev, "set pad format suc, code:%x w:%u h:%u size:%u\n", 915 fmt->code, fmt->width, fmt->height, 916 stream_info->image_size); 917 918 return 0; 919 } 920 921 static int isp4sd_enable_streams(struct v4l2_subdev *sd, 922 struct v4l2_subdev_state *state, u32 pad, 923 u64 streams_mask) 924 { 925 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 926 927 return isp4sd_start_stream(isp_subdev, state, pad); 928 } 929 930 static int isp4sd_disable_streams(struct v4l2_subdev *sd, 931 struct v4l2_subdev_state *state, u32 pad, 932 u64 streams_mask) 933 { 934 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 935 936 return isp4sd_stop_stream(isp_subdev, state, pad); 937 } 938 939 static const struct v4l2_subdev_pad_ops isp4sd_pad_ops = { 940 .get_fmt = v4l2_subdev_get_fmt, 941 .set_fmt = isp4sd_set_pad_format, 942 .enable_streams = isp4sd_enable_streams, 943 .disable_streams = isp4sd_disable_streams, 944 }; 945 946 static const struct v4l2_subdev_ops isp4sd_subdev_ops = { 947 .video = &isp4sd_video_ops, 948 .pad = &isp4sd_pad_ops, 949 }; 950 951 int isp4sd_init(struct isp4_subdev *isp_subdev, struct v4l2_device *v4l2_dev, 952 int irq[ISP4SD_MAX_FW_RESP_STREAM_NUM]) 953 { 954 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 955 struct isp4_interface *ispif = &isp_subdev->ispif; 956 struct device *dev = v4l2_dev->dev; 957 int ret; 958 959 isp_subdev->dev = dev; 960 v4l2_subdev_init(&isp_subdev->sdev, &isp4sd_subdev_ops); 961 isp_subdev->sdev.owner = THIS_MODULE; 962 isp_subdev->sdev.dev = dev; 963 snprintf(isp_subdev->sdev.name, sizeof(isp_subdev->sdev.name), "%s", 964 dev_name(dev)); 965 966 isp_subdev->sdev.entity.name = isp4sd_entity_name; 967 isp_subdev->sdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_ISP; 968 isp_subdev->sdev_pad.flags = MEDIA_PAD_FL_SOURCE; 969 ret = media_entity_pads_init(&isp_subdev->sdev.entity, 1, 970 &isp_subdev->sdev_pad); 971 if (ret) { 972 dev_err(dev, "fail to init isp4 subdev entity pad %d\n", ret); 973 return ret; 974 } 975 976 ret = v4l2_subdev_init_finalize(&isp_subdev->sdev); 977 if (ret < 0) { 978 dev_err(dev, "fail to init finalize isp4 subdev %d\n", 979 ret); 980 return ret; 981 } 982 983 ret = v4l2_device_register_subdev(v4l2_dev, &isp_subdev->sdev); 984 if (ret) { 985 dev_err(dev, "fail to register isp4 subdev to V4L2 device %d\n", 986 ret); 987 goto err_media_clean_up; 988 } 989 990 isp4if_init(ispif, dev, isp_subdev->mmio); 991 992 mutex_init(&isp_subdev->ops_mutex); 993 sensor_info->status = ISP4SD_START_STATUS_OFF; 994 995 /* create ISP enable gpio control */ 996 isp_subdev->enable_gpio = devm_gpiod_get(isp_subdev->dev, 997 "enable_isp", 998 GPIOD_OUT_LOW); 999 if (IS_ERR(isp_subdev->enable_gpio)) { 1000 ret = PTR_ERR(isp_subdev->enable_gpio); 1001 dev_err(dev, "fail to get gpiod %d\n", ret); 1002 goto err_subdev_unreg; 1003 } 1004 1005 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) 1006 isp_subdev->irq[i] = irq[i]; 1007 1008 isp_subdev->host2fw_seq_num = 1; 1009 ispif->status = ISP4IF_STATUS_PWR_OFF; 1010 1011 ret = isp4vid_dev_init(&isp_subdev->isp_vdev, &isp_subdev->sdev); 1012 if (ret) 1013 goto err_subdev_unreg; 1014 1015 return 0; 1016 1017 err_subdev_unreg: 1018 v4l2_device_unregister_subdev(&isp_subdev->sdev); 1019 err_media_clean_up: 1020 v4l2_subdev_cleanup(&isp_subdev->sdev); 1021 media_entity_cleanup(&isp_subdev->sdev.entity); 1022 return ret; 1023 } 1024 1025 void isp4sd_deinit(struct isp4_subdev *isp_subdev) 1026 { 1027 struct isp4_interface *ispif = &isp_subdev->ispif; 1028 1029 isp4vid_dev_deinit(&isp_subdev->isp_vdev); 1030 v4l2_device_unregister_subdev(&isp_subdev->sdev); 1031 media_entity_cleanup(&isp_subdev->sdev.entity); 1032 isp4if_deinit(ispif); 1033 isp4sd_module_enable(isp_subdev, false); 1034 1035 ispif->status = ISP4IF_STATUS_PWR_OFF; 1036 } 1037