1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support for Medifield PNW Camera Imaging ISP subsystem. 4 * 5 * Copyright (c) 2010 Intel Corporation. All Rights Reserved. 6 * 7 * Copyright (c) 2010 Silicon Hive www.siliconhive.com. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License version 11 * 2 as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * 19 */ 20 21 #include <linux/module.h> 22 #include <linux/pm_runtime.h> 23 24 #include <media/v4l2-ioctl.h> 25 #include <media/videobuf2-vmalloc.h> 26 27 #include "atomisp_cmd.h" 28 #include "atomisp_common.h" 29 #include "atomisp_fops.h" 30 #include "atomisp_internal.h" 31 #include "atomisp_ioctl.h" 32 #include "atomisp_compat.h" 33 #include "atomisp_subdev.h" 34 #include "atomisp_v4l2.h" 35 #include "atomisp-regs.h" 36 #include "hmm/hmm.h" 37 38 #include "ia_css_frame.h" 39 #include "type_support.h" 40 #include "device_access/device_access.h" 41 42 /* 43 * Videobuf2 ops 44 */ 45 static int atomisp_queue_setup(struct vb2_queue *vq, 46 unsigned int *nbuffers, unsigned int *nplanes, 47 unsigned int sizes[], struct device *alloc_devs[]) 48 { 49 struct atomisp_video_pipe *pipe = container_of(vq, struct atomisp_video_pipe, vb_queue); 50 u16 source_pad = atomisp_subdev_source_pad(&pipe->vdev); 51 int ret; 52 53 mutex_lock(&pipe->asd->isp->mutex); /* for get_css_frame_info() / set_fmt() */ 54 55 /* 56 * When VIDIOC_S_FMT has not been called before VIDIOC_REQBUFS, then 57 * this will fail. Call atomisp_set_fmt() ourselves and try again. 58 */ 59 ret = atomisp_get_css_frame_info(pipe->asd, source_pad, &pipe->frame_info); 60 if (ret) { 61 struct v4l2_format f = { 62 .fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420, 63 .fmt.pix.width = 10000, 64 .fmt.pix.height = 10000, 65 }; 66 67 ret = atomisp_set_fmt(&pipe->vdev, &f); 68 if (ret) 69 goto out; 70 71 ret = atomisp_get_css_frame_info(pipe->asd, source_pad, &pipe->frame_info); 72 if (ret) 73 goto out; 74 } 75 76 atomisp_alloc_css_stat_bufs(pipe->asd, ATOMISP_INPUT_STREAM_GENERAL); 77 78 *nplanes = 1; 79 sizes[0] = PAGE_ALIGN(pipe->pix.sizeimage); 80 81 out: 82 mutex_unlock(&pipe->asd->isp->mutex); 83 return 0; 84 } 85 86 static int atomisp_buf_init(struct vb2_buffer *vb) 87 { 88 struct atomisp_video_pipe *pipe = vb_to_pipe(vb); 89 struct ia_css_frame *frame = vb_to_frame(vb); 90 int ret; 91 92 ret = ia_css_frame_init_from_info(frame, &pipe->frame_info); 93 if (ret) 94 return ret; 95 96 if (frame->data_bytes > vb2_plane_size(vb, 0)) { 97 dev_err(pipe->asd->isp->dev, "Internal error frame.data_bytes(%u) > vb.length(%lu)\n", 98 frame->data_bytes, vb2_plane_size(vb, 0)); 99 return -EIO; 100 } 101 102 frame->data = hmm_create_from_vmalloc_buf(vb2_plane_size(vb, 0), 103 vb2_plane_vaddr(vb, 0)); 104 if (frame->data == mmgr_NULL) 105 return -ENOMEM; 106 107 return 0; 108 } 109 110 static int atomisp_q_one_metadata_buffer(struct atomisp_sub_device *asd, 111 enum atomisp_input_stream_id stream_id, 112 enum ia_css_pipe_id css_pipe_id) 113 { 114 struct atomisp_metadata_buf *metadata_buf; 115 enum atomisp_metadata_type md_type = 116 atomisp_get_metadata_type(asd, css_pipe_id); 117 struct list_head *metadata_list; 118 119 if (asd->metadata_bufs_in_css[stream_id][css_pipe_id] >= 120 ATOMISP_CSS_Q_DEPTH) 121 return 0; /* we have reached CSS queue depth */ 122 123 if (!list_empty(&asd->metadata[md_type])) { 124 metadata_list = &asd->metadata[md_type]; 125 } else if (!list_empty(&asd->metadata_ready[md_type])) { 126 metadata_list = &asd->metadata_ready[md_type]; 127 } else { 128 dev_warn(asd->isp->dev, "%s: No metadata buffers available for type %d!\n", 129 __func__, md_type); 130 return -EINVAL; 131 } 132 133 metadata_buf = list_entry(metadata_list->next, 134 struct atomisp_metadata_buf, list); 135 list_del_init(&metadata_buf->list); 136 137 if (atomisp_q_metadata_buffer_to_css(asd, metadata_buf, 138 stream_id, css_pipe_id)) { 139 list_add(&metadata_buf->list, metadata_list); 140 return -EINVAL; 141 } else { 142 list_add_tail(&metadata_buf->list, 143 &asd->metadata_in_css[md_type]); 144 } 145 asd->metadata_bufs_in_css[stream_id][css_pipe_id]++; 146 147 return 0; 148 } 149 150 static int atomisp_q_one_s3a_buffer(struct atomisp_sub_device *asd, 151 enum atomisp_input_stream_id stream_id, 152 enum ia_css_pipe_id css_pipe_id) 153 { 154 struct atomisp_s3a_buf *s3a_buf; 155 struct list_head *s3a_list; 156 unsigned int exp_id; 157 158 if (asd->s3a_bufs_in_css[css_pipe_id] >= ATOMISP_CSS_Q_DEPTH) 159 return 0; /* we have reached CSS queue depth */ 160 161 if (!list_empty(&asd->s3a_stats)) { 162 s3a_list = &asd->s3a_stats; 163 } else if (!list_empty(&asd->s3a_stats_ready)) { 164 s3a_list = &asd->s3a_stats_ready; 165 } else { 166 dev_warn(asd->isp->dev, "%s: No s3a buffers available!\n", 167 __func__); 168 return -EINVAL; 169 } 170 171 s3a_buf = list_entry(s3a_list->next, struct atomisp_s3a_buf, list); 172 list_del_init(&s3a_buf->list); 173 exp_id = s3a_buf->s3a_data->exp_id; 174 175 hmm_flush_vmap(s3a_buf->s3a_data->data_ptr); 176 if (atomisp_q_s3a_buffer_to_css(asd, s3a_buf, 177 stream_id, css_pipe_id)) { 178 /* got from head, so return back to the head */ 179 list_add(&s3a_buf->list, s3a_list); 180 return -EINVAL; 181 } else { 182 list_add_tail(&s3a_buf->list, &asd->s3a_stats_in_css); 183 if (s3a_list == &asd->s3a_stats_ready) 184 dev_dbg(asd->isp->dev, "drop one s3a stat with exp_id %d\n", exp_id); 185 } 186 187 asd->s3a_bufs_in_css[css_pipe_id]++; 188 return 0; 189 } 190 191 static int atomisp_q_one_dis_buffer(struct atomisp_sub_device *asd, 192 enum atomisp_input_stream_id stream_id, 193 enum ia_css_pipe_id css_pipe_id) 194 { 195 struct atomisp_dis_buf *dis_buf; 196 unsigned long irqflags; 197 198 if (asd->dis_bufs_in_css >= ATOMISP_CSS_Q_DEPTH) 199 return 0; /* we have reached CSS queue depth */ 200 201 spin_lock_irqsave(&asd->dis_stats_lock, irqflags); 202 if (list_empty(&asd->dis_stats)) { 203 spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags); 204 dev_warn(asd->isp->dev, "%s: No dis buffers available!\n", 205 __func__); 206 return -EINVAL; 207 } 208 209 dis_buf = list_entry(asd->dis_stats.prev, 210 struct atomisp_dis_buf, list); 211 list_del_init(&dis_buf->list); 212 spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags); 213 214 hmm_flush_vmap(dis_buf->dis_data->data_ptr); 215 if (atomisp_q_dis_buffer_to_css(asd, dis_buf, 216 stream_id, css_pipe_id)) { 217 spin_lock_irqsave(&asd->dis_stats_lock, irqflags); 218 /* got from tail, so return back to the tail */ 219 list_add_tail(&dis_buf->list, &asd->dis_stats); 220 spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags); 221 return -EINVAL; 222 } else { 223 spin_lock_irqsave(&asd->dis_stats_lock, irqflags); 224 list_add_tail(&dis_buf->list, &asd->dis_stats_in_css); 225 spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags); 226 } 227 228 asd->dis_bufs_in_css++; 229 230 return 0; 231 } 232 233 static int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd, 234 struct atomisp_video_pipe *pipe, 235 enum atomisp_input_stream_id stream_id, 236 enum ia_css_buffer_type css_buf_type, 237 enum ia_css_pipe_id css_pipe_id) 238 { 239 struct atomisp_css_params_with_list *param; 240 struct ia_css_dvs_grid_info *dvs_grid = 241 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info); 242 unsigned long irqflags; 243 int space, err = 0; 244 245 lockdep_assert_held(&asd->isp->mutex); 246 247 if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM)) 248 return -EINVAL; 249 250 if (pipe->stopping) 251 return -EINVAL; 252 253 space = ATOMISP_CSS_Q_DEPTH - atomisp_buffers_in_css(pipe); 254 while (space--) { 255 struct ia_css_frame *frame; 256 257 spin_lock_irqsave(&pipe->irq_lock, irqflags); 258 frame = list_first_entry_or_null(&pipe->activeq, struct ia_css_frame, queue); 259 if (frame) 260 list_move_tail(&frame->queue, &pipe->buffers_in_css); 261 spin_unlock_irqrestore(&pipe->irq_lock, irqflags); 262 263 if (!frame) 264 return -EINVAL; 265 266 /* 267 * If there is a per_frame setting to apply on the buffer, 268 * do it before buffer en-queueing. 269 */ 270 param = pipe->frame_params[frame->vb.vb2_buf.index]; 271 if (param) { 272 atomisp_makeup_css_parameters(asd, 273 &asd->params.css_param.update_flag, 274 ¶m->params); 275 atomisp_apply_css_parameters(asd, ¶m->params); 276 277 if (param->params.update_flag.dz_config && 278 asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO) { 279 err = atomisp_calculate_real_zoom_region(asd, 280 ¶m->params.dz_config, css_pipe_id); 281 if (!err) 282 asd->params.config.dz_config = ¶m->params.dz_config; 283 } 284 atomisp_css_set_isp_config_applied_frame(asd, frame); 285 atomisp_css_update_isp_params_on_pipe(asd, 286 asd->stream_env[stream_id].pipes[css_pipe_id]); 287 asd->params.dvs_6axis = (struct ia_css_dvs_6axis_config *) 288 param->params.dvs_6axis; 289 290 /* 291 * WORKAROUND: 292 * Because the camera halv3 can't ensure to set zoom 293 * region to per_frame setting and global setting at 294 * same time and only set zoom region to pre_frame 295 * setting now.so when the pre_frame setting include 296 * zoom region,I will set it to global setting. 297 */ 298 if (param->params.update_flag.dz_config && 299 asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO 300 && !err) { 301 memcpy(&asd->params.css_param.dz_config, 302 ¶m->params.dz_config, 303 sizeof(struct ia_css_dz_config)); 304 asd->params.css_param.update_flag.dz_config = 305 (struct atomisp_dz_config *) 306 &asd->params.css_param.dz_config; 307 asd->params.css_update_params_needed = true; 308 } 309 pipe->frame_params[frame->vb.vb2_buf.index] = NULL; 310 } 311 /* Enqueue buffer */ 312 err = atomisp_q_video_buffer_to_css(asd, frame, stream_id, 313 css_buf_type, css_pipe_id); 314 if (err) { 315 spin_lock_irqsave(&pipe->irq_lock, irqflags); 316 list_move_tail(&frame->queue, &pipe->activeq); 317 spin_unlock_irqrestore(&pipe->irq_lock, irqflags); 318 dev_err(asd->isp->dev, "%s, css q fails: %d\n", 319 __func__, err); 320 return -EINVAL; 321 } 322 323 /* enqueue 3A/DIS/metadata buffers */ 324 if (asd->params.curr_grid_info.s3a_grid.enable && 325 css_pipe_id == asd->params.s3a_enabled_pipe && 326 css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) 327 atomisp_q_one_s3a_buffer(asd, stream_id, 328 css_pipe_id); 329 330 if (asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream_info. 331 metadata_info.size && 332 css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) 333 atomisp_q_one_metadata_buffer(asd, stream_id, 334 css_pipe_id); 335 336 if (dvs_grid && dvs_grid->enable && 337 css_pipe_id == IA_CSS_PIPE_ID_VIDEO && 338 css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) 339 atomisp_q_one_dis_buffer(asd, stream_id, 340 css_pipe_id); 341 } 342 343 return 0; 344 } 345 346 static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd, 347 enum ia_css_pipe_id pipe_id, 348 uint16_t source_pad) 349 { 350 if (ATOMISP_USE_YUVPP(asd)) { 351 /* when run ZSL case */ 352 if (asd->continuous_mode->val && 353 asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) { 354 if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) 355 return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME; 356 else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) 357 return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME; 358 else 359 return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME; 360 } 361 362 /*when run SDV case*/ 363 if (asd->continuous_mode->val && 364 asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { 365 if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) 366 return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME; 367 else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) 368 return IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME; 369 else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) 370 return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME; 371 else 372 return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME; 373 } 374 375 /*other case: default setting*/ 376 if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE || 377 source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO || 378 (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW && 379 asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO)) 380 return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME; 381 else 382 return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME; 383 } 384 385 if (pipe_id == IA_CSS_PIPE_ID_COPY || 386 source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE || 387 source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO || 388 (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW && 389 asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO)) 390 return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME; 391 else 392 return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME; 393 } 394 395 /* queue all available buffers to css */ 396 int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd) 397 { 398 enum ia_css_buffer_type buf_type; 399 enum ia_css_pipe_id css_capture_pipe_id = IA_CSS_PIPE_ID_NUM; 400 enum ia_css_pipe_id css_preview_pipe_id = IA_CSS_PIPE_ID_NUM; 401 enum ia_css_pipe_id css_video_pipe_id = IA_CSS_PIPE_ID_NUM; 402 enum atomisp_input_stream_id input_stream_id; 403 struct atomisp_video_pipe *capture_pipe = NULL; 404 struct atomisp_video_pipe *vf_pipe = NULL; 405 struct atomisp_video_pipe *preview_pipe = NULL; 406 struct atomisp_video_pipe *video_pipe = NULL; 407 bool raw_mode = atomisp_is_mbuscode_raw( 408 asd->fmt[asd->capture_pad].fmt.code); 409 410 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) { 411 video_pipe = &asd->video_out_video_capture; 412 css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO; 413 } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) { 414 preview_pipe = &asd->video_out_capture; 415 css_preview_pipe_id = IA_CSS_PIPE_ID_CAPTURE; 416 } else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) { 417 if (asd->continuous_mode->val) { 418 capture_pipe = &asd->video_out_capture; 419 vf_pipe = &asd->video_out_vf; 420 css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE; 421 } 422 video_pipe = &asd->video_out_video_capture; 423 preview_pipe = &asd->video_out_preview; 424 css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO; 425 css_preview_pipe_id = IA_CSS_PIPE_ID_VIDEO; 426 } else if (asd->continuous_mode->val) { 427 capture_pipe = &asd->video_out_capture; 428 vf_pipe = &asd->video_out_vf; 429 preview_pipe = &asd->video_out_preview; 430 431 css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW; 432 css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE; 433 } else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) { 434 preview_pipe = &asd->video_out_preview; 435 css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW; 436 } else { 437 /* ATOMISP_RUN_MODE_STILL_CAPTURE */ 438 capture_pipe = &asd->video_out_capture; 439 if (!raw_mode) 440 vf_pipe = &asd->video_out_vf; 441 css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE; 442 } 443 444 if (IS_ISP2401 && asd->copy_mode) { 445 css_capture_pipe_id = IA_CSS_PIPE_ID_COPY; 446 css_preview_pipe_id = IA_CSS_PIPE_ID_COPY; 447 css_video_pipe_id = IA_CSS_PIPE_ID_COPY; 448 } 449 450 if (asd->yuvpp_mode) { 451 capture_pipe = &asd->video_out_capture; 452 video_pipe = &asd->video_out_video_capture; 453 preview_pipe = &asd->video_out_preview; 454 css_capture_pipe_id = IA_CSS_PIPE_ID_COPY; 455 css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP; 456 css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP; 457 } 458 459 if (capture_pipe) { 460 buf_type = atomisp_get_css_buf_type( 461 asd, css_capture_pipe_id, 462 atomisp_subdev_source_pad(&capture_pipe->vdev)); 463 input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; 464 465 /* 466 * use yuvpp pipe for SOC camera. 467 */ 468 if (ATOMISP_USE_YUVPP(asd)) 469 css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP; 470 471 atomisp_q_video_buffers_to_css(asd, capture_pipe, 472 input_stream_id, 473 buf_type, css_capture_pipe_id); 474 } 475 476 if (vf_pipe) { 477 buf_type = atomisp_get_css_buf_type( 478 asd, css_capture_pipe_id, 479 atomisp_subdev_source_pad(&vf_pipe->vdev)); 480 if (asd->stream_env[ATOMISP_INPUT_STREAM_POSTVIEW].stream) 481 input_stream_id = ATOMISP_INPUT_STREAM_POSTVIEW; 482 else 483 input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; 484 485 /* 486 * use yuvpp pipe for SOC camera. 487 */ 488 if (ATOMISP_USE_YUVPP(asd)) 489 css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP; 490 atomisp_q_video_buffers_to_css(asd, vf_pipe, 491 input_stream_id, 492 buf_type, css_capture_pipe_id); 493 } 494 495 if (preview_pipe) { 496 buf_type = atomisp_get_css_buf_type( 497 asd, css_preview_pipe_id, 498 atomisp_subdev_source_pad(&preview_pipe->vdev)); 499 if (ATOMISP_SOC_CAMERA(asd) && css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP) 500 input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; 501 /* else for ext isp use case */ 502 else if (css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP) 503 input_stream_id = ATOMISP_INPUT_STREAM_VIDEO; 504 else if (asd->stream_env[ATOMISP_INPUT_STREAM_PREVIEW].stream) 505 input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW; 506 else 507 input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; 508 509 /* 510 * use yuvpp pipe for SOC camera. 511 */ 512 if (ATOMISP_USE_YUVPP(asd)) 513 css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP; 514 515 atomisp_q_video_buffers_to_css(asd, preview_pipe, 516 input_stream_id, 517 buf_type, css_preview_pipe_id); 518 } 519 520 if (video_pipe) { 521 buf_type = atomisp_get_css_buf_type( 522 asd, css_video_pipe_id, 523 atomisp_subdev_source_pad(&video_pipe->vdev)); 524 if (asd->stream_env[ATOMISP_INPUT_STREAM_VIDEO].stream) 525 input_stream_id = ATOMISP_INPUT_STREAM_VIDEO; 526 else 527 input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; 528 529 /* 530 * use yuvpp pipe for SOC camera. 531 */ 532 if (ATOMISP_USE_YUVPP(asd)) 533 css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP; 534 535 atomisp_q_video_buffers_to_css(asd, video_pipe, 536 input_stream_id, 537 buf_type, css_video_pipe_id); 538 } 539 540 return 0; 541 } 542 543 static void atomisp_buf_queue(struct vb2_buffer *vb) 544 { 545 struct atomisp_video_pipe *pipe = vb_to_pipe(vb); 546 struct ia_css_frame *frame = vb_to_frame(vb); 547 struct atomisp_sub_device *asd = pipe->asd; 548 u16 source_pad = atomisp_subdev_source_pad(&pipe->vdev); 549 unsigned long irqflags; 550 int ret; 551 552 mutex_lock(&asd->isp->mutex); 553 554 ret = atomisp_pipe_check(pipe, false); 555 if (ret || pipe->stopping) { 556 spin_lock_irqsave(&pipe->irq_lock, irqflags); 557 atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR); 558 spin_unlock_irqrestore(&pipe->irq_lock, irqflags); 559 goto out_unlock; 560 } 561 562 /* FIXME this ugliness comes from the original atomisp buffer handling */ 563 if (!(vb->skip_cache_sync_on_finish && vb->skip_cache_sync_on_prepare)) 564 wbinvd(); 565 566 pipe->frame_params[vb->index] = NULL; 567 568 spin_lock_irqsave(&pipe->irq_lock, irqflags); 569 /* 570 * when a frame buffer meets following conditions, it should be put into 571 * the waiting list: 572 * 1. It is not a main output frame, and it has a per-frame parameter 573 * to go with it. 574 * 2. It is not a main output frame, and the waiting buffer list is not 575 * empty, to keep the FIFO sequence of frame buffer processing, it 576 * is put to waiting list until previous per-frame parameter buffers 577 * get enqueued. 578 */ 579 if (!atomisp_is_vf_pipe(pipe) && 580 (pipe->frame_request_config_id[vb->index] || 581 !list_empty(&pipe->buffers_waiting_for_param))) 582 list_add_tail(&frame->queue, &pipe->buffers_waiting_for_param); 583 else 584 list_add_tail(&frame->queue, &pipe->activeq); 585 586 spin_unlock_irqrestore(&pipe->irq_lock, irqflags); 587 588 /* TODO: do this better, not best way to queue to css */ 589 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) { 590 if (!list_empty(&pipe->buffers_waiting_for_param)) 591 atomisp_handle_parameter_and_buffer(pipe); 592 else 593 atomisp_qbuffers_to_css(asd); 594 } 595 596 /* 597 * Workaround: Due to the design of HALv3, 598 * sometimes in ZSL or SDV mode HAL needs to 599 * capture multiple images within one streaming cycle. 600 * But the capture number cannot be determined by HAL. 601 * So HAL only sets the capture number to be 1 and queue multiple 602 * buffers. Atomisp driver needs to check this case and re-trigger 603 * CSS to do capture when new buffer is queued. 604 */ 605 if (asd->continuous_mode->val && source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE && 606 !asd->enable_raw_buffer_lock->val && asd->params.offline_parm.num_captures == 1) { 607 asd->pending_capture_request++; 608 dev_dbg(asd->isp->dev, "Add one pending capture request.\n"); 609 } 610 611 out_unlock: 612 mutex_unlock(&asd->isp->mutex); 613 } 614 615 static void atomisp_buf_cleanup(struct vb2_buffer *vb) 616 { 617 struct atomisp_video_pipe *pipe = vb_to_pipe(vb); 618 struct ia_css_frame *frame = vb_to_frame(vb); 619 int index = frame->vb.vb2_buf.index; 620 621 pipe->frame_request_config_id[index] = 0; 622 pipe->frame_params[index] = NULL; 623 624 hmm_free(frame->data); 625 } 626 627 static const struct vb2_ops atomisp_vb2_ops = { 628 .queue_setup = atomisp_queue_setup, 629 .buf_init = atomisp_buf_init, 630 .buf_cleanup = atomisp_buf_cleanup, 631 .buf_queue = atomisp_buf_queue, 632 .start_streaming = atomisp_start_streaming, 633 .stop_streaming = atomisp_stop_streaming, 634 }; 635 636 static int atomisp_init_pipe(struct atomisp_video_pipe *pipe) 637 { 638 int ret; 639 640 /* init locks */ 641 spin_lock_init(&pipe->irq_lock); 642 mutex_init(&pipe->vb_queue_mutex); 643 644 /* Init videobuf2 queue structure */ 645 pipe->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 646 pipe->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR; 647 pipe->vb_queue.buf_struct_size = sizeof(struct ia_css_frame); 648 pipe->vb_queue.ops = &atomisp_vb2_ops; 649 pipe->vb_queue.mem_ops = &vb2_vmalloc_memops; 650 pipe->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 651 ret = vb2_queue_init(&pipe->vb_queue); 652 if (ret) 653 return ret; 654 655 pipe->vdev.queue = &pipe->vb_queue; 656 pipe->vdev.queue->lock = &pipe->vb_queue_mutex; 657 658 INIT_LIST_HEAD(&pipe->activeq); 659 INIT_LIST_HEAD(&pipe->buffers_waiting_for_param); 660 INIT_LIST_HEAD(&pipe->per_frame_params); 661 memset(pipe->frame_request_config_id, 0, 662 VIDEO_MAX_FRAME * sizeof(unsigned int)); 663 memset(pipe->frame_params, 0, 664 VIDEO_MAX_FRAME * 665 sizeof(struct atomisp_css_params_with_list *)); 666 667 return 0; 668 } 669 670 static void atomisp_dev_init_struct(struct atomisp_device *isp) 671 { 672 unsigned int i; 673 674 isp->need_gfx_throttle = true; 675 isp->isp_fatal_error = false; 676 isp->mipi_frame_size = 0; 677 678 for (i = 0; i < isp->input_cnt; i++) 679 isp->inputs[i].asd = NULL; 680 /* 681 * For Merrifield, frequency is scalable. 682 * After boot-up, the default frequency is 200MHz. 683 */ 684 isp->sw_contex.running_freq = ISP_FREQ_200MHZ; 685 } 686 687 static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd) 688 { 689 v4l2_ctrl_s_ctrl(asd->run_mode, ATOMISP_RUN_MODE_STILL_CAPTURE); 690 memset(&asd->params.css_param, 0, sizeof(asd->params.css_param)); 691 asd->params.color_effect = V4L2_COLORFX_NONE; 692 asd->params.bad_pixel_en = true; 693 asd->params.gdc_cac_en = false; 694 asd->params.video_dis_en = false; 695 asd->params.sc_en = false; 696 asd->params.fpn_en = false; 697 asd->params.xnr_en = false; 698 asd->params.false_color = 0; 699 asd->params.online_process = 1; 700 asd->params.yuv_ds_en = 0; 701 /* s3a grid not enabled for any pipe */ 702 asd->params.s3a_enabled_pipe = IA_CSS_PIPE_ID_NUM; 703 704 asd->params.offline_parm.num_captures = 1; 705 asd->params.offline_parm.skip_frames = 0; 706 asd->params.offline_parm.offset = 0; 707 asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED; 708 /* Add for channel */ 709 asd->input_curr = 0; 710 711 asd->mipi_frame_size = 0; 712 asd->copy_mode = false; 713 asd->yuvpp_mode = false; 714 715 asd->stream_prepared = false; 716 asd->high_speed_mode = false; 717 asd->sensor_array_res.height = 0; 718 asd->sensor_array_res.width = 0; 719 atomisp_css_init_struct(asd); 720 } 721 722 /* 723 * file operation functions 724 */ 725 static unsigned int atomisp_subdev_users(struct atomisp_sub_device *asd) 726 { 727 return asd->video_out_preview.users + 728 asd->video_out_vf.users + 729 asd->video_out_capture.users + 730 asd->video_out_video_capture.users; 731 } 732 733 unsigned int atomisp_dev_users(struct atomisp_device *isp) 734 { 735 unsigned int i, sum; 736 737 for (i = 0, sum = 0; i < isp->num_of_streams; i++) 738 sum += atomisp_subdev_users(&isp->asd[i]); 739 740 return sum; 741 } 742 743 static int atomisp_open(struct file *file) 744 { 745 struct video_device *vdev = video_devdata(file); 746 struct atomisp_device *isp = video_get_drvdata(vdev); 747 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 748 struct atomisp_sub_device *asd = pipe->asd; 749 int ret; 750 751 dev_dbg(isp->dev, "open device %s\n", vdev->name); 752 753 ret = v4l2_fh_open(file); 754 if (ret) 755 return ret; 756 757 mutex_lock(&isp->mutex); 758 759 asd->subdev.devnode = vdev; 760 /* Deferred firmware loading case. */ 761 if (isp->css_env.isp_css_fw.bytes == 0) { 762 dev_err(isp->dev, "Deferred firmware load.\n"); 763 isp->firmware = atomisp_load_firmware(isp); 764 if (!isp->firmware) { 765 dev_err(isp->dev, "Failed to load ISP firmware.\n"); 766 ret = -ENOENT; 767 goto error; 768 } 769 ret = atomisp_css_load_firmware(isp); 770 if (ret) { 771 dev_err(isp->dev, "Failed to init css.\n"); 772 goto error; 773 } 774 /* No need to keep FW in memory anymore. */ 775 release_firmware(isp->firmware); 776 isp->firmware = NULL; 777 isp->css_env.isp_css_fw.data = NULL; 778 } 779 780 if (!isp->input_cnt) { 781 dev_err(isp->dev, "no camera attached\n"); 782 ret = -EINVAL; 783 goto error; 784 } 785 786 /* 787 * atomisp does not allow multiple open 788 */ 789 if (pipe->users) { 790 dev_dbg(isp->dev, "video node already opened\n"); 791 mutex_unlock(&isp->mutex); 792 return -EBUSY; 793 } 794 795 ret = atomisp_init_pipe(pipe); 796 if (ret) 797 goto error; 798 799 if (atomisp_dev_users(isp)) { 800 dev_dbg(isp->dev, "skip init isp in open\n"); 801 goto init_subdev; 802 } 803 804 /* runtime power management, turn on ISP */ 805 ret = pm_runtime_resume_and_get(vdev->v4l2_dev->dev); 806 if (ret < 0) { 807 dev_err(isp->dev, "Failed to power on device\n"); 808 goto error; 809 } 810 811 atomisp_dev_init_struct(isp); 812 813 ret = v4l2_subdev_call(isp->flash, core, s_power, 1); 814 if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD) { 815 dev_err(isp->dev, "Failed to power-on flash\n"); 816 goto css_error; 817 } 818 819 init_subdev: 820 if (atomisp_subdev_users(asd)) 821 goto done; 822 823 atomisp_subdev_init_struct(asd); 824 825 done: 826 pipe->users++; 827 mutex_unlock(&isp->mutex); 828 829 /* Ensure that a mode is set */ 830 v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode); 831 832 return 0; 833 834 css_error: 835 pm_runtime_put(vdev->v4l2_dev->dev); 836 error: 837 mutex_unlock(&isp->mutex); 838 v4l2_fh_release(file); 839 return ret; 840 } 841 842 static int atomisp_release(struct file *file) 843 { 844 struct video_device *vdev = video_devdata(file); 845 struct atomisp_device *isp = video_get_drvdata(vdev); 846 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 847 struct atomisp_sub_device *asd = pipe->asd; 848 struct v4l2_subdev_fh fh; 849 struct v4l2_rect clear_compose = {0}; 850 unsigned long flags; 851 int ret; 852 853 v4l2_fh_init(&fh.vfh, vdev); 854 855 dev_dbg(isp->dev, "release device %s\n", vdev->name); 856 857 asd->subdev.devnode = vdev; 858 859 /* Note file must not be used after this! */ 860 vb2_fop_release(file); 861 862 mutex_lock(&isp->mutex); 863 864 pipe->users--; 865 if (pipe->users) 866 goto done; 867 868 /* 869 * A little trick here: 870 * file injection input resolution is recorded in the sink pad, 871 * therefore can not be cleared when releaseing one device node. 872 * The sink pad setting can only be cleared when all device nodes 873 * get released. 874 */ 875 if (asd->fmt_auto->val) { 876 struct v4l2_mbus_framefmt isp_sink_fmt = { 0 }; 877 878 atomisp_subdev_set_ffmt(&asd->subdev, fh.state, 879 V4L2_SUBDEV_FORMAT_ACTIVE, 880 ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt); 881 } 882 883 if (atomisp_subdev_users(asd)) 884 goto done; 885 886 atomisp_css_free_stat_buffers(asd); 887 atomisp_free_internal_buffers(asd); 888 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 889 core, s_power, 0); 890 if (ret) 891 dev_warn(isp->dev, "Failed to power-off sensor\n"); 892 893 /* clear the asd field to show this camera is not used */ 894 isp->inputs[asd->input_curr].asd = NULL; 895 spin_lock_irqsave(&isp->lock, flags); 896 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED; 897 spin_unlock_irqrestore(&isp->lock, flags); 898 899 if (atomisp_dev_users(isp)) 900 goto done; 901 902 atomisp_destroy_pipes_stream_force(asd); 903 904 if (defer_fw_load) { 905 ia_css_unload_firmware(); 906 isp->css_env.isp_css_fw.data = NULL; 907 isp->css_env.isp_css_fw.bytes = 0; 908 } 909 910 ret = v4l2_subdev_call(isp->flash, core, s_power, 0); 911 if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD) 912 dev_warn(isp->dev, "Failed to power-off flash\n"); 913 914 if (pm_runtime_put_sync(vdev->v4l2_dev->dev) < 0) 915 dev_err(isp->dev, "Failed to power off device\n"); 916 917 done: 918 atomisp_subdev_set_selection(&asd->subdev, fh.state, 919 V4L2_SUBDEV_FORMAT_ACTIVE, 920 atomisp_subdev_source_pad(vdev), 921 V4L2_SEL_TGT_COMPOSE, 0, 922 &clear_compose); 923 mutex_unlock(&isp->mutex); 924 return 0; 925 } 926 927 const struct v4l2_file_operations atomisp_fops = { 928 .owner = THIS_MODULE, 929 .open = atomisp_open, 930 .release = atomisp_release, 931 .mmap = vb2_fop_mmap, 932 .poll = vb2_fop_poll, 933 .unlocked_ioctl = video_ioctl2, 934 #ifdef CONFIG_COMPAT 935 /* 936 * this was removed because of bugs, the interface 937 * needs to be made safe for compat tasks instead. 938 .compat_ioctl32 = atomisp_compat_ioctl32, 939 */ 940 #endif 941 }; 942