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/11] OMAP2: clock: add DPLL autoidle support
Date: Tue, 15 Feb 2011 23:52:44 -0700	[thread overview]
Message-ID: <20110216065243.22089.78413.stgit@twilight.localdomain> (raw)
In-Reply-To: <20110216065030.22089.61217.stgit@twilight.localdomain>

Add the necessary code and data to allow the clock framework to enable
and disable the OMAP2 DPLL autoidle state.  This is so the direct
register access can be moved out of the mach-omap2/pm24xx.c code, and other
code that needs to control this (e.g., CPUIdle) can do so via an API.
As part of this patch, remove the pm24xx.c code that formerly wrote
directly to the autoidle bits.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@ti.com>
---
 arch/arm/mach-omap2/Makefile         |    3 +-
 arch/arm/mach-omap2/clkt2xxx_dpll.c  |   63 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/clock.h          |    1 +
 arch/arm/mach-omap2/clock2420_data.c |    2 +
 arch/arm/mach-omap2/clock2430_data.c |    2 +
 arch/arm/mach-omap2/cm2xxx_3xxx.c    |   27 +++++++++++++++
 arch/arm/mach-omap2/cm2xxx_3xxx.h    |    3 ++
 arch/arm/mach-omap2/pm24xx.c         |   12 ++++--
 8 files changed, 105 insertions(+), 8 deletions(-)
 create mode 100644 arch/arm/mach-omap2/clkt2xxx_dpll.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 3a798ef..41cb404 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -112,7 +112,8 @@ obj-$(CONFIG_ARCH_OMAP2)		+= $(clock-common) clock2xxx.o \
 					   clkt2xxx_sys.o \
 					   clkt2xxx_dpllcore.o \
 					   clkt2xxx_virt_prcm_set.o \
-					   clkt2xxx_apll.o clkt2xxx_osc.o
+					   clkt2xxx_apll.o clkt2xxx_osc.o \
+					   clkt2xxx_dpll.o
 obj-$(CONFIG_ARCH_OMAP2420)		+= clock2420_data.o
 obj-$(CONFIG_ARCH_OMAP2430)		+= clock2430.o clock2430_data.o
 obj-$(CONFIG_ARCH_OMAP3)		+= $(clock-common) clock3xxx.o \
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c
new file mode 100644
index 0000000..1502a7b
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c
@@ -0,0 +1,63 @@
+/*
+ * OMAP2-specific DPLL control functions
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* Private functions */
+
+/**
+ * _allow_idle - enable DPLL autoidle bits
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Enable DPLL automatic idle control.  The DPLL will enter low-power
+ * stop when its downstream clocks are gated.  No return value.
+ * REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
+ * instead.  Add some mechanism to optionally enter this mode.
+ */
+static void _allow_idle(struct clk *clk)
+{
+	if (!clk || !clk->dpll_data)
+		return;
+
+	omap2xxx_cm_set_dpll_auto_low_power_stop();
+}
+
+/**
+ * _deny_idle - prevent DPLL from automatically idling
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Disable DPLL automatic idle control.  No return value.
+ */
+static void _deny_idle(struct clk *clk)
+{
+	if (!clk || !clk->dpll_data)
+		return;
+
+	omap2xxx_cm_set_dpll_disable_autoidle();
+}
+
+
+/* Public data */
+
+const struct clkops clkops_omap2xxx_dpll_ops = {
+	.allow_idle	= _allow_idle,
+	.deny_idle	= _deny_idle,
+};
+
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 0725a6a..9972d89 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -148,6 +148,7 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
 #define omap2_clk_exit_cpufreq_table	0
 #endif
 
