diff options
author | Beata Michalska <b.michalska@samsung.com> | 2014-11-07 18:20:07 +0100 |
---|---|---|
committer | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2014-11-27 03:27:46 -0800 |
commit | d9a9c28fe46be55d1ebc3c239fd7015d93a2e3d0 (patch) | |
tree | c64fee1dfd309129fae9f05679f868fa8994dec0 /drivers | |
parent | d6b8b5cc902f61c25c2e1181783df80caa7c2267 (diff) | |
download | linux-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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite-reg.c | 32 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite-reg.h | 10 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.c | 11 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.h | 3 |
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 { |