[media] atmel-isi: prepare for the support of preview path
authorJosh Wu <josh.wu@atmel.com>
Tue, 3 Nov 2015 05:45:09 +0000 (03:45 -0200)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 17 Nov 2015 17:29:19 +0000 (15:29 -0200)
Atmel ISI support a preview path which can output RGB data.

So this patch introduces a bool variable to choose which path is
enabled currently. And also we need setup corresponding path registers.

By default the preview path is disabled. We only use Codec path.

Signed-off-by: Josh Wu <josh.wu@atmel.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/platform/soc_camera/atmel-isi.c

index 9c982e3b3f741a23732be1f5c72aaa75b36250f5..112a4b493bfec852bf3439398c181c77114c73c4 100644 (file)
@@ -79,6 +79,7 @@ struct atmel_isi {
        dma_addr_t                      fb_descriptors_phys;
        struct                          list_head dma_desc_head;
        struct isi_dma_desc             dma_desc[MAX_BUFFER_NUM];
+       bool                            enable_preview_path;
 
        struct completion               complete;
        /* ISI peripherial clock */
@@ -195,11 +196,19 @@ static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
                /* start next dma frame. */
                isi->active = list_entry(isi->video_buffer_list.next,
                                        struct frame_buffer, list);
-               isi_writel(isi, ISI_DMA_C_DSCR,
-                       (u32)isi->active->p_dma_desc->fbd_phys);
-               isi_writel(isi, ISI_DMA_C_CTRL,
-                       ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
-               isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
+               if (!isi->enable_preview_path) {
+                       isi_writel(isi, ISI_DMA_C_DSCR,
+                               (u32)isi->active->p_dma_desc->fbd_phys);
+                       isi_writel(isi, ISI_DMA_C_CTRL,
+                               ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
+                       isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
+               } else {
+                       isi_writel(isi, ISI_DMA_P_DSCR,
+                               (u32)isi->active->p_dma_desc->fbd_phys);
+                       isi_writel(isi, ISI_DMA_P_CTRL,
+                               ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
+                       isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
+               }
        }
        return IRQ_HANDLED;
 }
@@ -226,7 +235,8 @@ static irqreturn_t isi_interrupt(int irq, void *dev_id)
                isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
                ret = IRQ_HANDLED;
        } else {
-               if (likely(pending & ISI_SR_CXFR_DONE))
+               if (likely(pending & ISI_SR_CXFR_DONE) ||
+                               likely(pending & ISI_SR_PXFR_DONE))
                        ret = atmel_isi_handle_streaming(isi);
        }
 
@@ -371,21 +381,35 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
                        ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
 
        /* Check if already in a frame */
-       if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
-               dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
-               return;
-       }
+       if (!isi->enable_preview_path) {
+               if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
+                       dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
+                       return;
+               }
 
-       isi_writel(isi, ISI_DMA_C_DSCR, (u32)buffer->p_dma_desc->fbd_phys);
-       isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
-       isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
+               isi_writel(isi, ISI_DMA_C_DSCR,
+                               (u32)buffer->p_dma_desc->fbd_phys);
+               isi_writel(isi, ISI_DMA_C_CTRL,
+                               ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
+               isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
+       } else {
+               isi_writel(isi, ISI_DMA_P_DSCR,
+                               (u32)buffer->p_dma_desc->fbd_phys);
+               isi_writel(isi, ISI_DMA_P_CTRL,
+                               ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
+               isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH);
+       }
 
        cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
        /* Enable linked list */
        cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
 
-       /* Enable codec path and ISI */
-       ctrl = ISI_CTRL_CDC | ISI_CTRL_EN;
+       /* Enable ISI */
+       ctrl = ISI_CTRL_EN;
+
+       if (!isi->enable_preview_path)
+               ctrl |= ISI_CTRL_CDC;
+
        isi_writel(isi, ISI_CTRL, ctrl);
        isi_writel(isi, ISI_CFG1, cfg1);
 }
@@ -462,15 +486,17 @@ static void stop_streaming(struct vb2_queue *vq)
        }
        spin_unlock_irq(&isi->lock);
 
-       timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
-       /* Wait until the end of the current frame. */
-       while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
-                       time_before(jiffies, timeout))
-               msleep(1);
+       if (!isi->enable_preview_path) {
+               timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
+               /* Wait until the end of the current frame. */
+               while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
+                               time_before(jiffies, timeout))
+                       msleep(1);
 
-       if (time_after(jiffies, timeout))
-               dev_err(icd->parent,
-                       "Timeout waiting for finishing codec request\n");
+               if (time_after(jiffies, timeout))
+                       dev_err(icd->parent,
+                               "Timeout waiting for finishing codec request\n");
+       }
 
        /* Disable interrupts */
        isi_writel(isi, ISI_INTDIS,