+extern const struct clkops clkops_omap2xxx_dpll_ops;
 extern const struct clkops clkops_omap3_noncore_dpll_ops;
 extern const struct clkops clkops_omap3_core_dpll_ops;
 extern const struct clkops clkops_omap4_dpllmx_ops;
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index ee73e14..30fbcbd 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -125,7 +125,7 @@ static struct dpll_data dpll_dd = {
  */
 static struct clk dpll_ck = {
 	.name		= "dpll_ck",
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap2xxx_dpll_ops,
 	.parent		= &sys_ck,		/* Can be func_32k also */
 	.dpll_data	= &dpll_dd,
 	.clkdm_name	= "wkup_clkdm",
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index a1298e5..1ff150a 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -125,7 +125,7 @@ static struct dpll_data dpll_dd = {
  */
 static struct clk dpll_ck = {
 	.name		= "dpll_ck",
-	.ops		= &clkops_null,
+	.ops		= &clkops_omap2xxx_dpll_ops,
 	.parent		= &sys_ck,		/* Can be func_32k also */
 	.dpll_data	= &dpll_dd,
 	.clkdm_name	= "wkup_clkdm",
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
index 96954aa..6b0c7c8 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c
@@ -25,6 +25,10 @@
 #include "cm-regbits-24xx.h"
 #include "cm-regbits-34xx.h"
 
+/* CM_AUTOIDLE_PLL.AUTO_* bit values */
+#define DPLL_AUTOIDLE_DISABLE				0x0
+#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP		0x3
+
 static const u8 cm_idlest_offs[] = {
 	CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
 };
@@ -125,6 +129,29 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
 	_write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
 }
 
+/*
+ * DPLL autoidle control
+ */
+
+static void _omap2xxx_set_dpll_autoidle(u8 m)
+{
+	u32 v;
+
+	v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+	v &= ~OMAP24XX_AUTO_DPLL_MASK;
+	v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
+	omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_dpll_disable_autoidle(void)
+{
+	_omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
+}
+
+void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
+{
+	_omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
+}
 
 /*
  *
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
index 5e9ea5b..5f4df1c 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -122,6 +122,9 @@ extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
 extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
 extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
 
+extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
+extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
+
 #endif
 
 /* CM register bits shared between 24XX and 3430 */
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 97feb3a..23b4607 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -378,6 +378,7 @@ static void __init prcm_setup_regs(void)
 {
 	int i, num_mem_banks;
 	struct powerdomain *pwrdm;
+	u32 v;
 
 	/* Enable autoidle */
 	omap2_prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD,
@@ -468,11 +469,12 @@ static void __init prcm_setup_regs(void)
 	omap2_cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD,
 			       CM_AUTOIDLE);
 
-	/* Put DPLL and both APLLs into autoidle mode */
-	omap2_cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) |
-			       (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
-			       (0x03 << OMAP24XX_AUTO_54M_SHIFT),
-			       PLL_MOD, CM_AUTOIDLE);
+	/* Put both APLLs into autoidle mode */
+	v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+	v &= ~(OMAP24XX_AUTO_96M_MASK | OMAP24XX_AUTO_54M_SHIFT);
+	v |= (0x03 << OMAP24XX_AUTO_96M_SHIFT) |
+		(0x03 << OMAP24XX_AUTO_54M_SHIFT);
+	omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
 
 	omap2_cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK |
 			       OMAP24XX_AUTO_WDT1_MASK |

  parent reply	other threads:[~2011-02-16  6:52 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-16  6:52 [PATCH 00/11] OMAP2+: clock: add clockfw autoidle for iclks, OMAP2xxx Paul Walmsley
2011-02-16  6:52 ` [PATCH 01/11] OMAP2+: clock: disable autoidle on all clocks during clock init Paul Walmsley
2011-02-16  6:52 ` Paul Walmsley [this message]
2011-02-16  6:52 ` [PATCH 03/11] OMAP2xxx: clock: add clockfw autoidle support for APLLs Paul Walmsley
2011-02-16  6:52 ` [PATCH 04/11] OMAP2+: clock: comment that osc_ck/osc_sys_ck should use clockfw autoidle control Paul Walmsley
2011-02-16  6:52 ` [PATCH 05/11] OMAP2+: clock: add interface clock type code with autoidle support Paul Walmsley
2011-02-16  6:52 ` [PATCH 06/11] OMAP2420: clock: add sdrc_ick Paul Walmsley
2011-02-16  6:52 ` [PATCH 07/11] OMAP2420: clock: use autoidle clkops for all autoidle-controllable interface clocks Paul Walmsley
2011-02-16  6:52 ` [PATCH 08/11] OMAP2430/3xxx: clock: add modem clock autoidle support Paul Walmsley
2011-02-16  6:52 ` [PATCH 09/11] OMAP2430: clock: use autoidle clkops for all autoidle-controllable interface clocks Paul Walmsley
2011-02-16  6:52 ` [PATCH 10/11] OMAP3: " Paul Walmsley
2011-02-16  6:52 ` [PATCH 11/11] OMAP2/3: PM: remove manual CM_AUTOIDLE bit setting in mach-omap2/pm*xx.c Paul Walmsley
2011-02-16  9:37 ` [PATCH 00/11] OMAP2+: clock: add clockfw autoidle for iclks, OMAP2xxx Rajendra Nayak
2011-02-16 22:14   ` Paul Walmsley
2011-02-18  5:33     ` Rajendra Nayak
2011-02-16 11:15 ` Rajendra Nayak
2011-02-16 23:05   ` Paul Walmsley
2011-02-18  5:35     ` Rajendra Nayak
2011-03-01 20:58 ` Kevin Hilman
2011-03-08  3:06   ` 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=20110216065243.22089.78413.stgit@twilight.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).