diff mbox

[PATCHv3,14/20] OMAP: McBSP: Let element DMA mode hit retention also

Message ID 1250174133-451-15-git-send-email-eduardo.valentin@nokia.com (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Eduardo Valentin Aug. 13, 2009, 2:35 p.m. UTC
From: Eero Nurkkala <ext-eero.nurkkala@nokia.com>

The device no longer hits retention if element DMA
mode is taken for at least the duration of the
serial console timeout. Force element DMA mode to
shut down through smartidle.

Signed-off-by: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
Acked-by: Eduardo Valentin <eduardo.valentin@nokia.com>
---
 arch/arm/plat-omap/mcbsp.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

Comments

Woodruff, Richard Aug. 14, 2009, 3:19 a.m. UTC | #1
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> owner@vger.kernel.org] On Behalf Of Eduardo Valentin

> The device no longer hits retention if element DMA
> mode is taken for at least the duration of the
> serial console timeout. Force element DMA mode to
> shut down through smartidle.

Probably this behaves as you say but it seems possible that the bug is somewhere else in device handling.

The generic hope is you can set smart-idle + wakeups at init time and never need to touch them again.  There are a few known cases where the hardware IP does have some bug which force you to dynamically play with bits.

Clockactivity settings are usually static also, but depending on how you configure your device (slave or master clocking) you will need to dynamically set these.

It most you don't need all this dynamic twiddling of the idle protocol handshake bits.  Doing it once at pm_init is what should be necessary.

One example which comes to mind is MMC with DMA mode.  Early drivers were finding RET was gated once the driver was active. In the first pass port to 3430 the writer toggled smart/no/forced idle and the system went happily back to sleep.  However, after some profiling it was seen that this method of putting the device down ended up causing the clock disable to the device to take a very long time.  Another level of digging into documents was done and it was found that it was necessary to reset some command line as part of a clean shut down.  Doing it this way allowed the system to idle, and the time to shut down clocks was just a few nS instead of uS.  As I recall some status was not cleared until the reset of the line.  It did happen that toggling through handshakes had a side effect of also clearing it, but not in the intended way.

Regards,
Richard W.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
ext-eero.nurkkala@nokia.com Aug. 14, 2009, 4:40 a.m. UTC | #2
On Fri, 2009-08-14 at 05:19 +0200, ext Woodruff, Richard wrote:
> > From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> > owner@vger.kernel.org] On Behalf Of Eduardo Valentin
> 
> > The device no longer hits retention if element DMA
> > mode is taken for at least the duration of the
> > serial console timeout. Force element DMA mode to
> > shut down through smartidle.
> 
> Probably this behaves as you say but it seems possible that the bug is somewhere else in device handling.
> 

For some reason unknown to us, if NO_IDLE mode is taken,
and long enough of a arecord | aplay loop was tried (a minute or so),
then, and when closing the loop, the device never hit
retention anymore =) But after the fix, yes it does so.

> The generic hope is you can set smart-idle + wakeups at init time and never need to touch them again.  There are a few known cases where the hardware IP does have some bug which force you to dynamically play with bits.
> 

Right. I did try to set them initially at device init (that was one
of the first things I tried with McBSP), but things were not really
working as expected. (Well, having iclk and fclk on and putting those at
device init caused the whole HW device to jam).

Another thing is, that if the McBSP is a slave (external clocking),
then there will be unnecessary wakeups? If smart-idle + wakeups are
always set? (and the slave clocks the McBSP WCLK and BCLK). BTW, are
the wakeups active if McBSP is in reset state?

> Clockactivity settings are usually static also, but depending on how you configure your device (slave or master clocking) you will need to dynamically set these.

> It most you don't need all this dynamic twiddling of the idle protocol handshake bits.  Doing it once at pm_init is what should be necessary.

> One example which comes to mind is MMC with DMA mode.  Early drivers were finding RET was gated once the driver was active. In the first pass port to 3430 the writer toggled smart/no/forced idle and the system went happily back to sleep.  However, after some profiling it was seen that this method of putting the device down ended up causing the clock disable to the device to take a very long time.  Another level of digging into documents was done and it was found that it was necessary to reset some command line as part of a clean shut down.  Doing it this way allowed the system to idle, and the time to shut down clocks was just a few nS instead of uS.  As I recall some status was not cleared until the reset of the line.  It did happen that toggling through handshakes had a side effect of also clearing it, but not in the intended way.

Whether a few uSec:s or nS:s, doesn't really matter in this case?
(if that even was the case).

> 
> Regards,
> Richard W.

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index c6df47d..a4af1fa 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -343,6 +343,15 @@  static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
 
 		syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
 		syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
+		/*
+		 * HW bug workaround - If no_idle mode is taken, we need to
+		 * go to smart_idle before going to always_idle, or the
+		 * device will not hit retention anymore.
+		 */
+		syscon |= SIDLEMODE(0x02);
+		OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
+
+		syscon &= ~(SIDLEMODE(0x03));
 		OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
 
 		OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0);