summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeata Michalska <b.michalska@samsung.com>2014-11-07 18:20:07 +0100
committerSylwester Nawrocki <s.nawrocki@samsung.com>2014-11-27 03:27:46 -0800
commitd9a9c28fe46be55d1ebc3c239fd7015d93a2e3d0 (patch)
treec64fee1dfd309129fae9f05679f868fa8994dec0
parentd6b8b5cc902f61c25c2e1181783df80caa7c2267 (diff)
downloadlinux-3.10-d9a9c28fe46be55d1ebc3c239fd7015d93a2e3d0.tar.gz
linux-3.10-d9a9c28fe46be55d1ebc3c239fd7015d93a2e3d0.tar.bz2
linux-3.10-d9a9c28fe46be55d1ebc3c239fd7015d93a2e3d0.zip
exynos: fimc-lite: Add support for exynos3250
Add support for enabling/disabling local output path along with disabling interrupts upon capture being stopped. Change-Id: I8ed2e100138f567dbd10c2eb5083b12110a3c799 Signed-off-by: Beata Michalska <b.michalska@samsung.com>
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite-reg.c32
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite-reg.h10
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c11
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.h3
4 files changed, 45 insertions, 11 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
index 72a343e3b5e..6df640d9e13 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
@@ -83,6 +83,14 @@ void flite_hw_set_interrupt_mask(struct fimc_lite *dev)
writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
}
+
+void flite_hw_clear_interrupt_mask(struct fimc_lite *dev)
+{
+ u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
+ cfg |= FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK;
+ writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
+}
+
void flite_hw_capture_start(struct fimc_lite *dev)
{
u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
@@ -296,21 +304,29 @@ void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index)
writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
}
-/* Enable/disable output DMA, set output pixel size and offsets (composition) */
-void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
- bool enable)
+/* Enable/disable DMA/local output path */
+void flite_hw_set_output_path(struct fimc_lite* dev, bool dma, bool local)
{
u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- if (!enable) {
- cfg |= FLITE_REG_CIGCTRL_ODMA_DISABLE;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
- return;
+ if (dev->dd->has_out_local_enable) {
+ if (local)
+ cfg &= ~FLITE_REG_CIGCTRL_OUT_LOCAL_DISABLE;
+ else
+ cfg |= FLITE_REG_CIGCTRL_OUT_LOCAL_DISABLE;
}
- cfg &= ~FLITE_REG_CIGCTRL_ODMA_DISABLE;
+ if (dma)
+ cfg &= ~FLITE_REG_CIGCTRL_ODMA_DISABLE;
+ else
+ cfg |= FLITE_REG_CIGCTRL_ODMA_DISABLE;
+
writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
+}
+/* Configure output DMA, set output pixel size and offsets (composition) */
+void flite_hw_configure_output_dma(struct fimc_lite *dev, struct flite_frame *f)
+{
flite_hw_set_out_order(dev, f);
flite_hw_set_dma_window(dev, f);
flite_hw_set_pack12(dev, 0);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
index 10a7d7bbcc2..da100f8b11b 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
@@ -30,6 +30,7 @@
/* User defined formats. x = 0...15 */
#define FLITE_REG_CIGCTRL_USER(x) ((0x30 + x - 1) << 24)
#define FLITE_REG_CIGCTRL_FMT_MASK (0x3f << 24)
+#define FLITE_REG_CIGCTRL_OUT_LOCAL_DISABLE (1 << 22)
#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE (1 << 21)
#define FLITE_REG_CIGCTRL_ODMA_DISABLE (1 << 20)
#define FLITE_REG_CIGCTRL_SWRST_REQ (1 << 19)
@@ -111,6 +112,10 @@
#define FLITE_REG_CISTATUS2_LASTCAPEND (1 << 1)
#define FLITE_REG_CISTATUS2_FRMEND (1 << 0)
+/* Camera Status3 */
+#define FLITE_REG_CISTATUS3 0x48
+#define FLITE_REG_CISTATUS3_PRESENT_MASK 0x3f
+
/* Qos Threshold */
#define FLITE_REG_CITHOLD 0xf0
#define FLITE_REG_CITHOLD_W_QOS_EN (1 << 30)
@@ -131,6 +136,7 @@ void flite_hw_clear_pending_irq(struct fimc_lite *dev);
u32 flite_hw_get_interrupt_source(struct fimc_lite *dev);
void flite_hw_clear_last_capture_end(struct fimc_lite *dev);
void flite_hw_set_interrupt_mask(struct fimc_lite *dev);
+void flite_hw_clear_interrupt_mask(struct fimc_lite *dev);
void flite_hw_capture_start(struct fimc_lite *dev);
void flite_hw_capture_stop(struct fimc_lite *dev);
void flite_hw_set_camera_bus(struct fimc_lite *dev,
@@ -140,8 +146,8 @@ void flite_hw_set_camera_polarity(struct fimc_lite *dev,
void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f);
void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f);
-void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
- bool enable);
+void flite_hw_configure_output_dma(struct fimc_lite *dev, struct flite_frame *f);
+void flite_hw_set_output_path(struct fimc_lite *dev, bool dma, bool local);
void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 04ee8918722..76a194119e7 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -161,7 +161,10 @@ static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
flite_hw_set_source_format(fimc, &fimc->inp_frame);
flite_hw_set_window_offset(fimc, &fimc->inp_frame);
flite_hw_set_dma_buf_mask(fimc, 0);
- flite_hw_set_output_dma(fimc, &fimc->out_frame, !isp_output);
+ flite_hw_set_output_path(fimc, !isp_output, isp_output);
+ if (!isp_output)
+ flite_hw_configure_output_dma(fimc, &fimc->out_frame);
+ flite_hw_clear_last_capture_end(fimc);
flite_hw_set_interrupt_mask(fimc);
flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
@@ -1259,6 +1262,9 @@ static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
set_bit(ST_FLITE_OFF, &fimc->state);
spin_lock_irqsave(&fimc->slock, flags);
+ /* Make sure both output DMA and local FIFO are disabled */
+ flite_hw_set_output_path(fimc, false, false);
+ flite_hw_set_dma_buf_mask(fimc, 0);
flite_hw_capture_stop(fimc);
spin_unlock_irqrestore(&fimc->slock, flags);
@@ -1268,6 +1274,7 @@ static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
if (ret == 0)
v4l2_err(sd, "s_stream(0) timeout\n");
clear_bit(ST_FLITE_RUN, &fimc->state);
+ flite_hw_clear_interrupt_mask(fimc);
}
mutex_unlock(&fimc->lock);
@@ -1678,6 +1685,7 @@ static struct flite_drvdata fimc_lite_drvdata_exynos3250 = {
.out_hor_offs_align = 8,
.max_dma_bufs = 32,
.num_instances = 2,
+ .has_out_local_enable = 1,
};
/* EXYNOS4212, EXYNOS4412 */
@@ -1700,6 +1708,7 @@ static struct flite_drvdata fimc_lite_drvdata_exynos5 = {
.out_hor_offs_align = 8,
.max_dma_bufs = 32,
.num_instances = 3,
+ .has_out_local_enable = 1,
};
static const struct of_device_id flite_of_match[] = {
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
index 7428b2d22b5..ed338f686aa 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite.h
@@ -61,6 +61,8 @@ enum {
* offset alignment in pixels
* @max_dma_bufs: number of output DMA buffer start address registers
* @num_instances: total number of FIMC-LITE IP instances available
+ * @has_out_local_enable: set to 1 if this IP block supports
+ * OutLocalEnable bit in CIGCTRL register
*/
struct flite_drvdata {
unsigned short max_width;
@@ -70,6 +72,7 @@ struct flite_drvdata {
unsigned short out_hor_offs_align;
unsigned short max_dma_bufs;
unsigned short num_instances;
+ unsigned int has_out_local_enable:1;
};
struct fimc_lite_events {