From 16e9ab820ad43108513ec32bb18fb226df4cc7fc Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 3 May 2017 18:16:46 +0200 Subject: gpu: ipu-v3: prg: remove counter load enable The counter load enable bit has no effect when the shadow register set is activated. As we always operate the PRG with shadow enabled it is safe to remove this. Signed-off-by: Lucas Stach Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-prg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c index caca57febbd6..ecc9ea44dc50 100644 --- a/drivers/gpu/ipu-v3/ipu-prg.c +++ b/drivers/gpu/ipu-v3/ipu-prg.c @@ -318,8 +318,6 @@ int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan, writel(val, prg->regs + IPU_PRG_BADDR(prg_chan)); val = readl(prg->regs + IPU_PRG_CTL); - /* counter load enable */ - val |= IPU_PRG_CTL_CNT_LOAD_EN(prg_chan); /* config AXI ID */ val &= ~(IPU_PRG_CTL_SOFT_ARID_MASK << IPU_PRG_CTL_SOFT_ARID_SHIFT(prg_chan)); -- cgit v1.2.3 From e1e9733cd37908a9ba61e29154561f0c81420e06 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 17 Sep 2014 15:44:54 +0200 Subject: gpu: ipu-v3: Add support for double read/write reduction Allow to skip writing odd chroma rows by setting the RDRW bit for 4:2:0 chroma subsampled formats for any IDMAC write channel. This also allows to skip reading odd rows for the VDIC read channel. Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-cpmem.c | 6 ++++++ include/video/imx-ipu-v3.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c index 114160dfc3ad..1cb82f445f91 100644 --- a/drivers/gpu/ipu-v3/ipu-cpmem.c +++ b/drivers/gpu/ipu-v3/ipu-cpmem.c @@ -224,6 +224,12 @@ void ipu_cpmem_set_resolution(struct ipuv3_channel *ch, int xres, int yres) } EXPORT_SYMBOL_GPL(ipu_cpmem_set_resolution); +void ipu_cpmem_skip_odd_chroma_rows(struct ipuv3_channel *ch) +{ + ipu_ch_param_write_field(ch, IPU_FIELD_RDRW, 1); +} +EXPORT_SYMBOL_GPL(ipu_cpmem_skip_odd_chroma_rows); + void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride) { ipu_ch_param_write_field(ch, IPU_FIELD_SLY, stride - 1); diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index 8cb07680fb41..ce4c07688b13 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -250,6 +250,7 @@ struct ipu_image { void ipu_cpmem_zero(struct ipuv3_channel *ch); void ipu_cpmem_set_resolution(struct ipuv3_channel *ch, int xres, int yres); +void ipu_cpmem_skip_odd_chroma_rows(struct ipuv3_channel *ch); void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride); void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch); void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf); -- cgit v1.2.3 From 93adc8b5705c14d16be382d43699d2ba71248a4b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 May 2017 12:45:52 +0200 Subject: gpu: ipu-v3: allocate ipuv3_channels as needed Most of the 64 IPUv3 DMA channels are never used, some of them (channels 16, 30, 32, 34-39, and 53-63) are even marked as reserved. Allocate the channel control structure only when a channel is actually requested, replace the fixed size array with a list, and remove the unused enabled and busy fields from the ipuv3_channel structure. Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-common.c | 23 +++++++++++++++-------- drivers/gpu/ipu-v3/ipu-prv.h | 8 ++------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 16d556816b5f..61310f8be309 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -274,15 +274,22 @@ struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num) mutex_lock(&ipu->channel_lock); - channel = &ipu->channel[num]; + list_for_each_entry(channel, &ipu->channels, list) { + if (channel->num == num) { + channel = ERR_PTR(-EBUSY); + goto out; + } + } - if (channel->busy) { - channel = ERR_PTR(-EBUSY); + channel = kzalloc(sizeof(*channel), GFP_KERNEL); + if (!channel) { + channel = ERR_PTR(-ENOMEM); goto out; } - channel->busy = true; channel->num = num; + channel->ipu = ipu; + list_add(&channel->list, &ipu->channels); out: mutex_unlock(&ipu->channel_lock); @@ -299,7 +306,8 @@ void ipu_idmac_put(struct ipuv3_channel *channel) mutex_lock(&ipu->channel_lock); - channel->busy = false; + list_del(&channel->list); + kfree(channel); mutex_unlock(&ipu->channel_lock); } @@ -1376,7 +1384,7 @@ static int ipu_probe(struct platform_device *pdev) struct ipu_soc *ipu; struct resource *res; unsigned long ipu_base; - int i, ret, irq_sync, irq_err; + int ret, irq_sync, irq_err; const struct ipu_devtype *devtype; devtype = of_device_get_match_data(&pdev->dev); @@ -1409,13 +1417,12 @@ static int ipu_probe(struct platform_device *pdev) return -EPROBE_DEFER; } - for (i = 0; i < 64; i++) - ipu->channel[i].ipu = ipu; ipu->devtype = devtype; ipu->ipu_type = devtype->type; spin_lock_init(&ipu->lock); mutex_init(&ipu->channel_lock); + INIT_LIST_HEAD(&ipu->channels); dev_dbg(&pdev->dev, "cm_reg: 0x%08lx\n", ipu_base + devtype->cm_ofs); diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index ca2a223a0d1e..b6e22d64159f 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -157,11 +157,8 @@ enum ipu_modules { struct ipuv3_channel { unsigned int num; - - bool enabled; - bool busy; - struct ipu_soc *ipu; + struct list_head list; }; struct ipu_cpmem; @@ -184,6 +181,7 @@ struct ipu_soc { enum ipuv3_type ipu_type; spinlock_t lock; struct mutex channel_lock; + struct list_head channels; void __iomem *cm_reg; void __iomem *idmac_reg; @@ -193,8 +191,6 @@ struct ipu_soc { struct clk *clk; - struct ipuv3_channel channel[64]; - int irq_sync; int irq_err; struct irq_domain *domain; -- cgit v1.2.3 From ffb40733fe432b00fa12ff486364dcfe6d7f247c Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 15 May 2017 16:31:37 +0200 Subject: gpu: ipu-v3: remove interrupt busy waiting routine This is not used anymore since commit eb8c88808c83 ("drm/imx: add deferred plane disabling"), remove it. Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-common.c | 16 ---------------- drivers/gpu/ipu-v3/ipu-prv.h | 1 - 2 files changed, 17 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 61310f8be309..22e0a3eca7b1 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -597,22 +597,6 @@ int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms) } EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy); -int ipu_wait_interrupt(struct ipu_soc *ipu, int irq, int ms) -{ - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(ms); - ipu_cm_write(ipu, BIT(irq % 32), IPU_INT_STAT(irq / 32)); - while (!(ipu_cm_read(ipu, IPU_INT_STAT(irq / 32) & BIT(irq % 32)))) { - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - cpu_relax(); - } - - return 0; -} -EXPORT_SYMBOL_GPL(ipu_wait_interrupt); - int ipu_idmac_disable_channel(struct ipuv3_channel *channel) { struct ipu_soc *ipu = channel->ipu; diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index b6e22d64159f..ac4b8d658500 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -225,7 +225,6 @@ int ipu_module_enable(struct ipu_soc *ipu, u32 mask); int ipu_module_disable(struct ipu_soc *ipu, u32 mask); bool ipu_idmac_channel_busy(struct ipu_soc *ipu, unsigned int chno); -int ipu_wait_interrupt(struct ipu_soc *ipu, int irq, int ms); int ipu_csi_init(struct ipu_soc *ipu, struct device *dev, int id, unsigned long base, u32 module, struct clk *clk_ipu); -- cgit v1.2.3 From add1318723a0d7b1ec974d2d9ba309cc24bb298a Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Sun, 21 May 2017 15:02:10 -0700 Subject: gpu: ipu-v3: vdic: include AUTO field order bit in ipu_vdi_set_field_order The field order selection in VDIC_C register uses different bits depending on whether the VDIC is receiving from a CSI ("AUTO") or from memory ("MAN"). Since the VDIC cannot receive from both CSI and memory at the same time, set or clear both field order bits to cover both cases. Signed-off-by: Steve Longerbeam Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-vdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-vdi.c b/drivers/gpu/ipu-v3/ipu-vdi.c index f27bf5a12ebc..a66389366af7 100644 --- a/drivers/gpu/ipu-v3/ipu-vdi.c +++ b/drivers/gpu/ipu-v3/ipu-vdi.c @@ -88,9 +88,9 @@ void ipu_vdi_set_field_order(struct ipu_vdi *vdi, v4l2_std_id std, u32 field) reg = ipu_vdi_read(vdi, VDI_C); if (top_field_0) - reg &= ~VDI_C_TOP_FIELD_MAN_1; + reg &= ~(VDI_C_TOP_FIELD_MAN_1 | VDI_C_TOP_FIELD_AUTO_1); else - reg |= VDI_C_TOP_FIELD_MAN_1; + reg |= VDI_C_TOP_FIELD_MAN_1 | VDI_C_TOP_FIELD_AUTO_1; ipu_vdi_write(vdi, reg, VDI_C); spin_unlock_irqrestore(&vdi->lock, flags); -- cgit v1.2.3