public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] OMAP3: PM: introduce support for 3630 OPPs
@ 2009-11-12  5:45 Nishanth Menon
  2009-11-12  5:45 ` [PATCH 1/9] omap3: pm: introduce enabled flag to omap_opp Nishanth Menon
  0 siblings, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Nishanth Menon


Hi,
This patch series is based on previous discussions:
http://www.mail-archive.com/linux-omap@vger.kernel.org/msg17632.html

I have modified the initial patch From Sanjeev:
http://patchwork.kernel.org/patch/50998/

Other than these, we cannot use the old VDDx_MAX based usage
anymore as 3630 OPPs are now different and runtime handling
is a must-have, hence introducing these accessor functions is not
avoidable.

The changes are incremental and tries to avoid intrusive change
as much as possible. 3630 testing can only happen once the clock
tree relevant changes are also pushed in.. but most of the relevant
APIs have been exercised on 3430 itself as just the size of the OPP
table varies b/w 3630 and 3430.

The OPP accessor functions introduced in this series is hopefully
a start for us to optimize this heavily used path.

Finally, I have only done limited testing of SR, as it is still in
my TODO list to revamp SR in the form of a v5 patch next time I get
some bandwidth.

An alternate approach for detecting 3630 OPP is using FEATURES
instead of detecting the cpu_type as I have implemented in this series.

Nishanth Menon (9):
  omap3: pm: introduce enabled flag to omap_opp
  omap3: pm: introduce opp accessor functions
  omap3: pm: srf: introduce accessor function
  omap3: pm: use opp accessor functions for omap-target
  omap3: pm: sr: replace get_opp with freq_to_opp
  omap3: clk: use pm accessor functions for cpufreq table
  omap3: pm: remove VDDx_MIN/MAX macros
  omap3: pm: introduce dynamic OPP
  omap3: pm: introduce 3630 opps

 arch/arm/mach-omap2/board-3430sdp.c        |    1 +
 arch/arm/mach-omap2/board-omap3beagle.c    |    1 +
 arch/arm/mach-omap2/board-omap3evm.c       |    1 +
 arch/arm/mach-omap2/board-rx51.c           |    2 +
 arch/arm/mach-omap2/board-zoom2.c          |    2 +
 arch/arm/mach-omap2/clock34xx.c            |   46 +++++---
 arch/arm/mach-omap2/omap3-opp.h            |   49 ++------
 arch/arm/mach-omap2/pm.c                   |  160 +++++++++++++++++++++++++
 arch/arm/mach-omap2/pm.h                   |    8 ++
 arch/arm/mach-omap2/pm34xx.c               |  122 +++++++++++++++++++
 arch/arm/mach-omap2/resource34xx.c         |  174 +++++++++++++++++----------
 arch/arm/mach-omap2/smartreflex.c          |   36 ++-----
 arch/arm/plat-omap/cpu-omap.c              |   12 +--
 arch/arm/plat-omap/include/plat/omap-pm.h  |  111 ++++++++++++++++++
 arch/arm/plat-omap/include/plat/omap34xx.h |    5 -
 15 files changed, 573 insertions(+), 157 deletions(-)

Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/9] omap3: pm: introduce enabled flag to omap_opp
  2009-11-12  5:45 [PATCH 0/9] OMAP3: PM: introduce support for 3630 OPPs Nishanth Menon
@ 2009-11-12  5:45 ` Nishanth Menon
  2009-11-12  5:45   ` [PATCH 2/9] omap3: pm: introduce opp accessor functions Nishanth Menon
  0 siblings, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

We used to enable and disable OPPs based on rate being set to 0, this
has been confusing in general. So, we now allow specific OPPs to be
now enabled/disabled by an explicit enabled flag instead of re-using
rate flag itself.

Tested on: SDP3430

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/omap3-opp.h           |   32 ++++++++++++++--------------
 arch/arm/mach-omap2/resource34xx.c        |    4 +++
 arch/arm/plat-omap/include/plat/omap-pm.h |    2 +
 3 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-omap2/omap3-opp.h b/arch/arm/mach-omap2/omap3-opp.h
index c773ea7..42557e1 100644
--- a/arch/arm/mach-omap2/omap3-opp.h
+++ b/arch/arm/mach-omap2/omap3-opp.h
@@ -22,41 +22,41 @@
 #define S166M   166000000
 
 static struct omap_opp omap3_mpu_rate_table[] = {
-	{0, 0, 0},
+	{0, 0, 0, 0},
 	/*OPP1*/
-	{S125M, VDD1_OPP1, 0x1E},
+	{true, S125M, VDD1_OPP1, 0x1E},
 	/*OPP2*/
-	{S250M, VDD1_OPP2, 0x26},
+	{true, S250M, VDD1_OPP2, 0x26},
 	/*OPP3*/
-	{S500M, VDD1_OPP3, 0x30},
+	{true, S500M, VDD1_OPP3, 0x30},
 	/*OPP4*/
-	{S550M, VDD1_OPP4, 0x36},
+	{true, S550M, VDD1_OPP4, 0x36},
 	/*OPP5*/
-	{S600M, VDD1_OPP5, 0x3C},
+	{true, S600M, VDD1_OPP5, 0x3C},
 };
 
 static struct omap_opp omap3_l3_rate_table[] = {
-	{0, 0, 0},
+	{0, 0, 0, 0},
 	/*OPP1*/
-	{0, VDD2_OPP1, 0x1E},
+	{false, 0, VDD2_OPP1, 0x1E},
 	/*OPP2*/
-	{S83M, VDD2_OPP2, 0x24},
+	{true, S83M, VDD2_OPP2, 0x24},
 	/*OPP3*/
-	{S166M, VDD2_OPP3, 0x2C},
+	{true, S166M, VDD2_OPP3, 0x2C},
 };
 
 static struct omap_opp omap3_dsp_rate_table[] = {
-	{0, 0, 0},
+	{0, 0, 0, 0},
 	/*OPP1*/
-	{S90M, VDD1_OPP1, 0x1E},
+	{true, S90M, VDD1_OPP1, 0x1E},
 	/*OPP2*/
-	{S180M, VDD1_OPP2, 0x26},
+	{true, S180M, VDD1_OPP2, 0x26},
 	/*OPP3*/
-	{S360M, VDD1_OPP3, 0x30},
+	{true, S360M, VDD1_OPP3, 0x30},
 	/*OPP4*/
-	{S400M, VDD1_OPP4, 0x36},
+	{true, S400M, VDD1_OPP4, 0x36},
 	/*OPP5*/
-	{S430M, VDD1_OPP5, 0x3C},
+	{true, S430M, VDD1_OPP5, 0x3C},
 };
 
 #endif
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index 04be4d2..af6b3c1 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -285,6 +285,10 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
 	c_opp = ID_VDD(res) | ID_OPP_NO(opp[current_level].opp_id);
 #endif
 
+	/* Only allow enabled OPPs */
+	if (!opp[target_level].enabled)
+		return -EINVAL;
+
 	/* Sanity check of the OPP params before attempting to set */
 	if (!opp[target_level].rate || !opp[target_level].vsel)
 		return -EINVAL;
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 583e540..5dc2048 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -21,6 +21,7 @@
 
 /**
  * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
+ * @enabled: enabled if true, disabled if false
  * @rate: target clock rate
  * @opp_id: OPP ID
  * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
@@ -28,6 +29,7 @@
  * Operating performance point data.  Can vary by OMAP chip and board.
  */
 struct omap_opp {
+	bool enabled;
 	unsigned long rate;
 	u8 opp_id;
 	u16 vsel;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/9] omap3: pm: introduce opp accessor functions
  2009-11-12  5:45 ` [PATCH 1/9] omap3: pm: introduce enabled flag to omap_opp Nishanth Menon
@ 2009-11-12  5:45   ` Nishanth Menon
  2009-11-12  5:45     ` [PATCH 3/9] omap3: pm: srf: introduce accessor function Nishanth Menon
  0 siblings, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Santosh Shilimkar, Sergio Alberto Aguirre Rodriguez,
	Thara Gopinath, Vishwanath Sripathy, Sanjeev Premi

Modifies the initial patch From Sanjeev:
http://patchwork.kernel.org/patch/50998/

NOTE:
The original opp_table introduced by Sanjeev is not needed anymore as
we can use enabled flag to have better granularity in enable/disable
of OPPs.

This introduces the following accessor functions:

freq_to_opp and opp_to_freq: Matching functions to convert OPP to freq
and viceversa.

freq_to_vsel: Converts a frequency to corresponding voltage.

opp_onoff: To enable/disable a specific OPP in a OPP table this allows
granular runtime disable/enable of specific OPPs, esp when used in
conjunction with search and mapping functions

get_next_freq: A search function to get next matching frequency. This
could possibly provide the basis for more complex OPP transition algos
of the future.

get_limit_freq: A search function to get the least or maximum
frequency based on search criteria. Allows for independence from
OPP_IDs in the future.

Since the accessor functions hide the details of the table
implementation, the opp table is now moved away from omap3-opp.h to
pm34xx.c. The terminator entry is needed at the start and end of the
table as it is still needed for reverse and forward search as the
length of the table is unknown.

Tests done: Accessor functions standalone tested on a PC host with
dummy OPP table to simulate boundary, invalid and valid conditions,
SDP3430 for system stability.

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Sanjeev Premi <premi@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/omap3-opp.h           |   40 +-------
 arch/arm/mach-omap2/pm.c                  |  160 +++++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm34xx.c              |   42 ++++++++
 arch/arm/plat-omap/include/plat/omap-pm.h |  109 ++++++++++++++++++++
 4 files changed, 314 insertions(+), 37 deletions(-)

diff --git a/arch/arm/mach-omap2/omap3-opp.h b/arch/arm/mach-omap2/omap3-opp.h
index 42557e1..27e2ca5 100644
--- a/arch/arm/mach-omap2/omap3-opp.h
+++ b/arch/arm/mach-omap2/omap3-opp.h
@@ -21,42 +21,8 @@
 #define S83M    83000000
 #define S166M   166000000
 
-static struct omap_opp omap3_mpu_rate_table[] = {
-	{0, 0, 0, 0},
-	/*OPP1*/
-	{true, S125M, VDD1_OPP1, 0x1E},
-	/*OPP2*/
-	{true, S250M, VDD1_OPP2, 0x26},
-	/*OPP3*/
-	{true, S500M, VDD1_OPP3, 0x30},
-	/*OPP4*/
-	{true, S550M, VDD1_OPP4, 0x36},
-	/*OPP5*/
-	{true, S600M, VDD1_OPP5, 0x3C},
-};
-
-static struct omap_opp omap3_l3_rate_table[] = {
-	{0, 0, 0, 0},
-	/*OPP1*/
-	{false, 0, VDD2_OPP1, 0x1E},
-	/*OPP2*/
-	{true, S83M, VDD2_OPP2, 0x24},
-	/*OPP3*/
-	{true, S166M, VDD2_OPP3, 0x2C},
-};
-
-static struct omap_opp omap3_dsp_rate_table[] = {
-	{0, 0, 0, 0},
-	/*OPP1*/
-	{true, S90M, VDD1_OPP1, 0x1E},
-	/*OPP2*/
-	{true, S180M, VDD1_OPP2, 0x26},
-	/*OPP3*/
-	{true, S360M, VDD1_OPP3, 0x30},
-	/*OPP4*/
-	{true, S400M, VDD1_OPP4, 0x36},
-	/*OPP5*/
-	{true, S430M, VDD1_OPP5, 0x3C},
-};
+extern struct omap_opp omap3_mpu_rate_table[];
+extern struct omap_opp omap3_dsp_rate_table[];
+extern struct omap_opp omap3_l3_rate_table[];
 
 #endif
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index f50e93d..9dcb5c7 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -33,6 +33,7 @@
 #include <plat/powerdomain.h>
 #include <plat/resource.h>
 #include <plat/omap34xx.h>
+#include <plat/omap-pm.h>
 
 #include "prm-regbits-34xx.h"
 #include "pm.h"
@@ -203,3 +204,162 @@ static int __init omap_pm_init(void)
 	return error;
 }
 late_initcall(omap_pm_init);
