aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/exynos
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/exynos')
-rw-r--r--drivers/media/video/exynos/fimc-is/fimc-is-core.c15
-rw-r--r--drivers/media/video/exynos/fimc-is/fimc-is-core.h26
-rw-r--r--drivers/media/video/exynos/fimc-is/fimc-is-helper.c85
-rw-r--r--drivers/media/video/exynos/fimc-is/fimc-is-param.h12
-rw-r--r--drivers/media/video/exynos/fimc-is/fimc-is-v4l2.c14
-rw-r--r--drivers/media/video/exynos/fimc-is/fimc-is-video.c22
-rw-r--r--drivers/media/video/exynos/fimc-lite/fimc-lite-core.c14
7 files changed, 161 insertions, 27 deletions
diff --git a/drivers/media/video/exynos/fimc-is/fimc-is-core.c b/drivers/media/video/exynos/fimc-is/fimc-is-core.c
index 59da8d1..58b0fbc 100644
--- a/drivers/media/video/exynos/fimc-is/fimc-is-core.c
+++ b/drivers/media/video/exynos/fimc-is/fimc-is-core.c
@@ -357,6 +357,10 @@ static int fimc_is_probe(struct platform_device *pdev)
snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
"%s.isp", dev_name(&dev->pdev->dev));
ret = v4l2_device_register(NULL, v4l2_dev);
+ if (ret) {
+ v4l2_err(v4l2_dev, "Failed to register v4l2 device\n");
+ goto err_vd_reg;
+ }
snprintf(dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.name,
sizeof(dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.name),
@@ -385,10 +389,8 @@ static int fimc_is_probe(struct platform_device *pdev)
ret = video_register_device(&dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd,
VFL_TYPE_GRABBER, 30);
- if (ret) {
- v4l2_err(v4l2_dev, "Failed to register video device\n");
- goto err_vd_reg;
- }
+ if (ret)
+ goto p_err_device_register;
printk(KERN_INFO "FIMC-IS Video node :: ISP %d minor : %d\n",
dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.num,
@@ -412,6 +414,7 @@ static int fimc_is_probe(struct platform_device *pdev)
dev->pdata->clk_get(pdev);
} else {
err("#### failed to Get Clock####\n");
+ ret = -EINVAL;
goto p_err_init_mem;
}
/* Init v4l2 sub device */
@@ -464,11 +467,11 @@ static int fimc_is_probe(struct platform_device *pdev)
return 0;
p_err_init_mem:
- free_irq(dev->irq1, dev);
#if defined(CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER)
err_vd_reg:
- video_device_release(&dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd);
+p_err_device_register:
#endif
+ free_irq(dev->irq1, dev);
p_err_req_irq:
p_err_get_irq:
iounmap(dev->regs);
diff --git a/drivers/media/video/exynos/fimc-is/fimc-is-core.h b/drivers/media/video/exynos/fimc-is/fimc-is-core.h
index 1309e96..82be1a1 100644
--- a/drivers/media/video/exynos/fimc-is/fimc-is-core.h
+++ b/drivers/media/video/exynos/fimc-is/fimc-is-core.h
@@ -63,7 +63,7 @@
#define FIMC_IS_A5_MEM_SIZE 0x00A00000
#define FIMC_IS_REGION_SIZE 0x5000
-#define FIMC_IS_DEBUG_REGION_ADDR 0x00840000
+#define FIMC_IS_DEBUG_REGION_ADDR 0x0084B000
#define FIMC_IS_SHARED_REGION_ADDR 0x008C0000
#define FIMC_IS_FW_INFO_LENGTH 32
#define FIMC_IS_FW_VERSION_LENGTH 7
@@ -77,13 +77,23 @@
#define GED_FD_RANGE 1000
-#define BUS_LOCK_FREQ_L0 400200
-#define BUS_LOCK_FREQ_L1 267200
-#define BUS_LOCK_FREQ_L2 267160
-#define BUS_LOCK_FREQ_L3 160160
-#define BUS_LOCK_FREQ_L4 133133
-#define BUS_LOCK_FREQ_L5 100100
-
+#ifdef CONFIG_MACH_T0
+#define BUS_LOCK_FREQ_L0 440293
+#define BUS_LOCK_FREQ_L1 440220
+#define BUS_LOCK_FREQ_L2 293220
+#define BUS_LOCK_FREQ_L3 293176
+#define BUS_LOCK_FREQ_L4 176176
+#define BUS_LOCK_FREQ_L5 147147
+#define BUS_LOCK_FREQ_L6 110110
+#else
+#define BUS_LOCK_FREQ_L0 400266
+#define BUS_LOCK_FREQ_L1 400200
+#define BUS_LOCK_FREQ_L2 267200
+#define BUS_LOCK_FREQ_L3 267160
+#define BUS_LOCK_FREQ_L4 160160
+#define BUS_LOCK_FREQ_L5 133133
+#define BUS_LOCK_FREQ_L6 100100
+#endif
/* A5 debug message setting */
#define FIMC_IS_DEBUG_MSG 0x3F
#define FIMC_IS_DEBUG_LEVEL 3
diff --git a/drivers/media/video/exynos/fimc-is/fimc-is-helper.c b/drivers/media/video/exynos/fimc-is/fimc-is-helper.c
index ef0d163..8cac853 100644
--- a/drivers/media/video/exynos/fimc-is/fimc-is-helper.c
+++ b/drivers/media/video/exynos/fimc-is/fimc-is-helper.c
@@ -31,6 +31,7 @@
#include <linux/gpio.h>
#include <linux/gpio_event.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
#include "fimc-is-core.h"
#include "fimc-is-regs.h"
@@ -1039,18 +1040,46 @@ void fimc_is_hw_open_sensor(struct fimc_is_dev *dev, u32 id, u32 sensor_index)
writel(id, dev->regs + ISSR1);
switch (sensor_index) {
case SENSOR_S5K3H2_CSI_A:
+ sensor_ext = (struct sensor_open_extended *)
+ &dev->is_p_region->shared;
+ sensor_ext->actuator_type = 1;
+ sensor_ext->mclk = 0;
+ sensor_ext->mipi_lane_num = 0;
+ sensor_ext->mipi_speed = 0;
+ sensor_ext->fast_open_sensor = 0;
+ sensor_ext->self_calibration_mode = 0;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
+ fimc_is_mem_cache_clean((void *)dev->is_p_region,
+ IS_PARAM_SIZE);
dev->af.use_af = 1;
dev->sensor.sensor_type = SENSOR_S5K3H2_CSI_A;
writel(SENSOR_NAME_S5K3H2, dev->regs + ISSR2);
writel(SENSOR_CONTROL_I2C0, dev->regs + ISSR3);
- writel(0x0, dev->regs + ISSR4);
+ writel(virt_to_phys(sensor_ext), dev->regs + ISSR4);
break;
case SENSOR_S5K3H2_CSI_B:
+ sensor_ext = (struct sensor_open_extended *)
+ &dev->is_p_region->shared;
+ sensor_ext->actuator_type = 1;
+ sensor_ext->mclk = 0;
+ sensor_ext->mipi_lane_num = 0;
+ sensor_ext->mipi_speed = 0;
+ sensor_ext->fast_open_sensor = 0;
+ sensor_ext->self_calibration_mode = 0;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
+ fimc_is_mem_cache_clean((void *)dev->is_p_region,
+ IS_PARAM_SIZE);
dev->af.use_af = 1;
dev->sensor.sensor_type = SENSOR_S5K3H2_CSI_B;
writel(SENSOR_NAME_S5K3H2, dev->regs + ISSR2);
writel(SENSOR_CONTROL_I2C1, dev->regs + ISSR3);
- writel(0x0, dev->regs + ISSR4);
+ writel(virt_to_phys(sensor_ext), dev->regs + ISSR4);
break;
case SENSOR_S5K6A3_CSI_A:
sensor_ext = (struct sensor_open_extended *)
@@ -1061,6 +1090,10 @@ void fimc_is_hw_open_sensor(struct fimc_is_dev *dev, u32 id, u32 sensor_index)
sensor_ext->mipi_speed = 0;
sensor_ext->fast_open_sensor = 0;
sensor_ext->self_calibration_mode = 1;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
fimc_is_mem_cache_clean((void *)dev->is_p_region,
IS_PARAM_SIZE);
dev->af.use_af = 0;
@@ -1078,6 +1111,10 @@ void fimc_is_hw_open_sensor(struct fimc_is_dev *dev, u32 id, u32 sensor_index)
sensor_ext->mipi_speed = 0;
sensor_ext->fast_open_sensor = 0;
sensor_ext->self_calibration_mode = 1;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
fimc_is_mem_cache_clean((void *)dev->is_p_region,
IS_PARAM_SIZE);
dev->af.use_af = 0;
@@ -1095,6 +1132,10 @@ void fimc_is_hw_open_sensor(struct fimc_is_dev *dev, u32 id, u32 sensor_index)
sensor_ext->mipi_speed = 0;
sensor_ext->fast_open_sensor = 0;
sensor_ext->self_calibration_mode = 0;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
fimc_is_mem_cache_clean((void *)dev->is_p_region,
IS_PARAM_SIZE);
dev->af.use_af = 1;
@@ -1112,6 +1153,10 @@ void fimc_is_hw_open_sensor(struct fimc_is_dev *dev, u32 id, u32 sensor_index)
sensor_ext->mipi_speed = 0;
sensor_ext->fast_open_sensor = 0;
sensor_ext->self_calibration_mode = 0;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
fimc_is_mem_cache_clean((void *)dev->is_p_region,
IS_PARAM_SIZE);
dev->af.use_af = 1;
@@ -1121,18 +1166,46 @@ void fimc_is_hw_open_sensor(struct fimc_is_dev *dev, u32 id, u32 sensor_index)
writel(virt_to_phys(sensor_ext), dev->regs + ISSR4);
break;
case SENSOR_S5K4E5_CSI_A:
+ sensor_ext = (struct sensor_open_extended *)
+ &dev->is_p_region->shared;
+ sensor_ext->actuator_type = 1;
+ sensor_ext->mclk = 0;
+ sensor_ext->mipi_lane_num = 0;
+ sensor_ext->mipi_speed = 0;
+ sensor_ext->fast_open_sensor = 0;
+ sensor_ext->self_calibration_mode = 0;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
+ fimc_is_mem_cache_clean((void *)dev->is_p_region,
+ IS_PARAM_SIZE);
dev->af.use_af = 1;
dev->sensor.sensor_type = SENSOR_S5K4E5_CSI_A;
writel(SENSOR_NAME_S5K4E5, dev->regs + ISSR2);
writel(SENSOR_CONTROL_I2C0, dev->regs + ISSR3);
- writel(0x0, dev->regs + ISSR4);
+ writel(virt_to_phys(sensor_ext), dev->regs + ISSR4);
break;
case SENSOR_S5K4E5_CSI_B:
+ sensor_ext = (struct sensor_open_extended *)
+ &dev->is_p_region->shared;
+ sensor_ext->actuator_type = 1;
+ sensor_ext->mclk = 0;
+ sensor_ext->mipi_lane_num = 0;
+ sensor_ext->mipi_speed = 0;
+ sensor_ext->fast_open_sensor = 0;
+ sensor_ext->self_calibration_mode = 0;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
+ fimc_is_mem_cache_clean((void *)dev->is_p_region,
+ IS_PARAM_SIZE);
dev->af.use_af = 1;
dev->sensor.sensor_type = SENSOR_S5K4E5_CSI_B;
writel(SENSOR_NAME_S5K4E5, dev->regs + ISSR2);
writel(SENSOR_CONTROL_I2C1, dev->regs + ISSR3);
- writel(0x0, dev->regs + ISSR4);
+ writel(virt_to_phys(sensor_ext), dev->regs + ISSR4);
break;
case SENSOR_S5K6A3_CSI_B_CUSTOM:
sensor_ext = (struct sensor_open_extended *)
@@ -1143,6 +1216,10 @@ void fimc_is_hw_open_sensor(struct fimc_is_dev *dev, u32 id, u32 sensor_index)
sensor_ext->mipi_speed = 0;
sensor_ext->fast_open_sensor = 6;
sensor_ext->self_calibration_mode = 1;
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ sensor_ext->i2c_sclk = 88000000;
+ else
+ sensor_ext->i2c_sclk = 80000000;
fimc_is_mem_cache_clean((void *)dev->is_p_region,
IS_PARAM_SIZE);
dev->af.use_af = 0;
diff --git a/drivers/media/video/exynos/fimc-is/fimc-is-param.h b/drivers/media/video/exynos/fimc-is/fimc-is-param.h
index 9383c4a..b978e16 100644
--- a/drivers/media/video/exynos/fimc-is/fimc-is-param.h
+++ b/drivers/media/video/exynos/fimc-is/fimc-is-param.h
@@ -14,7 +14,7 @@
#ifndef FIMC_IS_PARAMS_H_
#define FIMC_IS_PARAMS_H_
-#define IS_REGION_VER 122 /* IS REGION VERSION 1.22 */
+#define IS_REGION_VER 124 /* IS REGION VERSION 1.24 */
/* MACROs */
#define IS_SET_PARAM_BIT(dev, num) \
@@ -237,6 +237,8 @@
(dev->is_p_region->parameter.isp.dma1_output.buffer_address = x)
#define IS_ISP_SET_PARAM_DMA_OUTPUT1_NODIFY_DMA_DONE(dev, x) \
(dev->is_p_region->parameter.isp.dma1_output.notify_dma_done = x)
+#define IS_ISP_SET_PARAM_DMA_OUTPUT1_MASK(dev, x) \
+ (dev->is_p_region->parameter.isp.dma1_output.dma_out_mask = x)
#define IS_ISP_SET_PARAM_DMA_OUTPUT1_ERR(dev, x) \
(dev->is_p_region->parameter.isp.dma1_output.err = x)
@@ -260,6 +262,8 @@
(dev->is_p_region->parameter.isp.dma2_output.buffer_address = x)
#define IS_ISP_SET_PARAM_DMA_OUTPUT2_NODIFY_DMA_DONE(dev, x) \
(dev->is_p_region->parameter.isp.dma2_output.notify_dma_done = x)
+#define IS_ISP_SET_PARAM_DMA_OUTPUT2_MASK(dev, x) \
+ (dev->is_p_region->parameter.isp.dma2_output.dma_out_mask = x)
#define IS_ISP_SET_PARAM_DMA_OUTPUT2_ERR(dev, x) \
(dev->is_p_region->parameter.isp.dma2_output.err = x)
@@ -1228,7 +1232,8 @@ struct param_dma_output {
u32 buffer_number;
u32 buffer_address;
u32 notify_dma_done;
- u32 reserved[PARAMETER_MAX_MEMBER-11];
+ u32 dma_out_mask;
+ u32 reserved[PARAMETER_MAX_MEMBER-12];
u32 err;
};
@@ -1697,5 +1702,8 @@ struct sensor_open_extended {
u32 fast_open_sensor;
/* Activatiing sensor self calibration mode (6A3) */
u32 self_calibration_mode;
+ /* This field is to adjust I2c clock based on ACLK200 */
+ /* This value is varied in case of rev 0.2 */
+ u32 i2c_sclk;
};
#endif
diff --git a/drivers/media/video/exynos/fimc-is/fimc-is-v4l2.c b/drivers/media/video/exynos/fimc-is/fimc-is-v4l2.c
index aa60198..066885f 100644
--- a/drivers/media/video/exynos/fimc-is/fimc-is-v4l2.c
+++ b/drivers/media/video/exynos/fimc-is/fimc-is-v4l2.c
@@ -373,7 +373,7 @@ int fimc_is_s_power(struct v4l2_subdev *sd, int on)
}
#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER)
/* lock bus frequency */
- dev_lock(is_dev->bus_dev, dev, BUS_LOCK_FREQ_L0);
+ dev_lock(is_dev->bus_dev, dev, BUS_LOCK_FREQ_L1);
#endif
fimc_is_hw_set_low_poweroff(is_dev, false);
ret = pm_runtime_get_sync(dev);
@@ -618,7 +618,7 @@ static int fimc_is_reset(struct v4l2_subdev *sd, u32 val)
/* Restart */
#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER)
/* lock bus frequency */
- dev_lock(is_dev->bus_dev, dev, BUS_LOCK_FREQ_L0);
+ dev_lock(is_dev->bus_dev, dev, BUS_LOCK_FREQ_L1);
#endif
fimc_is_hw_set_low_poweroff(is_dev, false);
ret = pm_runtime_get_sync(dev);
@@ -816,6 +816,16 @@ static int fimc_is_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_IS_FW_DEBUG_REGION_ADDR:
ctrl->value = dev->mem.base + FIMC_IS_DEBUG_REGION_ADDR;
break;
+#if defined(CONFIG_SLP)
+#define FRONT_CAM_STANDARD_REVISION 0x0b
+ case V4L2_CID_PHYSICAL_ROTATION:
+ if (system_rev > FRONT_CAM_STANDARD_REVISION || \
+ system_rev == 0x04 || system_rev == 0x06)
+ ctrl->value = IS_ROTATION_270;
+ else
+ ctrl->value = IS_ROTATION_90;
+ break;
+#endif
default:
return -EINVAL;
}
diff --git a/drivers/media/video/exynos/fimc-is/fimc-is-video.c b/drivers/media/video/exynos/fimc-is/fimc-is-video.c
index 85080af..6b81bb9 100644
--- a/drivers/media/video/exynos/fimc-is/fimc-is-video.c
+++ b/drivers/media/video/exynos/fimc-is/fimc-is-video.c
@@ -45,6 +45,11 @@
static struct fimc_is_fmt fimc_is_formats[] = {
{
+ .name = "Bayer8",
+ .fourcc = V4L2_PIX_FMT_SGRBG8,
+ .flags = 1,
+ },
+ {
.name = "Bayer10",
.fourcc = V4L2_PIX_FMT_SGRBG10,
.flags = 1,
@@ -233,6 +238,21 @@ static int fimc_is_isp_video_s_fmt_mplane(struct file *file, void *priv,
pix = &f->fmt.pix_mp;
switch (f->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_SGRBG8:
+ width = pix->width - is_dev->sensor.offset_x;
+ height = pix->height - is_dev->sensor.offset_y;
+ IS_ISP_SET_PARAM_DMA_OUTPUT2_CMD(is_dev,
+ DMA_OUTPUT_COMMAND_DISABLE);
+ IS_ISP_SET_PARAM_DMA_OUTPUT2_WIDTH(is_dev, width);
+ IS_ISP_SET_PARAM_DMA_OUTPUT2_HEIGHT(is_dev, height);
+ IS_ISP_SET_PARAM_DMA_OUTPUT2_FORMAT(is_dev,
+ DMA_OUTPUT_FORMAT_BAYER);
+ IS_ISP_SET_PARAM_DMA_OUTPUT2_BITWIDTH(is_dev,
+ DMA_OUTPUT_BIT_WIDTH_8BIT);
+ IS_ISP_SET_PARAM_DMA_OUTPUT2_PLANE(is_dev, DMA_OUTPUT_PLANE_1);
+ IS_ISP_SET_PARAM_DMA_OUTPUT2_ORDER(is_dev,
+ DMA_OUTPUT_ORDER_GB_BG);
+ break;
case V4L2_PIX_FMT_SGRBG10:
width = pix->width - is_dev->sensor.offset_x;
height = pix->height - is_dev->sensor.offset_y;
@@ -518,6 +538,8 @@ static int fimc_is_isp_start_streaming(struct vb2_queue *q)
+ 32 * sizeof(u32));
IS_ISP_SET_PARAM_DMA_OUTPUT2_NODIFY_DMA_DONE(is_dev,
DMA_OUTPUT_NOTIFY_DMA_DONE_ENBABLE);
+ /* All buffers are available to write image data */
+ IS_ISP_SET_PARAM_DMA_OUTPUT2_MASK(is_dev, 0xFFFFFFFF);
IS_SET_PARAM_BIT(is_dev, PARAM_ISP_DMA2_OUTPUT);
IS_INC_PARAM_NUM(is_dev);
diff --git a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c
index eddbf1d..011787c 100644
--- a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c
+++ b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c
@@ -2021,7 +2021,7 @@ static int flite_probe(struct platform_device *pdev)
pdev->name);
if (!regs_res) {
dev_err(&pdev->dev, "Failed to request io memory region\n");
- goto err_resource;
+ goto err_flite;
}
flite->regs_res = regs_res;
@@ -2044,8 +2044,10 @@ static int flite_probe(struct platform_device *pdev)
}
sd = kzalloc(sizeof(*sd), GFP_KERNEL);
- if (!sd)
- goto err_irq;
+ if (!sd) {
+ ret = -ENOMEM;
+ goto err_irq;
+ }
v4l2_subdev_init(sd, &flite_subdev_ops);
snprintf(sd->name, sizeof(sd->name), "flite-subdev.%d", flite->id);
@@ -2062,13 +2064,13 @@ static int flite_probe(struct platform_device *pdev)
mutex_init(&flite->lock);
flite->mdev = flite_get_capture_md(MDEV_CAPTURE);
if (IS_ERR_OR_NULL(flite->mdev))
- goto err_irq;
+ goto err_device_register;
flite_dbg("mdev = 0x%08x", (u32)flite->mdev);
ret = flite_register_video_device(flite);
if (ret)
- goto err_irq;
+ goto err_device_register;
/* Get mipi-csis subdev ptr using mdev */
flite->sd_csis = flite->mdev->csis_sd[flite->id];
@@ -2130,6 +2132,8 @@ err_vfd_alloc:
media_entity_cleanup(&flite->vfd->entity);
video_device_release(flite->vfd);
#endif
+err_device_register:
+ kfree(sd);
err_irq:
free_irq(flite->irq, flite);
err_reg_unmap: