staging: drm/imx: make waiting for idle channel optional
authorSascha Hauer <s.hauer@pengutronix.de>
Thu, 10 Oct 2013 14:18:41 +0000 (16:18 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Oct 2013 22:30:33 +0000 (15:30 -0700)
Currently we wait for a channel until it's idle before actually
disabling it. This is not needed for all channels though, so make
waiting for idle a separate function and call it where necessary.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
drivers/staging/imx-drm/ipu-v3/ipu-common.c
drivers/staging/imx-drm/ipuv3-crtc.c

index 9bee6403f1e55c3537e26d125956d130f88e6d3b..4826b5c0249d1b202cd69b8474d35a2729962c18 100644 (file)
@@ -97,6 +97,7 @@ void ipu_idmac_put(struct ipuv3_channel *);
 
 int ipu_idmac_enable_channel(struct ipuv3_channel *channel);
 int ipu_idmac_disable_channel(struct ipuv3_channel *channel);
+int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms);
 
 void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
                bool doublebuffer);
index f90bdb4c08c23502a73afad69122016c5581e734..5ca42f0900888e967614fd73ad4a45a93824e3e5 100644 (file)
@@ -698,24 +698,29 @@ int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
 }
 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
 
-int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
+int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms)
 {
        struct ipu_soc *ipu = channel->ipu;
-       u32 val;
-       unsigned long flags;
        unsigned long timeout;
 
-       timeout = jiffies + msecs_to_jiffies(50);
+       timeout = jiffies + msecs_to_jiffies(ms);
        while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) &
                        idma_mask(channel->num)) {
-               if (time_after(jiffies, timeout)) {
-                       dev_warn(ipu->dev, "disabling busy idmac channel %d\n",
-                                       channel->num);
-                       break;
-               }
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
                cpu_relax();
        }
 
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy);
+
+int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
+{
+       struct ipu_soc *ipu = channel->ipu;
+       u32 val;
+       unsigned long flags;
+
        spin_lock_irqsave(&ipu->lock, flags);
 
        /* Disable DMA channel(s) */
index 6fd37a7453e9691ac573c414d396e69357e7b38f..574633b9bc13abbacdc727d3d9515bed1018bfe3 100644 (file)
@@ -102,6 +102,7 @@ static void ipu_fb_disable(struct ipu_crtc *ipu_crtc)
        if (ipu_crtc->dp)
                ipu_dp_disable_channel(ipu_crtc->dp);
        ipu_dc_disable_channel(ipu_crtc->dc);
+       ipu_idmac_wait_busy(ipu_crtc->ipu_ch, 50);
        ipu_idmac_disable_channel(ipu_crtc->ipu_ch);
        ipu_dmfc_disable_channel(ipu_crtc->dmfc);
        ipu_di_disable(ipu_crtc->di);