+
+int opp_to_freq(unsigned long *freq, const struct omap_opp *opps, u8 opp_id)
+{
+	int i = 1;
+
+	BUG_ON(!freq || !opps);
+
+	/* The first entry is a dummy one, loop till we hit terminator */
+	while (!IS_OPP_TERMINATOR(opps, i)) {
+		if (opps[i].enabled && (opps[i].opp_id == opp_id)) {
+			*freq = opps[i].rate;
+			return 0;
+		}
+		i++;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(opp_to_freq);
+
+int freq_to_vsel(u8 *vsel, const struct omap_opp *opps, unsigned long freq)
+{
+	int i = 1;
+
+	BUG_ON(!vsel || !opps);
+
+	/* The first entry is a dummy one, loop till we hit terminator */
+	while (!IS_OPP_TERMINATOR(opps, i)) {
+		if (opps[i].enabled && (opps[i].rate == freq)) {
+			*vsel = opps[i].vsel;
+			return 0;
+		}
+		i++;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(freq_to_vsel);
+
+int freq_to_opp(u8 *opp_id, const struct omap_opp *opps, unsigned long freq)
+{
+	int i = 1;
+
+	BUG_ON(!opp_id || !opps);
+
+	/* The first entry is a dummy one, loop till we hit terminator */
+	while (!IS_OPP_TERMINATOR(opps, i)) {
+		if (opps[i].enabled && (opps[i].rate == freq)) {
+			*opp_id = opps[i].opp_id;
+			return 0;
+		}
+		i++;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(freq_to_opp);
+
+int opp_onoff(struct omap_opp *opps, unsigned long freq, bool enable)
+{
+	int i = 1;
+
+	BUG_ON(!opps);
+
+	/* The first entry is a dummy one, loop till we hit terminator */
+	while (!IS_OPP_TERMINATOR(opps, i)) {
+		if (opps[i].rate == freq) {
+			opps[i].enabled = enable;
+			return 0;
+		}
+		i++;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(opp_onoff);
+
+int get_next_freq(unsigned long *freq, const struct omap_opp *opps,
+		bool search_higher, bool search_enabled_only, bool exact_search)
+{
+	int i = 1, inc = 1;
+	bool found = false;
+
+	BUG_ON(!opps || !freq || !(*freq));
+
+	/* The first entry is a dummy one, loop till we hit terminator
+	 * XXX: The following algorithm works only on a presorted
+	 * list of OPPs
+	 */
+	while (!IS_OPP_TERMINATOR(opps, i)) {
+		/* if we found the original freq, then
+		 * case 1: enabled search ONLY, check opp is enabled or not
+		 * case 2: the next available freq if enabled is not searched
+		 */
+		if ((found && search_enabled_only && opps[i].enabled) ||
+		    (found && !search_enabled_only)) {
+			*freq = opps[i].rate;
+			return 0;
+		}
+
+		/* Find the baseline freq first.. */
+		if (!found && ((exact_search && opps[i].rate == *freq) ||
+				(!exact_search && opps[i].rate >= *freq))) {
+			/* found.. next decide direction */
+			inc = search_higher ? 1 : -1;
+			found = true;
+			/* handle an exception case for exact search.. */
+			if (exact_search || !search_higher)
+				i += inc;
+			/* fall thru to search for the right match */
+		} else {
+			i += inc;
+		}
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(get_next_freq);
+
+int get_limit_freq(unsigned long *freq, const struct omap_opp *opps,
+		bool search_highest, bool search_enabled_only)
+{
+	int i = 1;
+	unsigned long cur_freq_match = search_highest ? 0 : -1;
+	bool found = false;
+
+	BUG_ON(!opps || !freq);
+
+	/* The first entry is a dummy one, loop till we hit terminator
+	 * XXX: The following algorithm works only on a presorted
+	 * list of OPPs
+	 * We could use get_next_freq to search, but that will tend
+	 * to be inefficient
+	 */
+	while (!IS_OPP_TERMINATOR(opps, i)) {
+		/* match condition:
+		 * check if the enabled cases match (only invalid case is:
+		 * search_enabled=1,enabled=0)
+		 * then we look for comparison condition, based on direction
+		 */
+		if (!(search_enabled_only && !opps[i].enabled) &&
+		     ((search_highest && (opps[i].rate > cur_freq_match)) ||
+		     (!search_highest && (opps[i].rate < cur_freq_match)))) {
+			cur_freq_match = opps[i].rate;
+			found = true;
+			/* if we are searching for least, the first match
+			 * is the right one, look no further.
+			 */
+			if (!search_highest)
+				break;
+		}
+		i++;
+	}
+	if (!found)
+		return -EINVAL;
+	*freq = cur_freq_match;
+	return 0;
+}
+EXPORT_SYMBOL(get_limit_freq);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 3a2dc2b..92f11d7 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -50,6 +50,7 @@
 #include "prm.h"
 #include "pm.h"
 #include "sdrc.h"
+#include "omap3-opp.h"
 
 static int regset_save_on_suspend;
 
@@ -98,6 +99,47 @@ static struct prm_setup_vc prm_setup = {
 	.vdd1_off = 0x00,	/* 0.6v */
 };
 
+struct omap_opp omap3_mpu_rate_table[] = {
+	{0, 0, 0, 0},
+	/*OPP1*/
+	{true, S125M, VDD1_OPP1, 0x1E},
+	/*OPP2*/
+	{true, S250M, VDD1_OPP2, 0x26},
+	/*OPP3*/
+	{true, S500M, VDD1_OPP3, 0x30},
+	/*OPP4*/
+	{true, S550M, VDD1_OPP4, 0x36},
+	/*OPP5*/
+	{true, S600M, VDD1_OPP5, 0x3C},
+	{0, 0, 0, 0},
+};
+
+struct omap_opp omap3_l3_rate_table[] = {
+	{0, 0, 0, 0},
+	/*OPP1*/
+	{false, 0, VDD2_OPP1, 0x1E},
+	/*OPP2*/
+	{true, S83M, VDD2_OPP2, 0x24},
+	/*OPP3*/
+	{true, S166M, VDD2_OPP3, 0x2C},
+	{0, 0, 0, 0},
+};
+
+struct omap_opp omap3_dsp_rate_table[] = {
+	{0, 0, 0, 0},
+	/*OPP1*/
+	{true, S90M, VDD1_OPP1, 0x1E},
+	/*OPP2*/
+	{true, S180M, VDD1_OPP2, 0x26},
+	/*OPP3*/
+	{true, S360M, VDD1_OPP3, 0x30},
+	/*OPP4*/
+	{true, S400M, VDD1_OPP4, 0x36},
+	/*OPP5*/
+	{true, S430M, VDD1_OPP5, 0x3C},
+	{0, 0, 0, 0},
+};
+
 static inline void omap3_per_save_context(void)
 {
 	omap_gpio_save_context();
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 5dc2048..693b8c1 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -35,6 +35,10 @@ struct omap_opp {
 	u16 vsel;
 };
 
+/* Identify a OPP terminator */
+#define IS_OPP_TERMINATOR(opps, i) (!opps[i].enabled && (opps[i].rate == 0) &&\
+			(opps[i].vsel == 0))
+
 extern struct omap_opp *mpu_opps;
 extern struct omap_opp *dsp_opps;
 extern struct omap_opp *l3_opps;
@@ -324,5 +328,110 @@ unsigned long omap_pm_cpu_get_freq(void);
  */
 int omap_pm_get_dev_context_loss_count(struct device *dev);
 
+/**
+ * freq_to_opp - Get opp_id corresponding to a frequency if enabled
+ * This function can also be used to check if a certain frequency is enabled
+ * in the opp list.
+ *
+ * @opp_id: the ID to return
+ * @opps: the opps table to search through
+ * @freq: the frequency to search for
+ *
+ * returns 0 if *opp_id is populated, else returns EINVAL
+ */
+int freq_to_opp(u8 *opp_id, const struct omap_opp *opps, unsigned long freq);
 
+/**
+ * freq_to_vsel - Get voltage corresponding to a frequency if enabled
+ * This function can also be used to check if a certain frequency is enabled
+ * in the opp list.
+ *
+ * @vsel: voltage corresponding to return
+ * @opps: the opps table to search through
+ * @freq: the frequency to search for
+ *
+ * returns 0 if *vsel is populated, else returns EINVAL
+ */
+int freq_to_vsel(u8 *vsel, const struct omap_opp *opps, unsigned long freq);
+
+/**
+ * opp_to_freq - Get frequency corresponding to an OPP if enabled
+ * This function can also be used to check if a certain opp_id is enabled
+ * in the opp list.
+ *
+ * @freq: return the frequency on this
+ * @opps: the opps table to search through
+ * @opp_id: the ID to search for
+ *
+ * returns 0 if *freq is populated, else returns EINVAL
+ */
+int opp_to_freq(unsigned long *freq, const struct omap_opp *opps, u8 opp_id);
+
+/**
+ * opp_onoff - Disable or enable an OPP in the supported OPPs if available
+ *
+ * @opps: the opps table to search through
+ * @freq: the frequency to search for
+ * @enable: true to enable the OPP, false to disable it
+ *
+ * returns 0 if the OPP is found, else returns EINVAL. if the opp is found
+ * NOTE: Even if it was in the same state as requested, the functions returns 0.
+ */
+int opp_onoff(struct omap_opp *opps, unsigned long freq, bool enable);
+
+/**
+ * get_next_freq - search for next matching frequency, given a starting
+ * frequency. This can be combined to create a search logic etc without
+ * knowing OPP IDs.
+ * Example usages:
+ * a) I have an approximate frequency, get enabled opp freq at least freq
+ *	if a match is achieved, result_freq >= requested_freq
+ *   res = get_next_freq(&freq, opps, true, true, false)
+ * b) I have an approximate frequency, get enabled opp freq less than freq
+ *	if a match is achieved, result_freq < requested_freq
+ *   res = get_next_freq(&freq, opps, false, true, false)
+ * c) I have exact OPP freq I want to check -> search for higher enabled
+ *    frequency
+ *   res = get_next_freq(&freq, opps, true, true, true)
+ * d) I have exact OPP freq I want to check -> search for lower enabled
+ *    frequency
+ *   res = get_next_freq(&freq, opps, false, true, true)
+ *
+ * Then we can create all sorts of search combinations -> including searching
+ * for an OPP freq we would like to enable by controlling search_enabled_only
+ *
+ * @freq: Which frequency to start from- should be a valid frequency,
+ *	  even if not enabled.
+ *	  if a match is found, this will contain the matched frequency
+ * @opps: the opp table to search through
+ * @search_higher: should the search go up the list (search for higher freq)
+ *	  if true, searches for next highest freq, else searches for the next
+ *	  lowest frequency
+ * @search_enabled_only: Should the search only for enabled frequencies.
+ *	  if true, searches for only enabled OPP frequencies, else does not
+ *	  care for enabled status of the OPP (useful to enable OPPs)
+ * @exact_search: start search iff start *freq gets an exact match
+ *
+ * If a match is found, returns the matched frequency in *freq and returns 0,
+ * else, returns EINVAL, *freq is unchanged
+ */
+int get_next_freq(unsigned long *freq, const struct omap_opp *opps,
+	bool search_higher, bool search_enabled_only, bool exact_search);
+
+/**
+ * get_limit_freq: Get the max or min frequency for an opp table
+ * we can search for just the enabled opps, or the max or least in
+ * the table
+ *
+ * @freq: returns the max or min opp if a match was found
+ * @opps: opp table to search
+ * @search_highest: search for the highest if true, else search for lowest
+ *	frequency
+ * @search_enabled_only: search only for enabled OPPs
+ *
+ * returns 0 if a match is found and *freq contains the matched frequency
+ * else, returns EINVAL, *freq is unchanged
+ */
+int get_limit_freq(unsigned long *freq, const struct omap_opp *opps,
+		bool search_highest, bool search_enabled_only);
 #endif
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/9] omap3: pm: srf: introduce accessor function
  2009-11-12  5:45   ` [PATCH 2/9] omap3: pm: introduce opp accessor functions Nishanth Menon
@ 2009-11-12  5:45     ` Nishanth Menon
  2009-11-12  5:45       ` [PATCH 4/9] omap3: pm: use opp accessor functions for omap-target Nishanth Menon
  0 siblings, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

With the accessor functions, many of the direct accesses are
redundant. Cleanup of SRF to:
a) Remove get_opp as it redundant as freq_to_opp does exactly the
   samething.
b) Remove any direct dereference of opp tables except thru accessor
   functions.

NOTE: the implementation is just a start and leaves scope for
further performance and robustness improvements which can be added on
top.

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/resource34xx.c |  178 ++++++++++++++++++++++--------------
 1 files changed, 109 insertions(+), 69 deletions(-)

diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index af6b3c1..15b5cb6 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -155,29 +155,14 @@ static int curr_vdd1_opp;
 static int curr_vdd2_opp;
 static DEFINE_MUTEX(dvfs_mutex);
 
-static unsigned short get_opp(struct omap_opp *opp_freq_table,
-		unsigned long freq)
-{
-	struct omap_opp *prcm_config;
-	prcm_config = opp_freq_table;
-
-	if (prcm_config->rate <= freq)
-		return prcm_config->opp_id; /* Return the Highest OPP */
-	for (; prcm_config->rate; prcm_config--)
-		if (prcm_config->rate < freq)
-			return (prcm_config+1)->opp_id;
-		else if (prcm_config->rate == freq)
-			return prcm_config->opp_id;
-	/* Return the least OPP */
-	return (prcm_config+1)->opp_id;
-}
-
 /**
  * init_opp - Initialize the OPP resource
  */
 void init_opp(struct shared_resource *resp)
 {
 	struct clk *l3_clk;
+	int ret;
+	u8 opp_id;
 	resp->no_of_users = 0;
 
 	if (!mpu_opps || !dsp_opps || !l3_opps)
@@ -190,17 +175,18 @@ void init_opp(struct shared_resource *resp)
 		vdd1_resp = resp;
 		dpll1_clk = clk_get(NULL, "dpll1_ck");
 		dpll2_clk = clk_get(NULL, "dpll2_ck");
-		resp->curr_level = get_opp(mpu_opps + MAX_VDD1_OPP,
-				dpll1_clk->rate);
-		curr_vdd1_opp = resp->curr_level;
+		ret = freq_to_opp(&opp_id, mpu_opps, dpll1_clk->rate);
+		BUG_ON(ret); /* TBD Cleanup handling */
+		curr_vdd1_opp = opp_id;
 	} else if (strcmp(resp->name, "vdd2_opp") == 0) {
 		vdd2_resp = resp;
 		dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
 		l3_clk = clk_get(NULL, "l3_ick");
-		resp->curr_level = get_opp(l3_opps + MAX_VDD2_OPP,
-				l3_clk->rate);
-		curr_vdd2_opp = resp->curr_level;
+		ret = freq_to_opp(&opp_id, l3_opps, l3_clk->rate);
+		BUG_ON(ret); /* TBD Cleanup handling */
+		curr_vdd2_opp = opp_id;
 	}
+	resp->curr_level = opp_id;
 	return;
 }
 
@@ -242,24 +228,40 @@ static int program_opp_freq(int res, int target_level, int current_level)
 {
 	int ret = 0, l3_div;
 	int *curr_opp;
+	unsigned long mpu_freq, dsp_freq, l3_freq;
+#ifndef CONFIG_CPU_FREQ
+	unsigned long mpu_cur_freq
+#endif
+
+	/* Check if I can actually switch or not */
+	if (res == VDD1_OPP) {
+		ret = opp_to_freq(&mpu_freq, mpu_opps, target_level);
+		ret |= opp_to_freq(&dsp_freq, dsp_opps, target_level);
+#ifndef CONFIG_CPU_FREQ
+		ret |= opp_to_freq(&mpu_cur_freq, mpu_opps, current_level);
+#endif
+	} else {
+		ret = opp_to_freq(&l3_freq, l3_opps, target_level);
+	}
+	/* we would have caught all bad levels earlier.. */
+	if (unlikely(ret))
+		return ret;
 
 	lock_scratchpad_sem();
 	if (res == VDD1_OPP) {
 		curr_opp = &curr_vdd1_opp;
-		clk_set_rate(dpll1_clk, mpu_opps[target_level].rate);
-		clk_set_rate(dpll2_clk, dsp_opps[target_level].rate);
+		clk_set_rate(dpll1_clk, mpu_freq);
+		clk_set_rate(dpll2_clk, dsp_freq);
 #ifndef CONFIG_CPU_FREQ
 		/*Update loops_per_jiffy if processor speed is being changed*/
 		loops_per_jiffy = compute_lpj(loops_per_jiffy,
-			mpu_opps[current_level].rate/1000,
-			mpu_opps[target_level].rate/1000);
+			mpu_cur_freq / 1000, mpu_freq / 1000);
 #endif
 	} else {
 		curr_opp = &curr_vdd2_opp;
 		l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
 			OMAP3430_CLKSEL_L3_MASK;
-		ret = clk_set_rate(dpll3_clk,
-				l3_opps[target_level].rate * l3_div);
+		ret = clk_set_rate(dpll3_clk, l3_freq * l3_div);
 	}
 	if (ret) {
 		unlock_scratchpad_sem();
@@ -278,6 +280,7 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
 		int current_level)
 {
 	int i, ret = 0, raise;
+	unsigned long freq;
 #ifdef CONFIG_OMAP_SMARTREFLEX
 	unsigned long t_opp, c_opp;
 
@@ -285,13 +288,10 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
 	c_opp = ID_VDD(res) | ID_OPP_NO(opp[current_level].opp_id);
 #endif
 
-	/* Only allow enabled OPPs */
-	if (!opp[target_level].enabled)
-		return -EINVAL;
-
-	/* Sanity check of the OPP params before attempting to set */
-	if (!opp[target_level].rate || !opp[target_level].vsel)
-		return -EINVAL;
+	/* See if have a freq associated, if not, invalid opp */
+	ret = opp_to_freq(&freq, opp, target_level);
+	if (unlikely(ret))
+		return ret;
 
 	if (target_level > current_level)
 		raise = 1;
@@ -303,10 +303,16 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
 			ret = program_opp_freq(res, target_level,
 					current_level);
 #ifdef CONFIG_OMAP_SMARTREFLEX
-		else
+		else {
+			u8 v_current, v_target;
+			/* none of the following should fail.. */
+			BUG_ON(freq_to_vsel(&v_target, opp, freq));
+			BUG_ON(opp_to_freq(&freq, opp, current_level));
+			BUG_ON(freq_to_vsel(&v_current, opp, freq));
+			/* ok to scale.. */
 			sr_voltagescale_vcbypass(t_opp, c_opp,
-				opp[target_level].vsel,
-				opp[current_level].vsel);
+				v_target, v_current);
+		}
 #endif
 	}
 
@@ -315,7 +321,8 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
 
 int resource_set_opp_level(int res, u32 target_level, int flags)
 {
-	unsigned long mpu_freq, mpu_old_freq;
+	unsigned long mpu_freq, mpu_old_freq, l3_freq;
+	int ret;
 #ifdef CONFIG_CPU_FREQ
 	struct cpufreq_freqs freqs_notify;
 #endif
@@ -334,6 +341,16 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
 	if (!mpu_opps || !dsp_opps || !l3_opps)
 		return 0;
 
+	/* Check if I can actually switch or not */
+	if (res == VDD1_OPP) {
+		ret = opp_to_freq(&mpu_freq, mpu_opps, target_level);
+		ret |= opp_to_freq(&mpu_old_freq, mpu_opps, resp->curr_level);
+	} else {
+		ret = opp_to_freq(&l3_freq, l3_opps, target_level);
+	}
+	if (ret)
+		return ret;
+
 	mutex_lock(&dvfs_mutex);
 
 	if (res == VDD1_OPP) {
@@ -341,9 +358,6 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
 			mutex_unlock(&dvfs_mutex);
 			return 0;
 		}
-		mpu_old_freq = mpu_opps[resp->curr_level].rate;
-		mpu_freq = mpu_opps[target_level].rate;
-
 #ifdef CONFIG_CPU_FREQ
 		freqs_notify.old = mpu_old_freq/1000;
 		freqs_notify.new = mpu_freq/1000;
@@ -371,15 +385,13 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
 
 int set_opp(struct shared_resource *resp, u32 target_level)
 {
-	unsigned long tput;
-	unsigned long req_l3_freq;
-	int ind;
+	int ret = -EINVAL;
 
 	if (resp == vdd1_resp) {
 		if (target_level < 3)
 			resource_release("vdd2_opp", &vdd2_dev);
 
-		resource_set_opp_level(VDD1_OPP, target_level, 0);
+		ret = resource_set_opp_level(VDD1_OPP, target_level, 0);
 		/*
 		 * For VDD1 OPP3 and above, make sure the interconnect
 		 * is at 100Mhz or above.
@@ -389,21 +401,28 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 			resource_request("vdd2_opp", &vdd2_dev, 400000);
 
 	} else if (resp == vdd2_resp) {
-		tput = target_level;
+		unsigned long req_l3_freq;
 
 		/* Convert the tput in KiB/s to Bus frequency in MHz */
-		req_l3_freq = (tput * 1000)/4;
-
-		for (ind = 2; ind <= MAX_VDD2_OPP; ind++)
-			if ((l3_opps + ind)->rate >= req_l3_freq) {
-				target_level = ind;
-				break;
-			}
-
-		/* Set the highest OPP possible */
-		if (ind > MAX_VDD2_OPP)
-			target_level = ind-1;
-		resource_set_opp_level(VDD2_OPP, target_level, 0);
+		req_l3_freq = (target_level * 1000)/4;
+
+		/* Get the best freq around */
+		ret = get_next_freq(&req_l3_freq, l3_opps, true, true, false);
+
+		/* If we dont find a good freq, then use the highest
+		 * possible freq
+		 */
+		if (ret)
+			ret = get_limit_freq(&req_l3_freq, l3_opps, true, true);
+
+		/* uh uh.. no OPPs?? */
+		BUG_ON(ret);
+
+		ret = freq_to_opp((u8 *)&target_level, l3_opps, req_l3_freq);
+		/* we dont expect this to fail */
+		BUG_ON(ret);
+
+		ret = resource_set_opp_level(VDD2_OPP, target_level, 0);
 	}
 	return 0;
 }
@@ -416,6 +435,11 @@ int set_opp(struct shared_resource *resp, u32 target_level)
  */
 int validate_opp(struct shared_resource *resp, u32 target_level)
 {
+	unsigned long x;
+	if (strcmp(resp->name, "mpu_freq") == 0)
+		return opp_to_freq(&x, mpu_opps, target_level);
+	else if (strcmp(resp->name, "dsp_freq") == 0)
+		return opp_to_freq(&x, dsp_opps, target_level);
 	return 0;
 }
 
@@ -425,6 +449,8 @@ int validate_opp(struct shared_resource *resp, u32 target_level)
 void init_freq(struct shared_resource *resp)
 {
 	char *linked_res_name;
+	int ret = -EINVAL;
+	unsigned long freq;
 	resp->no_of_users = 0;
 
 	if (!mpu_opps || !dsp_opps)
@@ -436,32 +462,46 @@ void init_freq(struct shared_resource *resp)
 	*/
 	if (strcmp(resp->name, "mpu_freq") == 0)
 		/* MPU freq in Mhz */
-		resp->curr_level = mpu_opps[curr_vdd1_opp].rate;
+		ret = opp_to_freq(&freq, mpu_opps, curr_vdd1_opp);
 	else if (strcmp(resp->name, "dsp_freq") == 0)
 		/* DSP freq in Mhz */
-		resp->curr_level = dsp_opps[curr_vdd1_opp].rate;
+		ret = opp_to_freq(&freq, dsp_opps, curr_vdd1_opp);
+	BUG_ON(ret);
+
+	resp->curr_level = freq;
 	return;
 }
 
 int set_freq(struct shared_resource *resp, u32 target_level)
 {
-	unsigned int vdd1_opp;
+	u8 vdd1_opp;
+	int ret = -EINVAL;
 
 	if (!mpu_opps || !dsp_opps)
 		return 0;
 
 	if (strcmp(resp->name, "mpu_freq") == 0) {
-		vdd1_opp = get_opp(mpu_opps + MAX_VDD1_OPP, target_level);
-		resource_request("vdd1_opp", &dummy_mpu_dev, vdd1_opp);
+		ret = freq_to_opp(&vdd1_opp, mpu_opps, target_level);
+		if (!ret)
+			ret = resource_request("vdd1_opp", &dummy_mpu_dev,
+					vdd1_opp);
 	} else if (strcmp(resp->name, "dsp_freq") == 0) {
-		vdd1_opp = get_opp(dsp_opps + MAX_VDD1_OPP, target_level);
-		resource_request("vdd1_opp", &dummy_dsp_dev, vdd1_opp);
+		ret = freq_to_opp(&vdd1_opp, dsp_opps, target_level);
+		if (!ret)
+			ret = resource_request("vdd1_opp", &dummy_dsp_dev,
+					vdd1_opp);
 	}
-	resp->curr_level = target_level;
-	return 0;
+	if (!ret)
+		resp->curr_level = target_level;
+	return ret;
 }
 
 int validate_freq(struct shared_resource *resp, u32 target_level)
 {
+	u8 x;
+	if (strcmp(resp->name, "mpu_freq") == 0)
+		return freq_to_opp(&x, mpu_opps, target_level);
+	else if (strcmp(resp->name, "dsp_freq") == 0)
+		return freq_to_opp(&x, dsp_opps, target_level);
 	return 0;
 }
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/9] omap3: pm: use opp accessor functions for omap-target
  2009-11-12  5:45     ` [PATCH 3/9] omap3: pm: srf: introduce accessor function Nishanth Menon
@ 2009-11-12  5:45       ` Nishanth Menon
  2009-11-12  5:45         ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Nishanth Menon
  0 siblings, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

The logic in omap-target can now be improved with the accessor
functions. Dont scan through the list manually, instead use
get_next_freq to do the scanning.

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/plat-omap/cpu-omap.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index f9b480d..dac1eab 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -111,14 +111,10 @@ static int omap_target(struct cpufreq_policy *policy,
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 #elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
 	if (mpu_opps) {
-		int ind;
-		for (ind = 1; ind <= MAX_VDD1_OPP; ind++) {
-			if (mpu_opps[ind].rate/1000 >= target_freq) {
-				omap_pm_cpu_set_freq
-					(mpu_opps[ind].rate);
-				break;
-			}
-		}
+		unsigned long freq = target_freq * 1000;
+		int res = get_next_freq(&freq, mpu_opps, true, true, false);
+		if (!res)
+			omap_pm_cpu_set_freq(freq);
 	}
 #endif
 	return ret;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2009-11-12  5:45       ` [PATCH 4/9] omap3: pm: use opp accessor functions for omap-target Nishanth Menon
@ 2009-11-12  5:45         ` Nishanth Menon
  2009-11-12  5:45           ` [PATCH 6/9] omap3: clk: use pm accessor functions for cpufreq table Nishanth Menon
  2009-12-18 23:12           ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Kevin Hilman
  0 siblings, 2 replies; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

SmartReflex implements a get_opp to search through the opp table,
replace it with the accessor function as it is a duplicate of
freq_to_opp

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |   36 ++++++++----------------------------
 1 files changed, 8 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index be3a1da..d34224d 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -146,49 +146,29 @@ static u32 cal_test_nvalue(u32 sennval, u32 senpval)
 		(rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT);
 }
 
-/* determine the current OPP from the frequency
- * we need to give this function last element of OPP rate table
- * and the frequency
- */
-static u16 get_opp(struct omap_opp *opp_freq_table,
-					unsigned long freq)
-{
-	struct omap_opp *prcm_config;
-
-	prcm_config = opp_freq_table;
-
-	if (prcm_config->rate <= freq)
-		return prcm_config->opp_id; /* Return the Highest OPP */
-	for (; prcm_config->rate; prcm_config--)
-		if (prcm_config->rate < freq)
-			return (prcm_config+1)->opp_id;
-		else if (prcm_config->rate == freq)
-			return prcm_config->opp_id;
-	/* Return the least OPP */
-	return (prcm_config+1)->opp_id;
-}
-
-static u16 get_vdd1_opp(void)
+static u8 get_vdd1_opp(void)
 {
-	u16 opp;
+	u8 opp;
 
 	if (sr1.vdd_opp_clk == NULL || IS_ERR(sr1.vdd_opp_clk) ||
 							mpu_opps == NULL)
 		return 0;
 
-	opp = get_opp(mpu_opps + MAX_VDD1_OPP, sr1.vdd_opp_clk->rate);
+	/* Not expected to fail.. */
+	BUG_ON(freq_to_opp(&opp, mpu_opps, sr1.vdd_opp_clk->rate));
 	return opp;
 }
 
-static u16 get_vdd2_opp(void)
+static u8 get_vdd2_opp(void)
 {
-	u16 opp;
+	u8 opp;
 
 	if (sr2.vdd_opp_clk == NULL || IS_ERR(sr2.vdd_opp_clk) ||
 							l3_opps == NULL)
 		return 0;
 
-	opp = get_opp(l3_opps + MAX_VDD2_OPP, sr2.vdd_opp_clk->rate);
+	/* Not expected to fail.. */
+	BUG_ON(freq_to_opp(&opp, l3_opps, sr2.vdd_opp_clk->rate));
 	return opp;
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 6/9] omap3: clk: use pm accessor functions for cpufreq table
  2009-11-12  5:45         ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Nishanth Menon
@ 2009-11-12  5:45           ` Nishanth Menon
  2009-11-12  5:45             ` [PATCH 7/9] omap3: pm: remove VDDx_MIN/MAX macros Nishanth Menon
  2009-12-18 23:12           ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Kevin Hilman
  1 sibling, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

omap2_clk_init_cpufreq_table currently directly accesses the opp
table, making it unscalable to various OMAPs. Instead use the
accessor functions to populate the cpufreq table

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/clock34xx.c |   46 +++++++++++++++++++++++++++-----------
 1 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index da5bc1f..daec6ea 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -1042,28 +1042,46 @@ static unsigned long omap3_clkoutx2_recalc(struct clk *clk)
 #if defined(CONFIG_ARCH_OMAP3)
 
 #ifdef CONFIG_CPU_FREQ
-static struct cpufreq_frequency_table freq_table[MAX_VDD1_OPP+1];
+
+/* Use a dummy table with no entries to start with */
+static struct cpufreq_frequency_table dummy_freq_table = {
+	.frequency = CPUFREQ_TABLE_END,
+};
+static struct cpufreq_frequency_table *freq_table = &dummy_freq_table;
 
 void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
 {
-	struct omap_opp *prcm;
-	int i = 0;
+	int i;
+	int ret;
+	u8 opp_id;
+	unsigned long freq;
 
 	if (!mpu_opps)
 		return;
-
-	prcm = mpu_opps + MAX_VDD1_OPP;
-	for (; prcm->rate; prcm--) {
-		freq_table[i].index = i;
-		freq_table[i].frequency = prcm->rate / 1000;
-		i++;
+	ret = get_limit_freq(&freq, mpu_opps, true, true);
+	if (ret) {
+		pr_warning("%s: failed to initialize frequency"
+				"table\n", __func__);
+		return;
 	}
+	/* The following should'nt fail */
+	BUG_ON(freq_to_opp(&opp_id, mpu_opps, freq));
 
-	if (i == 0) {
-		printk(KERN_WARNING "%s: failed to initialize frequency \
-								table\n",
-								__func__);
-		return;
+	/* There is a risk of overallocating if the lower/intermediate
+	 * OPPs are disabled, but the amount is not expected to be high
+	 * in comparison to reallocating to exactly available opps
+	 */
+	freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
+			(opp_id + 1), GFP_KERNEL);
+
+	/* Populate the first index.. we already found the freq */
+	freq_table[0].index = 0;
+	freq_table[0].frequency =  freq / 1000;
+
+	/* Populate the table highest to lowest */
+	for (i = 1; !get_next_freq(&freq, mpu_opps, false, true, true); i++) {
+		freq_table[i].index = i;
+		freq_table[i].frequency =  freq / 1000;
 	}
 
 	freq_table[i].index = i;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 7/9] omap3: pm: remove VDDx_MIN/MAX macros
  2009-11-12  5:45           ` [PATCH 6/9] omap3: clk: use pm accessor functions for cpufreq table Nishanth Menon
@ 2009-11-12  5:45             ` Nishanth Menon
  2009-11-12  5:45               ` [PATCH 8/9] omap3: pm: introduce dynamic OPP Nishanth Menon
  0 siblings, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

Since accessor functions are used through out, we dont depend
on the predefined macros to know the limits of the opp table.
Hence, remove these.

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/plat-omap/include/plat/omap34xx.h |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
index 868e238..cc7cfae 100644
--- a/arch/arm/plat-omap/include/plat/omap34xx.h
+++ b/arch/arm/plat-omap/include/plat/omap34xx.h
@@ -104,10 +104,5 @@
 #define VDD2_OPP2	0x2
 #define VDD2_OPP3	0x3
 
-#define MIN_VDD1_OPP	VDD1_OPP1
-#define MAX_VDD1_OPP	VDD1_OPP5
-#define MIN_VDD2_OPP	VDD2_OPP1
-#define MAX_VDD2_OPP	VDD2_OPP3
-
 #endif /* __ASM_ARCH_OMAP34XX_H */
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 8/9] omap3: pm: introduce dynamic OPP
  2009-11-12  5:45             ` [PATCH 7/9] omap3: pm: remove VDDx_MIN/MAX macros Nishanth Menon
@ 2009-11-12  5:45               ` Nishanth Menon
  2009-11-12  5:45                 ` [PATCH 9/9] omap3: pm: introduce 3630 opps Nishanth Menon
  0 siblings, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

OPP tables have been used as static arrays till now this causes
limitations in terms of ability to dynamically making decisions
for cpu types and populating it with the right values. This
implementation is based on the discussions in the thread:
http://marc.info/?l=linux-omap&m=125482970102327&w=2
inputs from Romit, Benoit, Kevin, Sanjeev, Santosh acked.

omap3_pm_init_opp_table is introduced here, and the default omap3
tables have been renamed to omap34xx_ tables, original omap3_xx
tables are now dynamically allocated and populated.

Corresponding board files calling omap2_init_common_hw with the
active opp table params have been updated with this patch.

This now paves way to introduce 3630 OPP tables.

Tested on: SDP3430

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/board-3430sdp.c     |    1 +
 arch/arm/mach-omap2/board-omap3beagle.c |    1 +
 arch/arm/mach-omap2/board-omap3evm.c    |    1 +
 arch/arm/mach-omap2/board-rx51.c        |    2 ++
 arch/arm/mach-omap2/board-zoom2.c       |    2 ++
 arch/arm/mach-omap2/omap3-opp.h         |    6 +++---
 arch/arm/mach-omap2/pm.h                |    8 ++++++++
 arch/arm/mach-omap2/pm34xx.c            |   31 ++++++++++++++++++++++++++++---
 8 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 11f0dc5..de1b632 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -222,6 +222,7 @@ static void __init omap_3430sdp_init_irq(void)
 	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
 	omap3_pm_init_vc(&omap3_setuptime_table);
 	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
+	omap3_pm_init_opp_table();
 	omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL, omap3_mpu_rate_table,
 			     omap3_dsp_rate_table, omap3_l3_rate_table);
 	omap_init_irq();
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index d0a95ea..65bab97 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -351,6 +351,7 @@ static void __init omap3_beagle_init_irq(void)
 {
 	omap_board_config = omap3_beagle_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
+	omap3_pm_init_opp_table();
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 			     mt46h32m32lf6_sdrc_params, omap3_mpu_rate_table,
 			     omap3_dsp_rate_table, omap3_l3_rate_table);
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 2c63002..d8318cd 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -336,6 +336,7 @@ static void __init omap3_evm_init_irq(void)
 {
 	omap_board_config = omap3_evm_config;
 	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
+	omap3_pm_init_opp_table();
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL, omap3_mpu_rate_table,
 	                     omap3_dsp_rate_table, omap3_l3_rate_table);
 	omap_init_irq();
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 527f0c6..1f24933 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -31,6 +31,7 @@
 #include <plat/gpmc.h>
 #include <plat/usb.h>
 
+#include "pm.h"
 #include "omap3-opp.h"
 
 #define RX51_GPIO_SLEEP_IND 162
@@ -84,6 +85,7 @@ static void __init rx51_init_irq(void)
 {
 	omap_board_config = rx51_config;
 	omap_board_config_size = ARRAY_SIZE(rx51_config);
+	omap3_pm_init_opp_table();
 	omap2_init_common_hw(rx51_get_sdram_timings(),
 			     rx51_get_sdram_timings(), omap3_mpu_rate_table,
 			     omap3_dsp_rate_table, omap3_l3_rate_table);
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index b6801a7..a7e1fee 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -25,6 +25,7 @@
 #include <plat/usb.h>
 
 #include "mmc-twl4030.h"
+#include "pm.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "omap3-opp.h"
 
@@ -215,6 +216,7 @@ static void __init omap_zoom2_init_irq(void)
 {
 	omap_board_config = zoom2_config;
 	omap_board_config_size = ARRAY_SIZE(zoom2_config);
+	omap3_pm_init_opp_table();
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
 				 mt46h32m32lf6_sdrc_params, omap3_mpu_rate_table,
 				 omap3_dsp_rate_table, omap3_l3_rate_table);
diff --git a/arch/arm/mach-omap2/omap3-opp.h b/arch/arm/mach-omap2/omap3-opp.h
index 27e2ca5..7f27f44 100644
--- a/arch/arm/mach-omap2/omap3-opp.h
+++ b/arch/arm/mach-omap2/omap3-opp.h
@@ -21,8 +21,8 @@
 #define S83M    83000000
 #define S166M   166000000
 
-extern struct omap_opp omap3_mpu_rate_table[];
-extern struct omap_opp omap3_dsp_rate_table[];
-extern struct omap_opp omap3_l3_rate_table[];
+extern struct omap_opp *omap3_mpu_rate_table;
+extern struct omap_opp *omap3_dsp_rate_table;
+extern struct omap_opp *omap3_l3_rate_table;
 
 #endif
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index b576424..1aabf74 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -51,6 +51,14 @@ struct cpuidle_params {
 extern void omap3_pm_init_vc(struct prm_setup_vc *setup_vc);
 extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params);
 
+/**
+ * omap3_pm_init_opp_table - OMAP opp table lookup called after
+ * cpu is detected.
+ * Initialize the basic opp table here, board files
+ * could choose to modify opp table after the basic initialization
+ */
+extern void omap3_pm_init_opp_table(void);
+
 extern int resource_set_opp_level(int res, u32 target_level, int flags);
 extern int resource_access_opp_lock(int res, int delta);
 #define resource_lock_opp(res) resource_access_opp_lock(res, 1)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 92f11d7..511137c 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -99,7 +99,7 @@ static struct prm_setup_vc prm_setup = {
 	.vdd1_off = 0x00,	/* 0.6v */
 };
 
-struct omap_opp omap3_mpu_rate_table[] = {
+static __initdata struct omap_opp omap34xx_mpu_rate_table[] = {
 	{0, 0, 0, 0},
 	/*OPP1*/
 	{true, S125M, VDD1_OPP1, 0x1E},
@@ -114,7 +114,7 @@ struct omap_opp omap3_mpu_rate_table[] = {
 	{0, 0, 0, 0},
 };
 
-struct omap_opp omap3_l3_rate_table[] = {
+static __initdata struct omap_opp omap34xx_l3_rate_table[] = {
 	{0, 0, 0, 0},
 	/*OPP1*/
 	{false, 0, VDD2_OPP1, 0x1E},
@@ -125,7 +125,7 @@ struct omap_opp omap3_l3_rate_table[] = {
 	{0, 0, 0, 0},
 };
 
-struct omap_opp omap3_dsp_rate_table[] = {
+static __initdata struct omap_opp omap34xx_dsp_rate_table[] = {
 	{0, 0, 0, 0},
 	/*OPP1*/
 	{true, S90M, VDD1_OPP1, 0x1E},
@@ -140,6 +140,10 @@ struct omap_opp omap3_dsp_rate_table[] = {
 	{0, 0, 0, 0},
 };
 
+struct omap_opp *omap3_mpu_rate_table;
+struct omap_opp *omap3_dsp_rate_table;
+struct omap_opp *omap3_l3_rate_table;
+
 static inline void omap3_per_save_context(void)
 {
 	omap_gpio_save_context();
@@ -1276,6 +1280,27 @@ static void __init configure_vc(void)
 	pm_dbg_regset_init(2);
 }
 
+void __init omap3_pm_init_opp_table(void)
+{
+	/* Populate the base CPU rate tables here */
+	omap3_mpu_rate_table = kmalloc(sizeof(omap34xx_mpu_rate_table),
+			GFP_KERNEL);
+	omap3_dsp_rate_table = kmalloc(sizeof(omap34xx_dsp_rate_table),
+			GFP_KERNEL);
+	omap3_l3_rate_table = kmalloc(sizeof(omap34xx_l3_rate_table),
+			GFP_KERNEL);
+
+	BUG_ON(!omap3_mpu_rate_table || !omap3_dsp_rate_table ||
+		!omap3_l3_rate_table);
+
+	memcpy(omap3_mpu_rate_table, omap34xx_mpu_rate_table,
+			sizeof(omap34xx_mpu_rate_table));
+	memcpy(omap3_dsp_rate_table, omap34xx_dsp_rate_table,
+			sizeof(omap34xx_dsp_rate_table));
+	memcpy(omap3_l3_rate_table, omap34xx_l3_rate_table,
+			sizeof(omap34xx_l3_rate_table));
+}
+
 static int __init omap3_pm_early_init(void)
 {
 	prm_clear_mod_reg_bits(OMAP3430_OFFMODE_POL, OMAP3430_GR_MOD,
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 9/9] omap3: pm: introduce 3630 opps
  2009-11-12  5:45               ` [PATCH 8/9] omap3: pm: introduce dynamic OPP Nishanth Menon
@ 2009-11-12  5:45                 ` Nishanth Menon
  0 siblings, 0 replies; 22+ messages in thread
From: Nishanth Menon @ 2009-11-12  5:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

Introduce the OMAP3630 OPPs including the defined OPP tuples.

Further information on OMAP3630 can be found here:
http://focus.ti.com/general/docs/wtbu/wtbuproductcontent.tsp?templateId=6123&navigationId=12836&contentId=52606

OMAP36xx family introduces:
VDD1 with 4 OPPs, of which OPP3 & 4 are available only on devices yet
to be introduced in 36xx family. Meanwhile, VDD2 has 2 opps.

Device Support of OPPs->
           |<-3630-600->| (default)
           |<-      3630-800    ->| (device: TBD)
           |<-      3630-1000            ->| (device: TBD)
H/w OPP-> OPP50 OPP100       OPP-Turbo   OPP1G-SB
VDD1      OPP1  OPP2         OPP3        OPP4
VDD2      OPP1  OPP2         OPP2        OPP2

Note:
a) TI h/w naming for OPPs are now standardized in terms of OPP50, 100,
   Turbo and SB. This maps as shown above to the opp IDs (s/w term).
b) For boards which need custom VDD1/2 OPPs, the opp table can be
   updated by the board file on a need basis after the
   omap3_pm_init_opp_table call. The OPPs introduced here are the
   official OPP table at this point in time.

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/omap3-opp.h |    9 ++++
 arch/arm/mach-omap2/pm34xx.c    |   87 +++++++++++++++++++++++++++++++-------
 2 files changed, 80 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-omap2/omap3-opp.h b/arch/arm/mach-omap2/omap3-opp.h
index 7f27f44..a5880b8 100644
--- a/arch/arm/mach-omap2/omap3-opp.h
+++ b/arch/arm/mach-omap2/omap3-opp.h
@@ -4,22 +4,31 @@
 #include <plat/omap-pm.h>
 
 /* MPU speeds */
+#define S1000M  1000000000
+#define S800M   800000000
 #define S600M   600000000
 #define S550M   550000000
 #define S500M   500000000
+#define S300M   300000000
 #define S250M   250000000
 #define S125M   125000000
 
 /* DSP speeds */
+#define S875M   875000000
+#define S660M   660000000
+#define S520M   520000000
 #define S430M   430000000
 #define S400M   400000000
 #define S360M   360000000
+#define S260M   260000000
 #define S180M   180000000
 #define S90M    90000000
 
 /* L3 speeds */
 #define S83M    83000000
+#define S100M   100000000
 #define S166M   166000000
+#define S200M   200000000
 
 extern struct omap_opp *omap3_mpu_rate_table;
 extern struct omap_opp *omap3_dsp_rate_table;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 511137c..ffed70f 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -140,6 +140,41 @@ static __initdata struct omap_opp omap34xx_dsp_rate_table[] = {
 	{0, 0, 0, 0},
 };
 
+static __initdata struct omap_opp omap36xx_mpu_rate_table[] = {
+	{0, 0, 0, 0},
+	/*OPP1 - 930mV - OPP50*/
+	{true, S300M, VDD1_OPP1, 0x1A},
+	/*OPP2 - 1.100V - OPP100*/
+	{true, S600M, VDD1_OPP2, 0x28},
+	/*OPP3 - 1.260V - OPP-Turbo*/
+	{true, S800M, VDD1_OPP3, 0x34},
+	/*OPP4 - 1.310V - OPP-SB*/
+	{false, S1000M, VDD1_OPP4, 0x38},
+	{0, 0, 0, 0},
+};
+
+static __initdata struct omap_opp omap36xx_l3_rate_table[] = {
+	{0, 0, 0, 0},
+	/*OPP1 - 930mV - OPP50 */
+	{true, S100M, VDD2_OPP1, 0x1A},
+	/*OPP2 - 1.375V - OPP100, OPP-Turbo, OPP-SB*/
+	{true, S200M, VDD2_OPP2, 0x3E},
+	{0, 0, 0, 0},
+};
+
+static __initdata struct omap_opp omap36xx_dsp_rate_table[] = {
+	{0, 0, 0, 0},
+	/*OPP1 - OPP50*/
+	{true, S260M, VDD1_OPP1, 0x1A},
+	/*OPP2 - OPP100*/
+	{true, S520M, VDD1_OPP2, 0x28},
+	/*OPP3 - OPP-Turbo*/
+	{false, S660M, VDD1_OPP3, 0x34},
+	/*OPP4 - OPP-SB*/
+	{false, S875M, VDD1_OPP4, 0x38},
+	{0, 0, 0, 0},
+};
+
 struct omap_opp *omap3_mpu_rate_table;
 struct omap_opp *omap3_dsp_rate_table;
 struct omap_opp *omap3_l3_rate_table;
@@ -1283,22 +1318,42 @@ static void __init configure_vc(void)
 void __init omap3_pm_init_opp_table(void)
 {
 	/* Populate the base CPU rate tables here */
-	omap3_mpu_rate_table = kmalloc(sizeof(omap34xx_mpu_rate_table),
-			GFP_KERNEL);
-	omap3_dsp_rate_table = kmalloc(sizeof(omap34xx_dsp_rate_table),
-			GFP_KERNEL);
-	omap3_l3_rate_table = kmalloc(sizeof(omap34xx_l3_rate_table),
-			GFP_KERNEL);
-
-	BUG_ON(!omap3_mpu_rate_table || !omap3_dsp_rate_table ||
-		!omap3_l3_rate_table);
-
-	memcpy(omap3_mpu_rate_table, omap34xx_mpu_rate_table,
-			sizeof(omap34xx_mpu_rate_table));
-	memcpy(omap3_dsp_rate_table, omap34xx_dsp_rate_table,
-			sizeof(omap34xx_dsp_rate_table));
-	memcpy(omap3_l3_rate_table, omap34xx_l3_rate_table,
-			sizeof(omap34xx_l3_rate_table));
+	if (cpu_is_omap3630()) {
+		omap3_mpu_rate_table = kmalloc(sizeof(omap36xx_mpu_rate_table),
+				GFP_KERNEL);
+		omap3_dsp_rate_table = kmalloc(sizeof(omap36xx_dsp_rate_table),
+				GFP_KERNEL);
+		omap3_l3_rate_table = kmalloc(sizeof(omap36xx_l3_rate_table),
+				GFP_KERNEL);
+
+		BUG_ON(!omap3_mpu_rate_table || !omap3_dsp_rate_table ||
+			!omap3_l3_rate_table);
+
+		memcpy(omap3_mpu_rate_table, omap36xx_mpu_rate_table,
+				sizeof(omap36xx_mpu_rate_table));
+		memcpy(omap3_dsp_rate_table, omap36xx_dsp_rate_table,
+				sizeof(omap36xx_dsp_rate_table));
+		memcpy(omap3_l3_rate_table, omap36xx_l3_rate_table,
+				sizeof(omap36xx_l3_rate_table));
+	} else {
+		/* Default to 34xx devices */
+		omap3_mpu_rate_table = kmalloc(sizeof(omap34xx_mpu_rate_table),
+				GFP_KERNEL);
+		omap3_dsp_rate_table = kmalloc(sizeof(omap34xx_dsp_rate_table),
+				GFP_KERNEL);
+		omap3_l3_rate_table = kmalloc(sizeof(omap34xx_l3_rate_table),
+				GFP_KERNEL);
+
+		BUG_ON(!omap3_mpu_rate_table || !omap3_dsp_rate_table ||
+			!omap3_l3_rate_table);
+
+		memcpy(omap3_mpu_rate_table, omap34xx_mpu_rate_table,
+				sizeof(omap34xx_mpu_rate_table));
+		memcpy(omap3_dsp_rate_table, omap34xx_dsp_rate_table,
+				sizeof(omap34xx_dsp_rate_table));
+		memcpy(omap3_l3_rate_table, omap34xx_l3_rate_table,
+				sizeof(omap34xx_l3_rate_table));
+	}
 }
 
 static int __init omap3_pm_early_init(void)
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2009-11-13  6:05       ` [PATCH 4/9] omap3: pm: use opp accessor functions for omap-target Nishanth Menon
@ 2009-11-13  6:05         ` Nishanth Menon
  0 siblings, 0 replies; 22+ messages in thread
From: Nishanth Menon @ 2009-11-13  6:05 UTC (permalink / raw)
  To: linux-omap
  Cc: Nishanth Menon, Benoit Cousson, Jon Hunter, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Romit Dasgupta,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, SuiLun Lam, Thara Gopinath,
	Vishwanath Sripathy

SmartReflex implements a get_opp to search through the opp table,
replace it with the accessor function as it is a duplicate of
freq_to_opp

Tested on: SDP3430, SDP3630

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Jon Hunter <jon-hunter@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Romit Dasgupta <romit@ti.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: SuiLun Lam <s-lam@ti.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Nishanth Menon <nm@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |   36 ++++++++----------------------------
 1 files changed, 8 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index be3a1da..d34224d 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -146,49 +146,29 @@ static u32 cal_test_nvalue(u32 sennval, u32 senpval)
 		(rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT);
 }
 
-/* determine the current OPP from the frequency
- * we need to give this function last element of OPP rate table
- * and the frequency
- */
-static u16 get_opp(struct omap_opp *opp_freq_table,
-					unsigned long freq)
-{
-	struct omap_opp *prcm_config;
-
-	prcm_config = opp_freq_table;
-
-	if (prcm_config->rate <= freq)
-		return prcm_config->opp_id; /* Return the Highest OPP */
-	for (; prcm_config->rate; prcm_config--)
-		if (prcm_config->rate < freq)
-			return (prcm_config+1)->opp_id;
-		else if (prcm_config->rate == freq)
-			return prcm_config->opp_id;
-	/* Return the least OPP */
-	return (prcm_config+1)->opp_id;
-}
-
-static u16 get_vdd1_opp(void)
+static u8 get_vdd1_opp(void)
 {
-	u16 opp;
+	u8 opp;
 
 	if (sr1.vdd_opp_clk == NULL || IS_ERR(sr1.vdd_opp_clk) ||
 							mpu_opps == NULL)
 		return 0;
 
-	opp = get_opp(mpu_opps + MAX_VDD1_OPP, sr1.vdd_opp_clk->rate);
+	/* Not expected to fail.. */
+	BUG_ON(freq_to_opp(&opp, mpu_opps, sr1.vdd_opp_clk->rate));
 	return opp;
 }
 
-static u16 get_vdd2_opp(void)
+static u8 get_vdd2_opp(void)
 {
-	u16 opp;
+	u8 opp;
 
 	if (sr2.vdd_opp_clk == NULL || IS_ERR(sr2.vdd_opp_clk) ||
 							l3_opps == NULL)
 		return 0;
 
-	opp = get_opp(l3_opps + MAX_VDD2_OPP, sr2.vdd_opp_clk->rate);
+	/* Not expected to fail.. */
+	BUG_ON(freq_to_opp(&opp, l3_opps, sr2.vdd_opp_clk->rate));
 	return opp;
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2009-11-12  5:45         ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Nishanth Menon
  2009-11-12  5:45           ` [PATCH 6/9] omap3: clk: use pm accessor functions for cpufreq table Nishanth Menon
@ 2009-12-18 23:12           ` Kevin Hilman
  2009-12-19 11:35             ` Menon, Nishanth
  2009-12-21  6:58             ` Romit Dasgupta
  1 sibling, 2 replies; 22+ messages in thread
From: Kevin Hilman @ 2009-12-18 23:12 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: linux-omap, Benoit Cousson, Madhusudhan Chikkature Rajashekar,
	Paul Walmsley, Romit Dasgupta, Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Thara Gopinath,
	Vishwanath Sripathy

Nishanth Menon <nm@ti.com> writes:

> SmartReflex implements a get_opp to search through the opp table,
> replace it with the accessor function as it is a duplicate of
> freq_to_opp

SmartReflex is not quite working with this version which is in
pm-wip-opp.  My (untested) theory below...

[...]

> --- a/arch/arm/mach-omap2/smartreflex.c
> +++ b/arch/arm/mach-omap2/smartreflex.c
> @@ -146,49 +146,29 @@ static u32 cal_test_nvalue(u32 sennval, u32 senpval)
>  		(rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT);
>  }
>  
> -/* determine the current OPP from the frequency
> - * we need to give this function last element of OPP rate table
> - * and the frequency
> - */
> -static u16 get_opp(struct omap_opp *opp_freq_table,
> -					unsigned long freq)
> -{
> -	struct omap_opp *prcm_config;
> -
> -	prcm_config = opp_freq_table;
> -
> -	if (prcm_config->rate <= freq)
> -		return prcm_config->opp_id; /* Return the Highest OPP */
> -	for (; prcm_config->rate; prcm_config--)
> -		if (prcm_config->rate < freq)
> -			return (prcm_config+1)->opp_id;
> -		else if (prcm_config->rate == freq)
> -			return prcm_config->opp_id;
> -	/* Return the least OPP */
> -	return (prcm_config+1)->opp_id;
> -}

The function you removed here is doing the equivalent of
opp_find_freq_ceil()


> -static u16 get_vdd1_opp(void)
> +static u8 get_vdd1_opp(void)
>  {
> -	u16 opp;
> +	u8 opp;
>  
>  	if (sr1.vdd_opp_clk == NULL || IS_ERR(sr1.vdd_opp_clk) ||
>  							mpu_opps == NULL)
>  		return 0;
>  
> -	opp = get_opp(mpu_opps + MAX_VDD1_OPP, sr1.vdd_opp_clk->rate);
> +	/* Not expected to fail.. */
> +	BUG_ON(freq_to_opp(&opp, mpu_opps, sr1.vdd_opp_clk->rate));
>  	return opp;
>  }

Ih this version you use freq_to_opp(), but in the V5 tarball you sent,
you replace get_opp with:

	opp = opp_find_freq_exact(mpu_opps, sr1.vdd_opp_clk->rate, true);

This results in never finding an OPP, and SR never scaling.

This should probably be opp_find_freq_ceil(), right?

Kevin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2009-12-18 23:12           ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Kevin Hilman
@ 2009-12-19 11:35             ` Menon, Nishanth
  2009-12-22 16:45               ` Kevin Hilman
  2009-12-21  6:58             ` Romit Dasgupta
  1 sibling, 1 reply; 22+ messages in thread
From: Menon, Nishanth @ 2009-12-19 11:35 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, Cousson, Benoit, Chikkature Rajashekar, Madhusudhan,
	Paul Walmsley, Dasgupta, Romit, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Gopinath, Thara,
	Sripathy, Vishwanath, K, Ambresh

Kevin Hilman said the following on 12/19/2009 04:42 AM:
> Nishanth Menon <nm@ti.com> writes:
>
>   
>> SmartReflex implements a get_opp to search through the opp table,
>> replace it with the accessor function as it is a duplicate of
>> freq_to_opp
>>     
>
> SmartReflex is not quite working with this version which is in
> pm-wip-opp.  My (untested) theory below...
>
> [...]
>   
Ambresh and I  just tested the very latest of the pm-wip-opp branch and 
checked. Voltage transitions and SR adjustments are happily happening on 
SDP3430 ES3.1 at the very least (verified with a scope on vdd1).

and if you look closely in the code, sr2.vdd_opp_clk->rate and 
sr1.vdd_opp_clk->rate are based on
sr1.vdd_opp_clk = clk_get(NULL, "dpll1_ck")
sr2.vdd_opp_clk = clk_get(NULL, "l3_ick");

now, if the dpll1_ck ->rate and l3_ick->rate are not exact frequencies 
as the opp tables, I think we have a clockframework bug and the code 
here is correct. we should fix the clockframework/find the rootcause 
elsewhere.

Now is the clockframework wrong? we added a patch to print the 
frequencies and checked if IS_ERR(opp) is true -> not a single call 
while using cpu_freq transitions resulted in an error value and all the 
frequencies we printed were from the OPP table

Might be good to hear your rationale for saying this result..

Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2009-12-18 23:12           ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Kevin Hilman
  2009-12-19 11:35             ` Menon, Nishanth
@ 2009-12-21  6:58             ` Romit Dasgupta
  1 sibling, 0 replies; 22+ messages in thread
From: Romit Dasgupta @ 2009-12-21  6:58 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Menon, Nishanth, linux-omap, Cousson, Benoit,
	Chikkature Rajashekar, Madhusudhan, Paul Walmsley, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Gopinath, Thara,
	Sripathy, Vishwanath

Kevin Hilman wrote:
> Nishanth Menon <nm@ti.com> writes:
> 
> 
> SmartReflex is not quite working with this version which is in
> pm-wip-opp.  My (untested) theory below...
Mostly you have not included SR in the build. OTOH I raised this issue earlier
that the omap cpufreq driver is not honoring CPUFREQ_RELATION_L and
CPUFREQ_RELATION_H flags. I do not understand why do we need to do a
opp_find_freq_ceil here? The validate function of the frequency resources would
have already identified if we can get this exact frequency or not.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2009-12-19 11:35             ` Menon, Nishanth
@ 2009-12-22 16:45               ` Kevin Hilman
  2010-01-06 23:46                 ` Nishanth Menon
  0 siblings, 1 reply; 22+ messages in thread
From: Kevin Hilman @ 2009-12-22 16:45 UTC (permalink / raw)
  To: nm
  Cc: linux-omap, Cousson, Benoit, Chikkature Rajashekar, Madhusudhan,
	Paul Walmsley, Dasgupta, Romit, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Gopinath, Thara,
	Sripathy, Vishwanath, K, Ambresh

"Menon, Nishanth" <nm@ti.com> writes:

> Kevin Hilman said the following on 12/19/2009 04:42 AM:
>> Nishanth Menon <nm@ti.com> writes:
>>
>>   
>>> SmartReflex implements a get_opp to search through the opp table,
>>> replace it with the accessor function as it is a duplicate of
>>> freq_to_opp
>>>     
>>
>> SmartReflex is not quite working with this version which is in
>> pm-wip-opp.  My (untested) theory below...
>>
>> [...]
>>   
> Ambresh and I  just tested the very latest of the pm-wip-opp branch
> and checked. Voltage transitions and SR adjustments are happily
> happening on SDP3430 ES3.1 at the very least (verified with a scope on
> vdd1).
>
> and if you look closely in the code, sr2.vdd_opp_clk->rate and
> sr1.vdd_opp_clk->rate are based on
> sr1.vdd_opp_clk = clk_get(NULL, "dpll1_ck")
> sr2.vdd_opp_clk = clk_get(NULL, "l3_ick");
>
> now, if the dpll1_ck ->rate and l3_ick->rate are not exact frequencies
> as the opp tables, I think we have a clockframework bug and the code
> here is correct. we should fix the clockframework/find the rootcause
> elsewhere.
>
> Now is the clockframework wrong? we added a patch to print the
> frequencies and checked if IS_ERR(opp) is true -> not a single call
> while using cpu_freq transitions resulted in an error value and all
> the frequencies we printed were from the OPP table
>
> Might be good to hear your rationale for saying this result..

Part of my rationale was that the PM branch version get_vdd1_opp()
does an approximate match (actually the equivalent of
opp_find_freq_ceil() via get_opp.)  So you replaced an approximate
match with an exact match.  That may be the right solution and point
to a bug elsewhere, but it was not an equivalent replacement, and
probably should've been done in a separate patch with
justification/rationale.  I didn't catch it during initial review.

But the primary reason I noticed it in the first place was that I was
seeing DVFS errors on n900, which is the only platform I have that
actually can do SmartReflex.  Specifically, sr_reset_voltage() is
failing for VDD1.  Dumping out the clock rates used in get_vdd1_opp()
show that the clocks rates are close, but not the exact value used in
the OPP table.

Here is the patch I used to add some debugging, and I see that for the
250MHz OPP, the clock framework rate is 249600000 and for the 125MHz
OPP, the clock rate is 124800000.  As I said, close, but clearly an
find with exact match is going to fail.

Below the patch, is the console dump and backtrace of how get_vdd1_opp()
was called so you can see the call chain.

Kevin

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index d341857..01a3dbd 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -155,6 +155,8 @@ static u8 get_vdd1_opp(void)
 							mpu_opps == NULL)
 		return 0;
 
+	printk("%s: sr1.vdd_opp_clk->rate = %d\n", __func__,
+	       sr1.vdd_opp_clk->rate);
 	opp = opp_find_freq_exact(mpu_opps, sr1.vdd_opp_clk->rate, true);
 	if (IS_ERR(opp))
 		return 0;
@@ -451,6 +453,7 @@ static int sr_reset_voltage(int srid)
 		target_opp_no = get_vdd1_opp();
 		if (!target_opp_no) {
 			pr_info("Current OPP unknown: Cannot reset voltage\n");
+			__backtrace();
 			return 1;
 		}
 


/sys/devices/system/cpu/cpu0/cpufreq # echo 250000 > scaling_setspeed 
get_vdd1_opp: sr1.vdd_opp_clk->rate = 249600000
Current OPP unknown: Cannot reset voltage
[<c0042c98>] (sr_reset_voltage+0x0/0x190) from [<c0043094>] (sr_stop_vddautocomap+0x12c/0x148)
 r7:00000001 r6:00000001 r5:c03ac878 r4:00000000
[<c0042f68>] (sr_stop_vddautocomap+0x0/0x148) from [<c0043388>] (sr_voltagescale_vcbypass+0x2c/0x170)
 r7:00000001 r6:00000001 r5:00000030 r4:00000026
[<c004335c>] (sr_voltagescale_vcbypass+0x0/0x170) from [<c0043e00>] (program_opp+0x1e4/0x210)
[<c0043c1c>] (program_opp+0x0/0x210) from [<c0043f64>] (resource_set_opp_level+0x138/0x1b0)
[<c0043e2c>] (resource_set_opp_level+0x0/0x1b0) from [<c0044024>] (set_opp+0x48/0x120)
[<c0043fdc>] (set_opp+0x0/0x120) from [<c004bb48>] (update_resource_level+0xb0/0xd4)
 r5:c03b365c r4:00000002
[<c004ba98>] (update_resource_level+0x0/0xd4) from [<c004be34>] (resource_request+0x154/0x184)
 r7:00000002 r6:c03db5a0 r5:c03b365c r4:00000000
[<c004bce0>] (resource_request+0x0/0x184) from [<c0043a50>] (set_freq+0xb4/0xe8)
 r7:0ee6b280 r6:cf801080 r5:cf801000 r4:c0359347
[<c004399c>] (set_freq+0x0/0xe8) from [<c004bb48>] (update_resource_level+0xb0/0xd4)
 r8:c03d52f8 r7:0ee6b280 r6:c03dbf70 r5:c03b36a4 r4:0ee6b280
[<c004ba98>] (update_resource_level+0x0/0xd4) from [<c004be34>] (resource_request+0x154/0x184)
 r7:0ee6b280 r6:c03dbf70 r5:c03b36a4 r4:00000000
[<c004bce0>] (resource_request+0x0/0x184) from [<c004b7a4>] (omap_pm_cpu_set_freq+0x34/0x44)
 r7:00000007 r6:cfae7000 r5:cf96c100 r4:0003d090
[<c004b770>] (omap_pm_cpu_set_freq+0x0/0x44) from [<c004ac44>] (omap_target+0x64/0x74)
[<c004abe0>] (omap_target+0x0/0x74) from [<c02318c4>] (__cpufreq_driver_target+0x30/0x40)
[<c0231894>] (__cpufreq_driver_target+0x0/0x40) from [<c02339e8>] (cpufreq_set+0x58/0x74)
[<c0233990>] (cpufreq_set+0x0/0x74) from [<c0231b9c>] (store_scaling_setspeed+0x64/0x7c)
 r5:00000007 r4:cf96c100
[<c0231b38>] (store_scaling_setspeed+0x0/0x7c) from [<c0232ae0>] (store+0x60/0x7c)
 r5:cf96c100 r4:c03d53f8
[<c0232a80>] (store+0x0/0x7c) from [<c010c684>] (sysfs_write_file+0x110/0x144)
 r7:cf96c150 r6:cfb10bc0 r5:cf8fc000 r4:00000007
[<c010c574>] (sysfs_write_file+0x0/0x144) from [<c00bbdcc>] (vfs_write+0xb8/0x164)
[<c00bbd14>] (vfs_write+0x0/0x164) from [<c00bbf3c>] (sys_write+0x44/0x70)
 r8:40001000 r7:00000007 r6:cfafa280 r5:00000000 r4:00000000
[<c00bbef8>] (sys_write+0x0/0x70) from [<c0030fc0>] (ret_fast_syscall+0x0/0x2c)
 r8:c0031144 r7:00000004 r6:41149600 r5:40001000 r4:00000007



/sys/devices/system/cpu/cpu0/cpufreq # echo 125000 > scaling_setspeed 
get_vdd1_opp: sr1.vdd_opp_clk->rate = 124800000
Current OPP unknown: Cannot reset voltage
[<c0042c98>] (sr_reset_voltage+0x0/0x190) from [<c0043094>] (sr_stop_vddautocomap+0x12c/0x148)
 r7:00000001 r6:00000001 r5:c03ac878 r4:00000000
[<c0042f68>] (sr_stop_vddautocomap+0x0/0x148) from [<c0043388>] (sr_voltagescale_vcbypass+0x2c/0x170)
 r7:00000001 r6:00000001 r5:00000026 r4:0000001e
[<c004335c>] (sr_voltagescale_vcbypass+0x0/0x170) from [<c0043e00>] (program_opp+0x1e4/0x210)
[<c0043c1c>] (program_opp+0x0/0x210) from [<c0043f64>] (resource_set_opp_level+0x138/0x1b0)
[<c0043e2c>] (resource_set_opp_level+0x0/0x1b0) from [<c0044024>] (set_opp+0x48/0x120)
[<c0043fdc>] (set_opp+0x0/0x120) from [<c004bb48>] (update_resource_level+0xb0/0xd4)
 r5:c03b365c r4:00000001
[<c004ba98>] (update_resource_level+0x0/0xd4) from [<c004be34>] (resource_request+0x154/0x184)
 r7:00000001 r6:c03db5a0 r5:c03b365c r4:00000000
[<c004bce0>] (resource_request+0x0/0x184) from [<c0043a50>] (set_freq+0xb4/0xe8)
 r7:07735940 r6:cf801080 r5:cf801000 r4:c0359347
[<c004399c>] (set_freq+0x0/0xe8) from [<c004bb48>] (update_resource_level+0xb0/0xd4)
 r8:c03d52f8 r7:07735940 r6:c03dbf70 r5:c03b36a4 r4:07735940
[<c004ba98>] (update_resource_level+0x0/0xd4) from [<c004be34>] (resource_request+0x154/0x184)
 r7:07735940 r6:c03dbf70 r5:c03b36a4 r4:00000000
[<c004bce0>] (resource_request+0x0/0x184) from [<c004b7a4>] (omap_pm_cpu_set_freq+0x34/0x44)
 r7:00000007 r6:cfae7000 r5:cf96c100 r4:0001e848
[<c004b770>] (omap_pm_cpu_set_freq+0x0/0x44) from [<c004ac44>] (omap_target+0x64/0x74)
[<c004abe0>] (omap_target+0x0/0x74) from [<c02318c4>] (__cpufreq_driver_target+0x30/0x40)
[<c0231894>] (__cpufreq_driver_target+0x0/0x40) from [<c02339e8>] (cpufreq_set+0x58/0x74)
[<c0233990>] (cpufreq_set+0x0/0x74) from [<c0231b9c>] (store_scaling_setspeed+0x64/0x7c)
 r5:00000007 r4:cf96c100
[<c0231b38>] (store_scaling_setspeed+0x0/0x7c) from [<c0232ae0>] (store+0x60/0x7c)
 r5:cf96c100 r4:c03d53f8
[<c0232a80>] (store+0x0/0x7c) from [<c010c684>] (sysfs_write_file+0x110/0x144)
 r7:cf96c150 r6:cfb10bc0 r5:cf8fc000 r4:00000007
[<c010c574>] (sysfs_write_file+0x0/0x144) from [<c00bbdcc>] (vfs_write+0xb8/0x164)
[<c00bbd14>] (vfs_write+0x0/0x164) from [<c00bbf3c>] (sys_write+0x44/0x70)
 r8:40001000 r7:00000007 r6:cfafa700 r5:00000000 r4:00000000
[<c00bbef8>] (sys_write+0x0/0x70) from [<c0030fc0>] (ret_fast_syscall+0x0/0x2c)
 r8:c0031144 r7:00000004 r6:41149600 r5:40001000 r4:00000007

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2009-12-22 16:45               ` Kevin Hilman
@ 2010-01-06 23:46                 ` Nishanth Menon
  2010-01-07  0:23                   ` Kevin Hilman
  2010-01-07  8:35                   ` Sripathy, Vishwanath
  0 siblings, 2 replies; 22+ messages in thread
From: Nishanth Menon @ 2010-01-06 23:46 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, Cousson, Benoit, Chikkature Rajashekar, Madhusudhan,
	Paul Walmsley, Dasgupta, Romit, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Gopinath, Thara,
	Sripathy, Vishwanath, K, Ambresh

Kevin Hilman had written, on 12/22/2009 10:45 AM, the following:
> "Menon, Nishanth" <nm@ti.com> writes:
> 
>> Kevin Hilman said the following on 12/19/2009 04:42 AM:
>>> Nishanth Menon <nm@ti.com> writes:
>>>
>>>   
>>>> SmartReflex implements a get_opp to search through the opp table,
>>>> replace it with the accessor function as it is a duplicate of
>>>> freq_to_opp
>>>>     
>>> SmartReflex is not quite working with this version which is in
>>> pm-wip-opp.  My (untested) theory below...
>>>
>>> [...]
>>>   
>> Ambresh and I  just tested the very latest of the pm-wip-opp branch
>> and checked. Voltage transitions and SR adjustments are happily
>> happening on SDP3430 ES3.1 at the very least (verified with a scope on
>> vdd1).
>>
>> and if you look closely in the code, sr2.vdd_opp_clk->rate and
>> sr1.vdd_opp_clk->rate are based on
>> sr1.vdd_opp_clk = clk_get(NULL, "dpll1_ck")
>> sr2.vdd_opp_clk = clk_get(NULL, "l3_ick");
>>
>> now, if the dpll1_ck ->rate and l3_ick->rate are not exact frequencies
>> as the opp tables, I think we have a clockframework bug and the code
>> here is correct. we should fix the clockframework/find the rootcause
>> elsewhere.
>>
>> Now is the clockframework wrong? we added a patch to print the
>> frequencies and checked if IS_ERR(opp) is true -> not a single call
>> while using cpu_freq transitions resulted in an error value and all
>> the frequencies we printed were from the OPP table
>>
>> Might be good to hear your rationale for saying this result..
> 
> Part of my rationale was that the PM branch version get_vdd1_opp()
> does an approximate match (actually the equivalent of
> opp_find_freq_ceil() via get_opp.)  So you replaced an approximate
> match with an exact match.  That may be the right solution and point
> to a bug elsewhere, but it was not an equivalent replacement, and
> probably should've been done in a separate patch with
> justification/rationale.  I didn't catch it during initial review.
> 
> But the primary reason I noticed it in the first place was that I was
> seeing DVFS errors on n900, which is the only platform I have that
> actually can do SmartReflex.  Specifically, sr_reset_voltage() is
> failing for VDD1.  Dumping out the clock rates used in get_vdd1_opp()
> show that the clocks rates are close, but not the exact value used in
> the OPP table.
> 
> Here is the patch I used to add some debugging, and I see that for the
> 250MHz OPP, the clock framework rate is 249600000 and for the 125MHz
> OPP, the clock rate is 124800000.  As I said, close, but clearly an
> find with exact match is going to fail.
> 
> Below the patch, is the console dump and backtrace of how get_vdd1_opp()
> was called so you can see the call chain.
> 
> Kevin
> 
> diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
> index d341857..01a3dbd 100644
> --- a/arch/arm/mach-omap2/smartreflex.c
> +++ b/arch/arm/mach-omap2/smartreflex.c
> @@ -155,6 +155,8 @@ static u8 get_vdd1_opp(void)
>  							mpu_opps == NULL)
>  		return 0;
>  
> +	printk("%s: sr1.vdd_opp_clk->rate = %d\n", __func__,
> +	       sr1.vdd_opp_clk->rate);
>  	opp = opp_find_freq_exact(mpu_opps, sr1.vdd_opp_clk->rate, true);
>  	if (IS_ERR(opp))
>  		return 0;
> @@ -451,6 +453,7 @@ static int sr_reset_voltage(int srid)
>  		target_opp_no = get_vdd1_opp();
>  		if (!target_opp_no) {
>  			pr_info("Current OPP unknown: Cannot reset voltage\n");
> +			__backtrace();
>  			return 1;
>  		}
>  
> 
> 
> /sys/devices/system/cpu/cpu0/cpufreq # echo 250000 > scaling_setspeed 
> get_vdd1_opp: sr1.vdd_opp_clk->rate = 249600000
> Current OPP unknown: Cannot reset voltage
> [<c0042c98>] (sr_reset_voltage+0x0/0x190) from [<c0043094>] (sr_stop_vddautocomap+0x12c/0x148)
>  r7:00000001 r6:00000001 r5:c03ac878 r4:00000000
> [<c0042f68>] (sr_stop_vddautocomap+0x0/0x148) from [<c0043388>] (sr_voltagescale_vcbypass+0x2c/0x170)
[...]

Throws up my hands! 3430 on N900/SDP3430 should be essentially the same!

Configuration:
==============
kernel: 
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git
branch:
pm-wip-opp 6e1276f omap3:pm: remove map3_[mpu|dsp|l3]_rate_tables
Applied my bugfix: http://patchwork.kernel.org/patch/71457/

I have a 3430 ES3.1 SDP3430 where I did run the test:

Log Patch: http://pastebin.mozilla.org/695225
Test script: http://pastebin.mozilla.org/695226 (I call this test-me.sh)
Result log: http://pastebin.mozilla.org/695224

huh? no crash, all the frequencies and transitions are good, the rates 
of dpll1,2,3 look good! there is something definitely fishy about N900 
configuration??

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2010-01-06 23:46                 ` Nishanth Menon
@ 2010-01-07  0:23                   ` Kevin Hilman
  2010-01-07  8:35                   ` Sripathy, Vishwanath
  1 sibling, 0 replies; 22+ messages in thread
From: Kevin Hilman @ 2010-01-07  0:23 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: linux-omap, Cousson, Benoit, Chikkature Rajashekar, Madhusudhan,
	Paul Walmsley, Dasgupta, Romit, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Gopinath, Thara,
	Sripathy, Vishwanath, K, Ambresh

Nishanth Menon <nm@ti.com> writes:

> Kevin Hilman had written, on 12/22/2009 10:45 AM, the following:
>> "Menon, Nishanth" <nm@ti.com> writes:
>>
>>> Kevin Hilman said the following on 12/19/2009 04:42 AM:
>>>> Nishanth Menon <nm@ti.com> writes:
>>>>
>>>>   
>>>>> SmartReflex implements a get_opp to search through the opp table,
>>>>> replace it with the accessor function as it is a duplicate of
>>>>> freq_to_opp
>>>>>     
>>>> SmartReflex is not quite working with this version which is in
>>>> pm-wip-opp.  My (untested) theory below...
>>>>
>>>> [...]
>>>>   
>>> Ambresh and I  just tested the very latest of the pm-wip-opp branch
>>> and checked. Voltage transitions and SR adjustments are happily
>>> happening on SDP3430 ES3.1 at the very least (verified with a scope on
>>> vdd1).
>>>
>>> and if you look closely in the code, sr2.vdd_opp_clk->rate and
>>> sr1.vdd_opp_clk->rate are based on
>>> sr1.vdd_opp_clk = clk_get(NULL, "dpll1_ck")
>>> sr2.vdd_opp_clk = clk_get(NULL, "l3_ick");
>>>
>>> now, if the dpll1_ck ->rate and l3_ick->rate are not exact frequencies
>>> as the opp tables, I think we have a clockframework bug and the code
>>> here is correct. we should fix the clockframework/find the rootcause
>>> elsewhere.
>>>
>>> Now is the clockframework wrong? we added a patch to print the
>>> frequencies and checked if IS_ERR(opp) is true -> not a single call
>>> while using cpu_freq transitions resulted in an error value and all
>>> the frequencies we printed were from the OPP table
>>>
>>> Might be good to hear your rationale for saying this result..
>>
>> Part of my rationale was that the PM branch version get_vdd1_opp()
>> does an approximate match (actually the equivalent of
>> opp_find_freq_ceil() via get_opp.)  So you replaced an approximate
>> match with an exact match.  That may be the right solution and point
>> to a bug elsewhere, but it was not an equivalent replacement, and
>> probably should've been done in a separate patch with
>> justification/rationale.  I didn't catch it during initial review.
>>
>> But the primary reason I noticed it in the first place was that I was
>> seeing DVFS errors on n900, which is the only platform I have that
>> actually can do SmartReflex.  Specifically, sr_reset_voltage() is
>> failing for VDD1.  Dumping out the clock rates used in get_vdd1_opp()
>> show that the clocks rates are close, but not the exact value used in
>> the OPP table.
>>
>> Here is the patch I used to add some debugging, and I see that for the
>> 250MHz OPP, the clock framework rate is 249600000 and for the 125MHz
>> OPP, the clock rate is 124800000.  As I said, close, but clearly an
>> find with exact match is going to fail.
>>
>> Below the patch, is the console dump and backtrace of how get_vdd1_opp()
>> was called so you can see the call chain.
>>
>> Kevin
>>
>> diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
>> index d341857..01a3dbd 100644
>> --- a/arch/arm/mach-omap2/smartreflex.c
>> +++ b/arch/arm/mach-omap2/smartreflex.c
>> @@ -155,6 +155,8 @@ static u8 get_vdd1_opp(void)
>>  							mpu_opps == NULL)
>>  		return 0;
>>  +	printk("%s: sr1.vdd_opp_clk->rate = %d\n", __func__,
>> +	       sr1.vdd_opp_clk->rate);
>>  	opp = opp_find_freq_exact(mpu_opps, sr1.vdd_opp_clk->rate, true);
>>  	if (IS_ERR(opp))
>>  		return 0;
>> @@ -451,6 +453,7 @@ static int sr_reset_voltage(int srid)
>>  		target_opp_no = get_vdd1_opp();
>>  		if (!target_opp_no) {
>>  			pr_info("Current OPP unknown: Cannot reset voltage\n");
>> +			__backtrace();
>>  			return 1;
>>  		}
>>  
>>
>>
>> /sys/devices/system/cpu/cpu0/cpufreq # echo 250000 >
>> scaling_setspeed get_vdd1_opp: sr1.vdd_opp_clk->rate = 249600000
>> Current OPP unknown: Cannot reset voltage
>> [<c0042c98>] (sr_reset_voltage+0x0/0x190) from [<c0043094>] (sr_stop_vddautocomap+0x12c/0x148)
>>  r7:00000001 r6:00000001 r5:c03ac878 r4:00000000
>> [<c0042f68>] (sr_stop_vddautocomap+0x0/0x148) from [<c0043388>] (sr_voltagescale_vcbypass+0x2c/0x170)
> [...]
>
> Throws up my hands! 3430 on N900/SDP3430 should be essentially the same!
>
> Configuration:
> ==============
> kernel:
> git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git
> branch:
> pm-wip-opp 6e1276f omap3:pm: remove map3_[mpu|dsp|l3]_rate_tables
> Applied my bugfix: http://patchwork.kernel.org/patch/71457/
>
> I have a 3430 ES3.1 SDP3430 where I did run the test:
>
> Log Patch: http://pastebin.mozilla.org/695225
> Test script: http://pastebin.mozilla.org/695226 (I call this test-me.sh)
> Result log: http://pastebin.mozilla.org/695224
>
> huh? no crash, all the frequencies and transitions are good, the rates
> of dpll1,2,3 look good! there is something definitely fishy about N900
> configuration??

OK, so for now we need to at least replace the original approximate
match with an equivalent approximate match.  Then, use an additional
patch to change it to an exact match when we find out what's happening
on N900.

Kevin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2010-01-06 23:46                 ` Nishanth Menon
  2010-01-07  0:23                   ` Kevin Hilman
@ 2010-01-07  8:35                   ` Sripathy, Vishwanath
  2010-01-07  8:53                     ` Romit Dasgupta
  2010-01-07 12:15                     ` Nishanth Menon
  1 sibling, 2 replies; 22+ messages in thread
From: Sripathy, Vishwanath @ 2010-01-07  8:35 UTC (permalink / raw)
  To: Menon, Nishanth, Kevin Hilman
  Cc: linux-omap, Cousson, Benoit, Chikkature Rajashekar, Madhusudhan,
	Paul Walmsley, Dasgupta, Romit, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Gopinath, Thara, K, Ambresh

Nishant,
Have you tested your opp patches on 3630? Apparently opp changes in wip branch does not even boot on ZOOM3 board.

Vishwa

> -----Original Message-----
> From: Menon, Nishanth
> Sent: Thursday, January 07, 2010 5:16 AM
> To: Kevin Hilman
> Cc: linux-omap; Cousson, Benoit; Chikkature Rajashekar, Madhusudhan; Paul
> Walmsley; Dasgupta, Romit; Premi, Sanjeev; Shilimkar, Santosh; Aguirre, Sergio;
> Gopinath, Thara; Sripathy, Vishwanath; K, Ambresh
> Subject: Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
> 
> Kevin Hilman had written, on 12/22/2009 10:45 AM, the following:
> > "Menon, Nishanth" <nm@ti.com> writes:
> >
> >> Kevin Hilman said the following on 12/19/2009 04:42 AM:
> >>> Nishanth Menon <nm@ti.com> writes:
> >>>
> >>>
> >>>> SmartReflex implements a get_opp to search through the opp table,
> >>>> replace it with the accessor function as it is a duplicate of
> >>>> freq_to_opp
> >>>>
> >>> SmartReflex is not quite working with this version which is in
> >>> pm-wip-opp.  My (untested) theory below...
> >>>
> >>> [...]
> >>>
> >> Ambresh and I  just tested the very latest of the pm-wip-opp branch
> >> and checked. Voltage transitions and SR adjustments are happily
> >> happening on SDP3430 ES3.1 at the very least (verified with a scope on
> >> vdd1).
> >>
> >> and if you look closely in the code, sr2.vdd_opp_clk->rate and
> >> sr1.vdd_opp_clk->rate are based on
> >> sr1.vdd_opp_clk = clk_get(NULL, "dpll1_ck")
> >> sr2.vdd_opp_clk = clk_get(NULL, "l3_ick");
> >>
> >> now, if the dpll1_ck ->rate and l3_ick->rate are not exact frequencies
> >> as the opp tables, I think we have a clockframework bug and the code
> >> here is correct. we should fix the clockframework/find the rootcause
> >> elsewhere.
> >>
> >> Now is the clockframework wrong? we added a patch to print the
> >> frequencies and checked if IS_ERR(opp) is true -> not a single call
> >> while using cpu_freq transitions resulted in an error value and all
> >> the frequencies we printed were from the OPP table
> >>
> >> Might be good to hear your rationale for saying this result..
> >
> > Part of my rationale was that the PM branch version get_vdd1_opp()
> > does an approximate match (actually the equivalent of
> > opp_find_freq_ceil() via get_opp.)  So you replaced an approximate
> > match with an exact match.  That may be the right solution and point
> > to a bug elsewhere, but it was not an equivalent replacement, and
> > probably should've been done in a separate patch with
> > justification/rationale.  I didn't catch it during initial review.
> >
> > But the primary reason I noticed it in the first place was that I was
> > seeing DVFS errors on n900, which is the only platform I have that
> > actually can do SmartReflex.  Specifically, sr_reset_voltage() is
> > failing for VDD1.  Dumping out the clock rates used in get_vdd1_opp()
> > show that the clocks rates are close, but not the exact value used in
> > the OPP table.
> >
> > Here is the patch I used to add some debugging, and I see that for the
> > 250MHz OPP, the clock framework rate is 249600000 and for the 125MHz
> > OPP, the clock rate is 124800000.  As I said, close, but clearly an
> > find with exact match is going to fail.
> >
> > Below the patch, is the console dump and backtrace of how get_vdd1_opp()
> > was called so you can see the call chain.
> >
> > Kevin
> >
> > diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-
> omap2/smartreflex.c
> > index d341857..01a3dbd 100644
> > --- a/arch/arm/mach-omap2/smartreflex.c
> > +++ b/arch/arm/mach-omap2/smartreflex.c
> > @@ -155,6 +155,8 @@ static u8 get_vdd1_opp(void)
> >  							mpu_opps == NULL)
> >  		return 0;
> >
> > +	printk("%s: sr1.vdd_opp_clk->rate = %d\n", __func__,
> > +	       sr1.vdd_opp_clk->rate);
> >  	opp = opp_find_freq_exact(mpu_opps, sr1.vdd_opp_clk->rate, true);
> >  	if (IS_ERR(opp))
> >  		return 0;
> > @@ -451,6 +453,7 @@ static int sr_reset_voltage(int srid)
> >  		target_opp_no = get_vdd1_opp();
> >  		if (!target_opp_no) {
> >  			pr_info("Current OPP unknown: Cannot reset voltage\n");
> > +			__backtrace();
> >  			return 1;
> >  		}
> >
> >
> >
> > /sys/devices/system/cpu/cpu0/cpufreq # echo 250000 > scaling_setspeed
> > get_vdd1_opp: sr1.vdd_opp_clk->rate = 249600000
> > Current OPP unknown: Cannot reset voltage
> > [<c0042c98>] (sr_reset_voltage+0x0/0x190) from [<c0043094>]
> (sr_stop_vddautocomap+0x12c/0x148)
> >  r7:00000001 r6:00000001 r5:c03ac878 r4:00000000
> > [<c0042f68>] (sr_stop_vddautocomap+0x0/0x148) from [<c0043388>]
> (sr_voltagescale_vcbypass+0x2c/0x170)
> [...]
> 
> Throws up my hands! 3430 on N900/SDP3430 should be essentially the same!
> 
> Configuration:
> ==============
> kernel:
> git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git
> branch:
> pm-wip-opp 6e1276f omap3:pm: remove map3_[mpu|dsp|l3]_rate_tables
> Applied my bugfix: http://patchwork.kernel.org/patch/71457/
> 
> I have a 3430 ES3.1 SDP3430 where I did run the test:
> 
> Log Patch: http://pastebin.mozilla.org/695225
> Test script: http://pastebin.mozilla.org/695226 (I call this test-me.sh)
> Result log: http://pastebin.mozilla.org/695224
> 
> huh? no crash, all the frequencies and transitions are good, the rates
> of dpll1,2,3 look good! there is something definitely fishy about N900
> configuration??
> 
> --
> Regards,
> Nishanth Menon

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2010-01-07  8:35                   ` Sripathy, Vishwanath
@ 2010-01-07  8:53                     ` Romit Dasgupta
  2010-01-07  9:13                       ` Sripathy, Vishwanath
  2010-01-07 12:15                     ` Nishanth Menon
  1 sibling, 1 reply; 22+ messages in thread
From: Romit Dasgupta @ 2010-01-07  8:53 UTC (permalink / raw)
  To: Sripathy, Vishwanath
  Cc: Menon, Nishanth, Kevin Hilman, linux-omap, Cousson, Benoit,
	Chikkature Rajashekar, Madhusudhan, Paul Walmsley, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Gopinath, Thara, K, Ambresh

Sripathy, Vishwanath wrote:
> Nishant,
> Have you tested your opp patches on 3630? Apparently opp changes in wip branch does not even boot on ZOOM3 board.
> 
> Vishwa
Vishwa,
          did you try on top of my OPP patches?

Thanks,
-Romit

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2010-01-07  8:53                     ` Romit Dasgupta
@ 2010-01-07  9:13                       ` Sripathy, Vishwanath
  0 siblings, 0 replies; 22+ messages in thread
From: Sripathy, Vishwanath @ 2010-01-07  9:13 UTC (permalink / raw)
  To: Dasgupta, Romit
  Cc: Menon, Nishanth, Kevin Hilman, linux-omap, Cousson, Benoit,
	Chikkature Rajashekar, Madhusudhan, Paul Walmsley, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Gopinath, Thara, K, Ambresh

Yes Vijay tried with your OPP patches on 3630 ZOOM3 and it seems to work.

Vishwa

> -----Original Message-----
> From: Dasgupta, Romit
> Sent: Thursday, January 07, 2010 2:23 PM
> To: Sripathy, Vishwanath
> Cc: Menon, Nishanth; Kevin Hilman; linux-omap; Cousson, Benoit; Chikkature
> Rajashekar, Madhusudhan; Paul Walmsley; Premi, Sanjeev; Shilimkar, Santosh;
> Aguirre, Sergio; Gopinath, Thara; K, Ambresh
> Subject: Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
> 
> Sripathy, Vishwanath wrote:
> > Nishant,
> > Have you tested your opp patches on 3630? Apparently opp changes in wip branch
> does not even boot on ZOOM3 board.
> >
> > Vishwa
> Vishwa,
>           did you try on top of my OPP patches?
> 
> Thanks,
> -Romit

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2010-01-07  8:35                   ` Sripathy, Vishwanath
  2010-01-07  8:53                     ` Romit Dasgupta
@ 2010-01-07 12:15                     ` Nishanth Menon
  2010-01-07 14:18                       ` Nishanth Menon
  1 sibling, 1 reply; 22+ messages in thread
From: Nishanth Menon @ 2010-01-07 12:15 UTC (permalink / raw)
  To: Sripathy, Vishwanath
  Cc: Kevin Hilman, linux-omap, Cousson, Benoit,
	Chikkature Rajashekar, Madhusudhan, Paul Walmsley,
	Dasgupta, Romit, Premi, Sanjeev, Shilimkar, Santosh,
	Aguirre, Sergio, Gopinath, Thara, K, Ambresh

Sripathy, Vishwanath said the following on 01/07/2010 02:35 AM:
> Nishant,
> Have you tested your opp patches on 3630? Apparently opp changes in wip branch does not even boot on ZOOM3 board.
>   
The original series was tested and reported with results. I have'nt had 
a chance to try with the newer patch set. if there are patches, they are 
most welcome meanwhile. I will also try to do some on SDP3630 later today.

> Vishwa
>
>   
>> -----Original Message-----
>> From: Menon, Nishanth
>> Sent: Thursday, January 07, 2010 5:16 AM
>> To: Kevin Hilman
>> Cc: linux-omap; Cousson, Benoit; Chikkature Rajashekar, Madhusudhan; Paul
>> Walmsley; Dasgupta, Romit; Premi, Sanjeev; Shilimkar, Santosh; Aguirre, Sergio;
>> Gopinath, Thara; Sripathy, Vishwanath; K, Ambresh
>> Subject: Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
>>     
being a nitpick: could we avoid top-posting please?



Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp
  2010-01-07 12:15                     ` Nishanth Menon
@ 2010-01-07 14:18                       ` Nishanth Menon
  0 siblings, 0 replies; 22+ messages in thread
From: Nishanth Menon @ 2010-01-07 14:18 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: Sripathy, Vishwanath, Kevin Hilman, linux-omap, Cousson, Benoit,
	Chikkature Rajashekar, Madhusudhan, Paul Walmsley,
	Dasgupta, Romit, Premi, Sanjeev, Shilimkar, Santosh,
	Aguirre, Sergio, Gopinath, Thara, K, Ambresh

Nishanth Menon had written, on 01/07/2010 06:15 AM, the following:
> Sripathy, Vishwanath said the following on 01/07/2010 02:35 AM:
>> Nishant,
>> Have you tested your opp patches on 3630? Apparently opp changes in wip branch does not even boot on ZOOM3 board.
>>   
> The original series was tested and reported with results. I have'nt had 
> a chance to try with the newer patch set. if there are patches, they are 
> most welcome meanwhile. I will also try to do some on SDP3630 later today.
> 
[...]
http://pastebin.mozilla.org/695411 has the boot log on SDP3630! as 
reported previously clock framework is crashing, that is probably 
because the clock framework changes for 3630 corresponding to 3630 OPPs 
are not available.

the scripts and kernel details are part of
http://marc.info/?l=linux-omap&m=126282159227739&w=2

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2010-01-07 14:18 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-12  5:45 [PATCH 0/9] OMAP3: PM: introduce support for 3630 OPPs Nishanth Menon
2009-11-12  5:45 ` [PATCH 1/9] omap3: pm: introduce enabled flag to omap_opp Nishanth Menon
2009-11-12  5:45   ` [PATCH 2/9] omap3: pm: introduce opp accessor functions Nishanth Menon
2009-11-12  5:45     ` [PATCH 3/9] omap3: pm: srf: introduce accessor function Nishanth Menon
2009-11-12  5:45       ` [PATCH 4/9] omap3: pm: use opp accessor functions for omap-target Nishanth Menon
2009-11-12  5:45         ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Nishanth Menon
2009-11-12  5:45           ` [PATCH 6/9] omap3: clk: use pm accessor functions for cpufreq table Nishanth Menon
2009-11-12  5:45             ` [PATCH 7/9] omap3: pm: remove VDDx_MIN/MAX macros Nishanth Menon
2009-11-12  5:45               ` [PATCH 8/9] omap3: pm: introduce dynamic OPP Nishanth Menon
2009-11-12  5:45                 ` [PATCH 9/9] omap3: pm: introduce 3630 opps Nishanth Menon
2009-12-18 23:12           ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Kevin Hilman
2009-12-19 11:35             ` Menon, Nishanth
2009-12-22 16:45               ` Kevin Hilman
2010-01-06 23:46                 ` Nishanth Menon
2010-01-07  0:23                   ` Kevin Hilman
2010-01-07  8:35                   ` Sripathy, Vishwanath
2010-01-07  8:53                     ` Romit Dasgupta
2010-01-07  9:13                       ` Sripathy, Vishwanath
2010-01-07 12:15                     ` Nishanth Menon
2010-01-07 14:18                       ` Nishanth Menon
2009-12-21  6:58             ` Romit Dasgupta
  -- strict thread matches above, loose matches on Subject: below --
2009-11-13  6:05 [PATCH 0/9 v2] omap3: pm: introduce support for 3630 OPPs Nishanth Menon
2009-11-13  6:05 ` [PATCH 1/9] omap3: pm: introduce enabled flag to omap_opp Nishanth Menon
2009-11-13  6:05   ` [PATCH 2/9 v2] omap3: pm: introduce opp accessor functions Nishanth Menon
2009-11-13  6:05     ` [PATCH 3/9] omap3: pm: srf: use opp accessor function Nishanth Menon
2009-11-13  6:05       ` [PATCH 4/9] omap3: pm: use opp accessor functions for omap-target Nishanth Menon
2009-11-13  6:05         ` [PATCH 5/9] omap3: pm: sr: replace get_opp with freq_to_opp Nishanth Menon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox