Commit 6048fc1c authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

media: atomisp: Remove continuous mode support

Continues mode is a special mode where 2 /dev/video devices can be active
at the same time. Either the video-preview + video nodes or the
viewfinder (for still capture) + capture nodes.

For the video-preview + video-recording case modern userspace will
use a single stream multiplexed by pipewire.

The still-capture case is extra special only starting the preview
stream and then relying on a custom ATOMISP_IOC_S_CONT_CAPTURE_CONFIG
ioctl to set things up followed by a second stream on to capture
the amount of configured still pictures. While running the sensor
at full resolution all the time. This case too is better handled
with dma-buf + GPU downscaling for the view-finder rather then all this
custom special code. Besises this the ioctl expects a bunch of special
non error checked conditions to be met otherwise things will crash/hang.

The continues mode also involves a special cases all over the code
getting in the way of further cleanups and simplifying the code to
using just 1 /dev/video# node. So lets remove it and the
related custom ATOMISP_IOC_S_CONT_CAPTURE_CONFIG ioctl.

Link: https://lore.kernel.org/linux-media/ea81b17b-7d1f-a5e1-11dd-04db310e1e50@redhat.com/
Link: https://lore.kernel.org/r/20230221145906.8113-3-hdegoede@redhat.comSigned-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent d33b94c0
......@@ -299,26 +299,6 @@ struct atomisp_3a_statistics {
u32 isp_config_id; /* isp config ID */
};
/**
* struct atomisp_cont_capture_conf - continuous capture parameters
* @num_captures: number of still images to capture
* @skip_frames: number of frames to skip between 2 captures
* @offset: offset in ring buffer to start capture
*
* For example, to capture 1 frame from past, current, and 1 from future
* and skip one frame between each capture, parameters would be:
* num_captures:3
* skip_frames:1
* offset:-2
*/
struct atomisp_cont_capture_conf {
int num_captures;
unsigned int skip_frames;
int offset;
__u32 reserved[5];
};
struct atomisp_ae_window {
int x_left;
int x_right;
......@@ -958,9 +938,6 @@ struct atomisp_sensor_ae_bracketing_lut {
#define ATOMISP_IOC_S_PARAMETERS \
_IOW('v', BASE_VIDIOC_PRIVATE + 32, struct atomisp_parameters)
#define ATOMISP_IOC_S_CONT_CAPTURE_CONFIG \
_IOWR('v', BASE_VIDIOC_PRIVATE + 33, struct atomisp_cont_capture_conf)
#define ATOMISP_IOC_G_METADATA \
_IOWR('v', BASE_VIDIOC_PRIVATE + 34, struct atomisp_metadata)
......
......@@ -268,9 +268,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f);
int atomisp_set_shading_table(struct atomisp_sub_device *asd,
struct atomisp_shading_table *shading_table);
int atomisp_offline_capture_configure(struct atomisp_sub_device *asd,
struct atomisp_cont_capture_conf *cvf_config);
void atomisp_free_internal_buffers(struct atomisp_sub_device *asd);
int atomisp_s_ae_window(struct atomisp_sub_device *asd,
......
......@@ -658,13 +658,10 @@ static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd,
return false;
case ATOMISP_RUN_MODE_PREVIEW:
if (!asd->continuous_mode->val) {
if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
return true;
if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
return true;
return false;
}
fallthrough;
return false;
case ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE:
if (pipe_id == IA_CSS_PIPE_ID_CAPTURE ||
pipe_id == IA_CSS_PIPE_ID_PREVIEW)
......@@ -672,14 +669,10 @@ static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd,
return false;
case ATOMISP_RUN_MODE_VIDEO:
if (!asd->continuous_mode->val) {
if (pipe_id == IA_CSS_PIPE_ID_VIDEO ||
pipe_id == IA_CSS_PIPE_ID_YUVPP)
return true;
else
return false;
}
fallthrough;
if (pipe_id == IA_CSS_PIPE_ID_VIDEO || pipe_id == IA_CSS_PIPE_ID_YUVPP)
return true;
return false;
case ATOMISP_RUN_MODE_SDV:
if (pipe_id == IA_CSS_PIPE_ID_CAPTURE ||
pipe_id == IA_CSS_PIPE_ID_VIDEO)
......@@ -2139,17 +2132,8 @@ static void __configure_video_preview_output(struct atomisp_sub_device *asd,
__pipe_id_to_pipe_mode(asd, pipe_id);
stream_env->update_pipe[pipe_id] = true;
/*
* second_output will be as video main output in SDV mode
* with SOC camera. output will be as video main output in
* normal video mode.
*/
if (asd->continuous_mode->val)
css_output_info = &stream_env->pipe_configs[pipe_id].
output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX];
else
css_output_info = &stream_env->pipe_configs[pipe_id].
output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
css_output_info =
&stream_env->pipe_configs[pipe_id].output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
css_output_info->res.width = width;
css_output_info->res.height = height;
......@@ -2485,17 +2469,8 @@ static void __configure_video_vf_output(struct atomisp_sub_device *asd,
__pipe_id_to_pipe_mode(asd, pipe_id);
stream_env->update_pipe[pipe_id] = true;
/*
* second_vf_output will be as video viewfinder in SDV mode
* with SOC camera. vf_output will be as video viewfinder in
* normal video mode.
*/
if (asd->continuous_mode->val)
css_output_info = &stream_env->pipe_configs[pipe_id].
vf_output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX];
else
css_output_info = &stream_env->pipe_configs[pipe_id].
vf_output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
css_output_info =
&stream_env->pipe_configs[pipe_id].vf_output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
css_output_info->res.width = width;
css_output_info->res.height = height;
......@@ -2636,12 +2611,7 @@ int atomisp_get_css_frame_info(struct atomisp_sub_device *asd,
*frame_info = info.output_info[0];
break;
case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO:
if (ATOMISP_USE_YUVPP(asd) && asd->continuous_mode->val)
*frame_info = info.
output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX];
else
*frame_info = info.
output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
*frame_info = info.output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
break;
case ATOMISP_SUBDEV_PAD_SOURCE_VF:
if (stream_index == ATOMISP_INPUT_STREAM_POSTVIEW)
......@@ -2653,15 +2623,7 @@ int atomisp_get_css_frame_info(struct atomisp_sub_device *asd,
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
(pipe_index == IA_CSS_PIPE_ID_VIDEO ||
pipe_index == IA_CSS_PIPE_ID_YUVPP))
if (ATOMISP_USE_YUVPP(asd) && asd->continuous_mode->val)
*frame_info = info.
vf_output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX];
else
*frame_info = info.
vf_output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
else if (ATOMISP_USE_YUVPP(asd) && asd->continuous_mode->val)
*frame_info =
info.output_info[ATOMISP_CSS_OUTPUT_SECOND_INDEX];
*frame_info = info.vf_output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
else
*frame_info =
info.output_info[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX];
......@@ -2826,8 +2788,6 @@ int atomisp_css_video_get_viewfinder_frame_info(
if (ATOMISP_USE_YUVPP(asd)) {
pipe_id = IA_CSS_PIPE_ID_YUVPP;
if (asd->continuous_mode->val)
frame_type = ATOMISP_CSS_SECOND_VF_FRAME;
} else {
pipe_id = IA_CSS_PIPE_ID_VIDEO;
}
......@@ -2880,8 +2840,6 @@ int atomisp_css_preview_get_output_frame_info(
if (ATOMISP_USE_YUVPP(asd)) {
pipe_id = IA_CSS_PIPE_ID_YUVPP;
if (asd->continuous_mode->val)
frame_type = ATOMISP_CSS_SECOND_OUTPUT_FRAME;
} else {
pipe_id = IA_CSS_PIPE_ID_PREVIEW;
}
......@@ -2914,8 +2872,6 @@ int atomisp_css_video_get_output_frame_info(
if (ATOMISP_USE_YUVPP(asd)) {
pipe_id = IA_CSS_PIPE_ID_YUVPP;
if (asd->continuous_mode->val)
frame_type = ATOMISP_CSS_SECOND_OUTPUT_FRAME;
} else {
pipe_id = IA_CSS_PIPE_ID_VIDEO;
}
......
......@@ -348,31 +348,6 @@ static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd,
uint16_t source_pad)
{
if (ATOMISP_USE_YUVPP(asd)) {
/* when run ZSL case */
if (asd->continuous_mode->val &&
asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
else
return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
}
/*when run SDV case*/
if (asd->continuous_mode->val &&
asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
return IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME;
else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO)
return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
else
return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
}
/*other case: default setting*/
if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE ||
source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
(source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
......@@ -414,22 +389,10 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
preview_pipe = &asd->video_out_capture;
css_preview_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
if (asd->continuous_mode->val) {
capture_pipe = &asd->video_out_capture;
vf_pipe = &asd->video_out_vf;
css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
}
video_pipe = &asd->video_out_video_capture;
preview_pipe = &asd->video_out_preview;
css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
css_preview_pipe_id = IA_CSS_PIPE_ID_VIDEO;
} else if (asd->continuous_mode->val) {
capture_pipe = &asd->video_out_capture;
vf_pipe = &asd->video_out_vf;
preview_pipe = &asd->video_out_preview;
css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
} else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
preview_pipe = &asd->video_out_preview;
css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
......@@ -545,7 +508,6 @@ static void atomisp_buf_queue(struct vb2_buffer *vb)
struct atomisp_video_pipe *pipe = vb_to_pipe(vb);
struct ia_css_frame *frame = vb_to_frame(vb);
struct atomisp_sub_device *asd = pipe->asd;
u16 source_pad = atomisp_subdev_source_pad(&pipe->vdev);
unsigned long irqflags;
int ret;
......@@ -593,21 +555,6 @@ static void atomisp_buf_queue(struct vb2_buffer *vb)
atomisp_qbuffers_to_css(asd);
}
/*
* Workaround: Due to the design of HALv3,
* sometimes in ZSL or SDV mode HAL needs to
* capture multiple images within one streaming cycle.
* But the capture number cannot be determined by HAL.
* So HAL only sets the capture number to be 1 and queue multiple
* buffers. Atomisp driver needs to check this case and re-trigger
* CSS to do capture when new buffer is queued.
*/
if (asd->continuous_mode->val && source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE &&
!asd->enable_raw_buffer_lock->val && asd->params.offline_parm.num_captures == 1) {
asd->pending_capture_request++;
dev_dbg(asd->isp->dev, "Add one pending capture request.\n");
}
out_unlock:
mutex_unlock(&asd->isp->mutex);
}
......@@ -667,9 +614,6 @@ static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd)
/* s3a grid not enabled for any pipe */
asd->params.s3a_enabled_pipe = IA_CSS_PIPE_ID_NUM;
asd->params.offline_parm.num_captures = 1;
asd->params.offline_parm.skip_frames = 0;
asd->params.offline_parm.offset = 0;
asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
/* Add for channel */
asd->input_curr = 0;
......
......@@ -1123,13 +1123,6 @@ enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
if (ATOMISP_USE_YUVPP(asd))
return IA_CSS_PIPE_ID_YUVPP;
if (asd->continuous_mode->val) {
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
return IA_CSS_PIPE_ID_VIDEO;
else
return IA_CSS_PIPE_ID_PREVIEW;
}
/*
* Disable vf_pp and run CSS in video mode. This allows using ISP
* scaling but it has one frame delay due to CSS internal buffering.
......@@ -1164,10 +1157,7 @@ static unsigned int atomisp_sensor_start_stream(struct atomisp_sub_device *asd)
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO ||
(asd->run_mode->val == ATOMISP_RUN_MODE_STILL_CAPTURE &&
!atomisp_is_mbuscode_raw(
asd->fmt[
asd->capture_pad].fmt.code) &&
!asd->continuous_mode->val))
!atomisp_is_mbuscode_raw(asd->fmt[asd->capture_pad].fmt.code)))
return 2;
else
return 1;
......@@ -1221,57 +1211,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count)
*/
sensor_start_stream = atomisp_sensor_start_stream(asd);
/* Reset pending capture request count. */
asd->pending_capture_request = 0;
if (atomisp_subdev_streaming_count(asd) > sensor_start_stream) {
/* trigger still capture */
if (asd->continuous_mode->val &&
atomisp_subdev_source_pad(vdev)
== ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) {
if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
dev_dbg(isp->dev, "SDV last video raw buffer id: %u\n",
asd->latest_preview_exp_id);
else
dev_dbg(isp->dev, "ZSL last preview raw buffer id: %u\n",
asd->latest_preview_exp_id);
if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) {
flush_work(&asd->delayed_init_work);
mutex_unlock(&isp->mutex);
ret = wait_for_completion_interruptible(&asd->init_done);
mutex_lock(&isp->mutex);
if (ret) {
ret = -ERESTARTSYS;
goto out_unlock;
}
}
/* handle per_frame_setting parameter and buffers */
atomisp_handle_parameter_and_buffer(pipe);
/*
* only ZSL/SDV capture request will be here, raise
* the ISP freq to the highest possible to minimize
* the S2S latency.
*/
atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false);
/*
* When asd->enable_raw_buffer_lock->val is true,
* An extra IOCTL is needed to call
* atomisp_css_exp_id_capture and trigger real capture
*/
if (!asd->enable_raw_buffer_lock->val) {
ret = atomisp_css_offline_capture_configure(asd,
asd->params.offline_parm.num_captures,
asd->params.offline_parm.skip_frames,
asd->params.offline_parm.offset);
if (ret) {
ret = -EINVAL;
goto out_unlock;
}
}
}
atomisp_qbuffers_to_css(asd);
ret = 0;
goto out_unlock;
......@@ -1369,17 +1309,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count)
goto out_unlock;
}
if (asd->continuous_mode->val) {
atomisp_subdev_get_ffmt(&asd->subdev, NULL,
V4L2_SUBDEV_FORMAT_ACTIVE,
ATOMISP_SUBDEV_PAD_SINK);
reinit_completion(&asd->init_done);
asd->delayed_init = ATOMISP_DELAYED_INIT_QUEUED;
queue_work(asd->delayed_init_workq, &asd->delayed_init_work);
} else {
asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
}
asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
out_unlock:
mutex_unlock(&isp->mutex);
......@@ -1420,24 +1350,6 @@ void atomisp_stop_streaming(struct vb2_queue *vq)
if (ret == 0)
dev_warn(isp->dev, "Warning timeout waiting for CSS to return buffers\n");
/*
* do only videobuf_streamoff for capture & vf pipes in
* case of continuous capture
*/
if (asd->continuous_mode->val &&
atomisp_subdev_source_pad(vdev) != ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
atomisp_subdev_source_pad(vdev) != ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) {
if (atomisp_subdev_source_pad(vdev) == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) {
/* stop continuous still capture if needed */
if (asd->params.offline_parm.num_captures == -1)
atomisp_css_offline_capture_configure(asd,
0, 0, 0);
atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, false);
}
goto out_unlock;
}
if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED)
first_streamoff = true;
......@@ -2245,9 +2157,6 @@ static long atomisp_vidioc_default(struct file *file, void *fh,
err = atomisp_set_parameters(vdev, arg);
break;
case ATOMISP_IOC_S_CONT_CAPTURE_CONFIG:
err = atomisp_offline_capture_configure(asd, arg);
break;
case ATOMISP_IOC_G_METADATA:
err = atomisp_get_metadata(asd, 0, arg);
break;
......
......@@ -427,8 +427,7 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd,
isp_sd->params.video_dis_en = 0;
if (isp_sd->params.video_dis_en &&
isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
!isp_sd->continuous_mode->val) {
isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
/* This resolution contains 20 % of DVS slack
* (of the desired captured image before
* scaling, or 1 / 6 of what we get from the
......@@ -459,8 +458,7 @@ int atomisp_subdev_set_selection(struct v4l2_subdev *sd,
break;
if (isp_sd->params.video_dis_en &&
isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
!isp_sd->continuous_mode->val) {
isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
dvs_w = rounddown(crop[pad]->width / 5,
ATOM_ISP_STEP_WIDTH);
dvs_h = rounddown(crop[pad]->height / 5,
......@@ -727,11 +725,7 @@ static int __atomisp_update_run_mode(struct atomisp_sub_device *asd)
struct v4l2_ctrl *c;
s32 mode;
if (ctrl->val != ATOMISP_RUN_MODE_VIDEO &&
asd->continuous_mode->val)
mode = ATOMISP_RUN_MODE_PREVIEW;
else
mode = ctrl->val;
mode = ctrl->val;
c = v4l2_ctrl_find(
isp->inputs[asd->input_curr].camera->ctrl_handler,
......@@ -816,24 +810,6 @@ static const struct v4l2_ctrl_config ctrl_vfpp = {
.qmenu = ctrl_vfpp_mode_menu,
};
/*
* Control for ISP continuous mode
*
* When enabled, capture processing is possible without
* stopping the preview pipeline. When disabled, ISP needs
* to be restarted between preview and capture.
*/
static const struct v4l2_ctrl_config ctrl_continuous_mode = {
.ops = &ctrl_ops,
.id = V4L2_CID_ATOMISP_CONTINUOUS_MODE,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Continuous mode",
.min = 0,
.max = 1,
.step = 1,
.def = 0,
};
/*
* Control for continuous mode raw buffer size
*
......@@ -1040,8 +1016,6 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
&ctrl_run_mode, NULL);
asd->vfpp = v4l2_ctrl_new_custom(&asd->ctrl_handler,
&ctrl_vfpp, NULL);
asd->continuous_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler,
&ctrl_continuous_mode, NULL);
asd->continuous_viewfinder = v4l2_ctrl_new_custom(&asd->ctrl_handler,
&ctrl_continuous_viewfinder,
NULL);
......
......@@ -237,8 +237,6 @@ struct atomisp_subdev_params {
enum atomisp_flash_state flash_state;
enum atomisp_frame_status last_frame_status;
/* continuous capture */
struct atomisp_cont_capture_conf offline_parm;
/* Flag to check if driver needs to update params to css */
bool css_update_params_needed;
};
......@@ -267,7 +265,6 @@ struct atomisp_sub_device {
struct v4l2_ctrl *fmt_auto;
struct v4l2_ctrl *run_mode;
struct v4l2_ctrl *vfpp;
struct v4l2_ctrl *continuous_mode;
struct v4l2_ctrl *continuous_raw_buffer_size;
struct v4l2_ctrl *continuous_viewfinder;
struct v4l2_ctrl *enable_raw_buffer_lock;
......@@ -351,7 +348,6 @@ struct atomisp_sub_device {
struct atomisp_resolution sensor_array_res;
bool high_speed_mode; /* Indicate whether now is a high speed mode */
int pending_capture_request; /* Indicates the number of pending capture requests. */
unsigned int preview_exp_id;
unsigned int postview_exp_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment