From e430bd5079b6d1641624b4959858d094fb9b4f73 Mon Sep 17 00:00:00 2001 From: Wooki Min Date: Wed, 23 May 2018 13:49:32 +0900 Subject: [PATCH] [COMMON] fimc-is2: modify stream off/on sequence of module for pattern gen When the pattern generator is used, only sensor module stream on / off is skipped. Change-Id: I325f47f6a641be6a6bad1c272935aa4853bac629 Signed-off-by: Wooki Min --- .../exynos/fimc-is2/fimc-is-device-csi_v4.c | 48 ++++++++++---- .../exynos/fimc-is2/fimc-is-device-sensor.h | 2 + .../fimc-is2/fimc-is-device-sensor_v2.c | 64 ++++++++++++++----- 3 files changed, 84 insertions(+), 30 deletions(-) diff --git a/drivers/media/platform/exynos/fimc-is2/fimc-is-device-csi_v4.c b/drivers/media/platform/exynos/fimc-is2/fimc-is-device-csi_v4.c index 5476b555defd..594fb0dad7c7 100644 --- a/drivers/media/platform/exynos/fimc-is2/fimc-is-device-csi_v4.c +++ b/drivers/media/platform/exynos/fimc-is2/fimc-is-device-csi_v4.c @@ -1263,6 +1263,40 @@ static long csi_ioctl(struct v4l2_subdev *subdev, unsigned int cmd, void *arg) csi_s_output_dma(csi, CSI_VIRTUAL_CH_2, false); csi_s_output_dma(csi, CSI_VIRTUAL_CH_3, false); break; + case SENSOR_IOCTL_PATTERN_ENABLE: + { + struct fimc_is_device_csi_dma *csi_dma = csi->csi_dma; + struct fimc_is_sensor_cfg *sensor_cfg; + u32 clk = 533000000; /* Unit: Hz, This is just for debugging. So, value is fixed */ + u32 fps; + + sensor_cfg = csi->sensor_cfg; + if (!sensor_cfg) { + merr("[CSI] sensor cfg is null", csi); + ret = -EINVAL; + goto p_err; + } + + fps = sysfs_debug.pattern_fps > 0 ? + sysfs_debug.pattern_fps : sensor_cfg->framerate; + + ret = csi_hw_s_dma_common_pattern_enable(csi_dma->base_reg, + sensor_cfg->input[CSI_VIRTUAL_CH_0].width, + sensor_cfg->input[CSI_VIRTUAL_CH_0].height, + fps, clk); + if (ret) { + merr("[CSI] csi_hw_s_dma_common_pattern is fail(%d)\n", csi, ret); + goto p_err; + } + } + break; + case SENSOR_IOCTL_PATTERN_DISABLE: + { + struct fimc_is_device_csi_dma *csi_dma = csi->csi_dma; + + csi_hw_s_dma_common_pattern_disable(csi_dma->base_reg); + } + break; default: break; } @@ -1509,20 +1543,6 @@ static int csi_stream_on(struct v4l2_subdev *subdev, #if defined(ENABLE_PDP_STAT_DMA) csi_hw_s_dma_common_dynamic(csi_dma->base_reg_stat, 5 * SZ_1K, dma_ch); #endif - if (sysfs_debug.pattern_en) { - u32 clk = 533000000; /* Hz, This is just for debugging. So, value is fixed */ - - ret = csi_hw_s_dma_common_pattern(csi_dma->base_reg, - sensor_cfg->input[CSI_VIRTUAL_CH_0].width, - sensor_cfg->input[CSI_VIRTUAL_CH_0].height, - sysfs_debug.pattern_fps, - clk); - if (ret) { - merr("[CSI] csi_hw_s_dma_common_pattern is fail(%d)\n", csi, ret); - spin_unlock(&csi_dma->barrier); - goto p_err; - } - } } spin_unlock(&csi_dma->barrier); diff --git a/drivers/media/platform/exynos/fimc-is2/fimc-is-device-sensor.h b/drivers/media/platform/exynos/fimc-is2/fimc-is-device-sensor.h index e714c55fc4e5..78aeb3eee637 100644 --- a/drivers/media/platform/exynos/fimc-is2/fimc-is-device-sensor.h +++ b/drivers/media/platform/exynos/fimc-is2/fimc-is-device-sensor.h @@ -164,6 +164,8 @@ struct fimc_is_device_ischain; enum fimc_is_sensor_subdev_ioctl { SENSOR_IOCTL_DMA_CANCEL, + SENSOR_IOCTL_PATTERN_ENABLE, + SENSOR_IOCTL_PATTERN_DISABLE, }; #if defined(CONFIG_SECURE_CAMERA_USE) diff --git a/drivers/media/platform/exynos/fimc-is2/fimc-is-device-sensor_v2.c b/drivers/media/platform/exynos/fimc-is2/fimc-is-device-sensor_v2.c index c34b35d3ccbf..a63f484ddfe5 100644 --- a/drivers/media/platform/exynos/fimc-is2/fimc-is-device-sensor_v2.c +++ b/drivers/media/platform/exynos/fimc-is2/fimc-is-device-sensor_v2.c @@ -804,7 +804,7 @@ static void fimc_is_sensor_dtp(unsigned long data) } /* Don't need to dtp check */ - if (!device->force_stop && !device->dtp_check) + if ((!device->force_stop && !device->dtp_check) || sysfs_debug.pattern_en) return; err("forcely reset due to 0x%08lx", device->force_stop); @@ -840,6 +840,23 @@ static int fimc_is_sensor_start(struct fimc_is_device_sensor *device) } } + if (sysfs_debug.pattern_en) { + struct v4l2_subdev *subdev_csi; + + subdev_csi = device->subdev_csi; + if (!subdev_csi) + mwarn("subdev_csi is NULL", device); + + ret = v4l2_subdev_call(subdev_csi, core, ioctl, SENSOR_IOCTL_PATTERN_ENABLE, NULL); + if (ret) { + mwarn("v4l2_csi_call(ioctl) is fail(%d)", device, ret); + ret = -EINVAL; + goto p_err; + } + + goto p_skip_module_ctrl; + } + subdev_module = device->subdev_module; if (!subdev_module) { merr("subdev_module is NULL", device); @@ -853,6 +870,7 @@ static int fimc_is_sensor_start(struct fimc_is_device_sensor *device) } set_bit(FIMC_IS_SENSOR_WAIT_STREAMING, &device->state); +p_skip_module_ctrl: p_err: return ret; } @@ -868,6 +886,23 @@ static int fimc_is_sensor_stop(struct fimc_is_device_sensor *device) FIMC_BUG(!device); + if (sysfs_debug.pattern_en) { + struct v4l2_subdev *subdev_csi; + + subdev_csi = device->subdev_csi; + if (!subdev_csi) + mwarn("subdev_csi is NULL", device); + + ret = v4l2_subdev_call(subdev_csi, core, ioctl, SENSOR_IOCTL_PATTERN_DISABLE, NULL); + if (ret) { + mwarn("v4l2_csi_call(ioctl) is fail(%d)", device, ret); + ret = -EINVAL; + goto p_err; + } + + goto p_skip_module_ctrl; + } + while (--retry && test_bit(FIMC_IS_SENSOR_WAIT_STREAMING, &device->state)) { mwarn(" waiting first pixel..\n", device); usleep_range(3000, 3100); @@ -897,6 +932,7 @@ static int fimc_is_sensor_stop(struct fimc_is_device_sensor *device) ret = -EINVAL; } +p_skip_module_ctrl: if (!test_bit(FIMC_IS_SENSOR_STAND_ALONE, &device->state)) { struct fimc_is_device_ischain *ischain; @@ -3252,16 +3288,14 @@ int fimc_is_sensor_front_start(struct fimc_is_device_sensor *device, device->image.window.width, device->image.window.height); - if (!sysfs_debug.pattern_en) { - if (nonblock) { - schedule_work(&device->instant_work); - } else { - fimc_is_sensor_instanton(&device->instant_work); - if (device->instant_ret) { - merr("fimc_is_sensor_instanton is fail(%d)", device, device->instant_ret); - ret = device->instant_ret; - goto p_err; - } + if (nonblock) { + schedule_work(&device->instant_work); + } else { + fimc_is_sensor_instanton(&device->instant_work); + if (device->instant_ret) { + merr("fimc_is_sensor_instanton is fail(%d)", device, device->instant_ret); + ret = device->instant_ret; + goto p_err; } } @@ -3288,11 +3322,9 @@ int fimc_is_sensor_front_stop(struct fimc_is_device_sensor *device) subdev_csi = device->subdev_csi; - if (!sysfs_debug.pattern_en) { - ret = fimc_is_sensor_stop(device); - if (ret) - merr("sensor stream off is failed(%d)\n", device, ret); - } + ret = fimc_is_sensor_stop(device); + if (ret) + merr("sensor stream off is failed(%d)\n", device, ret); ret = v4l2_subdev_call(subdev_csi, video, s_stream, IS_DISABLE_STREAM); if (ret) -- 2.20.1