[PATCH 06/11] staging: drm/imx: make waiting for idle channel optional

Philipp Zabel p.zabel at pengutronix.de
Thu Oct 10 14:18:41 UTC 2013


From: Sascha Hauer <s.hauer at pengutronix.de>

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 at pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h |  1 +
 drivers/staging/imx-drm/ipu-v3/ipu-common.c | 23 ++++++++++++++---------
 drivers/staging/imx-drm/ipuv3-crtc.c        |  1 +
 3 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
index 9bee640..4826b5c 100644
--- a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
+++ b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
@@ -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);
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
index f90bdb4..5ca42f0 100644
--- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c
+++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
@@ -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) */
diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c
index 6fd37a7..574633b 100644
--- a/drivers/staging/imx-drm/ipuv3-crtc.c
+++ b/drivers/staging/imx-drm/ipuv3-crtc.c
@@ -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);
-- 
1.8.4.rc3



More information about the devel mailing list