[RFC v2 3/6] media: fimc-lite: Adding support for Exynos5
Shaik Ameer Basha
shaik.ameer at samsung.com
Wed Apr 24 17:41:10 EST 2013
FIMC-LITE supports multiple DMA shadow registers from Exynos5 onwards.
This patch adds the functionality of using shadow registers by
checking the driver data.
Signed-off-by: Shaik Ameer Basha <shaik.ameer at samsung.com>
---
drivers/media/platform/exynos4-is/fimc-lite-reg.c | 13 +++++++
drivers/media/platform/exynos4-is/fimc-lite-reg.h | 41 ++++++++++++++++++++-
drivers/media/platform/exynos4-is/fimc-lite.c | 12 ++++--
3 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
index 8cc0d39..a1d566a 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
@@ -215,6 +215,18 @@ void flite_hw_set_camera_bus(struct fimc_lite *dev,
flite_hw_set_camera_port(dev, si->mux_id);
}
+static void flite_hw_set_pack12(struct fimc_lite *dev, int on)
+{
+ u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
+
+ cfg &= ~FLITE_REG_CIODMAFMT_PACK12;
+
+ if (on)
+ cfg |= FLITE_REG_CIODMAFMT_PACK12;
+
+ writel(cfg, dev->regs + FLITE_REG_CIODMAFMT);
+}
+
static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
{
static const u32 pixcode[4][2] = {
@@ -267,6 +279,7 @@ void flite_hw_set_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);
}
void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
index 3903839..8e57e7a 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
@@ -120,6 +120,10 @@
/* b0: 1 - camera B, 0 - camera A */
#define FLITE_REG_CIGENERAL_CAM_B (1 << 0)
+
+#define FLITE_REG_CIFCNTSEQ 0x100
+#define FLITE_REG_CIOSAN(x) (0x200 + (4 * (x)))
+
/* ----------------------------------------------------------------------------
* Function declarations
*/
@@ -143,8 +147,41 @@ 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);
-static inline void flite_hw_set_output_addr(struct fimc_lite *dev, u32 paddr)
+static inline void flite_hw_set_output_addr(struct fimc_lite *dev,
+ u32 paddr, u32 index)
+{
+ u32 config;
+
+ /* FLITE in EXYNOS4 has only one DMA register */
+ if (!dev->dd->support_multi_dma_buf)
+ index = 0;
+
+ config = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
+ config |= 1 << index;
+ writel(config, dev->regs + FLITE_REG_CIFCNTSEQ);
+
+ if (index == 0)
+ writel(paddr, dev->regs + FLITE_REG_CIOSA);
+ else
+ writel(paddr, dev->regs + FLITE_REG_CIOSAN(index-1));
+}
+
+static inline void flite_hw_clear_output_addr(struct fimc_lite *dev, u32 index)
{
- writel(paddr, dev->regs + FLITE_REG_CIOSA);
+ u32 config;
+
+ /* FLITE in EXYNOS4 has only one DMA register */
+ if (!dev->dd->support_multi_dma_buf)
+ index = 0;
+
+ config = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
+ config &= ~(1 << index);
+ writel(config, dev->regs + FLITE_REG_CIFCNTSEQ);
}
+
+static inline void flite_hw_clear_output_index(struct fimc_lite *dev)
+{
+ writel(0, dev->regs + FLITE_REG_CIFCNTSEQ);
+}
+
#endif /* FIMC_LITE_REG_H */
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index cb173ec..1b12ea8 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -166,6 +166,8 @@ static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
if (fimc->inp_frame.fmt == NULL || fimc->out_frame.fmt == NULL)
return -EINVAL;
+ flite_hw_clear_output_index(fimc);
+
/* Get sensor configuration data from the sensor subdev */
si = v4l2_get_subdev_hostdata(fimc->sensor);
if (!si)
@@ -307,11 +309,12 @@ static irqreturn_t flite_irq_handler(int irq, void *priv)
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
+ flite_hw_clear_output_addr(fimc, vbuf->vb.v4l2_buf.index);
vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
vbuf = fimc_lite_pending_queue_pop(fimc);
- flite_hw_set_output_addr(fimc, vbuf->paddr);
- fimc_lite_active_queue_add(fimc, vbuf);
+ flite_hw_set_output_addr(fimc, vbuf->paddr,
+ vbuf->vb.v4l2_buf.index);
}
if (test_bit(ST_FLITE_CONFIG, &fimc->state))
@@ -439,7 +442,8 @@ static void buffer_queue(struct vb2_buffer *vb)
if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
!test_bit(ST_FLITE_STREAM, &fimc->state) &&
list_empty(&fimc->active_buf_q)) {
- flite_hw_set_output_addr(fimc, buf->paddr);
+ flite_hw_set_output_addr(fimc, buf->paddr,
+ buf->vb.v4l2_buf.index);
fimc_lite_active_queue_add(fimc, buf);
} else {
fimc_lite_pending_queue_add(fimc, buf);
@@ -643,7 +647,7 @@ static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
cap->bus_info[0] = 0;
cap->card[0] = 0;
- cap->capabilities = V4L2_CAP_STREAMING;
+ cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
return 0;
}
--
1.7.9.5
More information about the devicetree-discuss
mailing list