mirror of https://gitee.com/openkylin/linux.git
[media] atmel-isi: prepare for the support of preview path
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>
This commit is contained in:
parent
ba0422bf56
commit
0fb725750b
|
@ -79,6 +79,7 @@ struct atmel_isi {
|
||||||
dma_addr_t fb_descriptors_phys;
|
dma_addr_t fb_descriptors_phys;
|
||||||
struct list_head dma_desc_head;
|
struct list_head dma_desc_head;
|
||||||
struct isi_dma_desc dma_desc[MAX_BUFFER_NUM];
|
struct isi_dma_desc dma_desc[MAX_BUFFER_NUM];
|
||||||
|
bool enable_preview_path;
|
||||||
|
|
||||||
struct completion complete;
|
struct completion complete;
|
||||||
/* ISI peripherial clock */
|
/* ISI peripherial clock */
|
||||||
|
@ -195,11 +196,19 @@ static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
|
||||||
/* start next dma frame. */
|
/* start next dma frame. */
|
||||||
isi->active = list_entry(isi->video_buffer_list.next,
|
isi->active = list_entry(isi->video_buffer_list.next,
|
||||||
struct frame_buffer, list);
|
struct frame_buffer, list);
|
||||||
isi_writel(isi, ISI_DMA_C_DSCR,
|
if (!isi->enable_preview_path) {
|
||||||
(u32)isi->active->p_dma_desc->fbd_phys);
|
isi_writel(isi, ISI_DMA_C_DSCR,
|
||||||
isi_writel(isi, ISI_DMA_C_CTRL,
|
(u32)isi->active->p_dma_desc->fbd_phys);
|
||||||
ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
|
isi_writel(isi, ISI_DMA_C_CTRL,
|
||||||
isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
|
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;
|
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);
|
isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
|
||||||
ret = IRQ_HANDLED;
|
ret = IRQ_HANDLED;
|
||||||
} else {
|
} 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);
|
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);
|
ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
|
||||||
|
|
||||||
/* Check if already in a frame */
|
/* Check if already in a frame */
|
||||||
if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
|
if (!isi->enable_preview_path) {
|
||||||
dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
|
if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
|
||||||
return;
|
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_DSCR,
|
||||||
isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
|
(u32)buffer->p_dma_desc->fbd_phys);
|
||||||
isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
|
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;
|
cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK;
|
||||||
/* Enable linked list */
|
/* Enable linked list */
|
||||||
cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
|
cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR;
|
||||||
|
|
||||||
/* Enable codec path and ISI */
|
/* Enable ISI */
|
||||||
ctrl = ISI_CTRL_CDC | ISI_CTRL_EN;
|
ctrl = ISI_CTRL_EN;
|
||||||
|
|
||||||
|
if (!isi->enable_preview_path)
|
||||||
|
ctrl |= ISI_CTRL_CDC;
|
||||||
|
|
||||||
isi_writel(isi, ISI_CTRL, ctrl);
|
isi_writel(isi, ISI_CTRL, ctrl);
|
||||||
isi_writel(isi, ISI_CFG1, cfg1);
|
isi_writel(isi, ISI_CFG1, cfg1);
|
||||||
}
|
}
|
||||||
|
@ -462,15 +486,17 @@ static void stop_streaming(struct vb2_queue *vq)
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&isi->lock);
|
spin_unlock_irq(&isi->lock);
|
||||||
|
|
||||||
timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
|
if (!isi->enable_preview_path) {
|
||||||
/* Wait until the end of the current frame. */
|
timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
|
||||||
while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
|
/* Wait until the end of the current frame. */
|
||||||
time_before(jiffies, timeout))
|
while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
|
||||||
msleep(1);
|
time_before(jiffies, timeout))
|
||||||
|
msleep(1);
|
||||||
|
|
||||||
if (time_after(jiffies, timeout))
|
if (time_after(jiffies, timeout))
|
||||||
dev_err(icd->parent,
|
dev_err(icd->parent,
|
||||||
"Timeout waiting for finishing codec request\n");
|
"Timeout waiting for finishing codec request\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
isi_writel(isi, ISI_INTDIS,
|
isi_writel(isi, ISI_INTDIS,
|
||||||
|
|
Loading…
Reference in New Issue