imx-drm: ipu-common: add helpers to check for a busy IDMAC channel and to busywait...
authorPhilipp Zabel <p.zabel@pengutronix.de>
Mon, 14 Apr 2014 21:53:17 +0000 (23:53 +0200)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 26 Apr 2014 10:24:14 +0000 (11:24 +0100)
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/staging/imx-drm/ipu-v3/ipu-common.c
drivers/staging/imx-drm/ipu-v3/ipu-prv.h

index 0585517956779e439a104013423e18d920c6e8a0..8fb4c207f3f17ab185623fc31e5a72a579e6fdfe 100644 (file)
@@ -697,6 +697,12 @@ int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
 }
 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
 
+bool ipu_idmac_channel_busy(struct ipu_soc *ipu, unsigned int chno)
+{
+       return (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(chno)) & idma_mask(chno));
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_channel_busy);
+
 int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms)
 {
        struct ipu_soc *ipu = channel->ipu;
@@ -714,6 +720,22 @@ 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;
index 4df00501adc210c9b4406d421be644e5cf8f8d51..bfc1b336648823ab3c6be6a6fdecea7cdd430942 100644 (file)
@@ -185,6 +185,9 @@ void ipu_srm_dp_sync_update(struct ipu_soc *ipu);
 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_di_init(struct ipu_soc *ipu, struct device *dev, int id,
                unsigned long base, u32 module, struct clk *ipu_clk);
 void ipu_di_exit(struct ipu_soc *ipu, int id);