linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: paul@pwsan.com (Paul Walmsley)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 02/10] OMAP3 hwmod: Add automatic OCP_SYSCONFIG AUTOIDLE handling
Date: Thu, 03 Dec 2009 06:49:43 -0700	[thread overview]
Message-ID: <20091203134941.17146.9931.stgit@localhost.localdomain> (raw)
In-Reply-To: <20091203134852.17146.81997.stgit@localhost.localdomain>

This patch fills in the OCP_SYSCONFIG.AUTOIDLE handling in the OMAP
hwmod code.

After this patch, the hwmod code will set the module AUTOIDLE bit
(generally <module>.OCP_SYSCONFIG.AUTOIDLE) to 1 by default upon
enable.  If the hwmod flag HWMOD_NO_OCP_AUTOIDLE is set, AUTOIDLE will
be set to 0 upon enable.  Upon module disable, AUTOIDLE will be set to
1.

Enabling module autoidle should save some power.  The only reason to
not set the OCP_SYSCONFIG.AUTOIDLE bit is if there is a bug in the
module RTL, e.g., the MPUINTC block on OMAP3.

Comments from Kevin Hilman <khilman@deeprootsystems.com> inspired this patch,
and Kevin tested an earlier version of this patch.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Tested-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/omap_hwmod.c             |   37 +++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    8 +++++-
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 4aab1b8..709ec5d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -210,6 +210,32 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
 }
 
 /**
+ * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v
+ * @oh: struct omap_hwmod *
+ * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
+ * @v: pointer to register contents to modify
+ *
+ * Update the module autoidle bit in @v to be @autoidle for the @oh
+ * hwmod.  The autoidle bit controls whether the module can gate
+ * internal clocks automatically when it isn't doing anything; the
+ * exact function of this bit varies on a per-module basis.  This
+ * function does not write to the hardware.  Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
+				u32 *v)
+{
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE))
+		return -EINVAL;
+
+	*v &= ~SYSC_AUTOIDLE_MASK;
+	*v |= autoidle << SYSC_AUTOIDLE_SHIFT;
+
+	return 0;
+}
+
+/**
  * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
  * @oh: struct omap_hwmod *
  *
@@ -557,7 +583,13 @@ static void _sysc_enable(struct omap_hwmod *oh)
 		_set_master_standbymode(oh, idlemode, &v);
 	}
 
-	/* XXX OCP AUTOIDLE bit? */
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE) {
+		idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
+			0 : 1;
+		_set_module_autoidle(oh, idlemode, &v);
+	}
+
+	/* XXX OCP ENAWAKEUP bit? */
 
 	if (oh->flags & HWMOD_SET_DEFAULT_CLOCKACT &&
 	    oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)
@@ -622,7 +654,8 @@ static void _sysc_shutdown(struct omap_hwmod *oh)
 	if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)
 		_set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
 
-	/* XXX clear OCP AUTOIDLE bit? */
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE)
+		_set_module_autoidle(oh, 1, &v);
 
 	_write_sysconfig(v, oh);
 }
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index dbdd123..643a972 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -50,6 +50,8 @@ struct omap_device;
 #define SYSC_ENAWAKEUP_MASK		(1 << SYSC_ENAWAKEUP_SHIFT)
 #define SYSC_SOFTRESET_SHIFT		1
 #define SYSC_SOFTRESET_MASK		(1 << SYSC_SOFTRESET_SHIFT)
+#define SYSC_AUTOIDLE_SHIFT		0
+#define SYSC_AUTOIDLE_MASK		(1 << SYSC_AUTOIDLE_SHIFT)
 
 /* OCP SYSSTATUS bit shifts/masks */
 #define SYSS_RESETDONE_SHIFT		0
@@ -294,13 +296,17 @@ struct omap_hwmod_omap4_prcm {
  *     SDRAM controller, etc.
  * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
  *     controller, etc.
+ * HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
+ *     when module is enabled, rather than the default, which is to
+ *     enable autoidle
  * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits@startup
  */
 #define HWMOD_SWSUP_SIDLE			(1 << 0)
 #define HWMOD_SWSUP_MSTANDBY			(1 << 1)
 #define HWMOD_INIT_NO_RESET			(1 << 2)
 #define HWMOD_INIT_NO_IDLE			(1 << 3)
-#define HWMOD_SET_DEFAULT_CLOCKACT		(1 << 4)
+#define HWMOD_NO_OCP_AUTOIDLE			(1 << 4)
+#define HWMOD_SET_DEFAULT_CLOCKACT		(1 << 5)
 
 /*
  * omap_hwmod._int_flags definitions

  parent reply	other threads:[~2009-12-03 13:49 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-03 13:49 [PATCH 00/10] OMAP: omap_hwmod/omap_device patches for 2.6.33 Paul Walmsley
2009-12-03 13:49 ` [PATCH 01/10] OMAP3 hwmod: reprogram OCP_SYSCONFIG register after setting SOFTRESET Paul Walmsley
2009-12-03 13:49 ` Paul Walmsley [this message]
2009-12-03 13:49 ` [PATCH 03/10] OMAP hwmod: add names to module MPU IRQ lines Paul Walmsley
2009-12-03 13:49 ` [PATCH 04/10] OMAP3 hwmod: drop most of the OCP_SYSCONFIG.CLOCKACTIVITY code Paul Walmsley
2009-12-03 13:49 ` [PATCH 05/10] OMAP: omap_device: add to_omap_device() macro Paul Walmsley
2009-12-03 13:49 ` [PATCH 06/10] OMAP: omap_device: use UINT_MAX for default wakeup latency limit Paul Walmsley
2009-12-03 13:49 ` [PATCH 07/10] OMAP: omap_device: use read_persistent_clock() instead of getnstimeofday() Paul Walmsley
2009-12-03 13:49 ` [PATCH 08/10] OMAP: hwmod: warn on missing clockdomain Paul Walmsley
2009-12-03 13:49 ` [PATCH 09/10] OMAP: omap_device: fix nsec/usec conversion in latency calculations Paul Walmsley
2009-12-03 13:49 ` [PATCH 10/10] OMAP: omap_device: track latency in nanoseconds Paul Walmsley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091203134941.17146.9931.stgit@localhost.localdomain \
    --to=paul@pwsan.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).