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 isp4if_dealloc_buffer_node(prev); 472 else 473 dev_err(dev, "fail null prev buf\n"); 474 475 } else if (meta->preview.enabled) { 476 dev_err(dev, "fail bad preview status %u\n", 477 meta->preview.status); 478 } 479 480 if (isp_subdev->sensor_info.status == ISP4SD_START_STATUS_STARTED) 481 isp4sd_send_meta_info(isp_subdev, mc); 482 483 dev_dbg(dev, "stream_id:%d, status:%d\n", stream_id, 484 isp_subdev->sensor_info.status); 485 } 486 487 static void isp4sd_fw_resp_func(struct isp4_subdev *isp_subdev, 488 enum isp4if_stream_id stream_id) 489 { 490 struct isp4_interface *ispif = &isp_subdev->ispif; 491 struct device *dev = isp_subdev->dev; 492 struct isp4fw_resp resp; 493 494 while (true) { 495 if (isp4if_f2h_resp(ispif, stream_id, &resp)) { 496 /* Re-enable the interrupt */ 497 isp4_intr_enable(isp_subdev, stream_id, true); 498 /* 499 * Recheck to see if there is a new response. 500 * To ensure that an in-flight interrupt is not lost, 501 * enabling the interrupt must occur _before_ checking 502 * for a new response, hence a memory barrier is needed. 503 * Disable the interrupt again if there was a new 504 * response. 505 */ 506 mb(); 507 if (likely(isp4if_f2h_resp(ispif, stream_id, &resp))) 508 break; 509 510 isp4_intr_enable(isp_subdev, stream_id, false); 511 } 512 513 switch (resp.resp_id) { 514 case ISP4FW_RESP_ID_CMD_DONE: 515 isp4sd_fw_resp_cmd_done(isp_subdev, stream_id, 516 &resp.param.cmd_done); 517 break; 518 case ISP4FW_RESP_ID_NOTI_FRAME_DONE: 519 isp4sd_fw_resp_frame_done(isp_subdev, stream_id, 520 &resp.param.frame_done); 521 break; 522 default: 523 dev_err(dev, "-><- fail respid (0x%x)\n", 524 resp.resp_id); 525 break; 526 } 527 } 528 } 529 530 static s32 isp4sd_fw_resp_thread(void *context) 531 { 532 struct isp4_subdev_thread_param *para = context; 533 struct isp4_subdev *isp_subdev = para->isp_subdev; 534 struct isp4sd_thread_handler *thread_ctx = 535 &isp_subdev->fw_resp_thread[para->idx]; 536 struct device *dev = isp_subdev->dev; 537 538 dev_dbg(dev, "[%u] fw resp thread started\n", para->idx); 539 while (true) { 540 wait_event_interruptible(thread_ctx->waitq, 541 thread_ctx->resp_ready); 542 thread_ctx->resp_ready = false; 543 544 if (kthread_should_stop()) { 545 dev_dbg(dev, "[%u] fw resp thread quit\n", para->idx); 546 break; 547 } 548 549 isp4sd_fw_resp_func(isp_subdev, para->idx); 550 } 551 552 return 0; 553 } 554 555 static int isp4sd_stop_resp_proc_threads(struct isp4_subdev *isp_subdev) 556 { 557 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) { 558 struct isp4sd_thread_handler *thread_ctx = 559 &isp_subdev->fw_resp_thread[i]; 560 561 if (thread_ctx->thread) { 562 kthread_stop(thread_ctx->thread); 563 thread_ctx->thread = NULL; 564 } 565 } 566 567 return 0; 568 } 569 570 static int isp4sd_start_resp_proc_threads(struct isp4_subdev *isp_subdev) 571 { 572 struct device *dev = isp_subdev->dev; 573 574 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) { 575 struct isp4sd_thread_handler *thread_ctx = 576 &isp_subdev->fw_resp_thread[i]; 577 578 isp_subdev->isp_resp_para[i].idx = i; 579 isp_subdev->isp_resp_para[i].isp_subdev = isp_subdev; 580 init_waitqueue_head(&thread_ctx->waitq); 581 thread_ctx->resp_ready = false; 582 583 thread_ctx->thread = kthread_run(isp4sd_fw_resp_thread, 584 &isp_subdev->isp_resp_para[i], 585 isp4sd_thread_name[i]); 586 if (IS_ERR(thread_ctx->thread)) { 587 dev_err(dev, "create thread [%d] fail\n", i); 588 thread_ctx->thread = NULL; 589 isp4sd_stop_resp_proc_threads(isp_subdev); 590 return -EINVAL; 591 } 592 } 593 594 return 0; 595 } 596 597 int isp4sd_pwroff_and_deinit(struct v4l2_subdev *sd) 598 { 599 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 600 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 601 unsigned int perf_state = ISP4SD_PERFORMANCE_STATE_LOW; 602 struct isp4_interface *ispif = &isp_subdev->ispif; 603 struct device *dev = isp_subdev->dev; 604 int ret; 605 606 guard(mutex)(&isp_subdev->ops_mutex); 607 if (sensor_info->status == ISP4SD_START_STATUS_STARTED) { 608 dev_err(dev, "fail for stream still running\n"); 609 return -EINVAL; 610 } 611 612 sensor_info->status = ISP4SD_START_STATUS_OFF; 613 614 if (isp_subdev->irq_enabled) { 615 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) 616 disable_irq(isp_subdev->irq[i]); 617 isp_subdev->irq_enabled = false; 618 } 619 620 isp4sd_stop_resp_proc_threads(isp_subdev); 621 dev_dbg(dev, "isp_subdev stop resp proc threads suc\n"); 622 623 isp4if_stop(ispif); 624 625 ret = dev_pm_genpd_set_performance_state(dev, perf_state); 626 if (ret) 627 dev_err(dev, 628 "fail to set isp_subdev performance state %u,ret %d\n", 629 perf_state, ret); 630 631 /* hold ccpu reset */ 632 isp4hw_wreg(isp_subdev->mmio, ISP_SOFT_RESET, 0); 633 isp4hw_wreg(isp_subdev->mmio, ISP_POWER_STATUS, 0); 634 ret = pm_runtime_put_sync(dev); 635 if (ret) 636 dev_err(dev, "power off isp_subdev fail %d\n", ret); 637 else 638 dev_dbg(dev, "power off isp_subdev suc\n"); 639 640 ispif->status = ISP4IF_STATUS_PWR_OFF; 641 isp4if_clear_cmdq(ispif); 642 isp4sd_module_enable(isp_subdev, false); 643 644 /* 645 * When opening the camera, isp4sd_module_enable(isp_subdev, true) is 646 * called. Hardware requires at least a 20ms delay between disabling 647 * and enabling the module, so a sleep is added to ensure ISP stability 648 * during quick reopen scenarios. 649 */ 650 msleep(20); 651 652 return 0; 653 } 654 655 int isp4sd_pwron_and_init(struct v4l2_subdev *sd) 656 { 657 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 658 struct isp4_interface *ispif = &isp_subdev->ispif; 659 struct device *dev = isp_subdev->dev; 660 int ret; 661 662 guard(mutex)(&isp_subdev->ops_mutex); 663 if (ispif->status == ISP4IF_STATUS_FW_RUNNING) { 664 dev_dbg(dev, "camera already opened, do nothing\n"); 665 return 0; 666 } 667 668 isp4sd_module_enable(isp_subdev, true); 669 670 if (ispif->status < ISP4IF_STATUS_PWR_ON) { 671 unsigned int perf_state = ISP4SD_PERFORMANCE_STATE_HIGH; 672 673 ret = pm_runtime_resume_and_get(dev); 674 if (ret) { 675 dev_err(dev, "fail to power on isp_subdev ret %d\n", 676 ret); 677 goto err_deinit; 678 } 679 680 /* ISPPG ISP Power Status */ 681 isp4hw_wreg(isp_subdev->mmio, ISP_POWER_STATUS, 0x7FF); 682 ret = dev_pm_genpd_set_performance_state(dev, perf_state); 683 if (ret) { 684 dev_err(dev, 685 "fail to set performance state %u, ret %d\n", 686 perf_state, ret); 687 goto err_deinit; 688 } 689 690 ispif->status = ISP4IF_STATUS_PWR_ON; 691 } 692 693 isp_subdev->sensor_info.start_stream_cmd_sent = false; 694 isp_subdev->sensor_info.buf_sent_cnt = 0; 695 696 ret = isp4if_start(ispif); 697 if (ret) { 698 dev_err(dev, "fail to start isp_subdev interface\n"); 699 goto err_deinit; 700 } 701 702 if (isp4sd_start_resp_proc_threads(isp_subdev)) { 703 dev_err(dev, "isp_start_resp_proc_threads fail\n"); 704 goto err_deinit; 705 } 706 707 dev_dbg(dev, "create resp threads ok\n"); 708 709 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) 710 enable_irq(isp_subdev->irq[i]); 711 isp_subdev->irq_enabled = true; 712 713 return 0; 714 err_deinit: 715 isp4sd_pwroff_and_deinit(sd); 716 return -EINVAL; 717 } 718 719 static int isp4sd_stop_stream(struct isp4_subdev *isp_subdev, 720 struct v4l2_subdev_state *state, u32 pad) 721 { 722 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 723 struct isp4sd_output_info *output_info = &sensor_info->output_info; 724 struct isp4_interface *ispif = &isp_subdev->ispif; 725 struct device *dev = isp_subdev->dev; 726 727 guard(mutex)(&isp_subdev->ops_mutex); 728 dev_dbg(dev, "status %i\n", output_info->start_status); 729 730 if (output_info->start_status == ISP4SD_START_STATUS_STARTED) { 731 struct isp4fw_cmd_enable_out_ch cmd_ch_disable; 732 int ret; 733 734 /* 735 * The struct will be shared with ISP FW, use memset() to 736 * guarantee padding bits are zeroed, since this is not 737 * guaranteed on all compilers. 738 */ 739 memset(&cmd_ch_disable, 0, sizeof(cmd_ch_disable)); 740 cmd_ch_disable.ch = ISP4FW_ISP_PIPE_OUT_CH_PREVIEW; 741 /* `cmd_ch_disable.is_enable` is already false */ 742 ret = isp4if_send_command_sync(ispif, 743 ISP4FW_CMD_ID_ENABLE_OUT_CHAN, 744 &cmd_ch_disable, 745 sizeof(cmd_ch_disable)); 746 if (ret) 747 dev_err(dev, "fail to disable stream\n"); 748 else 749 dev_dbg(dev, "wait disable stream suc\n"); 750 751 ret = isp4if_send_command_sync(ispif, ISP4FW_CMD_ID_STOP_STREAM, 752 NULL, 0); 753 if (ret) 754 dev_err(dev, "fail to stop stream\n"); 755 else 756 dev_dbg(dev, "wait stop stream suc\n"); 757 } 758 759 isp4sd_uninit_stream(isp_subdev, state, pad); 760 761 /* 762 * Return success to ensure the stop process proceeds, 763 * and disregard any errors since they are not fatal. 764 */ 765 return 0; 766 } 767 768 static int isp4sd_start_stream(struct isp4_subdev *isp_subdev, 769 struct v4l2_subdev_state *state, u32 pad) 770 { 771 struct isp4sd_output_info *output_info = 772 &isp_subdev->sensor_info.output_info; 773 struct isp4_interface *ispif = &isp_subdev->ispif; 774 struct device *dev = isp_subdev->dev; 775 int ret; 776 777 guard(mutex)(&isp_subdev->ops_mutex); 778 779 if (ispif->status != ISP4IF_STATUS_FW_RUNNING) { 780 dev_err(dev, "fail, bad fsm %d\n", ispif->status); 781 return -EINVAL; 782 } 783 784 switch (output_info->start_status) { 785 case ISP4SD_START_STATUS_OFF: 786 break; 787 case ISP4SD_START_STATUS_STARTED: 788 dev_dbg(dev, "stream already started, do nothing\n"); 789 return 0; 790 case ISP4SD_START_STATUS_START_FAIL: 791 dev_err(dev, "stream previously failed to start\n"); 792 return -EINVAL; 793 } 794 795 ret = isp4sd_init_stream(isp_subdev); 796 if (ret) { 797 dev_err(dev, "fail to init isp_subdev stream\n"); 798 goto err_stop_stream; 799 } 800 801 ret = isp4sd_setup_output(isp_subdev, state, pad); 802 if (ret) { 803 dev_err(dev, "fail to setup output\n"); 804 goto err_stop_stream; 805 } 806 807 return 0; 808 809 err_stop_stream: 810 isp4sd_stop_stream(isp_subdev, state, pad); 811 return ret; 812 } 813 814 int isp4sd_ioc_send_img_buf(struct v4l2_subdev *sd, 815 struct isp4if_img_buf_info *buf_info) 816 { 817 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 818 struct isp4_interface *ispif = &isp_subdev->ispif; 819 struct isp4if_img_buf_node *buf_node; 820 struct device *dev = isp_subdev->dev; 821 int ret; 822 823 guard(mutex)(&isp_subdev->ops_mutex); 824 825 if (ispif->status != ISP4IF_STATUS_FW_RUNNING) { 826 dev_err(dev, "fail send img buf for bad fsm %d\n", 827 ispif->status); 828 return -EINVAL; 829 } 830 831 buf_node = isp4if_alloc_buffer_node(buf_info); 832 if (!buf_node) { 833 dev_err(dev, "fail alloc sys img buf info node\n"); 834 return -ENOMEM; 835 } 836 837 ret = isp4if_queue_buffer(ispif, buf_node); 838 if (ret) { 839 dev_err(dev, "fail to queue image buf, %d\n", ret); 840 goto error_release_buf_node; 841 } 842 843 if (!isp_subdev->sensor_info.start_stream_cmd_sent) { 844 isp_subdev->sensor_info.buf_sent_cnt++; 845 846 if (isp_subdev->sensor_info.buf_sent_cnt >= 847 ISP4SD_MIN_BUF_CNT_BEF_START_STREAM) { 848 ret = isp4if_send_command(ispif, 849 ISP4FW_CMD_ID_START_STREAM, 850 NULL, 0); 851 if (ret) { 852 dev_err(dev, "fail to START_STREAM"); 853 goto error_release_buf_node; 854 } 855 isp_subdev->sensor_info.start_stream_cmd_sent = true; 856 isp_subdev->sensor_info.output_info.start_status = 857 ISP4SD_START_STATUS_STARTED; 858 isp_subdev->sensor_info.status = 859 ISP4SD_START_STATUS_STARTED; 860 } else { 861 dev_dbg(dev, 862 "no send start, required %u, buf sent %u\n", 863 ISP4SD_MIN_BUF_CNT_BEF_START_STREAM, 864 isp_subdev->sensor_info.buf_sent_cnt); 865 } 866 } 867 868 return 0; 869 870 error_release_buf_node: 871 isp4if_dealloc_buffer_node(buf_node); 872 return ret; 873 } 874 875 static const struct v4l2_subdev_video_ops isp4sd_video_ops = { 876 .s_stream = v4l2_subdev_s_stream_helper, 877 }; 878 879 static int isp4sd_set_pad_format(struct v4l2_subdev *sd, 880 struct v4l2_subdev_state *sd_state, 881 struct v4l2_subdev_format *format) 882 { 883 struct isp4sd_output_info *stream_info = 884 &(to_isp4_subdev(sd)->sensor_info.output_info); 885 struct v4l2_mbus_framefmt *fmt; 886 887 fmt = v4l2_subdev_state_get_format(sd_state, format->pad); 888 889 if (!fmt) { 890 dev_err(sd->dev, "fail to get state format\n"); 891 return -EINVAL; 892 } 893 894 *fmt = format->format; 895 switch (fmt->code) { 896 case MEDIA_BUS_FMT_YUYV8_1X16: 897 stream_info->image_size = fmt->width * fmt->height * 2; 898 break; 899 case MEDIA_BUS_FMT_YUYV8_1_5X8: 900 default: 901 stream_info->image_size = fmt->width * fmt->height * 3 / 2; 902 break; 903 } 904 905 if (!stream_info->image_size) { 906 dev_err(sd->dev, 907 "fail set pad format,code 0x%x,width %u, height %u\n", 908 fmt->code, fmt->width, fmt->height); 909 return -EINVAL; 910 } 911 912 dev_dbg(sd->dev, "set pad format suc, code:%x w:%u h:%u size:%u\n", 913 fmt->code, fmt->width, fmt->height, 914 stream_info->image_size); 915 916 return 0; 917 } 918 919 static int isp4sd_enable_streams(struct v4l2_subdev *sd, 920 struct v4l2_subdev_state *state, u32 pad, 921 u64 streams_mask) 922 { 923 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 924 925 return isp4sd_start_stream(isp_subdev, state, pad); 926 } 927 928 static int isp4sd_disable_streams(struct v4l2_subdev *sd, 929 struct v4l2_subdev_state *state, u32 pad, 930 u64 streams_mask) 931 { 932 struct isp4_subdev *isp_subdev = to_isp4_subdev(sd); 933 934 return isp4sd_stop_stream(isp_subdev, state, pad); 935 } 936 937 static const struct v4l2_subdev_pad_ops isp4sd_pad_ops = { 938 .get_fmt = v4l2_subdev_get_fmt, 939 .set_fmt = isp4sd_set_pad_format, 940 .enable_streams = isp4sd_enable_streams, 941 .disable_streams = isp4sd_disable_streams, 942 }; 943 944 static const struct v4l2_subdev_ops isp4sd_subdev_ops = { 945 .video = &isp4sd_video_ops, 946 .pad = &isp4sd_pad_ops, 947 }; 948 949 int isp4sd_init(struct isp4_subdev *isp_subdev, struct v4l2_device *v4l2_dev, 950 int irq[ISP4SD_MAX_FW_RESP_STREAM_NUM]) 951 { 952 struct isp4sd_sensor_info *sensor_info = &isp_subdev->sensor_info; 953 struct isp4_interface *ispif = &isp_subdev->ispif; 954 struct device *dev = v4l2_dev->dev; 955 int ret; 956 957 isp_subdev->dev = dev; 958 v4l2_subdev_init(&isp_subdev->sdev, &isp4sd_subdev_ops); 959 isp_subdev->sdev.owner = THIS_MODULE; 960 isp_subdev->sdev.dev = dev; 961 snprintf(isp_subdev->sdev.name, sizeof(isp_subdev->sdev.name), "%s", 962 dev_name(dev)); 963 964 isp_subdev->sdev.entity.name = isp4sd_entity_name; 965 isp_subdev->sdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_ISP; 966 isp_subdev->sdev_pad.flags = MEDIA_PAD_FL_SOURCE; 967 ret = media_entity_pads_init(&isp_subdev->sdev.entity, 1, 968 &isp_subdev->sdev_pad); 969 if (ret) { 970 dev_err(dev, "fail to init isp4 subdev entity pad %d\n", ret); 971 return ret; 972 } 973 974 ret = v4l2_subdev_init_finalize(&isp_subdev->sdev); 975 if (ret < 0) { 976 dev_err(dev, "fail to init finalize isp4 subdev %d\n", 977 ret); 978 return ret; 979 } 980 981 ret = v4l2_device_register_subdev(v4l2_dev, &isp_subdev->sdev); 982 if (ret) { 983 dev_err(dev, "fail to register isp4 subdev to V4L2 device %d\n", 984 ret); 985 goto err_media_clean_up; 986 } 987 988 isp4if_init(ispif, dev, isp_subdev->mmio); 989 990 mutex_init(&isp_subdev->ops_mutex); 991 sensor_info->status = ISP4SD_START_STATUS_OFF; 992 993 /* create ISP enable gpio control */ 994 isp_subdev->enable_gpio = devm_gpiod_get(isp_subdev->dev, 995 "enable_isp", 996 GPIOD_OUT_LOW); 997 if (IS_ERR(isp_subdev->enable_gpio)) { 998 ret = PTR_ERR(isp_subdev->enable_gpio); 999 dev_err(dev, "fail to get gpiod %d\n", ret); 1000 goto err_subdev_unreg; 1001 } 1002 1003 for (unsigned int i = 0; i < ISP4SD_MAX_FW_RESP_STREAM_NUM; i++) 1004 isp_subdev->irq[i] = irq[i]; 1005 1006 isp_subdev->host2fw_seq_num = 1; 1007 ispif->status = ISP4IF_STATUS_PWR_OFF; 1008 1009 return 0; 1010 1011 err_subdev_unreg: 1012 v4l2_device_unregister_subdev(&isp_subdev->sdev); 1013 err_media_clean_up: 1014 v4l2_subdev_cleanup(&isp_subdev->sdev); 1015 media_entity_cleanup(&isp_subdev->sdev.entity); 1016 return ret; 1017 } 1018 1019 void isp4sd_deinit(struct isp4_subdev *isp_subdev) 1020 { 1021 struct isp4_interface *ispif = &isp_subdev->ispif; 1022 1023 v4l2_device_unregister_subdev(&isp_subdev->sdev); 1024 media_entity_cleanup(&isp_subdev->sdev.entity); 1025 isp4if_deinit(ispif); 1026 isp4sd_module_enable(isp_subdev, false); 1027 1028 ispif->status = ISP4IF_STATUS_PWR_OFF; 1029 } 1030