All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp
@ 2010-04-16  9:02 Thara Gopinath
  2010-04-16  9:02 ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Thara Gopinath
                   ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:02 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

The main motivations behind this patch series are the following
1. Making smartreflex a platform driver with omap-device layer.
2. Separating voltage specific code from smartreflex.c and other
   locations and consolidating them into voltage.c and voltage.h.
3. Smartreflex module can have Class 1 Class 2 or Class 3 implementations
   depending on the PMIC in use. Making smartreflex.c capable
   of handling both the Class 2 and 3  implementaions and separating out
   class specific code into a separate class driver.
4. Remove dependencies on opp id in the smartreflex and
   voltage drivers
5. Implementating  latest TI recommended register settings for
  Smartreflex and Voltage processor module as well as recommended
  sequences for enabling and disabling of Smartreflex and Voltage
  processor modules.
6. Implementing VP force update method of voltage scaling which is
   again TI hardware recommended.

What this patch series does not address are
1. Separating PMIC specific portions from smartreflex and voltage code.
2. OMAP3630 and OMP4 smartreflex support.

This patch series is based on Kevin's PM tree origin/pm-wip-opp branch
and is dependent on the following patches not yet applied onto this branch.

        http://patchwork.kernel.org/patch/81504/
        http://patchwork.kernel.org/patch/81606/

This patch series has been tested on OMAP3430 SDP with basic power
management tests including the dvfs scripts.


Thara Gopinath (22):
  OMAP3: PM: Adding hwmod data for Smartreflex
  OMAP3: PM: Create list to keep track of various smartreflex
    instances.
  OMAP3: PM: Convert smartreflex driver into a platform driver using
    hwmods and omap-device layer
  OMAP3: PM: Move smartreflex autocompensation enable disable hooks to
    PM debugfs.
  OMAP3: PM: Remove OPP id dependency from smartreflex driver
  OMAP3: PM: Correcting API names in samrtreflex driver.
  OMAP3: PM: Smartreflex class related changes for smartreflex.c
  OMAP3: PM: Adding smartreflex class 3 driver.
  OMAP3: PM: Creating separate files for handling OMAP3 voltage related
    operations.
  OMAP3: PM: Adding voltage table support in voltage driver.
  OMAP3: PM: Removing VP1, VP2, SR1 and SR2 defintions.
  OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c
  OMAP3: PM: Cleaning up of smartreflex header file.
  OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex
    Class 3
  OMAP3: PM: Support for enabling smartreflex autocompensation by
    default.
  OMAP3: PM: Correcting accessing of ERRCONFIG register in
    smartreflex.c
  OMAP3: PM: Implement latest h/w recommendations for SR and VP
    registers and SR VP enable disable sequence.
  OMAP3: PM: Optional reset of voltage during Smartreflex disable.
  OMAP3: PM: Disabling Smartreflex across both frequency and voltage
    scaling during DVFS.
  OMAP3: PM: VP force update method of voltage scaling
  OMAP3: PM: Enabling Smartreflex Class 3 driver by default in pm
    defconfig
  OMAP3: PM: Fix crash when enabling SmartReflex on non-supported
    OMAPs.

 arch/arm/configs/omap3_pm_defconfig        |    1 +
 arch/arm/mach-omap2/Makefile               |    6 +-
 arch/arm/mach-omap2/board-3430sdp.c        |    5 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  134 +++
 arch/arm/mach-omap2/pm-debug.c             |    4 +-
 arch/arm/mach-omap2/pm.h                   |    7 -
 arch/arm/mach-omap2/pm34xx.c               |   95 +--
 arch/arm/mach-omap2/resource34xx.c         |   27 +-
 arch/arm/mach-omap2/resource34xx.h         |    1 -
 arch/arm/mach-omap2/smartreflex-class3.c   |   60 ++
 arch/arm/mach-omap2/smartreflex-class3.h   |   18 +
 arch/arm/mach-omap2/smartreflex.c          | 1302 ++++++++++------------------
 arch/arm/mach-omap2/smartreflex.h          |  350 ++++----
 arch/arm/mach-omap2/sr_device.c            |  152 ++++
 arch/arm/mach-omap2/voltage.c              |  940 ++++++++++++++++++++
 arch/arm/mach-omap2/voltage.h              |   99 +++
 arch/arm/plat-omap/Kconfig                 |   11 +-
 17 files changed, 2088 insertions(+), 1124 deletions(-)
 create mode 100644 arch/arm/mach-omap2/smartreflex-class3.c
 create mode 100644 arch/arm/mach-omap2/smartreflex-class3.h
 create mode 100644 arch/arm/mach-omap2/sr_device.c
 create mode 100644 arch/arm/mach-omap2/voltage.c
 create mode 100644 arch/arm/mach-omap2/voltage.h


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

* [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex
  2010-04-16  9:02 [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp Thara Gopinath
@ 2010-04-16  9:02 ` Thara Gopinath
  2010-04-16  9:02   ` [PATCHv3 02/22] OMAP3: PM: Create list to keep track of various smartreflex instances Thara Gopinath
  2010-04-27 17:34   ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Kevin Hilman
  2010-04-20 23:49 ` [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp Kevin Hilman
  2010-04-27 19:18 ` Kevin Hilman
  2 siblings, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:02 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch adds the hwmod strucutres and other hwmod data for
OMAP3 Smartreflex IP's.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  135 ++++++++++++++++++++++++++++
 arch/arm/mach-omap2/smartreflex.h          |   33 +++++++
 2 files changed, 168 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index ed60840..049e4e2 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -17,10 +17,12 @@
 #include <mach/irqs.h>
 #include <plat/cpu.h>
 #include <plat/dma.h>
+#include <plat/control.h>
 
 #include "omap_hwmod_common_data.h"
 
 #include "prm-regbits-34xx.h"
+#include "smartreflex.h"
 
 /*
  * OMAP3xxx hardware module integration data
@@ -35,6 +37,8 @@ static struct omap_hwmod omap3xxx_mpu_hwmod;
 static struct omap_hwmod omap3xxx_l3_hwmod;
 static struct omap_hwmod omap3xxx_l4_core_hwmod;
 static struct omap_hwmod omap3xxx_l4_per_hwmod;
+static struct omap_hwmod omap34xx_sr1_hwmod;
+static struct omap_hwmod omap34xx_sr2_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap3xxx_l3__l4_core = {
@@ -88,9 +92,47 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
 	.user	= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* L4 CORE -> SR1 interface */
+static struct omap_hwmod_addr_space omap34xx_sr1_addr_space[] = {
+	{
+		.pa_start	= OMAP34XX_SR1_BASE,
+		.pa_end		= OMAP34XX_SR1_BASE + SZ_1K - 1,
+		.flags		= ADDR_TYPE_RT,
+	},
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__sr1 = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_sr1_hwmod,
+	.clk		= "sr_l4_ick",
+	.addr		= omap34xx_sr1_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_sr1_addr_space),
+	.user		= OCP_USER_MPU,
+};
+
+/* L4 CORE -> SR1 interface */
+static struct omap_hwmod_addr_space omap34xx_sr2_addr_space[] = {
+	{
+		.pa_start	= OMAP34XX_SR2_BASE,
+		.pa_end		= OMAP34XX_SR2_BASE + SZ_1K - 1,
+		.flags		= ADDR_TYPE_RT,
+	},
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__sr2 = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_sr2_hwmod,
+	.clk		= "sr_l4_ick",
+	.addr		= omap34xx_sr2_addr_space,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_sr2_addr_space),
+	.user		= OCP_USER_MPU,
+};
+
 /* Slave interfaces on the L4_CORE interconnect */
 static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
 	&omap3xxx_l3__l4_core,
+	&omap3_l4_core__sr1,
+	&omap3_l4_core__sr2,
 };
 
 /* Master interfaces on the L4_CORE interconnect */
@@ -164,12 +206,105 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
+/* SR common */
+static struct omap_hwmod_sysc_fields omap34xx_sr_sysc_fields = {
+	.clkact_shift	= 20,
+};
+
+static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = {
+	.sysc_offs	= 0x24,
+	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_NO_CACHE),
+	.clockact	= CLOCKACT_TEST_ICLK,
+	.sysc_fields	= &omap34xx_sr_sysc_fields,
+};
+
+static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = {
+	.name = "smartreflex",
+	.sysc = &omap34xx_sr_sysc,
+	.rev  = 1,
+};
+
+/* SR1 */
+static struct omap_hwmod_ocp_if *omap34xx_sr1_slaves[] = {
+	&omap3_l4_core__sr1,
+};
+
+static u32 omap34xx_sr1_efuse_offs[] = {
+	OMAP343X_CONTROL_FUSE_OPP1_VDD1, OMAP343X_CONTROL_FUSE_OPP2_VDD1,
+	OMAP343X_CONTROL_FUSE_OPP3_VDD1, OMAP343X_CONTROL_FUSE_OPP4_VDD1,
+	OMAP343X_CONTROL_FUSE_OPP5_VDD1,
+};
+
+static u32 omap34xx_sr1_test_nvalues[] = {
+	0x9A90E6, 0xAABE9A, 0xBBF5C5, 0xBBB292, 0xBBF5C5,
+};
+
+static struct omap_smartreflex_dev_data omap34xx_sr1_dev_attr = {
+	.volts_supported	= 5,
+	.efuse_sr_control	= OMAP343X_CONTROL_FUSE_SR,
+	.sennenable_shift	= OMAP343X_SR1_SENNENABLE_SHIFT,
+	.senpenable_shift	= OMAP343X_SR1_SENPENABLE_SHIFT,
+	.efuse_nvalues_offs	= omap34xx_sr1_efuse_offs,
+	.test_sennenable	= 0x3,
+	.test_senpenable	= 0x3,
+	.test_nvalues		= omap34xx_sr1_test_nvalues
+};
+
+static struct omap_hwmod omap34xx_sr1_hwmod = {
+	.name		= "sr1_hwmod",
+	.class		= &omap34xx_smartreflex_hwmod_class,
+	.main_clk	= "sr1_fck",
+	.slaves		= omap34xx_sr1_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr1_slaves),
+	.dev_attr	= &omap34xx_sr1_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+/* SR2 */
+static struct omap_hwmod_ocp_if *omap34xx_sr2_slaves[] = {
+	&omap3_l4_core__sr2,
+};
+
+static u32 omap34xx_sr2_efuse_offs[] = {
+	OMAP343X_CONTROL_FUSE_OPP1_VDD2, OMAP343X_CONTROL_FUSE_OPP2_VDD2,
+	OMAP343X_CONTROL_FUSE_OPP3_VDD2,
+};
+
+static u32 omap34xx_sr2_test_nvalues[] = {
+	0x0, 0xAAC098, 0xAB89D9
+};
+
+static struct omap_smartreflex_dev_data omap34xx_sr2_dev_attr = {
+	.volts_supported	= 3,
+	.efuse_sr_control	= OMAP343X_CONTROL_FUSE_SR,
+	.sennenable_shift	= OMAP343X_SR2_SENNENABLE_SHIFT,
+	.senpenable_shift	= OMAP343X_SR2_SENPENABLE_SHIFT,
+	.efuse_nvalues_offs	= omap34xx_sr2_efuse_offs,
+	.test_sennenable	= 0x3,
+	.test_senpenable	= 0x3,
+	.test_nvalues		= omap34xx_sr2_test_nvalues
+};
+
+static struct omap_hwmod omap34xx_sr2_hwmod = {
+	.name		= "sr2_hwmod",
+	.class		= &omap34xx_smartreflex_hwmod_class,
+	.main_clk	= "sr2_fck",
+	.slaves		= omap34xx_sr2_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_sr2_slaves),
+	.dev_attr	= &omap34xx_sr2_dev_attr,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_hwmod,
 	&omap3xxx_l4_core_hwmod,
 	&omap3xxx_l4_per_hwmod,
 	&omap3xxx_l4_wkup_hwmod,
 	&omap3xxx_mpu_hwmod,
+	&omap34xx_sr1_hwmod,
+	&omap34xx_sr2_hwmod,
 	NULL,
 };
 
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 2a0e823..d239eb2 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -237,6 +237,39 @@ extern u32 current_vdd2_opp;
 #define SR_TESTING_NVALUES 	0
 #endif
 
+/**
+ * omap_smartreflex_dev_data - Smartreflex device specific data
+ *
+ * @volts_supported	: Number of distinct voltages possible for the VDD
+ *			  associated with this smartreflex module.
+ * @efuse_sr_control	: The regisrter offset of control_fuse_sr efuse
+ *			  register from which sennenable and senpenable values
+ *			  are obtained.
+ * @sennenable_shift	: The shift in the control_fuse_sr register for
+ *			  obtaining the sennenable value for this smartreflex
+ *			  module.
+ * @senpenable_shift	: The shift in the control_fuse_sr register for
+ *			  obtaining the senpenable value for this smartreflex
+ *			  module.
+ * @efuse_nvalues_offs	: Array of efuse offsets from which ntarget values can
+ *			  be retrieved. Number of efuse offsets in this arrray
+ *			  is equal to the volts_supported value ie one efuse
+ *			  register per supported voltage.
+ * @test_sennenable	: SENNENABLE test value
+ * @test_senpenable	: SENPENABLE test value.
+ * @test_nvalues	: Array of test ntarget values.
+ */
+struct omap_smartreflex_dev_data {
+	int volts_supported;
+	u32 efuse_sr_control;
+	u32 sennenable_shift;
+	u32 senpenable_shift;
+	u32 *efuse_nvalues_offs;
+	u32 test_sennenable;
+	u32 test_senpenable;
+	u32 *test_nvalues;
+};
+
 /*
  * Smartreflex module enable/disable interface.
  * NOTE: if smartreflex is not enabled from sysfs, these functions will not
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 02/22] OMAP3: PM: Create list to keep track of various smartreflex instances.
  2010-04-16  9:02 ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Thara Gopinath
@ 2010-04-16  9:02   ` Thara Gopinath
  2010-04-16  9:02     ` [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer Thara Gopinath
  2010-04-27 17:34   ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Kevin Hilman
  1 sibling, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:02 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch removes the pointer sr1, sr2 in smartreflex.c and
instead creatse a list for keeping track of multiple smartreflex
instances.. This makes it scalable for next gen OMAPs where there
are more than two smartreflex modules.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |  114 ++++++++++++++++++++++++------------
 1 files changed, 76 insertions(+), 38 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 1c5ec37..dc8d6e1 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -26,6 +26,7 @@
 #include <linux/kobject.h>
 #include <linux/i2c/twl.h>
 #include <linux/io.h>
+#include <linux/list.h>
 
 #include <plat/omap34xx.h>
 #include <plat/control.h>
@@ -51,9 +52,12 @@ struct omap_sr {
 	u32		opp5_nvalue;
 	u32		senp_mod, senn_mod;
 	void __iomem	*srbase_addr;
-	void __iomem	*vpbase_addr;
+	struct list_head	node;
 };
 
+/* sr_list contains all the instances of smartreflex module */
+static LIST_HEAD(sr_list);
+
 #define SR_REGADDR(offs)	(sr->srbase_addr + offset)
 
 static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
@@ -78,6 +82,20 @@ static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset)
 	return __raw_readl(SR_REGADDR(offset));
 }
 
+static struct omap_sr *_sr_lookup(int srid)
+{
+	struct omap_sr *sr_info, *temp_sr_info;
+
+	sr_info = NULL;
+	list_for_each_entry(temp_sr_info, &sr_list, node) {
+		if (srid == temp_sr_info->srid) {
+			sr_info = temp_sr_info;
+			break;
+		}
+	}
+	return sr_info;
+}
+
 static int sr_clk_enable(struct omap_sr *sr)
 {
 	if (clk_enable(sr->clk) != 0) {
@@ -151,11 +169,17 @@ static u8 get_vdd1_opp(void)
 {
 	struct omap_opp *opp;
 	unsigned long freq;
+	struct omap_sr *sr_info = _sr_lookup(SR1);
 
-	if (sr1.vdd_opp_clk == NULL || IS_ERR(sr1.vdd_opp_clk))
+	if (!sr_info) {
+		pr_warning("omap_sr struct corresponding to SR1 not found\n");
+		return 0;
+	}
+
+	if (sr_info->vdd_opp_clk == NULL || IS_ERR(sr_info->vdd_opp_clk))
 		return 0;
 
-	freq = sr1.vdd_opp_clk->rate;
+	freq = sr_info->vdd_opp_clk->rate;
 	opp = opp_find_freq_ceil(OPP_MPU, &freq);
 	if (IS_ERR(opp))
 		return 0;
@@ -163,9 +187,9 @@ static u8 get_vdd1_opp(void)
 	 * Use higher freq voltage even if an exact match is not available
 	 * we are probably masking a clock framework bug, so warn
 	 */
-	if (unlikely(freq != sr1.vdd_opp_clk->rate))
+	if (unlikely(freq != sr_info->vdd_opp_clk->rate))
 		pr_warning("%s: Available freq %ld != dpll freq %ld.\n",
-			   __func__, freq, sr1.vdd_opp_clk->rate);
+			   __func__, freq, sr_info->vdd_opp_clk->rate);
 
 	return opp_get_opp_id(opp);
 }
@@ -174,11 +198,17 @@ static u8 get_vdd2_opp(void)
 {
 	struct omap_opp *opp;
 	unsigned long freq;
+	struct omap_sr *sr_info = _sr_lookup(SR2);
+
+	if (!sr_info) {
+		pr_warning("omap_sr struct corresponding to SR2 not found\n");
+		return 0;
+	}
 
-	if (sr2.vdd_opp_clk == NULL || IS_ERR(sr2.vdd_opp_clk))
+	if (sr_info->vdd_opp_clk == NULL || IS_ERR(sr_info->vdd_opp_clk))
 		return 0;
 
-	freq = sr2.vdd_opp_clk->rate;
+	freq = sr_info->vdd_opp_clk->rate;
 	opp = opp_find_freq_ceil(OPP_L3, &freq);
 	if (IS_ERR(opp))
 		return 0;
@@ -187,9 +217,9 @@ static u8 get_vdd2_opp(void)
 	 * Use higher freq voltage even if an exact match is not available
 	 * we are probably masking a clock framework bug, so warn
 	 */
-	if (unlikely(freq != sr2.vdd_opp_clk->rate))
+	if (unlikely(freq != sr_info->vdd_opp_clk->rate))
 		pr_warning("%s: Available freq %ld != dpll freq %ld.\n",
-			   __func__, freq, sr2.vdd_opp_clk->rate);
+			   __func__, freq, sr_info->vdd_opp_clk->rate);
 	return opp_get_opp_id(opp);
 }
 
@@ -694,14 +724,13 @@ static void sr_disable(struct omap_sr *sr)
 
 void sr_start_vddautocomap(int srid, u32 target_opp_no)
 {
-	struct omap_sr *sr = NULL;
+	struct omap_sr *sr = _sr_lookup(srid);
 
-	if (srid == SR1)
-		sr = &sr1;
-	else if (srid == SR2)
-		sr = &sr2;
-	else
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid);
 		return;
+	}
 
 	if (sr->is_sr_reset == 1) {
 		sr_clk_enable(sr);
@@ -719,14 +748,13 @@ EXPORT_SYMBOL(sr_start_vddautocomap);
 
 int sr_stop_vddautocomap(int srid)
 {
-	struct omap_sr *sr = NULL;
+	struct omap_sr *sr = _sr_lookup(srid);
 
-	if (srid == SR1)
-		sr = &sr1;
-	else if (srid == SR2)
-		sr = &sr2;
-	else
-		return -EINVAL;
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid);
+		return false;
+	}
 
 	if (sr->is_autocomp_active == 1) {
 		sr_disable(sr);
@@ -744,14 +772,13 @@ EXPORT_SYMBOL(sr_stop_vddautocomap);
 void enable_smartreflex(int srid)
 {
 	u32 target_opp_no = 0;
-	struct omap_sr *sr = NULL;
+	struct omap_sr *sr = _sr_lookup(srid);
 
-	if (srid == SR1)
-		sr = &sr1;
-	else if (srid == SR2)
-		sr = &sr2;
-	else
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid);
 		return;
+	}
 
 	if (sr->is_autocomp_active == 1) {
 		if (sr->is_sr_reset == 1) {
@@ -779,15 +806,13 @@ void enable_smartreflex(int srid)
 void disable_smartreflex(int srid)
 {
 	u32 i = 0;
+	struct omap_sr *sr = _sr_lookup(srid);
 
-	struct omap_sr *sr = NULL;
-
-	if (srid == SR1)
-		sr = &sr1;
-	else if (srid == SR2)
-		sr = &sr2;
-	else
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid);
 		return;
+	}
 
 	if (sr->is_autocomp_active == 1) {
 		if (sr->is_sr_reset == 0) {
@@ -920,7 +945,13 @@ int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
 static ssize_t omap_sr_vdd1_autocomp_show(struct kobject *kobj,
 					struct kobj_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", sr1.is_autocomp_active);
+	struct omap_sr *sr_info = _sr_lookup(SR1);
+
+	if (!sr_info) {
+		pr_warning("omap_sr struct corresponding to SR1 not found\n");
+		return 0;
+	}
+	return sprintf(buf, "%d\n", sr_info->is_autocomp_active);
 }
 
 static ssize_t omap_sr_vdd1_autocomp_store(struct kobject *kobj,
@@ -960,7 +991,13 @@ static struct kobj_attribute sr_vdd1_autocomp = {
 static ssize_t omap_sr_vdd2_autocomp_show(struct kobject *kobj,
 					struct kobj_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", sr2.is_autocomp_active);
+	struct omap_sr *sr_info = _sr_lookup(SR2);
+
+	if (!sr_info) {
+		pr_warning("omap_sr struct corresponding to SR2 not found\n");
+		return 0;
+	}
+	return sprintf(buf, "%d\n", sr_info->is_autocomp_active);
 }
 
 static ssize_t omap_sr_vdd2_autocomp_store(struct kobject *kobj,
@@ -1010,7 +1047,6 @@ static int __init omap3_sr_init(void)
 	RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
 	ret |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, RdReg,
 				R_DCDC_GLOBAL_CFG);
-
 	if (cpu_is_omap34xx()) {
 		sr1.clk = clk_get(NULL, "sr1_fck");
 		sr2.clk = clk_get(NULL, "sr2_fck");
@@ -1036,6 +1072,8 @@ static int __init omap3_sr_init(void)
 	ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
 	if (ret)
 		pr_err("sysfs_create_file failed: %d\n", ret);
+	list_add(&sr1.node, &sr_list);
+	list_add(&sr2.node, &sr_list);
 
 	return 0;
 }
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer
  2010-04-16  9:02   ` [PATCHv3 02/22] OMAP3: PM: Create list to keep track of various smartreflex instances Thara Gopinath
@ 2010-04-16  9:02     ` Thara Gopinath
  2010-04-16  9:02       ` [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs Thara Gopinath
  2010-04-27 17:47       ` [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer Kevin Hilman
  0 siblings, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:02 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch converts the exisitng smartreflex library into a
platform driver with device , driver registrations using hardware mods.
As part of this Ntarget values are passed as platform data.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/Makefile      |    2 +-
 arch/arm/mach-omap2/smartreflex.c |  325 +++++++++++++------------------------
 arch/arm/mach-omap2/smartreflex.h |   26 +++
 arch/arm/mach-omap2/sr_device.c   |  139 ++++++++++++++++
 4 files changed, 278 insertions(+), 214 deletions(-)
 create mode 100644 arch/arm/mach-omap2/sr_device.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index ab47043..62accd2 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -48,7 +48,7 @@ obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
-obj-$(CONFIG_OMAP_SMARTREFLEX)	+= smartreflex.o
+obj-$(CONFIG_OMAP_SMARTREFLEX)		+= sr_device.o smartreflex.o
 
 AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
 AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index dc8d6e1..b4e98e5 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -3,6 +3,9 @@
  *
  * OMAP34XX SmartReflex Voltage Control
  *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
  * Copyright (C) 2008 Nokia Corporation
  * Kalle Jokiniemi
  *
@@ -14,7 +17,6 @@
  * published by the Free Software Foundation.
  */
 
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -29,10 +31,11 @@
 #include <linux/list.h>
 
 #include <plat/omap34xx.h>
-#include <plat/control.h>
 #include <plat/clock.h>
 #include <plat/opp.h>
 #include <plat/opp_twl_tps.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
 
 #include "prm.h"
 #include "smartreflex.h"
@@ -41,45 +44,44 @@
 #define MAX_TRIES 100
 
 struct omap_sr {
-	int		srid;
-	int		is_sr_reset;
-	int		is_autocomp_active;
-	struct clk	*clk;
-	struct clk	*vdd_opp_clk;
-	u32		clk_length;
-	u32		req_opp_no;
-	u32		opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue;
-	u32		opp5_nvalue;
-	u32		senp_mod, senn_mod;
-	void __iomem	*srbase_addr;
+	int			srid;
+	int			is_sr_reset;
+	int			is_autocomp_active;
+	struct clk		*vdd_opp_clk;
+	u32			clk_length;
+	unsigned int		irq;
+	struct platform_device	*pdev;
 	struct list_head	node;
 };
 
 /* sr_list contains all the instances of smartreflex module */
 static LIST_HEAD(sr_list);
 
-#define SR_REGADDR(offs)	(sr->srbase_addr + offset)
-
 static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
 {
-	__raw_writel(value, SR_REGADDR(offset));
+	struct omap_device *odev = to_omap_device(sr->pdev);
+
+	omap_hwmod_writel(value, odev->hwmods[0], offset);
 }
 
 static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
 					u32 value)
 {
+	struct omap_device *odev = to_omap_device(sr->pdev);
 	u32 reg_val;
 
-	reg_val = __raw_readl(SR_REGADDR(offset));
+	reg_val = omap_hwmod_readl(odev->hwmods[0], offset);
 	reg_val &= ~mask;
 	reg_val |= value;
 
-	__raw_writel(reg_val, SR_REGADDR(offset));
+	omap_hwmod_writel(reg_val, odev->hwmods[0], offset);
 }
 
 static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset)
 {
-	return __raw_readl(SR_REGADDR(offset));
+	struct omap_device *odev = to_omap_device(sr->pdev);
+
+	return omap_hwmod_readl(odev->hwmods[0], offset);
 }
 
 static struct omap_sr *_sr_lookup(int srid)
@@ -98,71 +100,22 @@ static struct omap_sr *_sr_lookup(int srid)
 
 static int sr_clk_enable(struct omap_sr *sr)
 {
-	if (clk_enable(sr->clk) != 0) {
-		pr_err("Could not enable %s\n", sr->clk->name);
-		return -1;
-	}
+	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
 
-	/* set fclk- active , iclk- idle */
-	sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
-		      SR_CLKACTIVITY_IOFF_FON);
+	if (pdata->device_enable)
+		pdata->device_enable(sr->pdev);
 
 	return 0;
 }
 
 static void sr_clk_disable(struct omap_sr *sr)
 {
-	/* set fclk, iclk- idle */
-	sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
-		      SR_CLKACTIVITY_IOFF_FOFF);
-
-	clk_disable(sr->clk);
-	sr->is_sr_reset = 1;
-}
-
-static struct omap_sr sr1 = {
-	.srid			= SR1,
-	.is_sr_reset		= 1,
-	.is_autocomp_active	= 0,
-	.clk_length		= 0,
-	.srbase_addr		= OMAP2_L4_IO_ADDRESS(OMAP34XX_SR1_BASE),
-};
-
-static struct omap_sr sr2 = {
-	.srid			= SR2,
-	.is_sr_reset		= 1,
-	.is_autocomp_active	= 0,
-	.clk_length		= 0,
-	.srbase_addr		= OMAP2_L4_IO_ADDRESS(OMAP34XX_SR2_BASE),
-};
-
-static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
-{
-	u32 gn, rn, mul;
-
-	for (gn = 0; gn < GAIN_MAXLIMIT; gn++) {
-		mul = 1 << (gn + 8);
-		rn = mul / sensor;
-		if (rn < R_MAXLIMIT) {
-			*sengain = gn;
-			*rnsen = rn;
-		}
-	}
-}
-
-static u32 cal_test_nvalue(u32 sennval, u32 senpval)
-{
-	u32 senpgain, senngain;
-	u32 rnsenp, rnsenn;
+	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
 
-	/* Calculating the gain and reciprocal of the SenN and SenP values */
-	cal_reciprocal(senpval, &senpgain, &rnsenp);
-	cal_reciprocal(sennval, &senngain, &rnsenn);
+	if (pdata->device_idle)
+		pdata->device_idle(sr->pdev);
 
-	return (senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
-		(senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
-		(rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
-		(rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT);
+	sr->is_sr_reset = 1;
 }
 
 static u8 get_vdd1_opp(void)
@@ -255,76 +208,6 @@ static void sr_set_clk_length(struct omap_sr *sr)
 	}
 }
 
-static void sr_set_efuse_nvalues(struct omap_sr *sr)
-{
-	if (sr->srid == SR1) {
-		sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
-					OMAP343X_SR1_SENNENABLE_MASK) >>
-					OMAP343X_SR1_SENNENABLE_SHIFT;
-		sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
-					OMAP343X_SR1_SENPENABLE_MASK) >>
-					OMAP343X_SR1_SENPENABLE_SHIFT;
-
-		sr->opp5_nvalue = omap_ctrl_readl(
-					OMAP343X_CONTROL_FUSE_OPP5_VDD1);
-		sr->opp4_nvalue = omap_ctrl_readl(
-					OMAP343X_CONTROL_FUSE_OPP4_VDD1);
-		sr->opp3_nvalue = omap_ctrl_readl(
-					OMAP343X_CONTROL_FUSE_OPP3_VDD1);
-		sr->opp2_nvalue = omap_ctrl_readl(
-					OMAP343X_CONTROL_FUSE_OPP2_VDD1);
-		sr->opp1_nvalue = omap_ctrl_readl(
-					OMAP343X_CONTROL_FUSE_OPP1_VDD1);
-	} else if (sr->srid == SR2) {
-		sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
-					OMAP343X_SR2_SENNENABLE_MASK) >>
-					OMAP343X_SR2_SENNENABLE_SHIFT;
-
-		sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
-					OMAP343X_SR2_SENPENABLE_MASK) >>
-					OMAP343X_SR2_SENPENABLE_SHIFT;
-
-		sr->opp3_nvalue = omap_ctrl_readl(
-					OMAP343X_CONTROL_FUSE_OPP3_VDD2);
-		sr->opp2_nvalue = omap_ctrl_readl(
-					OMAP343X_CONTROL_FUSE_OPP2_VDD2);
-		sr->opp1_nvalue = omap_ctrl_readl(
-					OMAP343X_CONTROL_FUSE_OPP1_VDD2);
-	}
-}
-
-/* Hard coded nvalues for testing purposes, may cause device to hang! */
-static void sr_set_testing_nvalues(struct omap_sr *sr)
-{
-	if (sr->srid == SR1) {
-		sr->senp_mod = 0x03;	/* SenN-M5 enabled */
-		sr->senn_mod = 0x03;
-
-		/* calculate nvalues for each opp */
-		sr->opp5_nvalue = cal_test_nvalue(0xacd + 0x330, 0x848 + 0x330);
-		sr->opp4_nvalue = cal_test_nvalue(0x964 + 0x2a0, 0x727 + 0x2a0);
-		sr->opp3_nvalue = cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200);
-		sr->opp2_nvalue = cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0);
-		sr->opp1_nvalue = cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100);
-	} else if (sr->srid == SR2) {
-		sr->senp_mod = 0x03;
-		sr->senn_mod = 0x03;
-
-		sr->opp3_nvalue = cal_test_nvalue(0x76f + 0x200, 0x579 + 0x200);
-		sr->opp2_nvalue = cal_test_nvalue(0x4f5 + 0x1c0, 0x390 + 0x1c0);
-		sr->opp1_nvalue = cal_test_nvalue(0x359, 0x25d);
-	}
-
-}
-
-static void sr_set_nvalues(struct omap_sr *sr)
-{
-	if (SR_TESTING_NVALUES)
-		sr_set_testing_nvalues(sr);
-	else
-		sr_set_efuse_nvalues(sr);
-}
-
 static void sr_configure_vp(int srid)
 {
 	u32 vpconfig;
@@ -438,12 +321,13 @@ static void sr_configure(struct omap_sr *sr)
 {
 	u32 sr_config;
 	u32 senp_en , senn_en;
+	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
 
 	if (sr->clk_length == 0)
 		sr_set_clk_length(sr);
 
-	senp_en = sr->senp_mod;
-	senn_en = sr->senn_mod;
+	senp_en = pdata->senp_mod;
+	senn_en = pdata->senn_mod;
 	if (sr->srid == SR1) {
 		sr_config = SR1_SRCONFIG_ACCUMDATA |
 			(sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
@@ -571,57 +455,28 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
 {
 	u32 nvalue_reciprocal, v;
 	struct omap_opp *opp;
+	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
 	int uvdc;
 	char vsel;
 
-	sr->req_opp_no = target_opp_no;
-
 	if (sr->srid == SR1) {
-		switch (target_opp_no) {
-		case 5:
-			nvalue_reciprocal = sr->opp5_nvalue;
-			break;
-		case 4:
-			nvalue_reciprocal = sr->opp4_nvalue;
-			break;
-		case 3:
-			nvalue_reciprocal = sr->opp3_nvalue;
-			break;
-		case 2:
-			nvalue_reciprocal = sr->opp2_nvalue;
-			break;
-		case 1:
-			nvalue_reciprocal = sr->opp1_nvalue;
-			break;
-		default:
-			nvalue_reciprocal = sr->opp3_nvalue;
-			break;
-		}
-
 		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
 		if (!opp)
 			return false;
 	} else {
-		switch (target_opp_no) {
-		case 3:
-			nvalue_reciprocal = sr->opp3_nvalue;
-			break;
-		case 2:
-			nvalue_reciprocal = sr->opp2_nvalue;
-			break;
-		case 1:
-			nvalue_reciprocal = sr->opp1_nvalue;
-			break;
-		default:
-			nvalue_reciprocal = sr->opp3_nvalue;
-			break;
-		}
-
 		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
 		if (!opp)
 			return false;
 	}
 
+	if (!pdata->sr_nvalue) {
+		pr_notice("N target values does not exist for SR%d\n",
+								sr->srid);
+		return false;
+	}
+
+	nvalue_reciprocal = pdata->sr_nvalue[target_opp_no - 1];
+
 	if (nvalue_reciprocal == 0) {
 		pr_notice("OPP%d doesn't support SmartReflex\n",
 								target_opp_no);
@@ -1033,49 +888,93 @@ static struct kobj_attribute sr_vdd2_autocomp = {
 	.store = omap_sr_vdd2_autocomp_store,
 };
 
+static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
+{
+	struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
+	struct omap_device *odev = to_omap_device(pdev);
+	int ret = 0;
+
+	if (WARN_ON(!sr_info))
+		return -ENOMEM;
+	sr_info->pdev = pdev;
+	sr_info->srid = pdev->id + 1;
+	sr_info->is_sr_reset = 1,
+	sr_info->is_autocomp_active = 0;
+	sr_info->clk_length = 0;
+	if (odev->hwmods[0]->mpu_irqs)
+		sr_info->irq = odev->hwmods[0]->mpu_irqs[0].irq;
+	sr_set_clk_length(sr_info);
+
+	if (sr_info->srid == SR1) {
+		sr_info->vdd_opp_clk = clk_get(NULL, "dpll1_ck");
+		ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
+		if (ret)
+			pr_err("sysfs_create_file failed: %d\n", ret);
+	} else {
+		sr_info->vdd_opp_clk = clk_get(NULL, "l3_ick");
+		ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
+		if (ret)
+			pr_err("sysfs_create_file failed: %d\n", ret);
+	}
+
+	/* Call the VPConfig */
+	sr_configure_vp(sr_info->srid);
+	list_add(&sr_info->node, &sr_list);
+	pr_info("SmartReflex driver initialized\n");
+
+	return ret;
+}
+
+static int __devexit omap_smartreflex_remove(struct platform_device *pdev)
+{
+	struct omap_sr *sr_info = _sr_lookup(pdev->id + 1);
 
+	/* Disable Autocompensation if enabled before removing the module */
+	if (sr_info->is_autocomp_active == 1)
+		sr_stop_vddautocomap(sr_info->srid);
+	list_del(&sr_info->node);
+	kfree(sr_info);
 
-static int __init omap3_sr_init(void)
+	return 0;
+}
+
+static struct platform_driver smartreflex_driver = {
+	.probe          = omap_smartreflex_probe,
+	.remove         = omap_smartreflex_remove,
+	.driver		= {
+		.name	= "smartreflex",
+	},
+};
+
+static int __init sr_init(void)
 {
 	int ret = 0;
 	u8 RdReg;
 
+	/* TODO: Find an appropriate place for this */
 	/* Enable SR on T2 */
 	ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
 			      R_DCDC_GLOBAL_CFG);
-
 	RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
 	ret |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, RdReg,
 				R_DCDC_GLOBAL_CFG);
-	if (cpu_is_omap34xx()) {
-		sr1.clk = clk_get(NULL, "sr1_fck");
-		sr2.clk = clk_get(NULL, "sr2_fck");
-	}
-	sr1.vdd_opp_clk = clk_get(NULL, "dpll1_ck");
-	sr2.vdd_opp_clk = clk_get(NULL, "l3_ick");
-	sr_set_clk_length(&sr1);
-	sr_set_clk_length(&sr2);
-
-	/* Call the VPConfig, VCConfig, set N Values. */
-	sr_set_nvalues(&sr1);
-	sr_configure_vp(SR1);
-
-	sr_set_nvalues(&sr2);
-	sr_configure_vp(SR2);
-
-	pr_info("SmartReflex driver initialized\n");
 
-	ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
-	if (ret)
-		pr_err("sysfs_create_file failed: %d\n", ret);
+	ret = platform_driver_probe(&smartreflex_driver,
+				omap_smartreflex_probe);
 
-	ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
 	if (ret)
-		pr_err("sysfs_create_file failed: %d\n", ret);
-	list_add(&sr1.node, &sr_list);
-	list_add(&sr2.node, &sr_list);
-
+		pr_err("platform driver register failed for smartreflex");
 	return 0;
 }
 
-late_initcall(omap3_sr_init);
+void __exit sr_exit(void)
+{
+	platform_driver_unregister(&smartreflex_driver);
+}
+late_initcall(sr_init);
+module_exit(sr_exit);
+
+MODULE_DESCRIPTION("OMAP SMARTREFLEX DRIVER");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index d239eb2..5eb8846 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -14,6 +14,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/platform_device.h>
+
 #define PHY_TO_OFF_PM_MASTER(p)		(p - 0x36)
 #define PHY_TO_OFF_PM_RECIEVER(p)	(p - 0x5b)
 #define PHY_TO_OFF_PM_INT(p)		(p - 0x2e)
@@ -276,6 +278,30 @@ struct omap_smartreflex_dev_data {
  * do anything.
  */
 #ifdef CONFIG_OMAP_SMARTREFLEX
+/**
+ * omap_smartreflex_data - Smartreflex platform data
+ *
+ * @senp_mod		: SENPENABLE value for the sr
+ * @senn_mod		: SENNENABLE value for sr
+ * @sr_nvalue		: array of n target values for sr
+ * @enable_on_init	: whether this sr module needs to enabled at
+ *			  boot up or not
+ * @device_enable	: fn pointer to be populated with omap_device
+ *			enable API
+ * @device_shutdown	: fn pointer to be populated with omap_device
+ *			shutdown API
+ * @device_idle		: fn pointer to be pouplated with omap_device idle API
+ */
+struct omap_smartreflex_data {
+	u32		senp_mod;
+	u32		senn_mod;
+	u32		*sr_nvalue;
+	bool		enable_on_init;
+	int (*device_enable)(struct platform_device *pdev);
+	int (*device_shutdown)(struct platform_device *pdev);
+	int (*device_idle)(struct platform_device *pdev);
+};
+
 void enable_smartreflex(int srid);
 void disable_smartreflex(int srid);
 int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
new file mode 100644
index 0000000..a9c1ef0
--- /dev/null
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/arm/mach-omap2/sr_device.c
+ *
+ * OMAP3/OMAP4 smartreflex device file
+ *
+ * Author: Thara Gopinath	<thara@ti.com>
+ *
+ * Based originally on code from smartreflex.c
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+
+#include <plat/control.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+#include <plat/opp.h>
+
+#include "smartreflex.h"
+
+#define MAX_HWMOD_NAME_LEN	16
+
+struct omap_device_pm_latency omap_sr_latency[] = {
+	{
+		.deactivate_func = omap_device_idle_hwmods,
+		.activate_func	 = omap_device_enable_hwmods,
+		.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST
+	},
+};
+
+/* Read EFUSE values from control registers for OMAP3430 */
+static void __init sr_read_efuse(
+				struct omap_smartreflex_dev_data *dev_data,
+				struct omap_smartreflex_data *sr_data)
+{
+	int i;
+
+	if (WARN_ON(!dev_data || !dev_data->volts_supported ||
+			!dev_data->efuse_sr_control ||
+			!dev_data->efuse_nvalues_offs))
+		return;
+
+	sr_data->sr_nvalue = kzalloc(sizeof(sr_data->sr_nvalue) *
+			dev_data->volts_supported , GFP_KERNEL);
+	sr_data->senn_mod = (omap_ctrl_readl(dev_data->efuse_sr_control) &
+				(0x3 << dev_data->sennenable_shift) >>
+				dev_data->sennenable_shift);
+	sr_data->senp_mod = (omap_ctrl_readl(dev_data->efuse_sr_control) &
+				(0x3 << dev_data->senpenable_shift) >>
+				dev_data->senpenable_shift);
+	for (i = 0; i < dev_data->volts_supported; i++)
+		sr_data->sr_nvalue[i] = omap_ctrl_readl(
+				dev_data->efuse_nvalues_offs[i]);
+}
+
+/*
+ * Hard coded nvalues for testing purposes for OMAP3430,
+ * may cause device to hang!
+ */
+static void __init sr_set_testing_nvalues(
+				struct omap_smartreflex_dev_data *dev_data,
+				struct omap_smartreflex_data *sr_data)
+{
+	int i;
+
+	if (WARN_ON(!dev_data || !dev_data->volts_supported ||
+			!dev_data->test_nvalues))
+		return;
+
+	sr_data->sr_nvalue = kzalloc(sizeof(sr_data->sr_nvalue) *
+			dev_data->volts_supported , GFP_KERNEL);
+	sr_data->senn_mod = dev_data->test_sennenable;
+	sr_data->senp_mod = dev_data->test_senpenable;
+	for (i = 0; i < dev_data->volts_supported; i++)
+		sr_data->sr_nvalue[i] = dev_data->test_nvalues[i];
+}
+
+static void __init sr_set_nvalues(struct omap_smartreflex_dev_data *dev_data,
+		struct omap_smartreflex_data *sr_data)
+{
+	if (cpu_is_omap34xx()) {
+		if (SR_TESTING_NVALUES)
+			sr_set_testing_nvalues(dev_data, sr_data);
+		else
+			sr_read_efuse(dev_data, sr_data);
+	}
+}
+
+static int __init omap_devinit_smartreflex(void)
+{
+	int i = 0;
+	char *name = "smartreflex";
+
+	do {
+		struct omap_smartreflex_data *sr_data;
+		struct omap_smartreflex_dev_data *sr_dev_data;
+		struct omap_device *od;
+		struct omap_hwmod *oh;
+		char oh_name[MAX_HWMOD_NAME_LEN + 1];
+
+		snprintf(oh_name, MAX_HWMOD_NAME_LEN, "sr%d_hwmod", i + 1);
+		oh = omap_hwmod_lookup(oh_name);
+		if (!oh)
+			break;
+
+		sr_data = kzalloc(sizeof(struct omap_smartreflex_data),
+								GFP_KERNEL);
+		sr_dev_data = (struct omap_smartreflex_dev_data *)oh->dev_attr;
+		if (WARN_ON(!sr_data))
+			return -ENOMEM;
+
+		sr_data->enable_on_init = false;
+		sr_data->device_enable = omap_device_enable;
+		sr_data->device_shutdown = omap_device_shutdown;
+		sr_data->device_idle = omap_device_idle;
+		sr_set_nvalues(sr_dev_data, sr_data);
+
+		od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
+				       omap_sr_latency,
+				       ARRAY_SIZE(omap_sr_latency), 0);
+		WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
+		     name, oh->name);
+		i++;
+	} while (1);
+
+	return 0;
+}
+arch_initcall(omap_devinit_smartreflex);
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs.
  2010-04-16  9:02     ` [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer Thara Gopinath
@ 2010-04-16  9:02       ` Thara Gopinath
  2010-04-16  9:03         ` [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver Thara Gopinath
  2010-04-27 17:57         ` [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs Kevin Hilman
  2010-04-27 17:47       ` [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer Kevin Hilman
  1 sibling, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:02 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch moves the hooks to enable disable smartreflex
autocompensation to pm debugfs from the /sys/power/.

To enable autocompensation for smartreflex SR<n> do
        echo 1 > <path>/pm_debug/sr<n>_autocomp
To disable autocompensation for smartreflex SR<n> do
        echo 0 > <path>/pm_debug/sr<n>_autocomp

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/pm-debug.c    |    4 +-
 arch/arm/mach-omap2/smartreflex.c |  114 ++++++++++--------------------------
 arch/arm/mach-omap2/smartreflex.h |    2 +
 3 files changed, 36 insertions(+), 84 deletions(-)

diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 8aafd71..ce46059 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -162,7 +162,7 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
 
 static void pm_dbg_regset_store(u32 *ptr);
 
-struct dentry *pm_dbg_dir;
+struct dentry *pm_dbg_dir, *pm_dbg_main_dir;
 
 static int pm_dbg_init_done;
 
@@ -613,7 +613,7 @@ static int __init pm_dbg_init(void)
 					   S_IRUGO | S_IWUGO, d,
 					   &voltage_off_while_idle,
 					   &pm_dbg_option_fops);
-
+	pm_dbg_main_dir = d;
 	pm_dbg_init_done = 1;
 
 	return 0;
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index b4e98e5..2f89d79 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -24,11 +24,11 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/clk.h>
-#include <linux/sysfs.h>
 #include <linux/kobject.h>
 #include <linux/i2c/twl.h>
 #include <linux/io.h>
 #include <linux/list.h>
+#include <linux/debugfs.h>
 
 #include <plat/omap34xx.h>
 #include <plat/clock.h>
@@ -42,6 +42,7 @@
 #include "prm-regbits-34xx.h"
 
 #define MAX_TRIES 100
+#define SMARTREFLEX_NAME_LEN	16
 
 struct omap_sr {
 	int			srid;
@@ -796,103 +797,53 @@ int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
 	return 0;
 }
 
-/* Sysfs interface to select SR VDD1 auto compensation */
-static ssize_t omap_sr_vdd1_autocomp_show(struct kobject *kobj,
-					struct kobj_attribute *attr, char *buf)
+/* PM Debug Fs enteries to enable disable smartreflex.*/
+
+static int omap_sr_autocomp_show(void *data, u64 *val)
 {
-	struct omap_sr *sr_info = _sr_lookup(SR1);
+	struct omap_sr *sr_info = (struct omap_sr *) data;
 
 	if (!sr_info) {
-		pr_warning("omap_sr struct corresponding to SR1 not found\n");
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+							sr_info->srid);
 		return 0;
 	}
-	return sprintf(buf, "%d\n", sr_info->is_autocomp_active);
+	*val = sr_info->is_autocomp_active;
+	return 0;
 }
 
-static ssize_t omap_sr_vdd1_autocomp_store(struct kobject *kobj,
-					struct kobj_attribute *attr,
-					const char *buf, size_t n)
+static int omap_sr_autocomp_store(void *data, u64 val)
 {
-	unsigned short value;
-
-	if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
-		pr_err("sr_vdd1_autocomp: Invalid value\n");
-		return -EINVAL;
-	}
-
-	if (value == 0) {
-		sr_stop_vddautocomap(SR1);
-	} else {
-		u32 current_vdd1opp_no = get_vdd1_opp();
-		if (!current_vdd1opp_no) {
-			pr_err("sr_vdd1_autocomp: Current VDD1 opp unknown\n");
-			return -EINVAL;
-		}
-		sr_start_vddautocomap(SR1, current_vdd1opp_no);
-	}
-	return n;
-}
-
-static struct kobj_attribute sr_vdd1_autocomp = {
-	.attr = {
-	.name = __stringify(sr_vdd1_autocomp),
-	.mode = 0644,
-	},
-	.show = omap_sr_vdd1_autocomp_show,
-	.store = omap_sr_vdd1_autocomp_store,
-};
-
-/* Sysfs interface to select SR VDD2 auto compensation */
-static ssize_t omap_sr_vdd2_autocomp_show(struct kobject *kobj,
-					struct kobj_attribute *attr, char *buf)
-{
-	struct omap_sr *sr_info = _sr_lookup(SR2);
+	struct omap_sr *sr_info = (struct omap_sr *) data;
 
 	if (!sr_info) {
-		pr_warning("omap_sr struct corresponding to SR2 not found\n");
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+							sr_info->srid);
 		return 0;
 	}
-	return sprintf(buf, "%d\n", sr_info->is_autocomp_active);
-}
-
-static ssize_t omap_sr_vdd2_autocomp_store(struct kobject *kobj,
-					struct kobj_attribute *attr,
-					const char *buf, size_t n)
-{
-	unsigned short value;
-
-	if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
-		pr_err("sr_vdd2_autocomp: Invalid value\n");
-		return -EINVAL;
-	}
-
-	if (value == 0) {
-		sr_stop_vddautocomap(SR2);
+	if (val == 0) {
+		sr_stop_vddautocomap(sr_info->srid);
 	} else {
-		u32 current_vdd2opp_no = get_vdd2_opp();
-		if (!current_vdd2opp_no) {
-			pr_err("sr_vdd2_autocomp: Current VDD2 opp unknown\n");
-			return -EINVAL;
-		}
-		sr_start_vddautocomap(SR2, current_vdd2opp_no);
+		u32 current_opp;
+
+		if (sr_info->srid == SR1)
+			current_opp = get_vdd1_opp();
+		else
+			current_opp = get_vdd2_opp();
+		sr_start_vddautocomap(sr_info->srid, current_opp);
 	}
-	return n;
+	return 0;
 }
 
-static struct kobj_attribute sr_vdd2_autocomp = {
-	.attr = {
-	.name = __stringify(sr_vdd2_autocomp),
-	.mode = 0644,
-	},
-	.show = omap_sr_vdd2_autocomp_show,
-	.store = omap_sr_vdd2_autocomp_store,
-};
+DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
+		omap_sr_autocomp_store, "%llu\n");
 
 static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 {
 	struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
 	struct omap_device *odev = to_omap_device(pdev);
 	int ret = 0;
+	char name[SMARTREFLEX_NAME_LEN + 1];
 
 	if (WARN_ON(!sr_info))
 		return -ENOMEM;
@@ -907,16 +858,15 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 
 	if (sr_info->srid == SR1) {
 		sr_info->vdd_opp_clk = clk_get(NULL, "dpll1_ck");
-		ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
-		if (ret)
-			pr_err("sysfs_create_file failed: %d\n", ret);
 	} else {
 		sr_info->vdd_opp_clk = clk_get(NULL, "l3_ick");
-		ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
-		if (ret)
-			pr_err("sysfs_create_file failed: %d\n", ret);
 	}
 
+	/* Create the debug fs enteries */
+	sprintf(name, "sr%d_autocomp", sr_info->srid);
+	(void) debugfs_create_file(name, S_IRUGO | S_IWUGO, pm_dbg_main_dir,
+				(void *)sr_info, &pm_sr_fops);
+
 	/* Call the VPConfig */
 	sr_configure_vp(sr_info->srid);
 	list_add(&sr_info->node, &sr_list);
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 5eb8846..ea0ddd3 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -16,6 +16,8 @@
 
 #include <linux/platform_device.h>
 
+extern struct dentry *pm_dbg_main_dir;
+
 #define PHY_TO_OFF_PM_MASTER(p)		(p - 0x36)
 #define PHY_TO_OFF_PM_RECIEVER(p)	(p - 0x5b)
 #define PHY_TO_OFF_PM_INT(p)		(p - 0x2e)
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver
  2010-04-16  9:02       ` [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs Thara Gopinath
@ 2010-04-16  9:03         ` Thara Gopinath
  2010-04-16  9:03           ` [PATCHv3 06/22] OMAP3: PM: Correcting API names in samrtreflex driver Thara Gopinath
  2010-04-27 18:43           ` [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver Kevin Hilman
  2010-04-27 17:57         ` [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs Kevin Hilman
  1 sibling, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch removes get_vdd1_opp and get_vdd2_opp API's and replaces
them with get_curr_vdd1_voltage and get_curr_vdd2_voltage API's.
N-target values are now linked to voltages and the link bewtween
voltage and n-target values is managed internally in smartreflex
driver and sr_devices.c.

get_curr_vdd1_voltage and get_curr_vdd2_voltage are added in
smartreflex driver in this patch. These API's will be moved to the
voltage driver in a later patch when voltage specific code is separated
out of smartreflex. The link between various voltages and n-target
values will also be separated out later.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |  201 +++++++++++++++----------------------
 arch/arm/mach-omap2/smartreflex.h |   21 +++-
 arch/arm/mach-omap2/sr_device.c   |   39 ++++++-
 3 files changed, 129 insertions(+), 132 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 2f89d79..669f1bb 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -48,7 +48,6 @@ struct omap_sr {
 	int			srid;
 	int			is_sr_reset;
 	int			is_autocomp_active;
-	struct clk		*vdd_opp_clk;
 	u32			clk_length;
 	unsigned int		irq;
 	struct platform_device	*pdev;
@@ -119,64 +118,65 @@ static void sr_clk_disable(struct omap_sr *sr)
 	sr->is_sr_reset = 1;
 }
 
-static u8 get_vdd1_opp(void)
+static unsigned long get_curr_vdd1_voltage(void)
 {
 	struct omap_opp *opp;
 	unsigned long freq;
-	struct omap_sr *sr_info = _sr_lookup(SR1);
+	struct clk *dpll1_clk;
 
-	if (!sr_info) {
-		pr_warning("omap_sr struct corresponding to SR1 not found\n");
-		return 0;
-	}
-
-	if (sr_info->vdd_opp_clk == NULL || IS_ERR(sr_info->vdd_opp_clk))
+	dpll1_clk = clk_get(NULL, "dpll1_ck");
+	if (IS_ERR(dpll1_clk))
 		return 0;
 
-	freq = sr_info->vdd_opp_clk->rate;
-	opp = opp_find_freq_ceil(OPP_MPU, &freq);
+	freq = dpll1_clk->rate;;
+	opp = opp_find_freq_exact(OPP_MPU, freq, 1);
 	if (IS_ERR(opp))
 		return 0;
-	/*
-	 * Use higher freq voltage even if an exact match is not available
-	 * we are probably masking a clock framework bug, so warn
-	 */
-	if (unlikely(freq != sr_info->vdd_opp_clk->rate))
-		pr_warning("%s: Available freq %ld != dpll freq %ld.\n",
-			   __func__, freq, sr_info->vdd_opp_clk->rate);
 
-	return opp_get_opp_id(opp);
+	return opp_get_voltage(opp);
 }
 
-static u8 get_vdd2_opp(void)
+static unsigned long get_curr_vdd2_voltage(void)
 {
 	struct omap_opp *opp;
 	unsigned long freq;
-	struct omap_sr *sr_info = _sr_lookup(SR2);
+	struct clk *l3_clk;
 
-	if (!sr_info) {
-		pr_warning("omap_sr struct corresponding to SR2 not found\n");
-		return 0;
-	}
-
-	if (sr_info->vdd_opp_clk == NULL || IS_ERR(sr_info->vdd_opp_clk))
+	l3_clk = clk_get(NULL, "l3_ick");
+	if (IS_ERR(l3_clk))
 		return 0;
 
-	freq = sr_info->vdd_opp_clk->rate;
-	opp = opp_find_freq_ceil(OPP_L3, &freq);
+	freq = l3_clk->rate;
+	opp = opp_find_freq_exact(OPP_L3, freq, 1);
 	if (IS_ERR(opp))
 		return 0;
 
-	/*
-	 * Use higher freq voltage even if an exact match is not available
-	 * we are probably masking a clock framework bug, so warn
-	 */
-	if (unlikely(freq != sr_info->vdd_opp_clk->rate))
-		pr_warning("%s: Available freq %ld != dpll freq %ld.\n",
-			   __func__, freq, sr_info->vdd_opp_clk->rate);
-	return opp_get_opp_id(opp);
+	return opp_get_voltage(opp);
 }
 
+static int sr_match_volt(struct omap_sr *sr, unsigned long volt,
+				struct omap_volt_data *volt_data)
+{
+	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
+	struct omap_device *odev = to_omap_device(sr->pdev);
+	struct omap_smartreflex_dev_data *sr_dev_data =
+					odev->hwmods[0]->dev_attr;
+	int i;
+
+	if (!pdata->sr_volt_data) {
+		pr_notice("voltage table does not exist for SR %d\n", sr->srid);
+		return false;
+	}
+	for (i = 0; i < sr_dev_data->volts_supported; i++) {
+		if (pdata->sr_volt_data[i].voltage == volt) {
+			*volt_data = pdata->sr_volt_data[i];
+			return true;
+		}
+	}
+	pr_notice("Unable to match the current voltage with \
+				the voltage table for SR %d\n", sr->srid);
+	return false;
+}
 
 static void sr_set_clk_length(struct omap_sr *sr)
 {
@@ -211,21 +211,14 @@ static void sr_set_clk_length(struct omap_sr *sr)
 
 static void sr_configure_vp(int srid)
 {
-	u32 vpconfig;
-	u32 vsel;
-	int uvdc;
-	u32 target_opp_no;
-	struct omap_opp *opp;
+	u32 vpconfig, vsel;
+	unsigned long uvdc;
 
 	if (srid == SR1) {
-		target_opp_no = get_vdd1_opp();
-		if (!target_opp_no)
-			target_opp_no = VDD1_OPP3;
-
-		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
-		BUG_ON(!opp); /* XXX ugh */
-
-		uvdc = opp_get_voltage(opp);
+		uvdc = get_curr_vdd1_voltage();
+		if (!uvdc)
+			pr_err("Something wrong.Current voltage not obtained \
+				from OPP framework for SR %d!\n", srid);
 		vsel = omap_twl_uv_to_vsel(uvdc);
 
 		vpconfig = PRM_VP1_CONFIG_ERROROFFSET |
@@ -267,14 +260,10 @@ static void sr_configure_vp(int srid)
 				       OMAP3_PRM_VP1_CONFIG_OFFSET);
 
 	} else if (srid == SR2) {
-		target_opp_no = get_vdd2_opp();
-		if (!target_opp_no)
-			target_opp_no = VDD2_OPP3;
-
-		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
-		BUG_ON(!opp); /* XXX ugh */
-
-		uvdc = opp_get_voltage(opp);
+		uvdc = get_curr_vdd2_voltage();
+		if (!uvdc)
+			pr_err("Something wrong.Current voltage not obtained \
+				from OPP framework for SR %d!\n", srid);
 		vsel = omap_twl_uv_to_vsel(uvdc);
 
 		vpconfig = PRM_VP2_CONFIG_ERROROFFSET |
@@ -368,9 +357,8 @@ static void sr_configure(struct omap_sr *sr)
 
 static int sr_reset_voltage(int srid)
 {
-	struct omap_opp *opp;
 	unsigned long uvdc;
-	u32 target_opp_no, vsel = 0;
+	u32 vsel = 0;
 	u32 reg_addr = 0;
 	u32 loop_cnt = 0, retries_cnt = 0;
 	u32 vc_bypass_value;
@@ -379,17 +367,12 @@ static int sr_reset_voltage(int srid)
 	u32 prm_vp1_voltage, prm_vp2_voltage;
 
 	if (srid == SR1) {
-		target_opp_no = get_vdd1_opp();
-		if (!target_opp_no) {
-			pr_info("Current OPP unknown: Cannot reset voltage\n");
+		uvdc = get_curr_vdd1_voltage();
+		if (!uvdc) {
+			pr_err("Something wrong.Current voltage not obtained \
+				from OPP framework for SR %d!\n", srid);
 			return 1;
 		}
-
-		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
-		if (!opp)
-			return 1;
-
-		uvdc = opp_get_voltage(opp);
 		vsel = omap_twl_uv_to_vsel(uvdc);
 
 		reg_addr = R_VDD1_SR_CONTROL;
@@ -397,17 +380,12 @@ static int sr_reset_voltage(int srid)
 						OMAP3_PRM_VP1_VOLTAGE_OFFSET);
 		t2_smps_steps = abs(vsel - prm_vp1_voltage);
 	} else if (srid == SR2) {
-		target_opp_no = get_vdd2_opp();
-		if (!target_opp_no) {
-			pr_info("Current OPP unknown: Cannot reset voltage\n");
+		uvdc = get_curr_vdd2_voltage();
+		if (!uvdc) {
+			pr_err("Something wrong.Current voltage not obtained \
+				from OPP framework for SR %d!\n", srid);
 			return 1;
 		}
-
-		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
-		if (!opp)
-			return 1;
-
-		uvdc = opp_get_voltage(opp);
 		vsel = omap_twl_uv_to_vsel(uvdc);
 
 		reg_addr = R_VDD2_SR_CONTROL;
@@ -452,35 +430,20 @@ static int sr_reset_voltage(int srid)
 	return 0;
 }
 
-static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
+static int sr_enable(struct omap_sr *sr, unsigned long volt)
 {
 	u32 nvalue_reciprocal, v;
-	struct omap_opp *opp;
-	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
-	int uvdc;
+	struct omap_volt_data volt_data;
 	char vsel;
 
-	if (sr->srid == SR1) {
-		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
-		if (!opp)
-			return false;
-	} else {
-		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
-		if (!opp)
-			return false;
-	}
-
-	if (!pdata->sr_nvalue) {
-		pr_notice("N target values does not exist for SR%d\n",
-								sr->srid);
+	if (!sr_match_volt(sr, volt, &volt_data))
 		return false;
-	}
 
-	nvalue_reciprocal = pdata->sr_nvalue[target_opp_no - 1];
+	nvalue_reciprocal = volt_data.sr_nvalue;
 
 	if (nvalue_reciprocal == 0) {
-		pr_notice("OPP%d doesn't support SmartReflex\n",
-								target_opp_no);
+		pr_notice("NVALUE = 0 at voltage %ld for Smartreflex %d\n",
+						volt, sr->srid);
 		return false;
 	}
 
@@ -491,8 +454,7 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
 			(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
 			(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
 
-	uvdc = opp_get_voltage(opp);
-	vsel = omap_twl_uv_to_vsel(uvdc);
+	vsel = omap_twl_uv_to_vsel(volt);
 
 	if (sr->srid == SR1) {
 		/* set/latch init voltage */
@@ -578,7 +540,7 @@ static void sr_disable(struct omap_sr *sr)
 }
 
 
-void sr_start_vddautocomap(int srid, u32 target_opp_no)
+void sr_start_vddautocomap(int srid, unsigned long volt)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
 
@@ -594,7 +556,7 @@ void sr_start_vddautocomap(int srid, u32 target_opp_no)
 	}
 
 	sr->is_autocomp_active = 1;
-	if (!sr_enable(sr, target_opp_no)) {
+	if (!sr_enable(sr, volt)) {
 		sr->is_autocomp_active = 0;
 		if (sr->is_sr_reset == 1)
 			sr_clk_disable(sr);
@@ -627,7 +589,7 @@ EXPORT_SYMBOL(sr_stop_vddautocomap);
 
 void enable_smartreflex(int srid)
 {
-	u32 target_opp_no = 0;
+	unsigned long curr_volt = 0;
 	struct omap_sr *sr = _sr_lookup(srid);
 
 	if (!sr) {
@@ -642,18 +604,18 @@ void enable_smartreflex(int srid)
 			sr_clk_enable(sr);
 
 			if (srid == SR1)
-				target_opp_no = get_vdd1_opp();
+				curr_volt = get_curr_vdd1_voltage();
 			else if (srid == SR2)
-				target_opp_no = get_vdd2_opp();
+				curr_volt = get_curr_vdd2_voltage();
 
-			if (!target_opp_no) {
-				pr_info("Current OPP unknown \
+			if (!curr_volt) {
+				pr_info("Current voltage unknown \
 						 Cannot configure SR\n");
 			}
 
 			sr_configure(sr);
 
-			if (!sr_enable(sr, target_opp_no))
+			if (!sr_enable(sr, curr_volt))
 				sr_clk_disable(sr);
 		}
 	}
@@ -788,10 +750,13 @@ int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
 	udelay(t2_smps_delay);
 
 	if (sr_status) {
+		unsigned long volt;
+
+		volt = (target_vsel * 12500) + 600000;
 		if (vdd == VDD1_OPP)
-			sr_start_vddautocomap(SR1, target_opp_no);
+			sr_start_vddautocomap(SR1, volt);
 		else if (vdd == VDD2_OPP)
-			sr_start_vddautocomap(SR2, target_opp_no);
+			sr_start_vddautocomap(SR2, volt);
 	}
 
 	return 0;
@@ -824,13 +789,13 @@ static int omap_sr_autocomp_store(void *data, u64 val)
 	if (val == 0) {
 		sr_stop_vddautocomap(sr_info->srid);
 	} else {
-		u32 current_opp;
+		unsigned long curr_volt;
 
 		if (sr_info->srid == SR1)
-			current_opp = get_vdd1_opp();
+			curr_volt = get_curr_vdd1_voltage();
 		else
-			current_opp = get_vdd2_opp();
-		sr_start_vddautocomap(sr_info->srid, current_opp);
+			curr_volt = get_curr_vdd2_voltage();
+		sr_start_vddautocomap(sr_info->srid, curr_volt);
 	}
 	return 0;
 }
@@ -856,12 +821,6 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 		sr_info->irq = odev->hwmods[0]->mpu_irqs[0].irq;
 	sr_set_clk_length(sr_info);
 
-	if (sr_info->srid == SR1) {
-		sr_info->vdd_opp_clk = clk_get(NULL, "dpll1_ck");
-	} else {
-		sr_info->vdd_opp_clk = clk_get(NULL, "l3_ick");
-	}
-
 	/* Create the debug fs enteries */
 	sprintf(name, "sr%d_autocomp", sr_info->srid);
 	(void) debugfs_create_file(name, S_IRUGO | S_IWUGO, pm_dbg_main_dir,
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index ea0ddd3..b14ba50 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -242,6 +242,17 @@ extern u32 current_vdd2_opp;
 #endif
 
 /**
+ * omap_volt_data - Omap voltage specific data.
+ *
+ * @voltage	: The possible voltage value
+ * @sr_nvalue	: Smartreflex N target value at voltage <voltage>
+ */
+struct omap_volt_data {
+	unsigned long	voltage;
+	u32		sr_nvalue;
+};
+
+/**
  * omap_smartreflex_dev_data - Smartreflex device specific data
  *
  * @volts_supported	: Number of distinct voltages possible for the VDD
@@ -295,10 +306,10 @@ struct omap_smartreflex_dev_data {
  * @device_idle		: fn pointer to be pouplated with omap_device idle API
  */
 struct omap_smartreflex_data {
-	u32		senp_mod;
-	u32		senn_mod;
-	u32		*sr_nvalue;
-	bool		enable_on_init;
+	u32				senp_mod;
+	u32				senn_mod;
+	struct omap_volt_data		*sr_volt_data;
+	bool				enable_on_init;
 	int (*device_enable)(struct platform_device *pdev);
 	int (*device_shutdown)(struct platform_device *pdev);
 	int (*device_idle)(struct platform_device *pdev);
@@ -307,7 +318,7 @@ struct omap_smartreflex_data {
 void enable_smartreflex(int srid);
 void disable_smartreflex(int srid);
 int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
-void sr_start_vddautocomap(int srid, u32 target_opp_no);
+void sr_start_vddautocomap(int srid, unsigned long volt);
 int sr_stop_vddautocomap(int srid);
 #else
 static inline void enable_smartreflex(int srid) {}
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index a9c1ef0..544d575 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -51,8 +51,9 @@ static void __init sr_read_efuse(
 			!dev_data->efuse_nvalues_offs))
 		return;
 
-	sr_data->sr_nvalue = kzalloc(sizeof(sr_data->sr_nvalue) *
-			dev_data->volts_supported , GFP_KERNEL);
+	if (WARN_ON(!sr_data->sr_volt_data))
+		return;
+
 	sr_data->senn_mod = (omap_ctrl_readl(dev_data->efuse_sr_control) &
 				(0x3 << dev_data->sennenable_shift) >>
 				dev_data->sennenable_shift);
@@ -60,7 +61,7 @@ static void __init sr_read_efuse(
 				(0x3 << dev_data->senpenable_shift) >>
 				dev_data->senpenable_shift);
 	for (i = 0; i < dev_data->volts_supported; i++)
-		sr_data->sr_nvalue[i] = omap_ctrl_readl(
+		sr_data->sr_volt_data[i].sr_nvalue = omap_ctrl_readl(
 				dev_data->efuse_nvalues_offs[i]);
 }
 
@@ -78,12 +79,13 @@ static void __init sr_set_testing_nvalues(
 			!dev_data->test_nvalues))
 		return;
 
-	sr_data->sr_nvalue = kzalloc(sizeof(sr_data->sr_nvalue) *
-			dev_data->volts_supported , GFP_KERNEL);
+	if (WARN_ON(!sr_data->sr_volt_data))
+		return;
+
 	sr_data->senn_mod = dev_data->test_sennenable;
 	sr_data->senp_mod = dev_data->test_senpenable;
 	for (i = 0; i < dev_data->volts_supported; i++)
-		sr_data->sr_nvalue[i] = dev_data->test_nvalues[i];
+		sr_data->sr_volt_data[i].sr_nvalue = dev_data->test_nvalues[i];
 }
 
 static void __init sr_set_nvalues(struct omap_smartreflex_dev_data *dev_data,
@@ -97,6 +99,28 @@ static void __init sr_set_nvalues(struct omap_smartreflex_dev_data *dev_data,
 	}
 }
 
+static void __init omap34xx_sr_volt_details(struct omap_smartreflex_data
+						*sr_data, int srid,
+						int volt_count)
+{
+	sr_data->sr_volt_data = kzalloc(sizeof(sr_data->sr_volt_data) *
+				volt_count , GFP_KERNEL);
+	if (WARN_ON(!sr_data->sr_volt_data))
+		return;
+
+	if (srid == SR1) {
+		sr_data->sr_volt_data[0].voltage = 975000;
+		sr_data->sr_volt_data[1].voltage = 1075000;
+		sr_data->sr_volt_data[2].voltage = 1200000;
+		sr_data->sr_volt_data[3].voltage = 1270000;
+		sr_data->sr_volt_data[4].voltage = 1350000;
+	} else if (srid == SR2) {
+		sr_data->sr_volt_data[0].voltage = 975000;
+		sr_data->sr_volt_data[1].voltage = 1050000;
+		sr_data->sr_volt_data[2].voltage = 1150000;
+	}
+}
+
 static int __init omap_devinit_smartreflex(void)
 {
 	int i = 0;
@@ -124,6 +148,9 @@ static int __init omap_devinit_smartreflex(void)
 		sr_data->device_enable = omap_device_enable;
 		sr_data->device_shutdown = omap_device_shutdown;
 		sr_data->device_idle = omap_device_idle;
+		if (cpu_is_omap34xx())
+			omap34xx_sr_volt_details(sr_data, i + 1,
+					sr_dev_data->volts_supported);
 		sr_set_nvalues(sr_dev_data, sr_data);
 
 		od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 06/22] OMAP3: PM: Correcting API names in samrtreflex driver.
  2010-04-16  9:03         ` [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver Thara Gopinath
@ 2010-04-16  9:03           ` Thara Gopinath
  2010-04-16  9:03             ` [PATCHv3 07/22] OMAP3: PM: Smartreflex class related changes for smartreflex.c Thara Gopinath
  2010-04-27 18:43           ` [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver Kevin Hilman
  1 sibling, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch corrects typo in some of the API names in smartreflex driver. It
also renames enable_smartreflex, disable_smartreflex APIs to
omap_smartreflex_enable and omap_smartreflex_disable to be
more consistent with rest of the API's in the driver code.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c      |    8 ++++----
 arch/arm/mach-omap2/smartreflex.c |   26 +++++++++++++-------------
 arch/arm/mach-omap2/smartreflex.h |   12 ++++++------
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b51b461..9777ab2 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -430,9 +430,9 @@ void omap_sram_idle(void)
 	 * Only needed if we are going to enter retention or off.
 	 */
 	if (mpu_next_state <= PWRDM_POWER_RET)
-		disable_smartreflex(SR1);
+		omap_smartreflex_disable(SR1);
 	if (core_next_state <= PWRDM_POWER_RET)
-		disable_smartreflex(SR2);
+		omap_smartreflex_disable(SR2);
 
 	/* CORE */
 	if (core_next_state < PWRDM_POWER_ON) {
@@ -531,9 +531,9 @@ void omap_sram_idle(void)
 	 * retention or off
 	 */
 	if (mpu_next_state <= PWRDM_POWER_RET)
-		enable_smartreflex(SR1);
+		omap_smartreflex_enable(SR1);
 	if (core_next_state <= PWRDM_POWER_RET)
-		enable_smartreflex(SR2);
+		omap_smartreflex_enable(SR2);
 
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 669f1bb..359f7ec 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -540,7 +540,7 @@ static void sr_disable(struct omap_sr *sr)
 }
 
 
-void sr_start_vddautocomap(int srid, unsigned long volt)
+void sr_start_vddautocomp(int srid, unsigned long volt)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
 
@@ -562,9 +562,9 @@ void sr_start_vddautocomap(int srid, unsigned long volt)
 			sr_clk_disable(sr);
 	}
 }
-EXPORT_SYMBOL(sr_start_vddautocomap);
+EXPORT_SYMBOL(sr_start_vddautocomp);
 
-int sr_stop_vddautocomap(int srid)
+int sr_stop_vddautocomp(int srid)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
 
@@ -585,9 +585,9 @@ int sr_stop_vddautocomap(int srid)
 		return false;
 
 }
-EXPORT_SYMBOL(sr_stop_vddautocomap);
+EXPORT_SYMBOL(sr_stop_vddautocomp);
 
-void enable_smartreflex(int srid)
+void omap_smartreflex_enable(int srid)
 {
 	unsigned long curr_volt = 0;
 	struct omap_sr *sr = _sr_lookup(srid);
@@ -621,7 +621,7 @@ void enable_smartreflex(int srid)
 	}
 }
 
-void disable_smartreflex(int srid)
+void omap_smartreflex_disable(int srid)
 {
 	u32 i = 0;
 	struct omap_sr *sr = _sr_lookup(srid);
@@ -696,7 +696,7 @@ int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
 	current_opp_no = get_opp_no(current_opp);
 
 	if (vdd == VDD1_OPP) {
-		sr_status = sr_stop_vddautocomap(SR1);
+		sr_status = sr_stop_vddautocomp(SR1);
 		t2_smps_steps = abs(target_vsel - current_vsel);
 
 		prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
@@ -706,7 +706,7 @@ int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
 		reg_addr = R_VDD1_SR_CONTROL;
 
 	} else if (vdd == VDD2_OPP) {
-		sr_status = sr_stop_vddautocomap(SR2);
+		sr_status = sr_stop_vddautocomp(SR2);
 		t2_smps_steps =  abs(target_vsel - current_vsel);
 
 		prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
@@ -754,9 +754,9 @@ int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
 
 		volt = (target_vsel * 12500) + 600000;
 		if (vdd == VDD1_OPP)
-			sr_start_vddautocomap(SR1, volt);
+			sr_start_vddautocomp(SR1, volt);
 		else if (vdd == VDD2_OPP)
-			sr_start_vddautocomap(SR2, volt);
+			sr_start_vddautocomp(SR2, volt);
 	}
 
 	return 0;
@@ -787,7 +787,7 @@ static int omap_sr_autocomp_store(void *data, u64 val)
 		return 0;
 	}
 	if (val == 0) {
-		sr_stop_vddautocomap(sr_info->srid);
+		sr_stop_vddautocomp(sr_info->srid);
 	} else {
 		unsigned long curr_volt;
 
@@ -795,7 +795,7 @@ static int omap_sr_autocomp_store(void *data, u64 val)
 			curr_volt = get_curr_vdd1_voltage();
 		else
 			curr_volt = get_curr_vdd2_voltage();
-		sr_start_vddautocomap(sr_info->srid, curr_volt);
+		sr_start_vddautocomp(sr_info->srid, curr_volt);
 	}
 	return 0;
 }
@@ -840,7 +840,7 @@ static int __devexit omap_smartreflex_remove(struct platform_device *pdev)
 
 	/* Disable Autocompensation if enabled before removing the module */
 	if (sr_info->is_autocomp_active == 1)
-		sr_stop_vddautocomap(sr_info->srid);
+		sr_stop_vddautocomp(sr_info->srid);
 	list_del(&sr_info->node);
 	kfree(sr_info);
 
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index b14ba50..12c7ce0 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -315,14 +315,14 @@ struct omap_smartreflex_data {
 	int (*device_idle)(struct platform_device *pdev);
 };
 
-void enable_smartreflex(int srid);
-void disable_smartreflex(int srid);
+void omap_smartreflex_enable(int srid);
+void omap_smartreflex_disable(int srid);
 int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
-void sr_start_vddautocomap(int srid, unsigned long volt);
-int sr_stop_vddautocomap(int srid);
+void sr_start_vddautocomp(int srid, unsigned long volt);
+int sr_stop_vddautocomp(int srid);
 #else
-static inline void enable_smartreflex(int srid) {}
-static inline void disable_smartreflex(int srid) {}
+static inline void omap_smartreflex_enable(int srid) {}
+static inline void omap_smartreflex_disable(int srid) {}
 #endif
 
 #endif
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 07/22] OMAP3: PM: Smartreflex class related changes for smartreflex.c
  2010-04-16  9:03           ` [PATCHv3 06/22] OMAP3: PM: Correcting API names in samrtreflex driver Thara Gopinath
@ 2010-04-16  9:03             ` Thara Gopinath
  2010-04-16  9:03               ` [PATCHv3 08/22] OMAP3: PM: Adding smartreflex class 3 driver Thara Gopinath
  0 siblings, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

OMAP3 smartreflex modules are capable of two different classes
of implementaion -
	Class-2: Continuous Software Calibration
	Class-3: Continuous Hardware Calibration.
OMAP3 along with T2/Gaia supports the Class 3 implementaion.
With a different PMIC it can support Class 2 implementaion also.

The idea behind this patch is that smartreflex.c should be able
to support both the classes of Smartreflex and the class specific
details for smartreflex should stay out of this file in a separate
class file.
This patch introduces smartreflex class specific hooks in
smartreflex.c. This patch only takes care of smartreflex enable
disable hooks which differ between Class 2 and Class 3. There
are some register setting changes between both the classes which
will be taken care of in a later patch.
This will form the base for adding class specific
drivers in later patches.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |  259 ++++++++++++++++++++----------------
 arch/arm/mach-omap2/smartreflex.h |   44 ++++++-
 2 files changed, 181 insertions(+), 122 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 359f7ec..e307c8c 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -56,6 +56,7 @@ struct omap_sr {
 
 /* sr_list contains all the instances of smartreflex module */
 static LIST_HEAD(sr_list);
+static struct omap_smartreflex_class_data *sr_class;
 
 static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
 {
@@ -430,12 +431,84 @@ static int sr_reset_voltage(int srid)
 	return 0;
 }
 
-static int sr_enable(struct omap_sr *sr, unsigned long volt)
+static void sr_start_vddautocomp(int srid)
+{
+	struct omap_sr *sr = _sr_lookup(srid);
+
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid);
+		return;
+	}
+
+	if (!sr_class || !(sr_class->enable)) {
+		pr_warning("smartreflex class driver not registered\n");
+		return;
+	}
+
+	if (sr->is_sr_reset == 1) {
+		sr_clk_enable(sr);
+		sr_configure(sr);
+	}
+
+	sr->is_autocomp_active = 1;
+	if (!sr_class->enable(srid)) {
+		sr->is_autocomp_active = 0;
+		if (sr->is_sr_reset == 1)
+			sr_clk_disable(sr);
+	}
+}
+
+static void  sr_stop_vddautocomp(int srid)
+{
+	struct omap_sr *sr = _sr_lookup(srid);
+
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid);
+		return;
+	}
+
+	if (!sr_class || !(sr_class->disable)) {
+		pr_warning("smartreflex class driver not registered\n");
+		return;
+	}
+
+	if (sr->is_autocomp_active == 1) {
+		sr_class->disable(srid);
+		sr_clk_disable(sr);
+		sr->is_autocomp_active = 0;
+		/* Reset the volatage for current OPP */
+		sr_reset_voltage(srid);
+	}
+}
+
+/* Public Functions */
+
+/**
+ * sr_enable : Enables the smartreflex module.
+ * @srid - The id of the sr module to be enabled.
+ * @volt - The voltage at which the Voltage domain associated with
+ * the smartreflex module is operating at. This is required only to program
+ * the correct Ntarget value.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * enable a smartreflex module. Returns true on success.Returns false if the
+ * target opp id passed is wrong or if ntarget value is wrong.
+ */
+int sr_enable(int srid, unsigned long volt)
 {
 	u32 nvalue_reciprocal, v;
 	struct omap_volt_data volt_data;
+	struct omap_sr *sr = _sr_lookup(srid);
 	char vsel;
 
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid);
+		return false;
+	}
+
 	if (!sr_match_volt(sr, volt, &volt_data))
 		return false;
 
@@ -498,10 +571,24 @@ static int sr_enable(struct omap_sr *sr, unsigned long volt)
 	return true;
 }
 
-static void sr_disable(struct omap_sr *sr)
+/**
+ * sr_disable : Disables the smartreflex module.
+ * @srid - The id of the sr module to be disabled.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * disable a smartreflex module.
+ */
+void sr_disable(int srid)
 {
+	struct omap_sr *sr = _sr_lookup(srid);
 	u32 i = 0;
 
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid);
+		return;
+	}
+
 	sr->is_sr_reset = 1;
 
 	/* SRCONFIG - disable SR */
@@ -539,8 +626,17 @@ static void sr_disable(struct omap_sr *sr)
 	}
 }
 
-
-void sr_start_vddautocomp(int srid, unsigned long volt)
+/**
+ * omap_smartreflex_enable : API to enable SR clocks and to call into the
+ * registered smartreflex class enable API.
+ * @srid - The id of the sr module to be enabled.
+ *
+ * This API is to be called from the kernel in order to enable
+ * a particular smartreflex module. This API will do the initial
+ * configurations to turn on the smartreflex module and in turn call
+ * into the registered smartreflex class enable API.
+ */
+void omap_smartreflex_enable(int srid)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
 
@@ -550,51 +646,8 @@ void sr_start_vddautocomp(int srid, unsigned long volt)
 		return;
 	}
 
-	if (sr->is_sr_reset == 1) {
-		sr_clk_enable(sr);
-		sr_configure(sr);
-	}
-
-	sr->is_autocomp_active = 1;
-	if (!sr_enable(sr, volt)) {
-		sr->is_autocomp_active = 0;
-		if (sr->is_sr_reset == 1)
-			sr_clk_disable(sr);
-	}
-}
-EXPORT_SYMBOL(sr_start_vddautocomp);
-
-int sr_stop_vddautocomp(int srid)
-{
-	struct omap_sr *sr = _sr_lookup(srid);
-
-	if (!sr) {
-		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid);
-		return false;
-	}
-
-	if (sr->is_autocomp_active == 1) {
-		sr_disable(sr);
-		sr_clk_disable(sr);
-		sr->is_autocomp_active = 0;
-		/* Reset the volatage for current OPP */
-		sr_reset_voltage(srid);
-		return true;
-	} else
-		return false;
-
-}
-EXPORT_SYMBOL(sr_stop_vddautocomp);
-
-void omap_smartreflex_enable(int srid)
-{
-	unsigned long curr_volt = 0;
-	struct omap_sr *sr = _sr_lookup(srid);
-
-	if (!sr) {
-		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid);
+	if (!sr_class || !(sr_class->enable)) {
+		pr_warning("smartreflex class driver not registered\n");
 		return;
 	}
 
@@ -602,28 +655,24 @@ void omap_smartreflex_enable(int srid)
 		if (sr->is_sr_reset == 1) {
 			/* Enable SR clks */
 			sr_clk_enable(sr);
-
-			if (srid == SR1)
-				curr_volt = get_curr_vdd1_voltage();
-			else if (srid == SR2)
-				curr_volt = get_curr_vdd2_voltage();
-
-			if (!curr_volt) {
-				pr_info("Current voltage unknown \
-						 Cannot configure SR\n");
-			}
-
 			sr_configure(sr);
-
-			if (!sr_enable(sr, curr_volt))
+			if (!sr_class->enable(srid))
 				sr_clk_disable(sr);
 		}
 	}
 }
 
+/**
+ * omap_smartreflex_disable : API to disable SR clocks and to call into the
+ * registered smartreflex class disable API.
+ * @srid - The id of the sr module to be disabled.
+ *
+ * This API is to be called from the kernel in order to disable
+ * a particular smartreflex module. This API will in turn call
+ * into the registered smartreflex class disable API.
+ */
 void omap_smartreflex_disable(int srid)
 {
-	u32 i = 0;
 	struct omap_sr *sr = _sr_lookup(srid);
 
 	if (!sr) {
@@ -632,53 +681,43 @@ void omap_smartreflex_disable(int srid)
 		return;
 	}
 
+	if (!sr_class || !(sr_class->disable)) {
+		pr_warning("smartreflex class driver not registered\n");
+		return;
+	}
+
 	if (sr->is_autocomp_active == 1) {
 		if (sr->is_sr_reset == 0) {
-
-			sr->is_sr_reset = 1;
-			/* SRCONFIG - disable SR */
-			sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
-							~SRCONFIG_SRENABLE);
-
+			sr_class->disable(srid);
 			/* Disable SR clk */
 			sr_clk_disable(sr);
-			if (sr->srid == SR1) {
-				/* Wait for VP idle before disabling VP */
-				while ((!prm_read_mod_reg(OMAP3430_GR_MOD,
-						OMAP3_PRM_VP1_STATUS_OFFSET))
-						&& i++ < MAX_TRIES)
-					udelay(1);
-
-				if (i >= MAX_TRIES)
-					pr_warning("VP1 not idle, still going \
-						ahead with VP1 disable\n");
-
-				/* Disable VP1 */
-				prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE,
-						OMAP3430_GR_MOD,
-						OMAP3_PRM_VP1_CONFIG_OFFSET);
-			} else if (sr->srid == SR2) {
-				/* Wait for VP idle before disabling VP */
-				while ((!prm_read_mod_reg(OMAP3430_GR_MOD,
-						OMAP3_PRM_VP2_STATUS_OFFSET))
-						&& i++ < MAX_TRIES)
-					udelay(1);
-
-				if (i >= MAX_TRIES)
-					pr_warning("VP2 not idle, still going \
-						 ahead with VP2 disable\n");
-
-				/* Disable VP2 */
-				prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE,
-						OMAP3430_GR_MOD,
-						OMAP3_PRM_VP2_CONFIG_OFFSET);
-			}
 			/* Reset the volatage for current OPP */
 			sr_reset_voltage(srid);
 		}
 	}
 }
 
+/**
+ * omap_sr_register_class : API to register a smartreflex class parameters.
+ * @class_data - The structure containing various sr class specific data.
+ *
+ * This API is to be called by the smartreflex class driver to register itself
+ * with the smartreflex driver during init.
+ */
+void omap_sr_register_class(struct omap_smartreflex_class_data *class_data)
+{
+	if (!class_data) {
+		pr_warning("Smartreflex class data passed is NULL\n");
+		return;
+	}
+
+	if (sr_class) {
+		pr_warning("Smartreflex class driver already registered\n");
+		return;
+	}
+	sr_class = class_data;
+}
+
 /* Voltage Scaling using SR VCBYPASS */
 int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
 					u8 target_vsel, u8 current_vsel)
@@ -750,13 +789,10 @@ int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
 	udelay(t2_smps_delay);
 
 	if (sr_status) {
-		unsigned long volt;
-
-		volt = (target_vsel * 12500) + 600000;
 		if (vdd == VDD1_OPP)
-			sr_start_vddautocomp(SR1, volt);
+			sr_start_vddautocomp(SR1);
 		else if (vdd == VDD2_OPP)
-			sr_start_vddautocomp(SR2, volt);
+			sr_start_vddautocomp(SR2);
 	}
 
 	return 0;
@@ -786,17 +822,10 @@ static int omap_sr_autocomp_store(void *data, u64 val)
 							sr_info->srid);
 		return 0;
 	}
-	if (val == 0) {
+	if (val == 0)
 		sr_stop_vddautocomp(sr_info->srid);
-	} else {
-		unsigned long curr_volt;
-
-		if (sr_info->srid == SR1)
-			curr_volt = get_curr_vdd1_voltage();
-		else
-			curr_volt = get_curr_vdd2_voltage();
-		sr_start_vddautocomp(sr_info->srid, curr_volt);
-	}
+	else
+		sr_start_vddautocomp(sr_info->srid);
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 12c7ce0..8863c3b 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -285,13 +285,28 @@ struct omap_smartreflex_dev_data {
 	u32 *test_nvalues;
 };
 
-/*
- * Smartreflex module enable/disable interface.
- * NOTE: if smartreflex is not enabled from sysfs, these functions will not
- * do anything.
- */
 #ifdef CONFIG_OMAP_SMARTREFLEX
 /**
+ * omap_smartreflex_class_data : Structure to be populated by
+ * Smartreflex class driver with corresponding class enable disable API's
+ *
+ * @enable - API to enable a particular class smaartreflex.
+ * @disable - API to disable a particular class smartreflex.
+ * @notify - API to notify the class driver about an event in SR. Not needed
+ *		for class3.
+ * @notify_flags - specify the events to be notified to the class driver
+ * @class_type - specify which smartreflex class. Can be used by the SR driver
+ *		to take any class based decisions.
+ */
+struct omap_smartreflex_class_data {
+	int (*enable)(int sr_id);
+	int (*disable)(int sr_id);
+	int (*notify)(int sr_id, u32 status);
+	u8 notify_flags;
+	u8 class_type;
+};
+
+/**
  * omap_smartreflex_data - Smartreflex platform data
  *
  * @senp_mod		: SENPENABLE value for the sr
@@ -315,11 +330,26 @@ struct omap_smartreflex_data {
 	int (*device_idle)(struct platform_device *pdev);
 };
 
+/*
+ * Smartreflex module enable/disable interface.
+ * NOTE: if smartreflex is not enabled from sysfs, these functions will not
+ * do anything.
+ */
 void omap_smartreflex_enable(int srid);
 void omap_smartreflex_disable(int srid);
+
+/*
+ * Smartreflex driver hooks to be called from Smartreflex class driver
+ */
+int sr_enable(int srid, unsigned long volt);
+void sr_disable(int srid);
+
+/*
+ * API to register the smartreflex class driver with the smartreflex driver
+ */
+void omap_sr_register_class(struct omap_smartreflex_class_data *class_data);
+
 int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
-void sr_start_vddautocomp(int srid, unsigned long volt);
-int sr_stop_vddautocomp(int srid);
 #else
 static inline void omap_smartreflex_enable(int srid) {}
 static inline void omap_smartreflex_disable(int srid) {}
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 08/22] OMAP3: PM: Adding smartreflex class 3 driver.
  2010-04-16  9:03             ` [PATCHv3 07/22] OMAP3: PM: Smartreflex class related changes for smartreflex.c Thara Gopinath
@ 2010-04-16  9:03               ` Thara Gopinath
  2010-04-16  9:03                 ` [PATCHv3 09/22] OMAP3: PM: Creating separate files for handling OMAP3 voltage related operations Thara Gopinath
  0 siblings, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch adds smartreflex class 3 driver. This driver hooks
up with the generic smartreflex driver smartreflex.c to abstract
out class specific implementations out of the generic driver.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/Makefile             |    1 +
 arch/arm/mach-omap2/board-3430sdp.c      |    2 +
 arch/arm/mach-omap2/smartreflex-class3.c |   48 ++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/smartreflex-class3.h |   18 +++++++++++
 arch/arm/plat-omap/Kconfig               |   11 ++++++-
 5 files changed, 79 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/smartreflex-class3.c
 create mode 100644 arch/arm/mach-omap2/smartreflex-class3.h

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 62accd2..0f8c406 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 obj-$(CONFIG_OMAP_SMARTREFLEX)		+= sr_device.o smartreflex.o
+obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)	+= smartreflex-class3.o
 
 AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
 AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index cda9eae..6221a45 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -50,6 +50,7 @@
 #include "hsmmc.h"
 #include "pm.h"
 #include "omap3-opp.h"
+#include "smartreflex-class3.h"
 
 #define SDP3430_TS_GPIO_IRQ_SDPV1	3
 #define SDP3430_TS_GPIO_IRQ_SDPV2	2
@@ -913,6 +914,7 @@ static void __init omap_3430sdp_init(void)
 	sdp3430_display_init();
 	enable_board_wakeup_source();
 	usb_ehci_init(&ehci_pdata);
+	sr_class3_init();
 }
 
 static void __init omap_3430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
new file mode 100644
index 0000000..1ac39bf
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -0,0 +1,48 @@
+/*
+ * Smart reflex Class 3 specific implementations
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "smartreflex.h"
+#include "smartreflex-class3.h"
+
+static int sr_class3_enable(int id)
+{
+	unsigned long volt = 0;
+
+	if (id == SR1)
+		volt = get_curr_vdd1_voltage();
+	else if (id == SR2)
+		volt = get_curr_vdd2_voltage();
+	if (!volt) {
+		pr_warning("Current voltage unknown.Cannot enable SR%d\n", id);
+		return false;
+	}
+
+	return sr_enable(id, volt);
+}
+
+static int sr_class3_disable(int id)
+{
+	sr_disable(id);
+
+	return true;
+}
+
+/* SR class3 structure */
+struct omap_smartreflex_class_data class3_data = {
+	.enable = sr_class3_enable,
+	.disable = sr_class3_disable,
+};
+
+int __init sr_class3_init(void)
+{
+	omap_sr_register_class(&class3_data);
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/smartreflex-class3.h b/arch/arm/mach-omap2/smartreflex-class3.h
new file mode 100644
index 0000000..6cd4d11
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex-class3.h
@@ -0,0 +1,18 @@
+/*
+ * Smartreflex Class 3 Routines
+ *
+ * Author: Thara Gopinath      <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_OMAP_SMARTREFLEX_CLASS3
+int sr_class3_init(void);
+#else
+static int sr_class3_init(void) {}
+#endif
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 232fd9e..785b7e6 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -55,7 +55,7 @@ config OMAP_DEBUG_LEDS
 
 config OMAP_SMARTREFLEX
 	bool "SmartReflex support"
-	depends on ARCH_OMAP3 && TWL4030_CORE && PM
+	depends on ARCH_OMAP3 && PM
 	help
 	  Say Y if you want to enable SmartReflex.
 
@@ -70,6 +70,15 @@ config OMAP_SMARTREFLEX
 	  compensation for VDD1 and VDD2, user must write 1 to
 	  /sys/power/sr_vddX_autocomp, where X is 1 or 2.
 
+config OMAP_SMARTREFLEX_CLASS3
+	bool "Class 3 mode of Smartreflex Implementation"
+	depends on OMAP_SMARTREFLEX && TWL4030_CORE
+	help
+	  Say Y to enable Class 3 implementation of Smartreflex
+
+	  Class 3 implementation of Smartreflex employs continuous hardware
+	  voltage caliberation.
+
 config OMAP_SMARTREFLEX_TESTING
 	bool "Smartreflex testing support"
 	depends on OMAP_SMARTREFLEX
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 09/22] OMAP3: PM: Creating separate files for handling OMAP3 voltage related operations.
  2010-04-16  9:03               ` [PATCHv3 08/22] OMAP3: PM: Adding smartreflex class 3 driver Thara Gopinath
@ 2010-04-16  9:03                 ` Thara Gopinath
  2010-04-16  9:03                   ` [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver Thara Gopinath
  0 siblings, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch creates voltage.c and voltage.h files and
moves all voltage processor and voltage controller specific code
from smartreflex.c and other places in the OMAP3 codebase into
these two files.
This along with smartreflex class driver addition will make
smartreflex.c a generic driver to support both Class 2 and
Class 3 smartreflex implementaions.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/Makefile             |    3 +-
 arch/arm/mach-omap2/board-3430sdp.c      |    3 +-
 arch/arm/mach-omap2/pm.h                 |    7 -
 arch/arm/mach-omap2/pm34xx.c             |   87 +----
 arch/arm/mach-omap2/smartreflex-class3.c |    4 +
 arch/arm/mach-omap2/smartreflex.c        |  378 +------------------
 arch/arm/mach-omap2/smartreflex.h        |  137 -------
 arch/arm/mach-omap2/voltage.c            |  626 ++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/voltage.h            |   74 ++++
 9 files changed, 712 insertions(+), 607 deletions(-)
 create mode 100644 arch/arm/mach-omap2/voltage.c
 create mode 100644 arch/arm/mach-omap2/voltage.h

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 0f8c406..184badd 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -46,7 +46,8 @@ obj-$(CONFIG_ARCH_OMAP2)		+= sdrc2xxx.o
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o \
+					   voltage.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 obj-$(CONFIG_OMAP_SMARTREFLEX)		+= sr_device.o smartreflex.o
 obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)	+= smartreflex-class3.o
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 6221a45..e80f8d4 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -49,6 +49,7 @@
 #include "sdram-qimonda-hyb18m512160af-6.h"
 #include "hsmmc.h"
 #include "pm.h"
+#include "voltage.h"
 #include "omap3-opp.h"
 #include "smartreflex-class3.h"
 
@@ -347,7 +348,7 @@ static void __init omap_3430sdp_init_irq(void)
 	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
 	omap3_pm_init_opp_table();
 	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
-	omap3_pm_init_vc(&omap3_setuptime_table);
+	omap_voltage_init_vc(&omap3_setuptime_table);
 	omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
 	omap_init_irq();
 	omap_gpio_init();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index b761be5..55bde0d 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -57,13 +57,6 @@ struct prm_setup_vc {
 	u16 vdd1_ret;
 	u16 vdd1_off;
 };
-#ifdef CONFIG_PM
-extern void omap3_pm_init_vc(struct prm_setup_vc *setup_vc);
-#else
-static inline void omap3_pm_init_vc(struct prm_setup_vc *setup_vc)
-{
-}
-#endif
 
 extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
 extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 9777ab2..2f5c894 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -49,6 +49,7 @@
 #include "prm-regbits-34xx.h"
 
 #include "smartreflex.h"
+#include "voltage.h"
 #include "prm.h"
 #include "pm.h"
 #include "sdrc.h"
@@ -96,22 +97,6 @@ static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
 static struct powerdomain *core_pwrdm, *per_pwrdm;
 static struct powerdomain *cam_pwrdm;
 
-static struct prm_setup_vc prm_setup = {
-	.clksetup = 0xff,
-	.voltsetup_time1 = 0xfff,
-	.voltsetup_time2 = 0xfff,
-	.voltoffset = 0xff,
-	.voltsetup2 = 0xff,
-	.vdd0_on = 0x30,	/* 1.2v */
-	.vdd0_onlp = 0x20,	/* 1.0v */
-	.vdd0_ret = 0x1e,	/* 0.975v */
-	.vdd0_off = 0x00,	/* 0.6v */
-	.vdd1_on = 0x2c,	/* 1.15v */
-	.vdd1_onlp = 0x20,	/* 1.0v */
-	.vdd1_ret = 0x1e,	/* .975v */
-	.vdd1_off = 0x00,	/* 0.6v */
-};
-
 static inline void omap3_per_save_context(void)
 {
 	omap_gpio_save_context();
@@ -1077,26 +1062,6 @@ int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state)
 	return -EINVAL;
 }
 
-void omap3_pm_init_vc(struct prm_setup_vc *setup_vc)
-{
-	if (!setup_vc)
-		return;
-
-	prm_setup.clksetup = setup_vc->clksetup;
-	prm_setup.voltsetup_time1 = setup_vc->voltsetup_time1;
-	prm_setup.voltsetup_time2 = setup_vc->voltsetup_time2;
-	prm_setup.voltoffset = setup_vc->voltoffset;
-	prm_setup.voltsetup2 = setup_vc->voltsetup2;
-	prm_setup.vdd0_on = setup_vc->vdd0_on;
-	prm_setup.vdd0_onlp = setup_vc->vdd0_onlp;
-	prm_setup.vdd0_ret = setup_vc->vdd0_ret;
-	prm_setup.vdd0_off = setup_vc->vdd0_off;
-	prm_setup.vdd1_on = setup_vc->vdd1_on;
-	prm_setup.vdd1_onlp = setup_vc->vdd1_onlp;
-	prm_setup.vdd1_ret = setup_vc->vdd1_ret;
-	prm_setup.vdd1_off = setup_vc->vdd1_off;
-}
-
 static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 {
 	struct power_state *pwrst;
@@ -1242,58 +1207,12 @@ err2:
 	return ret;
 }
 
-static void __init configure_vc(void)
-{
-
-	prm_write_mod_reg((R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA1_SHIFT) |
-			  (R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA0_SHIFT),
-			  OMAP3430_GR_MOD, OMAP3_PRM_VC_SMPS_SA_OFFSET);
-	prm_write_mod_reg((R_VDD2_SR_CONTROL << OMAP3430_VOLRA1_SHIFT) |
-			  (R_VDD1_SR_CONTROL << OMAP3430_VOLRA0_SHIFT),
-			  OMAP3430_GR_MOD, OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET);
-
-	prm_write_mod_reg((prm_setup.vdd0_on << OMAP3430_VC_CMD_ON_SHIFT) |
-		(prm_setup.vdd0_onlp << OMAP3430_VC_CMD_ONLP_SHIFT) |
-		(prm_setup.vdd0_ret << OMAP3430_VC_CMD_RET_SHIFT) |
-		(prm_setup.vdd0_off << OMAP3430_VC_CMD_OFF_SHIFT),
-		OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
-
-	prm_write_mod_reg((prm_setup.vdd1_on << OMAP3430_VC_CMD_ON_SHIFT) |
-		(prm_setup.vdd1_onlp << OMAP3430_VC_CMD_ONLP_SHIFT) |
-		(prm_setup.vdd1_ret << OMAP3430_VC_CMD_RET_SHIFT) |
-		(prm_setup.vdd1_off << OMAP3430_VC_CMD_OFF_SHIFT),
-		OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_1_OFFSET);
-
-	prm_write_mod_reg(OMAP3430_CMD1 | OMAP3430_RAV1, OMAP3430_GR_MOD,
-			  OMAP3_PRM_VC_CH_CONF_OFFSET);
-
-	prm_write_mod_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN,
-			  OMAP3430_GR_MOD,
-			  OMAP3_PRM_VC_I2C_CFG_OFFSET);
-
-	/* Write setup times */
-	prm_write_mod_reg(prm_setup.clksetup, OMAP3430_GR_MOD,
-			OMAP3_PRM_CLKSETUP_OFFSET);
-	prm_write_mod_reg((prm_setup.voltsetup_time2 <<
-			OMAP3430_SETUP_TIME2_SHIFT) |
-			(prm_setup.voltsetup_time1 <<
-			OMAP3430_SETUP_TIME1_SHIFT),
-			OMAP3430_GR_MOD, OMAP3_PRM_VOLTSETUP1_OFFSET);
-
-	prm_write_mod_reg(prm_setup.voltoffset, OMAP3430_GR_MOD,
-			OMAP3_PRM_VOLTOFFSET_OFFSET);
-	prm_write_mod_reg(prm_setup.voltsetup2, OMAP3430_GR_MOD,
-			OMAP3_PRM_VOLTSETUP2_OFFSET);
-}
-
-
 static int __init omap3_pm_early_init(void)
 {
 	prm_clear_mod_reg_bits(OMAP3430_OFFMODE_POL, OMAP3430_GR_MOD,
 				OMAP3_PRM_POLCTRL_OFFSET);
-
-	configure_vc();
-
+	/* Initializes OMAP3 voltage modules */
+	omap_voltage_init();
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index 1ac39bf..1b098ff 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -11,6 +11,7 @@
 
 #include "smartreflex.h"
 #include "smartreflex-class3.h"
+#include "voltage.h"
 
 static int sr_class3_enable(int id)
 {
@@ -25,12 +26,15 @@ static int sr_class3_enable(int id)
 		return false;
 	}
 
+	omap_voltageprocessor_enable(id);
 	return sr_enable(id, volt);
 }
 
 static int sr_class3_disable(int id)
 {
+	omap_voltageprocessor_disable(id);
 	sr_disable(id);
+	omap_reset_voltage(id);
 
 	return true;
 }
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index e307c8c..a89f74f 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -17,11 +17,9 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/kobject.h>
@@ -30,18 +28,11 @@
 #include <linux/list.h>
 #include <linux/debugfs.h>
 
-#include <plat/omap34xx.h>
-#include <plat/clock.h>
-#include <plat/opp.h>
-#include <plat/opp_twl_tps.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
-#include "prm.h"
 #include "smartreflex.h"
-#include "prm-regbits-34xx.h"
 
-#define MAX_TRIES 100
 #define SMARTREFLEX_NAME_LEN	16
 
 struct omap_sr {
@@ -119,42 +110,6 @@ static void sr_clk_disable(struct omap_sr *sr)
 	sr->is_sr_reset = 1;
 }
 
-static unsigned long get_curr_vdd1_voltage(void)
-{
-	struct omap_opp *opp;
-	unsigned long freq;
-	struct clk *dpll1_clk;
-
-	dpll1_clk = clk_get(NULL, "dpll1_ck");
-	if (IS_ERR(dpll1_clk))
-		return 0;
-
-	freq = dpll1_clk->rate;;
-	opp = opp_find_freq_exact(OPP_MPU, freq, 1);
-	if (IS_ERR(opp))
-		return 0;
-
-	return opp_get_voltage(opp);
-}
-
-static unsigned long get_curr_vdd2_voltage(void)
-{
-	struct omap_opp *opp;
-	unsigned long freq;
-	struct clk *l3_clk;
-
-	l3_clk = clk_get(NULL, "l3_ick");
-	if (IS_ERR(l3_clk))
-		return 0;
-
-	freq = l3_clk->rate;
-	opp = opp_find_freq_exact(OPP_L3, freq, 1);
-	if (IS_ERR(opp))
-		return 0;
-
-	return opp_get_voltage(opp);
-}
-
 static int sr_match_volt(struct omap_sr *sr, unsigned long volt,
 				struct omap_volt_data *volt_data)
 {
@@ -210,104 +165,6 @@ static void sr_set_clk_length(struct omap_sr *sr)
 	}
 }
 
-static void sr_configure_vp(int srid)
-{
-	u32 vpconfig, vsel;
-	unsigned long uvdc;
-
-	if (srid == SR1) {
-		uvdc = get_curr_vdd1_voltage();
-		if (!uvdc)
-			pr_err("Something wrong.Current voltage not obtained \
-				from OPP framework for SR %d!\n", srid);
-		vsel = omap_twl_uv_to_vsel(uvdc);
-
-		vpconfig = PRM_VP1_CONFIG_ERROROFFSET |
-			PRM_VP1_CONFIG_ERRORGAIN |
-			PRM_VP1_CONFIG_TIMEOUTEN |
-			vsel << OMAP3430_INITVOLTAGE_SHIFT;
-
-		prm_write_mod_reg(vpconfig, OMAP3430_GR_MOD,
-					OMAP3_PRM_VP1_CONFIG_OFFSET);
-		prm_write_mod_reg(PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
-					PRM_VP1_VSTEPMIN_VSTEPMIN,
-					OMAP3430_GR_MOD,
-					OMAP3_PRM_VP1_VSTEPMIN_OFFSET);
-
-		prm_write_mod_reg(PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
-					PRM_VP1_VSTEPMAX_VSTEPMAX,
-					OMAP3430_GR_MOD,
-					OMAP3_PRM_VP1_VSTEPMAX_OFFSET);
-
-		prm_write_mod_reg(PRM_VP1_VLIMITTO_VDDMAX |
-					PRM_VP1_VLIMITTO_VDDMIN |
-					PRM_VP1_VLIMITTO_TIMEOUT,
-					OMAP3430_GR_MOD,
-					OMAP3_PRM_VP1_VLIMITTO_OFFSET);
-
-		/* Trigger initVDD value copy to voltage processor */
-		prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP1_CONFIG_OFFSET);
-
-		/* Clear initVDD copy trigger bit */
-		prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
-				       OMAP3_PRM_VP1_CONFIG_OFFSET);
-
-		/* Force update of voltage */
-		prm_set_mod_reg_bits(OMAP3430_FORCEUPDATE, OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP1_CONFIG_OFFSET);
-		/* Clear force bit */
-		prm_clear_mod_reg_bits(OMAP3430_FORCEUPDATE, OMAP3430_GR_MOD,
-				       OMAP3_PRM_VP1_CONFIG_OFFSET);
-
-	} else if (srid == SR2) {
-		uvdc = get_curr_vdd2_voltage();
-		if (!uvdc)
-			pr_err("Something wrong.Current voltage not obtained \
-				from OPP framework for SR %d!\n", srid);
-		vsel = omap_twl_uv_to_vsel(uvdc);
-
-		vpconfig = PRM_VP2_CONFIG_ERROROFFSET |
-			PRM_VP2_CONFIG_ERRORGAIN |
-			PRM_VP2_CONFIG_TIMEOUTEN |
-			vsel << OMAP3430_INITVOLTAGE_SHIFT;
-
-		prm_write_mod_reg(vpconfig, OMAP3430_GR_MOD,
-					OMAP3_PRM_VP2_CONFIG_OFFSET);
-		prm_write_mod_reg(PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
-					PRM_VP2_VSTEPMIN_VSTEPMIN,
-					OMAP3430_GR_MOD,
-					OMAP3_PRM_VP2_VSTEPMIN_OFFSET);
-
-		prm_write_mod_reg(PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
-					PRM_VP2_VSTEPMAX_VSTEPMAX,
-					OMAP3430_GR_MOD,
-					OMAP3_PRM_VP2_VSTEPMAX_OFFSET);
-
-		prm_write_mod_reg(PRM_VP2_VLIMITTO_VDDMAX |
-					PRM_VP2_VLIMITTO_VDDMIN |
-					PRM_VP2_VLIMITTO_TIMEOUT,
-					OMAP3430_GR_MOD,
-					OMAP3_PRM_VP2_VLIMITTO_OFFSET);
-
-		/* Trigger initVDD value copy to voltage processor */
-		prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP2_CONFIG_OFFSET);
-
-		/* Clear initVDD copy trigger bit */
-		prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
-				       OMAP3_PRM_VP2_CONFIG_OFFSET);
-
-		/* Force update of voltage */
-		prm_set_mod_reg_bits(OMAP3430_FORCEUPDATE, OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP2_CONFIG_OFFSET);
-		/* Clear force bit */
-		prm_clear_mod_reg_bits(OMAP3430_FORCEUPDATE, OMAP3430_GR_MOD,
-				       OMAP3_PRM_VP2_CONFIG_OFFSET);
-
-	}
-}
-
 static void sr_configure(struct omap_sr *sr)
 {
 	u32 sr_config;
@@ -356,81 +213,6 @@ static void sr_configure(struct omap_sr *sr)
 	sr->is_sr_reset = 0;
 }
 
-static int sr_reset_voltage(int srid)
-{
-	unsigned long uvdc;
-	u32 vsel = 0;
-	u32 reg_addr = 0;
-	u32 loop_cnt = 0, retries_cnt = 0;
-	u32 vc_bypass_value;
-	u32 t2_smps_steps = 0;
-	u32 t2_smps_delay = 0;
-	u32 prm_vp1_voltage, prm_vp2_voltage;
-
-	if (srid == SR1) {
-		uvdc = get_curr_vdd1_voltage();
-		if (!uvdc) {
-			pr_err("Something wrong.Current voltage not obtained \
-				from OPP framework for SR %d!\n", srid);
-			return 1;
-		}
-		vsel = omap_twl_uv_to_vsel(uvdc);
-
-		reg_addr = R_VDD1_SR_CONTROL;
-		prm_vp1_voltage = prm_read_mod_reg(OMAP3430_GR_MOD,
-						OMAP3_PRM_VP1_VOLTAGE_OFFSET);
-		t2_smps_steps = abs(vsel - prm_vp1_voltage);
-	} else if (srid == SR2) {
-		uvdc = get_curr_vdd2_voltage();
-		if (!uvdc) {
-			pr_err("Something wrong.Current voltage not obtained \
-				from OPP framework for SR %d!\n", srid);
-			return 1;
-		}
-		vsel = omap_twl_uv_to_vsel(uvdc);
-
-		reg_addr = R_VDD2_SR_CONTROL;
-		prm_vp2_voltage = prm_read_mod_reg(OMAP3430_GR_MOD,
-						OMAP3_PRM_VP2_VOLTAGE_OFFSET);
-		t2_smps_steps = abs(vsel - prm_vp2_voltage);
-	}
-
-	vc_bypass_value = (vsel << OMAP3430_DATA_SHIFT) |
-			(reg_addr << OMAP3430_REGADDR_SHIFT) |
-			(R_SRI2C_SLAVE_ADDR << OMAP3430_SLAVEADDR_SHIFT);
-
-	prm_write_mod_reg(vc_bypass_value, OMAP3430_GR_MOD,
-			OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
-
-	vc_bypass_value = prm_set_mod_reg_bits(OMAP3430_VALID, OMAP3430_GR_MOD,
-					OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
-
-	while ((vc_bypass_value & OMAP3430_VALID) != 0x0) {
-		loop_cnt++;
-		if (retries_cnt > 10) {
-			pr_info("Loop count exceeded in check SR I2C"
-								"write\n");
-			return 1;
-		}
-		if (loop_cnt > 50) {
-			retries_cnt++;
-			loop_cnt = 0;
-			udelay(10);
-		}
-		vc_bypass_value = prm_read_mod_reg(OMAP3430_GR_MOD,
-					OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
-	}
-
-	/*
-	 *  T2 SMPS slew rate (min) 4mV/uS, step size 12.5mV,
-	 *  2us added as buffer.
-	 */
-	t2_smps_delay = ((t2_smps_steps * 125) / 40) + 2;
-	udelay(t2_smps_delay);
-
-	return 0;
-}
-
 static void sr_start_vddautocomp(int srid)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
@@ -478,8 +260,6 @@ static void  sr_stop_vddautocomp(int srid)
 		sr_class->disable(srid);
 		sr_clk_disable(sr);
 		sr->is_autocomp_active = 0;
-		/* Reset the volatage for current OPP */
-		sr_reset_voltage(srid);
 	}
 }
 
@@ -498,10 +278,9 @@ static void  sr_stop_vddautocomp(int srid)
  */
 int sr_enable(int srid, unsigned long volt)
 {
-	u32 nvalue_reciprocal, v;
+	u32 nvalue_reciprocal;
 	struct omap_volt_data volt_data;
 	struct omap_sr *sr = _sr_lookup(srid);
-	char vsel;
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
@@ -527,45 +306,6 @@ int sr_enable(int srid, unsigned long volt)
 			(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
 			(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
 
-	vsel = omap_twl_uv_to_vsel(volt);
-
-	if (sr->srid == SR1) {
-		/* set/latch init voltage */
-		v = prm_read_mod_reg(OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP1_CONFIG_OFFSET);
-		v &= ~(OMAP3430_INITVOLTAGE_MASK | OMAP3430_INITVDD);
-
-		v |= vsel << OMAP3430_INITVOLTAGE_SHIFT;
-		prm_write_mod_reg(v, OMAP3430_GR_MOD,
-				  OMAP3_PRM_VP1_CONFIG_OFFSET);
-		/* write1 to latch */
-		prm_set_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP1_CONFIG_OFFSET);
-		/* write2 clear */
-		prm_clear_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
-				       OMAP3_PRM_VP1_CONFIG_OFFSET);
-		/* Enable VP1 */
-		prm_set_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP1_CONFIG_OFFSET);
-	} else if (sr->srid == SR2) {
-		/* set/latch init voltage */
-		v = prm_read_mod_reg(OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP2_CONFIG_OFFSET);
-		v &= ~(OMAP3430_INITVOLTAGE_MASK | OMAP3430_INITVDD);
-		v |= vsel << OMAP3430_INITVOLTAGE_SHIFT;
-		prm_write_mod_reg(v, OMAP3430_GR_MOD,
-				  OMAP3_PRM_VP2_CONFIG_OFFSET);
-		/* write1 to latch */
-		prm_set_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP2_CONFIG_OFFSET);
-		/* write2 clear */
-		prm_clear_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
-				       OMAP3_PRM_VP2_CONFIG_OFFSET);
-		/* Enable VP2 */
-		prm_set_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
-				     OMAP3_PRM_VP2_CONFIG_OFFSET);
-	}
-
 	/* SRCONFIG - enable SR */
 	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
 	return true;
@@ -581,7 +321,6 @@ int sr_enable(int srid, unsigned long volt)
 void sr_disable(int srid)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
-	u32 i = 0;
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
@@ -590,40 +329,9 @@ void sr_disable(int srid)
 	}
 
 	sr->is_sr_reset = 1;
-
 	/* SRCONFIG - disable SR */
 	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
 
-	if (sr->srid == SR1) {
-		/* Wait for VP idle before disabling VP */
-		while ((!prm_read_mod_reg(OMAP3430_GR_MOD,
-					OMAP3_PRM_VP1_STATUS_OFFSET))
-					&& i++ < MAX_TRIES)
-			udelay(1);
-
-		if (i >= MAX_TRIES)
-			pr_warning("VP1 not idle, still going ahead with \
-							VP1 disable\n");
-
-		/* Disable VP1 */
-		prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
-					OMAP3_PRM_VP1_CONFIG_OFFSET);
-
-	} else if (sr->srid == SR2) {
-		/* Wait for VP idle before disabling VP */
-		while ((!prm_read_mod_reg(OMAP3430_GR_MOD,
-					OMAP3_PRM_VP2_STATUS_OFFSET))
-					&& i++ < MAX_TRIES)
-			udelay(1);
-
-		if (i >= MAX_TRIES)
-			pr_warning("VP2 not idle, still going ahead with \
-							 VP2 disable\n");
-
-		/* Disable VP2 */
-		prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
-					OMAP3_PRM_VP2_CONFIG_OFFSET);
-	}
 }
 
 /**
@@ -691,8 +399,6 @@ void omap_smartreflex_disable(int srid)
 			sr_class->disable(srid);
 			/* Disable SR clk */
 			sr_clk_disable(sr);
-			/* Reset the volatage for current OPP */
-			sr_reset_voltage(srid);
 		}
 	}
 }
@@ -718,86 +424,6 @@ void omap_sr_register_class(struct omap_smartreflex_class_data *class_data)
 	sr_class = class_data;
 }
 
-/* Voltage Scaling using SR VCBYPASS */
-int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
-					u8 target_vsel, u8 current_vsel)
-{
-	int sr_status = 0;
-	u32 vdd, target_opp_no, current_opp_no;
-	u32 vc_bypass_value;
-	u32 reg_addr = 0;
-	u32 loop_cnt = 0, retries_cnt = 0;
-	u32 t2_smps_steps = 0;
-	u32 t2_smps_delay = 0;
-
-	vdd = get_vdd(target_opp);
-	target_opp_no = get_opp_no(target_opp);
-	current_opp_no = get_opp_no(current_opp);
-
-	if (vdd == VDD1_OPP) {
-		sr_status = sr_stop_vddautocomp(SR1);
-		t2_smps_steps = abs(target_vsel - current_vsel);
-
-		prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
-				(target_vsel << OMAP3430_VC_CMD_ON_SHIFT),
-				OMAP3430_GR_MOD,
-				OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
-		reg_addr = R_VDD1_SR_CONTROL;
-
-	} else if (vdd == VDD2_OPP) {
-		sr_status = sr_stop_vddautocomp(SR2);
-		t2_smps_steps =  abs(target_vsel - current_vsel);
-
-		prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
-				(target_vsel << OMAP3430_VC_CMD_ON_SHIFT),
-				OMAP3430_GR_MOD,
-				OMAP3_PRM_VC_CMD_VAL_1_OFFSET);
-		reg_addr = R_VDD2_SR_CONTROL;
-	}
-
-	vc_bypass_value = (target_vsel << OMAP3430_DATA_SHIFT) |
-			(reg_addr << OMAP3430_REGADDR_SHIFT) |
-			(R_SRI2C_SLAVE_ADDR << OMAP3430_SLAVEADDR_SHIFT);
-
-	prm_write_mod_reg(vc_bypass_value, OMAP3430_GR_MOD,
-			OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
-
-	vc_bypass_value = prm_set_mod_reg_bits(OMAP3430_VALID, OMAP3430_GR_MOD,
-					OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
-
-	while ((vc_bypass_value & OMAP3430_VALID) != 0x0) {
-		loop_cnt++;
-		if (retries_cnt > 10) {
-			pr_info("Loop count exceeded in check SR I2C"
-								"write\n");
-			return 1;
-		}
-		if (loop_cnt > 50) {
-			retries_cnt++;
-			loop_cnt = 0;
-			udelay(10);
-		}
-		vc_bypass_value = prm_read_mod_reg(OMAP3430_GR_MOD,
-					OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
-	}
-
-	/*
-	 *  T2 SMPS slew rate (min) 4mV/uS, step size 12.5mV,
-	 *  2us added as buffer.
-	 */
-	t2_smps_delay = ((t2_smps_steps * 125) / 40) + 2;
-	udelay(t2_smps_delay);
-
-	if (sr_status) {
-		if (vdd == VDD1_OPP)
-			sr_start_vddautocomp(SR1);
-		else if (vdd == VDD2_OPP)
-			sr_start_vddautocomp(SR2);
-	}
-
-	return 0;
-}
-
 /* PM Debug Fs enteries to enable disable smartreflex.*/
 
 static int omap_sr_autocomp_show(void *data, u64 *val)
@@ -855,8 +481,6 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 	(void) debugfs_create_file(name, S_IRUGO | S_IWUGO, pm_dbg_main_dir,
 				(void *)sr_info, &pm_sr_fops);
 
-	/* Call the VPConfig */
-	sr_configure_vp(sr_info->srid);
 	list_add(&sr_info->node, &sr_list);
 	pr_info("SmartReflex driver initialized\n");
 
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 8863c3b..073f6d0 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -18,9 +18,7 @@
 
 extern struct dentry *pm_dbg_main_dir;
 
-#define PHY_TO_OFF_PM_MASTER(p)		(p - 0x36)
 #define PHY_TO_OFF_PM_RECIEVER(p)	(p - 0x5b)
-#define PHY_TO_OFF_PM_INT(p)		(p - 0x2e)
 
 /* SMART REFLEX REG ADDRESS OFFSET */
 #define SRCONFIG	0x00
@@ -38,64 +36,12 @@ extern struct dentry *pm_dbg_main_dir;
 #define SR1		1
 #define SR2		2
 
-#define SR_FAIL		1
-#define SR_PASS		0
-
-#define SR_TRUE		1
-#define SR_FALSE	0
-
 #define GAIN_MAXLIMIT	16
 #define R_MAXLIMIT	256
 
 #define SR1_CLK_ENABLE	BIT(6)
 #define SR2_CLK_ENABLE	BIT(7)
 
-/* PRM_VP1_CONFIG */
-#define PRM_VP1_CONFIG_ERROROFFSET	(0x00 << 24)
-#define PRM_VP1_CONFIG_ERRORGAIN	(0x20 << 16)
-
-#define PRM_VP1_CONFIG_INITVOLTAGE	(0x30 << 8) /* 1.2 volt */
-#define PRM_VP1_CONFIG_TIMEOUTEN	BIT(3)
-#define PRM_VP1_CONFIG_INITVDD		BIT(2)
-#define PRM_VP1_CONFIG_FORCEUPDATE	BIT(1)
-#define PRM_VP1_CONFIG_VPENABLE		BIT(0)
-
-/* PRM_VP1_VSTEPMIN */
-#define PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN	(0x01F4 << 8)
-#define PRM_VP1_VSTEPMIN_VSTEPMIN		BIT(0)
-
-/* PRM_VP1_VSTEPMAX */
-#define PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX	(0x01F4 << 8)
-#define PRM_VP1_VSTEPMAX_VSTEPMAX		(0x04 << 0)
-
-/* PRM_VP1_VLIMITTO */
-#define PRM_VP1_VLIMITTO_VDDMAX		(0x3C << 24)
-#define PRM_VP1_VLIMITTO_VDDMIN		(0x0 << 16)
-#define PRM_VP1_VLIMITTO_TIMEOUT	(0xFFFF << 0)
-
-/* PRM_VP2_CONFIG */
-#define PRM_VP2_CONFIG_ERROROFFSET	(0x00 << 24)
-#define PRM_VP2_CONFIG_ERRORGAIN	(0x20 << 16)
-
-#define PRM_VP2_CONFIG_INITVOLTAGE	(0x30 << 8) /* 1.2 volt */
-#define PRM_VP2_CONFIG_TIMEOUTEN	BIT(3)
-#define PRM_VP2_CONFIG_INITVDD		BIT(2)
-#define PRM_VP2_CONFIG_FORCEUPDATE	BIT(1)
-#define PRM_VP2_CONFIG_VPENABLE		BIT(0)
-
-/* PRM_VP2_VSTEPMIN */
-#define PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN	(0x01F4 << 8)
-#define PRM_VP2_VSTEPMIN_VSTEPMIN		BIT(0)
-
-/* PRM_VP2_VSTEPMAX */
-#define PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX	(0x01F4 << 8)
-#define PRM_VP2_VSTEPMAX_VSTEPMAX		(0x04 << 0)
-
-/* PRM_VP2_VLIMITTO */
-#define PRM_VP2_VLIMITTO_VDDMAX		(0x2C << 24)
-#define PRM_VP2_VLIMITTO_VDDMIN		(0x0 << 16)
-#define PRM_VP2_VLIMITTO_TIMEOUT	(0xFFFF << 0)
-
 /* SRCONFIG */
 #define SR1_SRCONFIG_ACCUMDATA		(0x1F4 << 22)
 #define SR2_SRCONFIG_ACCUMDATA		(0x1F4 << 22)
@@ -137,9 +83,6 @@ extern struct dentry *pm_dbg_main_dir;
 #define SR_ERRMAXLIMIT_MASK		(0xFF << 8)
 #define SR_ERRMINLIMIT_MASK		(0xFF << 0)
 
-#define SR_CLKACTIVITY_IOFF_FOFF	(0x00 << 20)
-#define SR_CLKACTIVITY_IOFF_FON		(0x02 << 20)
-
 #define ERRCONFIG_VPBOUNDINTEN		BIT(31)
 #define ERRCONFIG_VPBOUNDINTST		BIT(30)
 
@@ -151,90 +94,12 @@ extern struct dentry *pm_dbg_main_dir;
 #define SR2_ERRMAXLIMIT			(0x02 << 8)
 #define SR2_ERRMINLIMIT			(0xF9 << 0)
 
-/* T2 SMART REFLEX */
-#define R_SRI2C_SLAVE_ADDR		0x12
-#define R_VDD1_SR_CONTROL		0x00
-#define R_VDD2_SR_CONTROL		0x01
-#define T2_SMPS_UPDATE_DELAY		360	/* In uSec */
-
 /* Vmode control */
 #define R_DCDC_GLOBAL_CFG	PHY_TO_OFF_PM_RECIEVER(0x61)
 
-#define R_VDD1_VSEL		PHY_TO_OFF_PM_RECIEVER(0xb9)
-#define R_VDD1_VMODE_CFG	PHY_TO_OFF_PM_RECIEVER(0xba)
-#define R_VDD1_VFLOOR		PHY_TO_OFF_PM_RECIEVER(0xbb)
-#define R_VDD1_VROOF		PHY_TO_OFF_PM_RECIEVER(0xbc)
-#define R_VDD1_STEP		PHY_TO_OFF_PM_RECIEVER(0xbd)
-
-#define R_VDD2_VSEL		PHY_TO_OFF_PM_RECIEVER(0xc7)
-#define R_VDD2_VMODE_CFG	PHY_TO_OFF_PM_RECIEVER(0xc8)
-#define R_VDD2_VFLOOR		PHY_TO_OFF_PM_RECIEVER(0xc9)
-#define R_VDD2_VROOF		PHY_TO_OFF_PM_RECIEVER(0xca)
-#define R_VDD2_STEP		PHY_TO_OFF_PM_RECIEVER(0xcb)
-
 /* R_DCDC_GLOBAL_CFG register, SMARTREFLEX_ENABLE values */
 #define DCDC_GLOBAL_CFG_ENABLE_SRFLX	0x08
 
-#define PRCM_MAX_SYSC_REGS 30
-
-/*
- * XXX: These should be removed/moved from here once we have a working DVFS
- * implementation in place
- */
-#define AT_3430		1	/*3430 ES 1.0 */
-#define AT_3430_ES2	2	/*3430 ES 2.0 */
-
-#define ID_OPP			0xE2 	/*OPP*/
-
-/* DEVICE ID/DPLL ID/CLOCK ID: bits 28-31 for OMAP type */
-#define OMAP_TYPE_SHIFT		28
-#define OMAP_TYPE_MASK		0xF
-/* OPP ID: bits: 0-4 for OPP number */
-#define OPP_NO_POS		0
-#define OPP_NO_MASK		0x1F
-/* OPP ID: bits: 5-6 for VDD */
-#define VDD_NO_POS		5
-#define VDD_NO_MASK		0x3
-/* Other IDs: bits 20-27 for ID type */
-/* These IDs have bits 25,26,27 as 1 */
-#define OTHER_ID_TYPE_SHIFT		20
-#define OTHER_ID_TYPE_MASK		0xFF
-
-#define OTHER_ID_TYPE(X) ((X & OTHER_ID_TYPE_MASK) << OTHER_ID_TYPE_SHIFT)
-#define ID_OPP_NO(X)	 ((X & OPP_NO_MASK) << OPP_NO_POS)
-#define ID_VDD(X)	 ((X & VDD_NO_MASK) << VDD_NO_POS)
-#define OMAP(X)		 ((X >> OMAP_TYPE_SHIFT) & OMAP_TYPE_MASK)
-#define get_opp_no(X)	 ((X >> OPP_NO_POS) & OPP_NO_MASK)
-#define get_vdd(X)	 ((X >> VDD_NO_POS) & VDD_NO_MASK)
-
-/* VDD1 OPPs */
-#define PRCM_VDD1_OPP1		(OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
-					ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x1))
-#define PRCM_VDD1_OPP2		(OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
-					ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x2))
-#define PRCM_VDD1_OPP3		(OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
-					ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x3))
-#define PRCM_VDD1_OPP4		(OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
-					ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x4))
-#define PRCM_VDD1_OPP5		(OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
-					ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x5))
-#define PRCM_NO_VDD1_OPPS	5
-
-
-/* VDD2 OPPs */
-#define PRCM_VDD2_OPP1		(OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
-					ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x1))
-#define PRCM_VDD2_OPP2		(OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
-					ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x2))
-#define PRCM_VDD2_OPP3		(OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
-					ID_VDD(PRCM_VDD2) | ID_OPP_NO(0x3))
-#define PRCM_NO_VDD2_OPPS	3
-/* XXX: end remove/move */
-
-/* XXX: find more appropriate place for these once DVFS is in place */
-extern u32 current_vdd1_opp;
-extern u32 current_vdd2_opp;
-
 #ifdef CONFIG_OMAP_SMARTREFLEX_TESTING
 #define SR_TESTING_NVALUES 	1
 #else
@@ -348,8 +213,6 @@ void sr_disable(int srid);
  * API to register the smartreflex class driver with the smartreflex driver
  */
 void omap_sr_register_class(struct omap_smartreflex_class_data *class_data);
-
-int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
 #else
 static inline void omap_smartreflex_enable(int srid) {}
 static inline void omap_smartreflex_disable(int srid) {}
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
new file mode 100644
index 0000000..f84d02c
--- /dev/null
+++ b/arch/arm/mach-omap2/voltage.c
@@ -0,0 +1,626 @@
+/*
+ * OMAP3/OMAP4 Voltage Management Routines
+ *
+ * Author: Thara Gopinath	<thara@ti.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/pm.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/omap-pm.h>
+#include <plat/omap34xx.h>
+#include <plat/opp.h>
+#include <plat/opp_twl_tps.h>
+#include <plat/clock.h>
+
+#include "prm-regbits-34xx.h"
+#include "voltage.h"
+
+#define MAX_TRIES 100
+
+/**
+ * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
+ * board data or PMIC data
+ */
+#define R_SRI2C_SLAVE_ADDR              0x12
+#define R_VDD1_SR_CONTROL               0x00
+#define R_VDD2_SR_CONTROL		0x01
+
+/* PRM voltage module */
+u32 volt_mod;
+
+/* Voltage processor register offsets */
+struct vp_reg_offs {
+	u8 vpconfig_reg;
+	u8 vstepmin_reg;
+	u8 vstepmax_reg;
+	u8 vlimitto_reg;
+	u8 status_reg;
+	u8 voltage_reg;
+};
+
+/*
+ * Voltage processor structure conttaining info about
+ * the various register offsets and the bit field values
+ * for a particular instance of voltage processor.
+ */
+struct vp_info {
+	struct vp_reg_offs vp_offs;
+	/* Bit fields for VPx_VPCONFIG */
+	u32 vp_erroroffset;
+	u32 vp_errorgain;
+	/* Bit fields for VPx_VSTEPMIN */
+	u32 vp_stepmin;
+	u32 vp_smpswaittimemin;
+	/* Bit fields for VPx_VSTEPMAX */
+	u32 vp_stepmax;
+	u32 vp_smpswaittimemax;
+	/* Bit fields for VPx_VLIMITTO */
+	u32 vp_vddmin;
+	u32 vp_vddmax;
+	u32 vp_timeout;
+};
+static struct vp_info *vp_reg;
+/*
+ * Number of scalable voltage domains that has an independent
+ * Voltage processor
+ */
+static int no_scalable_vdd;
+
+/* OMAP3 VP register offsets and other definitions */
+struct __init vp_reg_offs omap3_vp_offs[] = {
+	/* VP1 */
+	{
+		.vpconfig_reg = OMAP3_PRM_VP1_CONFIG_OFFSET,
+		.vstepmin_reg = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
+		.vstepmax_reg = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
+		.vlimitto_reg = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
+		.status_reg = OMAP3_PRM_VP1_STATUS_OFFSET,
+		.voltage_reg = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
+	},
+	/* VP2 */
+	{	.vpconfig_reg = OMAP3_PRM_VP2_CONFIG_OFFSET,
+		.vstepmin_reg = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
+		.vstepmax_reg = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
+		.vlimitto_reg = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
+		.status_reg = OMAP3_PRM_VP2_STATUS_OFFSET,
+		.voltage_reg = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
+	},
+};
+
+#define OMAP3_NO_SCALABLE_VDD ARRAY_SIZE(omap3_vp_offs)
+static struct vp_info omap3_vp_reg[OMAP3_NO_SCALABLE_VDD];
+
+
+/* TODO: OMAP4 register offsets */
+
+/*
+ * Voltage controller register offsets
+ */
+struct vc_reg_info {
+	u8 cmdval0_reg;
+	u8 cmdval1_reg;
+	u8 bypass_val_reg;
+} vc_reg;
+
+/*
+ * Default voltage controller settings for OMAP3
+ */
+static struct prm_setup_vc vc_config = {
+	.clksetup = 0xff,
+	.voltsetup_time1 = 0xfff,
+	.voltsetup_time2 = 0xfff,
+	.voltoffset = 0xff,
+	.voltsetup2 = 0xff,
+	.vdd0_on = 0x30,        /* 1.2v */
+	.vdd0_onlp = 0x20,      /* 1.0v */
+	.vdd0_ret = 0x1e,       /* 0.975v */
+	.vdd0_off = 0x00,       /* 0.6v */
+	.vdd1_on = 0x2c,        /* 1.15v */
+	.vdd1_onlp = 0x20,      /* 1.0v */
+	.vdd1_ret = 0x1e,       /* .975v */
+	.vdd1_off = 0x00,       /* 0.6v */
+};
+
+static inline u32 voltage_read_reg(u8 offset)
+{
+	return prm_read_mod_reg(volt_mod, offset);
+}
+
+static inline void voltage_write_reg(u8 offset, u32 value)
+{
+	prm_write_mod_reg(value, volt_mod, offset);
+}
+
+/**
+ * voltagecontroller_init - initializes the voltage controller.
+ *
+ * Intializes the voltage controller registers with the PMIC and board
+ * specific parameters and voltage setup times. If the board file does not
+ * populate the voltage controller parameters through omap3_pm_init_vc,
+ * default values specified in vc_config is used.
+ */
+static void __init init_voltagecontroller(void)
+{
+
+	u8 vc_ch_conf_reg, vc_i2c_cfg_reg, vc_smps_sa_reg, vc_smps_vol_ra_reg;
+	u8 prm_clksetup_reg, prm_voltsetup1_reg;
+	u8 prm_voltsetup2_reg, prm_voltoffset_reg;
+
+	if (cpu_is_omap34xx()) {
+		vc_reg.cmdval0_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET;
+		vc_reg.cmdval1_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET;
+		vc_reg.bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET;
+		vc_ch_conf_reg = OMAP3_PRM_VC_CH_CONF_OFFSET;
+		vc_i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET;
+		vc_smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET;
+		vc_smps_vol_ra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET;
+		prm_clksetup_reg = OMAP3_PRM_CLKSETUP_OFFSET;
+		prm_voltoffset_reg = OMAP3_PRM_VOLTOFFSET_OFFSET;
+		prm_voltsetup1_reg = OMAP3_PRM_VOLTSETUP1_OFFSET;
+		prm_voltsetup2_reg = OMAP3_PRM_VOLTSETUP2_OFFSET;
+	} else {
+		pr_warning("support for voltage controller not added\n");
+		return;
+	}
+	voltage_write_reg(vc_smps_sa_reg, (R_SRI2C_SLAVE_ADDR <<
+			VC_SMPS_SA1_SHIFT) | (R_SRI2C_SLAVE_ADDR <<
+			VC_SMPS_SA0_SHIFT));
+
+	voltage_write_reg(vc_smps_vol_ra_reg, (R_VDD2_SR_CONTROL <<
+			VC_VOLRA1_SHIFT) | (R_VDD1_SR_CONTROL <<
+			VC_VOLRA0_SHIFT));
+
+	voltage_write_reg(vc_reg.cmdval0_reg,
+			(vc_config.vdd0_on << VC_CMD_ON_SHIFT) |
+			(vc_config.vdd0_onlp << VC_CMD_ONLP_SHIFT) |
+			(vc_config.vdd0_ret << VC_CMD_RET_SHIFT) |
+			(vc_config.vdd0_off << VC_CMD_OFF_SHIFT));
+
+	voltage_write_reg(vc_reg.cmdval1_reg,
+			(vc_config.vdd1_on << VC_CMD_ON_SHIFT) |
+			(vc_config.vdd1_onlp << VC_CMD_ONLP_SHIFT) |
+			(vc_config.vdd1_ret << VC_CMD_RET_SHIFT) |
+			(vc_config.vdd1_off << VC_CMD_OFF_SHIFT));
+
+	voltage_write_reg(vc_ch_conf_reg, VC_CMD1 | VC_RAV1);
+
+	voltage_write_reg(vc_i2c_cfg_reg, VC_MCODE_SHIFT | VC_HSEN);
+
+	/* Write setup times */
+	voltage_write_reg(prm_clksetup_reg, vc_config.clksetup);
+	voltage_write_reg(prm_voltsetup1_reg,
+			(vc_config.voltsetup_time2 << VC_SETUP_TIME2_SHIFT) |
+			(vc_config.voltsetup_time1 << VC_SETUP_TIME1_SHIFT));
+	voltage_write_reg(prm_voltoffset_reg, vc_config.voltoffset);
+	voltage_write_reg(prm_voltsetup2_reg, vc_config.voltsetup2);
+}
+
+static void vp_latch_vsel(int vp_id)
+{
+	u32 vpconfig;
+	unsigned long uvdc;
+	char vsel;
+
+	/* Should remove this once OPP framework is fixed */
+	if (vp_id == VP1) {
+		uvdc = get_curr_vdd1_voltage();
+		if (!uvdc)
+			return;
+	} else if (vp_id == VP2) {
+		uvdc = get_curr_vdd2_voltage();
+		if (!uvdc)
+			return;
+	} else {
+		pr_warning("Voltage processor%d does not exisit", vp_id);
+		return;
+	}
+
+	vsel = omap_twl_uv_to_vsel(uvdc);
+	vpconfig = voltage_read_reg(vp_reg[vp_id].vp_offs.vpconfig_reg);
+	vpconfig &= ~(VP_INITVOLTAGE_MASK | VP_CONFIG_INITVDD);
+	vpconfig |= vsel << VP_INITVOLTAGE_SHIFT;
+
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg, vpconfig);
+
+	/* Trigger initVDD value copy to voltage processor */
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg,
+			(vpconfig | VP_CONFIG_INITVDD));
+
+	/* Clear initVDD copy trigger bit */
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg, vpconfig);
+}
+
+static void __init vp_configure(int vp_id)
+{
+	u32 vpconfig;
+
+	vpconfig = vp_reg[vp_id].vp_erroroffset | vp_reg[vp_id].vp_errorgain |
+			VP_CONFIG_TIMEOUTEN;
+
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg, vpconfig);
+
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vstepmin_reg,
+			(vp_reg[vp_id].vp_smpswaittimemin |
+			vp_reg[vp_id].vp_stepmin));
+
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vstepmax_reg,
+			(vp_reg[vp_id].vp_smpswaittimemax |
+			vp_reg[vp_id].vp_stepmax));
+
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vlimitto_reg,
+			(vp_reg[vp_id].vp_vddmax | vp_reg[vp_id].vp_vddmin |
+			vp_reg[vp_id].vp_timeout));
+
+	/* Set the init voltage */
+	vp_latch_vsel(vp_id);
+
+	vpconfig = voltage_read_reg(vp_reg[vp_id].vp_offs.vpconfig_reg);
+	/* Force update of voltage */
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg,
+			(vpconfig | VP_FORCEUPDATE));
+	/* Clear force bit */
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg, vpconfig);
+}
+
+static void __init vp_data_configure(int vp_id)
+{
+	if (cpu_is_omap34xx()) {
+		vp_reg[vp_id].vp_offs = omap3_vp_offs[vp_id];
+		if (vp_id == VP1) {
+			vp_reg[vp_id].vp_vddmin = (OMAP3_VP1_VLIMITTO_VDDMIN <<
+					OMAP3430_VDDMIN_SHIFT);
+			vp_reg[vp_id].vp_vddmax = (OMAP3_VP1_VLIMITTO_VDDMAX <<
+					OMAP3430_VDDMAX_SHIFT);
+		} else if (vp_id == VP2) {
+			vp_reg[vp_id].vp_vddmin = (OMAP3_VP2_VLIMITTO_VDDMIN <<
+					OMAP3430_VDDMIN_SHIFT);
+			vp_reg[vp_id].vp_vddmax = (OMAP3_VP2_VLIMITTO_VDDMAX <<
+					OMAP3430_VDDMAX_SHIFT);
+		} else {
+			pr_warning("Voltage processor%d does not exisit\
+					in OMAP3 \n", vp_id);
+			return;
+		}
+		vp_reg[vp_id].vp_erroroffset = (OMAP3_VP_CONFIG_ERROROFFSET <<
+					OMAP3430_INITVOLTAGE_SHIFT);
+		vp_reg[vp_id].vp_errorgain = (OMAP3_VP_CONFIG_ERRORGAIN <<
+					OMAP3430_ERRORGAIN_SHIFT);
+		vp_reg[vp_id].vp_smpswaittimemin =
+					(OMAP3_VP_VSTEPMIN_SMPSWAITTIMEMIN <<
+					OMAP3430_SMPSWAITTIMEMIN_SHIFT);
+		vp_reg[vp_id].vp_smpswaittimemax =
+					(OMAP3_VP_VSTEPMAX_SMPSWAITTIMEMAX <<
+					OMAP3430_SMPSWAITTIMEMAX_SHIFT);
+		vp_reg[vp_id].vp_stepmin = (OMAP3_VP_VSTEPMIN_VSTEPMIN <<
+					OMAP3430_VSTEPMIN_SHIFT);
+		vp_reg[vp_id].vp_stepmax = (OMAP3_VP_VSTEPMAX_VSTEPMAX <<
+					OMAP3430_VSTEPMAX_SHIFT);
+		vp_reg[vp_id].vp_timeout = (OMAP3_VP_VLIMITTO_TIMEOUT <<
+					OMAP3430_TIMEOUT_SHIFT);
+	}
+	/* TODO Extend this for OMAP4 ?? Or need a separate file  */
+}
+
+/*
+ * vc_bypass_scale_voltage - VC bypass method of voltage scaling
+ */
+static int vc_bypass_scale_voltage(u32 vdd, unsigned long target_volt,
+						unsigned long current_volt)
+{
+	u32 vc_bypass_value;
+	u32 reg_addr = 0;
+	u32 loop_cnt = 0, retries_cnt = 0;
+	u32 smps_steps = 0;
+	u32 smps_delay = 0;
+	u8 target_vsel, current_vsel;
+
+	target_vsel = omap_twl_uv_to_vsel(target_volt);
+	current_vsel = omap_twl_uv_to_vsel(current_volt);
+	smps_steps = abs(target_vsel - current_vsel);
+
+	if (vdd == VDD1_OPP) {
+		u32 vc_cmdval0;
+
+		vc_cmdval0 = voltage_read_reg(vc_reg.cmdval0_reg);
+		vc_cmdval0 &= ~VC_CMD_ON_MASK;
+		vc_cmdval0 |= (target_vsel << VC_CMD_ON_SHIFT);
+		voltage_write_reg(vc_reg.cmdval0_reg, vc_cmdval0);
+		reg_addr = R_VDD1_SR_CONTROL;
+
+	} else if (vdd == VDD2_OPP) {
+		u32 vc_cmdval1;
+
+		vc_cmdval1 = voltage_read_reg(vc_reg.cmdval1_reg);
+		vc_cmdval1 &= ~VC_CMD_ON_MASK;
+		vc_cmdval1 |= (target_vsel << VC_CMD_ON_SHIFT);
+		voltage_write_reg(vc_reg.cmdval1_reg, vc_cmdval1);
+		reg_addr = R_VDD2_SR_CONTROL;
+	} else {
+		pr_warning("Wrong VDD passed in vc_bypass_scale_voltage %d\n",
+				vdd);
+		return false;
+	}
+
+	vc_bypass_value = (target_vsel << VC_DATA_SHIFT) |
+			(reg_addr << VC_REGADDR_SHIFT) |
+			(R_SRI2C_SLAVE_ADDR << VC_SLAVEADDR_SHIFT);
+
+	voltage_write_reg(vc_reg.bypass_val_reg, vc_bypass_value);
+
+	voltage_write_reg(vc_reg.bypass_val_reg,
+			vc_bypass_value | VC_VALID);
+	vc_bypass_value = voltage_read_reg(vc_reg.bypass_val_reg);
+
+	while ((vc_bypass_value & VC_VALID) != 0x0) {
+		loop_cnt++;
+		if (retries_cnt > 10) {
+			pr_warning("Loop count exceeded in check SR I2C write\
+						during voltgae scaling\n");
+			return false;
+		}
+		if (loop_cnt > 50) {
+			retries_cnt++;
+			loop_cnt = 0;
+			udelay(10);
+		}
+		vc_bypass_value = voltage_read_reg(vc_reg.bypass_val_reg);
+	}
+
+	/*
+	 *  T2 SMPS slew rate (min) 4mV/uS, step size 12.5mV,
+	 *  2us added as buffer.
+	 */
+	smps_delay = ((smps_steps * 125) / 40) + 2;
+	udelay(smps_delay);
+	return true;
+}
+
+
+static void __init init_voltageprocessors(void)
+{
+	int i;
+
+	if (cpu_is_omap34xx()) {
+		vp_reg = omap3_vp_reg;
+		no_scalable_vdd = OMAP3_NO_SCALABLE_VDD;
+	} else {
+		/* TODO: Add support for OMAP4 */
+		pr_warning("Voltage processor support not yet added\n");
+		return;
+	}
+	for (i = 0; i < no_scalable_vdd; i++) {
+		vp_data_configure(i);
+		vp_configure(i);
+	}
+}
+
+/* Public functions */
+
+/**
+ * get_curr_vdd1_voltage : Gets the current non-auto-compensated vdd1 voltage
+ *
+ * This is a temporary placeholder for this API. This should ideally belong
+ * to Shared resource framework.
+ */
+unsigned long get_curr_vdd1_voltage(void)
+{
+	struct omap_opp *opp;
+	unsigned long freq;
+	struct clk *dpll1_clk;
+
+	dpll1_clk = clk_get(NULL, "dpll1_ck");
+	if (IS_ERR(dpll1_clk))
+		return 0;
+
+	freq = dpll1_clk->rate;
+	opp = opp_find_freq_ceil(OPP_MPU, &freq);
+	if (IS_ERR(opp)) {
+		clk_put(dpll1_clk);
+		return 0;
+	}
+
+	/*
+	 * Use higher freq voltage even if an exact match is not available
+	 * we are probably masking a clock framework bug, so warn
+	 */
+	if (unlikely(freq != dpll1_clk->rate))
+		pr_warning("%s: Available freq %ld != dpll freq %ld.\n",
+			__func__, freq, dpll1_clk->rate);
+
+	clk_put(dpll1_clk);
+	return opp_get_voltage(opp);
+}
+
+/**
+ * get_curr_vdd2_voltage : Gets the current non-auto-compensated vdd2 voltage
+ *
+ * This is a temporary placeholder for this API. This should ideally belong
+ * to Shared resource framework.
+ */
+unsigned long get_curr_vdd2_voltage(void)
+{
+	struct omap_opp *opp;
+	unsigned long freq;
+	struct clk *l3_clk;
+
+	l3_clk = clk_get(NULL, "l3_ick");
+	if (IS_ERR(l3_clk))
+		return 0;
+
+	freq = l3_clk->rate;
+	opp = opp_find_freq_ceil(OPP_L3, &freq);
+	if (IS_ERR(opp)) {
+		clk_put(l3_clk);
+		return 0;
+	}
+
+	/*
+	 * Use higher freq voltage even if an exact match is not available
+	 * we are probably masking a clock framework bug, so warn
+	 */
+	if (unlikely(freq != l3_clk->rate))
+		pr_warning("%s: Available freq %ld != dpll freq %ld.\n",
+			__func__, freq, l3_clk->rate);
+
+	clk_put(l3_clk);
+	return opp_get_voltage(opp);
+}
+
+/**
+ * omap_voltageprocessor_enable : API to enable a particular VP
+ * @vp_id : The id of the VP to be enable.
+ *
+ * This API enables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_voltageprocessor_enable(int vp_id)
+{
+	u32 vpconfig;
+
+	/*
+	 * This latching is required only if VC bypass method is used for
+	 * voltage scaling during dvfs.
+	 */
+	vp_latch_vsel(vp_id - 1);
+	vpconfig = voltage_read_reg(vp_reg[vp_id - 1].vp_offs.vpconfig_reg);
+	/* Enable VP */
+	voltage_write_reg(vp_reg[vp_id - 1].vp_offs.vpconfig_reg,
+				vpconfig | VP_CONFIG_VPENABLE);
+}
+
+/**
+ * omap_voltageprocessor_disable : API to disable a particular VP
+ * @vp_id : The id of the VP to be disable.
+ *
+ * This API disables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_voltageprocessor_disable(int vp_id)
+{
+	int i = 0;
+	u32 vpconfig;
+
+	/* Wait for VP idle before disabling VP */
+	while ((!voltage_read_reg(vp_reg[vp_id - 1].vp_offs.status_reg)) &&
+				i++ < MAX_TRIES)
+		udelay(1);
+
+	if (i >= MAX_TRIES)
+		pr_warning("VP1 not idle, still going ahead with \
+						VP1 disable\n");
+	/* Disable VP1 */
+	vpconfig = voltage_read_reg(vp_reg[vp_id - 1].vp_offs.vpconfig_reg);
+	vpconfig &= ~VP_CONFIG_VPENABLE;
+	voltage_write_reg(vp_reg[vp_id - 1].vp_offs.vpconfig_reg, vpconfig);
+}
+
+/**
+ * omap_voltage_scale : API to scale voltage of a particular voltage domain.
+ * @vdd : the voltage domain whose voltage is to be scaled
+ * @target_vsel : The target voltage of the voltage domain
+ * @current_vsel : the current voltage of the voltage domain.
+ *
+ * This API should be called by the kernel to do the voltage scaling
+ * for a particular voltage domain during dvfs or any other situation.
+ */
+int omap_voltage_scale(int vdd, unsigned long target_volt,
+					unsigned long current_volt)
+{	/*
+	 * TODO add VP force update method of voltage scaling
+	 * and choose btw the two
+	 */
+	return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
+}
+
+/**
+ * omap_reset_voltage : Resets the voltage of a particular voltage domain
+ * to that of the current OPP.
+ * @vdd : the voltage domain whose voltage is to be reset.
+ *
+ * This API finds out the correct voltage the voltage domain is supposed
+ * to be at and resets the voltage to that level. Should be used expecially
+ * while disabling any voltage compensation modules.
+ */
+void omap_reset_voltage(int vdd)
+{
+	unsigned long target_uvdc, current_uvdc;
+	char vsel;
+
+	/* Should remove this once OPP framework is fixed */
+	if ((vdd - 1) == VP1) {
+		target_uvdc = get_curr_vdd1_voltage();
+		if (!target_uvdc)
+			return;
+	} else if ((vdd - 1) == VP2) {
+		target_uvdc = get_curr_vdd2_voltage();
+		if (!target_uvdc)
+			return;
+	} else {
+		pr_warning("Wrong VDD passed in omap_reset_voltage %d\n", vdd);
+		return;
+	}
+	vsel = voltage_read_reg(vp_reg[vdd - 1].vp_offs.voltage_reg);
+	current_uvdc = (vsel * 12500) + 600000;
+	omap_voltage_scale(vdd, target_uvdc, current_uvdc);
+}
+
+/**
+ * omap3_pm_init_vc - polpulates vc_config with values specified in board file
+ * @setup_vc - the structure with various vc parameters
+ *
+ * Updates vc_config with the voltage setup times and other parameters as
+ * specified in setup_vc. vc_config is later used in init_voltagecontroller
+ * to initialize the voltage controller registers. Board files should call
+ * this function with the correct volatge settings corresponding
+ * the particular PMIC and chip.
+ */
+void __init omap_voltage_init_vc(struct prm_setup_vc *setup_vc)
+{
+	if (!setup_vc)
+		return;
+
+	vc_config.clksetup = setup_vc->clksetup;
+	vc_config.voltsetup_time1 = setup_vc->voltsetup_time1;
+	vc_config.voltsetup_time2 = setup_vc->voltsetup_time2;
+	vc_config.voltoffset = setup_vc->voltoffset;
+	vc_config.voltsetup2 = setup_vc->voltsetup2;
+	vc_config.vdd0_on = setup_vc->vdd0_on;
+	vc_config.vdd0_onlp = setup_vc->vdd0_onlp;
+	vc_config.vdd0_ret = setup_vc->vdd0_ret;
+	vc_config.vdd0_off = setup_vc->vdd0_off;
+	vc_config.vdd1_on = setup_vc->vdd1_on;
+	vc_config.vdd1_onlp = setup_vc->vdd1_onlp;
+	vc_config.vdd1_ret = setup_vc->vdd1_ret;
+	vc_config.vdd1_off = setup_vc->vdd1_off;
+}
+
+/**
+ * omap_voltage_init : Volatage init API which does VP and VC init.
+ */
+void __init omap_voltage_init(void)
+{
+	if (cpu_is_omap34xx())
+		volt_mod = OMAP3430_GR_MOD;
+	else
+		return;
+	init_voltagecontroller();
+	init_voltageprocessors();
+}
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
new file mode 100644
index 0000000..663c6fe
--- /dev/null
+++ b/arch/arm/mach-omap2/voltage.h
@@ -0,0 +1,74 @@
+/*
+ * OMAP3 Voltage Management Routines
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include "pm.h"
+
+/* Voltageprocessor instances */
+#define VP1	0
+#define VP2	1
+
+
+/* Generic VP definitions. Need to be redefined for OMAP4 */
+#define VP_CONFIG_TIMEOUTEN	OMAP3430_TIMEOUTEN
+#define VP_CONFIG_INITVDD	OMAP3430_INITVDD
+#define VP_FORCEUPDATE		OMAP3430_FORCEUPDATE
+#define VP_CONFIG_VPENABLE	OMAP3430_VPENABLE
+#define VP_INITVOLTAGE_MASK	OMAP3430_INITVOLTAGE_MASK
+#define VP_INITVOLTAGE_SHIFT	OMAP3430_INITVOLTAGE_SHIFT
+
+/* Generic VC definitions. Need to be redefined for OMAP4 */
+#define VC_SMPS_SA1_SHIFT	OMAP3430_SMPS_SA1_SHIFT
+#define VC_SMPS_SA0_SHIFT	OMAP3430_SMPS_SA0_SHIFT
+#define VC_VOLRA1_SHIFT		OMAP3430_VOLRA1_SHIFT
+#define VC_VOLRA0_SHIFT		OMAP3430_VOLRA0_SHIFT
+#define VC_CMD_ON_SHIFT		OMAP3430_VC_CMD_ON_SHIFT
+#define VC_CMD_ONLP_SHIFT	OMAP3430_VC_CMD_ONLP_SHIFT
+#define VC_CMD_RET_SHIFT	OMAP3430_VC_CMD_RET_SHIFT
+#define VC_CMD_OFF_SHIFT	OMAP3430_VC_CMD_OFF_SHIFT
+#define VC_SETUP_TIME2_SHIFT	OMAP3430_SETUP_TIME2_SHIFT
+#define VC_SETUP_TIME1_SHIFT	OMAP3430_SETUP_TIME1_SHIFT
+#define VC_DATA_SHIFT		OMAP3430_DATA_SHIFT
+#define VC_REGADDR_SHIFT	OMAP3430_REGADDR_SHIFT
+#define VC_SLAVEADDR_SHIFT	OMAP3430_SLAVEADDR_SHIFT
+#define VC_CMD_ON_MASK		OMAP3430_VC_CMD_ON_MASK
+#define VC_CMD1			OMAP3430_CMD1
+#define VC_RAV1			OMAP3430_RAV1
+#define VC_MCODE_SHIFT		OMAP3430_MCODE_SHIFT
+#define VC_HSEN			OMAP3430_HSEN
+#define VC_VALID		OMAP3430_VALID
+
+
+/*
+ * Omap 3430 VP registerspecific values. Maybe these need to come from
+ * board file or PMIC data structure
+ */
+#define OMAP3_VP_CONFIG_ERROROFFSET		0x00
+#define OMAP3_VP_CONFIG_ERRORGAIN		0x20
+#define	OMAP3_VP_VSTEPMIN_SMPSWAITTIMEMIN	0x01F4
+#define OMAP3_VP_VSTEPMIN_VSTEPMIN		0x1
+#define OMAP3_VP_VSTEPMAX_SMPSWAITTIMEMAX	0x01F4
+#define OMAP3_VP_VSTEPMAX_VSTEPMAX		0x04
+#define OMAP3_VP1_VLIMITTO_VDDMIN		0x0
+#define OMAP3_VP1_VLIMITTO_VDDMAX		0x3C
+#define OMAP3_VP2_VLIMITTO_VDDMAX		0x2C
+#define OMAP3_VP2_VLIMITTO_VDDMIN		0x0
+#define OMAP3_VP_VLIMITTO_TIMEOUT		0xFFFF
+
+/* TODO OMAP4 VP register values if the same file is used for OMAP4*/
+
+void omap_voltageprocessor_enable(int vp_id);
+void omap_voltageprocessor_disable(int vp_id);
+void omap_voltage_init_vc(struct prm_setup_vc *setup_vc);
+void omap_voltage_init(void);
+int omap_voltage_scale(int vdd, unsigned long target_volt,
+					unsigned long current_volt);
+void omap_reset_voltage(int vdd);
+unsigned long get_curr_vdd1_voltage(void);
+unsigned long get_curr_vdd2_voltage(void);
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver.
  2010-04-16  9:03                 ` [PATCHv3 09/22] OMAP3: PM: Creating separate files for handling OMAP3 voltage related operations Thara Gopinath
@ 2010-04-16  9:03                   ` Thara Gopinath
  2010-04-16  9:03                     ` [PATCHv3 11/22] OMAP3: PM: Removing VP1, VP2, SR1 and SR2 defintions Thara Gopinath
  2010-04-27 18:58                     ` [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver Kevin Hilman
  0 siblings, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch introduces the framework to create voltage table per
VDD basis in voltage driver. Each VDD will have one voltage table,
which in turn will contain one entry per voltage supported and
other data associated with the voltage like smartreflex N-target
values. This patch also generates voltage tables for VDD1 and VDD2 of
OMAP3430 and passes them as dev_attr to sr_device.c in order
to populate the smartreflex n-target values.

These voltage tables are extended in a later patch to contain more
voltage specific information like errminlimt and errorgain values.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |    7 +-
 arch/arm/mach-omap2/smartreflex.c          |   27 +--------
 arch/arm/mach-omap2/smartreflex.h          |   13 +----
 arch/arm/mach-omap2/sr_device.c            |   42 ++----------
 arch/arm/mach-omap2/voltage.c              |   93 +++++++++++++++++++++++++++-
 arch/arm/mach-omap2/voltage.h              |   15 +++++
 6 files changed, 118 insertions(+), 79 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 049e4e2..1f41310 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -23,6 +23,7 @@
 
 #include "prm-regbits-34xx.h"
 #include "smartreflex.h"
+#include "voltage.h"
 
 /*
  * OMAP3xxx hardware module integration data
@@ -240,14 +241,13 @@ static u32 omap34xx_sr1_test_nvalues[] = {
 };
 
 static struct omap_smartreflex_dev_data omap34xx_sr1_dev_attr = {
-	.volts_supported	= 5,
 	.efuse_sr_control	= OMAP343X_CONTROL_FUSE_SR,
 	.sennenable_shift	= OMAP343X_SR1_SENNENABLE_SHIFT,
 	.senpenable_shift	= OMAP343X_SR1_SENPENABLE_SHIFT,
 	.efuse_nvalues_offs	= omap34xx_sr1_efuse_offs,
 	.test_sennenable	= 0x3,
 	.test_senpenable	= 0x3,
-	.test_nvalues		= omap34xx_sr1_test_nvalues
+	.test_nvalues		= omap34xx_sr1_test_nvalues,
 };
 
 static struct omap_hwmod omap34xx_sr1_hwmod = {
@@ -276,14 +276,13 @@ static u32 omap34xx_sr2_test_nvalues[] = {
 };
 
 static struct omap_smartreflex_dev_data omap34xx_sr2_dev_attr = {
-	.volts_supported	= 3,
 	.efuse_sr_control	= OMAP343X_CONTROL_FUSE_SR,
 	.sennenable_shift	= OMAP343X_SR2_SENNENABLE_SHIFT,
 	.senpenable_shift	= OMAP343X_SR2_SENPENABLE_SHIFT,
 	.efuse_nvalues_offs	= omap34xx_sr2_efuse_offs,
 	.test_sennenable	= 0x3,
 	.test_senpenable	= 0x3,
-	.test_nvalues		= omap34xx_sr2_test_nvalues
+	.test_nvalues		= omap34xx_sr2_test_nvalues,
 };
 
 static struct omap_hwmod omap34xx_sr2_hwmod = {
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index a89f74f..d3222a5 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -31,6 +31,7 @@
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+#include "voltage.h"
 #include "smartreflex.h"
 
 #define SMARTREFLEX_NAME_LEN	16
@@ -110,30 +111,6 @@ static void sr_clk_disable(struct omap_sr *sr)
 	sr->is_sr_reset = 1;
 }
 
-static int sr_match_volt(struct omap_sr *sr, unsigned long volt,
-				struct omap_volt_data *volt_data)
-{
-	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
-	struct omap_device *odev = to_omap_device(sr->pdev);
-	struct omap_smartreflex_dev_data *sr_dev_data =
-					odev->hwmods[0]->dev_attr;
-	int i;
-
-	if (!pdata->sr_volt_data) {
-		pr_notice("voltage table does not exist for SR %d\n", sr->srid);
-		return false;
-	}
-	for (i = 0; i < sr_dev_data->volts_supported; i++) {
-		if (pdata->sr_volt_data[i].voltage == volt) {
-			*volt_data = pdata->sr_volt_data[i];
-			return true;
-		}
-	}
-	pr_notice("Unable to match the current voltage with \
-				the voltage table for SR %d\n", sr->srid);
-	return false;
-}
-
 static void sr_set_clk_length(struct omap_sr *sr)
 {
 	struct clk *sys_ck;
@@ -288,7 +265,7 @@ int sr_enable(int srid, unsigned long volt)
 		return false;
 	}
 
-	if (!sr_match_volt(sr, volt, &volt_data))
+	if (omap_match_volt(sr->srid, volt, &volt_data))
 		return false;
 
 	nvalue_reciprocal = volt_data.sr_nvalue;
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 073f6d0..0f60a97 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -107,17 +107,6 @@ extern struct dentry *pm_dbg_main_dir;
 #endif
 
 /**
- * omap_volt_data - Omap voltage specific data.
- *
- * @voltage	: The possible voltage value
- * @sr_nvalue	: Smartreflex N target value at voltage <voltage>
- */
-struct omap_volt_data {
-	unsigned long	voltage;
-	u32		sr_nvalue;
-};
-
-/**
  * omap_smartreflex_dev_data - Smartreflex device specific data
  *
  * @volts_supported	: Number of distinct voltages possible for the VDD
@@ -148,6 +137,7 @@ struct omap_smartreflex_dev_data {
 	u32 test_sennenable;
 	u32 test_senpenable;
 	u32 *test_nvalues;
+	struct omap_volt_data *volt_data;
 };
 
 #ifdef CONFIG_OMAP_SMARTREFLEX
@@ -188,7 +178,6 @@ struct omap_smartreflex_class_data {
 struct omap_smartreflex_data {
 	u32				senp_mod;
 	u32				senn_mod;
-	struct omap_volt_data		*sr_volt_data;
 	bool				enable_on_init;
 	int (*device_enable)(struct platform_device *pdev);
 	int (*device_shutdown)(struct platform_device *pdev);
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index 544d575..c9b6533 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -28,6 +28,7 @@
 #include <plat/opp.h>
 
 #include "smartreflex.h"
+#include "voltage.h"
 
 #define MAX_HWMOD_NAME_LEN	16
 
@@ -47,13 +48,10 @@ static void __init sr_read_efuse(
 	int i;
 
 	if (WARN_ON(!dev_data || !dev_data->volts_supported ||
-			!dev_data->efuse_sr_control ||
+			!dev_data->volt_data || !dev_data->efuse_sr_control ||
 			!dev_data->efuse_nvalues_offs))
 		return;
 
-	if (WARN_ON(!sr_data->sr_volt_data))
-		return;
-
 	sr_data->senn_mod = (omap_ctrl_readl(dev_data->efuse_sr_control) &
 				(0x3 << dev_data->sennenable_shift) >>
 				dev_data->sennenable_shift);
@@ -61,7 +59,7 @@ static void __init sr_read_efuse(
 				(0x3 << dev_data->senpenable_shift) >>
 				dev_data->senpenable_shift);
 	for (i = 0; i < dev_data->volts_supported; i++)
-		sr_data->sr_volt_data[i].sr_nvalue = omap_ctrl_readl(
+		dev_data->volt_data[i].sr_nvalue = omap_ctrl_readl(
 				dev_data->efuse_nvalues_offs[i]);
 }
 
@@ -76,16 +74,13 @@ static void __init sr_set_testing_nvalues(
 	int i;
 
 	if (WARN_ON(!dev_data || !dev_data->volts_supported ||
-			!dev_data->test_nvalues))
-		return;
-
-	if (WARN_ON(!sr_data->sr_volt_data))
+			!dev_data->volt_data || !dev_data->test_nvalues))
 		return;
 
 	sr_data->senn_mod = dev_data->test_sennenable;
 	sr_data->senp_mod = dev_data->test_senpenable;
 	for (i = 0; i < dev_data->volts_supported; i++)
-		sr_data->sr_volt_data[i].sr_nvalue = dev_data->test_nvalues[i];
+		dev_data->volt_data[i].sr_nvalue = dev_data->test_nvalues[i];
 }
 
 static void __init sr_set_nvalues(struct omap_smartreflex_dev_data *dev_data,
@@ -99,28 +94,6 @@ static void __init sr_set_nvalues(struct omap_smartreflex_dev_data *dev_data,
 	}
 }
 
-static void __init omap34xx_sr_volt_details(struct omap_smartreflex_data
-						*sr_data, int srid,
-						int volt_count)
-{
-	sr_data->sr_volt_data = kzalloc(sizeof(sr_data->sr_volt_data) *
-				volt_count , GFP_KERNEL);
-	if (WARN_ON(!sr_data->sr_volt_data))
-		return;
-
-	if (srid == SR1) {
-		sr_data->sr_volt_data[0].voltage = 975000;
-		sr_data->sr_volt_data[1].voltage = 1075000;
-		sr_data->sr_volt_data[2].voltage = 1200000;
-		sr_data->sr_volt_data[3].voltage = 1270000;
-		sr_data->sr_volt_data[4].voltage = 1350000;
-	} else if (srid == SR2) {
-		sr_data->sr_volt_data[0].voltage = 975000;
-		sr_data->sr_volt_data[1].voltage = 1050000;
-		sr_data->sr_volt_data[2].voltage = 1150000;
-	}
-}
-
 static int __init omap_devinit_smartreflex(void)
 {
 	int i = 0;
@@ -148,9 +121,8 @@ static int __init omap_devinit_smartreflex(void)
 		sr_data->device_enable = omap_device_enable;
 		sr_data->device_shutdown = omap_device_shutdown;
 		sr_data->device_idle = omap_device_idle;
-		if (cpu_is_omap34xx())
-			omap34xx_sr_volt_details(sr_data, i + 1,
-					sr_dev_data->volts_supported);
+		omap_get_voltage_table(i, &sr_dev_data->volt_data,
+					&sr_dev_data->volts_supported);
 		sr_set_nvalues(sr_dev_data, sr_data);
 
 		od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index f84d02c..dd9618c 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -57,12 +57,15 @@ struct vp_reg_offs {
 };
 
 /*
- * Voltage processor structure conttaining info about
- * the various register offsets and the bit field values
- * for a particular instance of voltage processor.
+ * Voltage processor structure containing info about
+ * the various register offsets, the bit field values
+ * and the info on various supported volatges and dependent
+ * data for a particular instance of voltage processor.
  */
 struct vp_info {
+	struct omap_volt_data *volt_data;
 	struct vp_reg_offs vp_offs;
+	int volt_data_count;
 	/* Bit fields for VPx_VPCONFIG */
 	u32 vp_erroroffset;
 	u32 vp_errorgain;
@@ -139,6 +142,29 @@ static struct prm_setup_vc vc_config = {
 	.vdd1_off = 0x00,       /* 0.6v */
 };
 
+/*
+ * Structures containing OMAP3430 voltage supported and various data
+ * associated with it per voltage domain basis. Smartreflex Ntarget
+ * vales are left as 0 as they have to be populated by smartreflex
+ * driver after reading the efuse.
+ */
+
+/* VDD1 */
+static struct omap_volt_data omap34xx_vdd1_volt_data[] = {
+	{975000, 0},
+	{1075000, 0},
+	{1200000, 0},
+	{1270000, 0},
+	{1350000, 0},
+};
+
+/* VDD2 */
+static struct omap_volt_data omap34xx_vdd2_volt_data[] = {
+	{975000, 0},
+	{1050000, 0},
+	{1150000, 0},
+};
+
 static inline u32 voltage_read_reg(u8 offset)
 {
 	return prm_read_mod_reg(volt_mod, offset);
@@ -285,11 +311,17 @@ static void __init vp_data_configure(int vp_id)
 	if (cpu_is_omap34xx()) {
 		vp_reg[vp_id].vp_offs = omap3_vp_offs[vp_id];
 		if (vp_id == VP1) {
+			vp_reg[vp_id].volt_data = omap34xx_vdd1_volt_data;
+			vp_reg[vp_id].volt_data_count =
+					ARRAY_SIZE(omap34xx_vdd1_volt_data);
 			vp_reg[vp_id].vp_vddmin = (OMAP3_VP1_VLIMITTO_VDDMIN <<
 					OMAP3430_VDDMIN_SHIFT);
 			vp_reg[vp_id].vp_vddmax = (OMAP3_VP1_VLIMITTO_VDDMAX <<
 					OMAP3430_VDDMAX_SHIFT);
 		} else if (vp_id == VP2) {
+			vp_reg[vp_id].volt_data = omap34xx_vdd2_volt_data;
+			vp_reg[vp_id].volt_data_count =
+					ARRAY_SIZE(omap34xx_vdd2_volt_data);
 			vp_reg[vp_id].vp_vddmin = (OMAP3_VP2_VLIMITTO_VDDMIN <<
 					OMAP3430_VDDMIN_SHIFT);
 			vp_reg[vp_id].vp_vddmax = (OMAP3_VP2_VLIMITTO_VDDMAX <<
@@ -613,6 +645,61 @@ void __init omap_voltage_init_vc(struct prm_setup_vc *setup_vc)
 }
 
 /**
+ * omap_get_voltage_table : API to get the voltage table associated with a
+ *			    particular voltage domain.
+ *
+ * @vdd : the voltage domain id for which the voltage table is required
+ * @volt_data : the voltage table for the particular vdd which is to be
+ *		populated by this API
+ * @volt_count : number of distinct voltages supported by this vdd which
+ *		is to be populated by this API.
+ *
+ * This API populates the voltage table associated with a VDD and the count
+ * of number of voltages supported into the passed parameter pointers.
+ */
+void omap_get_voltage_table(int vdd, struct omap_volt_data **volt_data,
+						int *volt_count)
+{
+	*volt_data = vp_reg[vdd].volt_data;
+	*volt_count = vp_reg[vdd].volt_data_count;
+}
+
+/**
+ * omap_match_volt : API to get the voltage table entry for a particular
+ *		     voltage
+ * @vdd : the voltage domain id for whose voltage table has to be searched
+ * @volt : the voltage to be searched in the voltage table
+ * @volt_data : the matching voltage table entry which has to be populate
+ *		by this API.
+ *
+ * This API searches through the voltage table for the required voltage
+ * domain and tries to find a matching entry for the passed voltage volt.
+ * If a matching entry is found volt_data is populated with that entry.
+ * Returns -ENXIO if not voltage table exisits for the passed voltage
+ * domain or if there is no matching entry. On success returns true.
+ */
+int omap_match_volt(int vdd, unsigned long volt,
+				struct omap_volt_data *volt_data)
+{
+	int i;
+
+	if (!vp_reg[vdd].volt_data) {
+		pr_notice("voltage table does not exist for VDD %d\n", vdd + 1);
+		return -ENXIO;
+	}
+
+	for (i = 0; i < vp_reg[vdd].volt_data_count; i++) {
+		if (vp_reg[vdd].volt_data[i].voltage == volt) {
+			*volt_data = vp_reg[vdd].volt_data[i];
+			return 0;
+		}
+	}
+	pr_notice("Unable to match the current voltage with \
+				the voltage table for VDD %d\n", vdd + 1);
+	return -ENXIO;
+}
+
+/**
  * omap_voltage_init : Volatage init API which does VP and VC init.
  */
 void __init omap_voltage_init(void)
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 663c6fe..cc3308e 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -63,6 +63,17 @@
 
 /* TODO OMAP4 VP register values if the same file is used for OMAP4*/
 
+/**
+ * omap_volt_data - Omap voltage specific data.
+ *
+ * @voltage	: The possible voltage value
+ * @sr_nvalue	: Smartreflex N target value at voltage <voltage>
+ */
+struct omap_volt_data {
+	unsigned long	voltage;
+	u32		sr_nvalue;
+};
+
 void omap_voltageprocessor_enable(int vp_id);
 void omap_voltageprocessor_disable(int vp_id);
 void omap_voltage_init_vc(struct prm_setup_vc *setup_vc);
@@ -70,5 +81,9 @@ void omap_voltage_init(void);
 int omap_voltage_scale(int vdd, unsigned long target_volt,
 					unsigned long current_volt);
 void omap_reset_voltage(int vdd);
+void omap_get_voltage_table(int vdd, struct omap_volt_data **volt_data,
+						int *volt_count);
+int omap_match_volt(int vdd, unsigned long volt,
+				struct omap_volt_data *volt_data);
 unsigned long get_curr_vdd1_voltage(void);
 unsigned long get_curr_vdd2_voltage(void);
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 11/22] OMAP3: PM: Removing VP1, VP2, SR1 and SR2 defintions.
  2010-04-16  9:03                   ` [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver Thara Gopinath
@ 2010-04-16  9:03                     ` Thara Gopinath
  2010-04-16  9:03                       ` [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c Thara Gopinath
  2010-04-27 18:58                     ` [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver Kevin Hilman
  1 sibling, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch removes VP1, VP2, SR1 and SR2 macros and replaces them with
VDD1 and VDD2 macros.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c             |    8 +++---
 arch/arm/mach-omap2/smartreflex-class3.c |    4 +-
 arch/arm/mach-omap2/smartreflex.c        |   26 +++++++++++-----------
 arch/arm/mach-omap2/smartreflex.h        |    4 ---
 arch/arm/mach-omap2/voltage.c            |   35 +++++++++++++++--------------
 arch/arm/mach-omap2/voltage.h            |    6 ++--
 6 files changed, 40 insertions(+), 43 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 2f5c894..f3994c0 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -415,9 +415,9 @@ void omap_sram_idle(void)
 	 * Only needed if we are going to enter retention or off.
 	 */
 	if (mpu_next_state <= PWRDM_POWER_RET)
-		omap_smartreflex_disable(SR1);
+		omap_smartreflex_disable(VDD1);
 	if (core_next_state <= PWRDM_POWER_RET)
-		omap_smartreflex_disable(SR2);
+		omap_smartreflex_disable(VDD2);
 
 	/* CORE */
 	if (core_next_state < PWRDM_POWER_ON) {
@@ -516,9 +516,9 @@ void omap_sram_idle(void)
 	 * retention or off
 	 */
 	if (mpu_next_state <= PWRDM_POWER_RET)
-		omap_smartreflex_enable(SR1);
+		omap_smartreflex_enable(VDD1);
 	if (core_next_state <= PWRDM_POWER_RET)
-		omap_smartreflex_enable(SR2);
+		omap_smartreflex_enable(VDD2);
 
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index 1b098ff..66696be 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -17,9 +17,9 @@ static int sr_class3_enable(int id)
 {
 	unsigned long volt = 0;
 
-	if (id == SR1)
+	if (id == VDD1)
 		volt = get_curr_vdd1_voltage();
-	else if (id == SR2)
+	else if (id == VDD2)
 		volt = get_curr_vdd2_voltage();
 	if (!volt) {
 		pr_warning("Current voltage unknown.Cannot enable SR%d\n", id);
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index d3222a5..fffd5f7 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -153,7 +153,7 @@ static void sr_configure(struct omap_sr *sr)
 
 	senp_en = pdata->senp_mod;
 	senn_en = pdata->senn_mod;
-	if (sr->srid == SR1) {
+	if (sr->srid == VDD1) {
 		sr_config = SR1_SRCONFIG_ACCUMDATA |
 			(sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
 			SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
@@ -170,7 +170,7 @@ static void sr_configure(struct omap_sr *sr)
 			SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
 			(SR1_ERRWEIGHT | SR1_ERRMAXLIMIT | SR1_ERRMINLIMIT));
 
-	} else if (sr->srid == SR2) {
+	} else if (sr->srid == VDD2) {
 		sr_config = SR2_SRCONFIG_ACCUMDATA |
 			(sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
 			SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
@@ -196,7 +196,7 @@ static void sr_start_vddautocomp(int srid)
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid);
+								srid + 1);
 		return;
 	}
 
@@ -224,7 +224,7 @@ static void  sr_stop_vddautocomp(int srid)
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid);
+								srid + 1);
 		return;
 	}
 
@@ -261,7 +261,7 @@ int sr_enable(int srid, unsigned long volt)
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid);
+								srid + 1);
 		return false;
 	}
 
@@ -272,7 +272,7 @@ int sr_enable(int srid, unsigned long volt)
 
 	if (nvalue_reciprocal == 0) {
 		pr_notice("NVALUE = 0 at voltage %ld for Smartreflex %d\n",
-						volt, sr->srid);
+						volt, sr->srid + 1);
 		return false;
 	}
 
@@ -301,7 +301,7 @@ void sr_disable(int srid)
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid);
+								srid + 1);
 		return;
 	}
 
@@ -327,7 +327,7 @@ void omap_smartreflex_enable(int srid)
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid);
+								srid + 1);
 		return;
 	}
 
@@ -362,7 +362,7 @@ void omap_smartreflex_disable(int srid)
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid);
+								srid + 1);
 		return;
 	}
 
@@ -409,7 +409,7 @@ static int omap_sr_autocomp_show(void *data, u64 *val)
 
 	if (!sr_info) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-							sr_info->srid);
+							sr_info->srid + 1);
 		return 0;
 	}
 	*val = sr_info->is_autocomp_active;
@@ -422,7 +422,7 @@ static int omap_sr_autocomp_store(void *data, u64 val)
 
 	if (!sr_info) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-							sr_info->srid);
+							sr_info->srid + 1);
 		return 0;
 	}
 	if (val == 0)
@@ -445,7 +445,7 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 	if (WARN_ON(!sr_info))
 		return -ENOMEM;
 	sr_info->pdev = pdev;
-	sr_info->srid = pdev->id + 1;
+	sr_info->srid = pdev->id;
 	sr_info->is_sr_reset = 1,
 	sr_info->is_autocomp_active = 0;
 	sr_info->clk_length = 0;
@@ -454,7 +454,7 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 	sr_set_clk_length(sr_info);
 
 	/* Create the debug fs enteries */
-	sprintf(name, "sr%d_autocomp", sr_info->srid);
+	sprintf(name, "sr%d_autocomp", sr_info->srid + 1);
 	(void) debugfs_create_file(name, S_IRUGO | S_IWUGO, pm_dbg_main_dir,
 				(void *)sr_info, &pm_sr_fops);
 
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 0f60a97..50d534a 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -32,10 +32,6 @@ extern struct dentry *pm_dbg_main_dir;
 #define SENERROR	0x20
 #define ERRCONFIG	0x24
 
-/* SR Modules */
-#define SR1		1
-#define SR2		2
-
 #define GAIN_MAXLIMIT	16
 #define R_MAXLIMIT	256
 
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index dd9618c..7777e28 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -246,11 +246,11 @@ static void vp_latch_vsel(int vp_id)
 	char vsel;
 
 	/* Should remove this once OPP framework is fixed */
-	if (vp_id == VP1) {
+	if (vp_id == VDD1) {
 		uvdc = get_curr_vdd1_voltage();
 		if (!uvdc)
 			return;
-	} else if (vp_id == VP2) {
+	} else if (vp_id == VDD2) {
 		uvdc = get_curr_vdd2_voltage();
 		if (!uvdc)
 			return;
@@ -310,7 +310,7 @@ static void __init vp_data_configure(int vp_id)
 {
 	if (cpu_is_omap34xx()) {
 		vp_reg[vp_id].vp_offs = omap3_vp_offs[vp_id];
-		if (vp_id == VP1) {
+		if (vp_id == VDD1) {
 			vp_reg[vp_id].volt_data = omap34xx_vdd1_volt_data;
 			vp_reg[vp_id].volt_data_count =
 					ARRAY_SIZE(omap34xx_vdd1_volt_data);
@@ -318,7 +318,7 @@ static void __init vp_data_configure(int vp_id)
 					OMAP3430_VDDMIN_SHIFT);
 			vp_reg[vp_id].vp_vddmax = (OMAP3_VP1_VLIMITTO_VDDMAX <<
 					OMAP3430_VDDMAX_SHIFT);
-		} else if (vp_id == VP2) {
+		} else if (vp_id == VDD2) {
 			vp_reg[vp_id].volt_data = omap34xx_vdd2_volt_data;
 			vp_reg[vp_id].volt_data_count =
 					ARRAY_SIZE(omap34xx_vdd2_volt_data);
@@ -368,7 +368,7 @@ static int vc_bypass_scale_voltage(u32 vdd, unsigned long target_volt,
 	current_vsel = omap_twl_uv_to_vsel(current_volt);
 	smps_steps = abs(target_vsel - current_vsel);
 
-	if (vdd == VDD1_OPP) {
+	if (vdd == VDD1) {
 		u32 vc_cmdval0;
 
 		vc_cmdval0 = voltage_read_reg(vc_reg.cmdval0_reg);
@@ -377,7 +377,7 @@ static int vc_bypass_scale_voltage(u32 vdd, unsigned long target_volt,
 		voltage_write_reg(vc_reg.cmdval0_reg, vc_cmdval0);
 		reg_addr = R_VDD1_SR_CONTROL;
 
-	} else if (vdd == VDD2_OPP) {
+	} else if (vdd == VDD2) {
 		u32 vc_cmdval1;
 
 		vc_cmdval1 = voltage_read_reg(vc_reg.cmdval1_reg);
@@ -387,7 +387,7 @@ static int vc_bypass_scale_voltage(u32 vdd, unsigned long target_volt,
 		reg_addr = R_VDD2_SR_CONTROL;
 	} else {
 		pr_warning("Wrong VDD passed in vc_bypass_scale_voltage %d\n",
-				vdd);
+				vdd + 1);
 		return false;
 	}
 
@@ -531,10 +531,10 @@ void omap_voltageprocessor_enable(int vp_id)
 	 * This latching is required only if VC bypass method is used for
 	 * voltage scaling during dvfs.
 	 */
-	vp_latch_vsel(vp_id - 1);
-	vpconfig = voltage_read_reg(vp_reg[vp_id - 1].vp_offs.vpconfig_reg);
+	vp_latch_vsel(vp_id);
+	vpconfig = voltage_read_reg(vp_reg[vp_id].vp_offs.vpconfig_reg);
 	/* Enable VP */
-	voltage_write_reg(vp_reg[vp_id - 1].vp_offs.vpconfig_reg,
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg,
 				vpconfig | VP_CONFIG_VPENABLE);
 }
 
@@ -551,7 +551,7 @@ void omap_voltageprocessor_disable(int vp_id)
 	u32 vpconfig;
 
 	/* Wait for VP idle before disabling VP */
-	while ((!voltage_read_reg(vp_reg[vp_id - 1].vp_offs.status_reg)) &&
+	while ((!voltage_read_reg(vp_reg[vp_id].vp_offs.status_reg)) &&
 				i++ < MAX_TRIES)
 		udelay(1);
 
@@ -559,9 +559,9 @@ void omap_voltageprocessor_disable(int vp_id)
 		pr_warning("VP1 not idle, still going ahead with \
 						VP1 disable\n");
 	/* Disable VP1 */
-	vpconfig = voltage_read_reg(vp_reg[vp_id - 1].vp_offs.vpconfig_reg);
+	vpconfig = voltage_read_reg(vp_reg[vp_id].vp_offs.vpconfig_reg);
 	vpconfig &= ~VP_CONFIG_VPENABLE;
-	voltage_write_reg(vp_reg[vp_id - 1].vp_offs.vpconfig_reg, vpconfig);
+	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg, vpconfig);
 }
 
 /**
@@ -597,19 +597,20 @@ void omap_reset_voltage(int vdd)
 	char vsel;
 
 	/* Should remove this once OPP framework is fixed */
-	if ((vdd - 1) == VP1) {
+	if (vdd == VDD1) {
 		target_uvdc = get_curr_vdd1_voltage();
 		if (!target_uvdc)
 			return;
-	} else if ((vdd - 1) == VP2) {
+	} else if (vdd == VDD2) {
 		target_uvdc = get_curr_vdd2_voltage();
 		if (!target_uvdc)
 			return;
 	} else {
-		pr_warning("Wrong VDD passed in omap_reset_voltage %d\n", vdd);
+		pr_warning("Wrong VDD passed in omap_reset_voltage %d\n",
+					vdd + 1);
 		return;
 	}
-	vsel = voltage_read_reg(vp_reg[vdd - 1].vp_offs.voltage_reg);
+	vsel = voltage_read_reg(vp_reg[vdd].vp_offs.voltage_reg);
 	current_uvdc = (vsel * 12500) + 600000;
 	omap_voltage_scale(vdd, target_uvdc, current_uvdc);
 }
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index cc3308e..2effa3e 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -10,9 +10,9 @@
  */
 #include "pm.h"
 
-/* Voltageprocessor instances */
-#define VP1	0
-#define VP2	1
+/* VoltageDomain instances */
+#define VDD1	0
+#define VDD2	1
 
 
 /* Generic VP definitions. Need to be redefined for OMAP4 */
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c
  2010-04-16  9:03                     ` [PATCHv3 11/22] OMAP3: PM: Removing VP1, VP2, SR1 and SR2 defintions Thara Gopinath
@ 2010-04-16  9:03                       ` Thara Gopinath
  2010-04-16  9:03                         ` [PATCHv3 13/22] OMAP3: PM: Cleaning up of smartreflex header file Thara Gopinath
  2010-04-27 19:02                         ` [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c Kevin Hilman
  0 siblings, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch ensures that sr id is passed as a parameter only to
public APIs in smartreflex.c and other APIs in smartreflex.c
uses the omap_sr strucutres.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |   36 +++++++++++++-----------------------
 1 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index fffd5f7..c6942e9 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -190,16 +190,8 @@ static void sr_configure(struct omap_sr *sr)
 	sr->is_sr_reset = 0;
 }
 
-static void sr_start_vddautocomp(int srid)
+static void sr_start_vddautocomp(struct omap_sr *sr)
 {
-	struct omap_sr *sr = _sr_lookup(srid);
-
-	if (!sr) {
-		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid + 1);
-		return;
-	}
-
 	if (!sr_class || !(sr_class->enable)) {
 		pr_warning("smartreflex class driver not registered\n");
 		return;
@@ -211,30 +203,22 @@ static void sr_start_vddautocomp(int srid)
 	}
 
 	sr->is_autocomp_active = 1;
-	if (!sr_class->enable(srid)) {
+	if (!sr_class->enable(sr->srid)) {
 		sr->is_autocomp_active = 0;
 		if (sr->is_sr_reset == 1)
 			sr_clk_disable(sr);
 	}
 }
 
-static void  sr_stop_vddautocomp(int srid)
+static void  sr_stop_vddautocomp(struct omap_sr *sr)
 {
-	struct omap_sr *sr = _sr_lookup(srid);
-
-	if (!sr) {
-		pr_warning("omap_sr struct corresponding to SR%d not found\n",
-								srid + 1);
-		return;
-	}
-
 	if (!sr_class || !(sr_class->disable)) {
 		pr_warning("smartreflex class driver not registered\n");
 		return;
 	}
 
 	if (sr->is_autocomp_active == 1) {
-		sr_class->disable(srid);
+		sr_class->disable(sr->srid);
 		sr_clk_disable(sr);
 		sr->is_autocomp_active = 0;
 	}
@@ -426,9 +410,9 @@ static int omap_sr_autocomp_store(void *data, u64 val)
 		return 0;
 	}
 	if (val == 0)
-		sr_stop_vddautocomp(sr_info->srid);
+		sr_stop_vddautocomp(sr_info);
 	else
-		sr_start_vddautocomp(sr_info->srid);
+		sr_start_vddautocomp(sr_info);
 	return 0;
 }
 
@@ -468,9 +452,15 @@ static int __devexit omap_smartreflex_remove(struct platform_device *pdev)
 {
 	struct omap_sr *sr_info = _sr_lookup(pdev->id + 1);
 
+	if (!sr_info) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+							pdev->id + 1);
+		return 0;
+	}
+
 	/* Disable Autocompensation if enabled before removing the module */
 	if (sr_info->is_autocomp_active == 1)
-		sr_stop_vddautocomp(sr_info->srid);
+		sr_stop_vddautocomp(sr_info);
 	list_del(&sr_info->node);
 	kfree(sr_info);
 
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 13/22] OMAP3: PM: Cleaning up of smartreflex header file.
  2010-04-16  9:03                       ` [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c Thara Gopinath
@ 2010-04-16  9:03                         ` Thara Gopinath
  2010-04-16  9:03                           ` [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3 Thara Gopinath
  2010-04-27 19:02                         ` [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c Kevin Hilman
  1 sibling, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch cleans up smartreflex.h removing all unnecessary and
duplicate definitions.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.h |   96 +++++++++++++++++++++----------------
 1 files changed, 55 insertions(+), 41 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 50d534a..85cfbe3 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -18,54 +18,38 @@
 
 extern struct dentry *pm_dbg_main_dir;
 
-#define PHY_TO_OFF_PM_RECIEVER(p)	(p - 0x5b)
-
 /* SMART REFLEX REG ADDRESS OFFSET */
-#define SRCONFIG	0x00
-#define SRSTATUS	0x04
-#define SENVAL		0x08
-#define SENMIN		0x0C
-#define SENMAX		0x10
-#define SENAVG		0x14
-#define AVGWEIGHT	0x18
+#define SRCONFIG		0x00
+#define SRSTATUS		0x04
+#define SENVAL			0x08
+#define SENMIN			0x0C
+#define SENMAX			0x10
+#define SENAVG			0x14
+#define AVGWEIGHT		0x18
 #define NVALUERECIPROCAL	0x1C
-#define SENERROR	0x20
-#define ERRCONFIG	0x24
+#define SENERROR		0x20
+#define ERRCONFIG		0x24
 
-#define GAIN_MAXLIMIT	16
-#define R_MAXLIMIT	256
-
-#define SR1_CLK_ENABLE	BIT(6)
-#define SR2_CLK_ENABLE	BIT(7)
+/* Bit/Shift Positions */
 
 /* SRCONFIG */
-#define SR1_SRCONFIG_ACCUMDATA		(0x1F4 << 22)
-#define SR2_SRCONFIG_ACCUMDATA		(0x1F4 << 22)
-
-#define SRCLKLENGTH_12MHZ_SYSCLK	0x3C
-#define SRCLKLENGTH_13MHZ_SYSCLK	0x41
-#define SRCLKLENGTH_19MHZ_SYSCLK	0x60
-#define SRCLKLENGTH_26MHZ_SYSCLK	0x82
-#define SRCLKLENGTH_38MHZ_SYSCLK	0xC0
-
+#define SRCONFIG_ACCUMDATA_SHIFT	22
 #define SRCONFIG_SRCLKLENGTH_SHIFT	12
 #define SRCONFIG_SENNENABLE_SHIFT	5
 #define SRCONFIG_SENPENABLE_SHIFT	3
+#define SRCONFIG_CLKCTRL_SHIFT		0
+
+#define SRCONFIG_ACCUMDATA_MASK		(0x3FF << 22)
 
 #define SRCONFIG_SRENABLE		BIT(11)
 #define SRCONFIG_SENENABLE		BIT(10)
 #define SRCONFIG_ERRGEN_EN		BIT(9)
 #define SRCONFIG_MINMAXAVG_EN		BIT(8)
-
 #define SRCONFIG_DELAYCTRL		BIT(2)
-#define SRCONFIG_CLKCTRL		(0x00 << 0)
 
 /* AVGWEIGHT */
-#define SR1_AVGWEIGHT_SENPAVGWEIGHT	(0x03 << 2)
-#define SR1_AVGWEIGHT_SENNAVGWEIGHT	(0x03 << 0)
-
-#define SR2_AVGWEIGHT_SENPAVGWEIGHT	BIT(2)
-#define SR2_AVGWEIGHT_SENNAVGWEIGHT	BIT(0)
+#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT	2
+#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT	0
 
 /* NVALUERECIPROCAL */
 #define NVALUERECIPROCAL_SENPGAIN_SHIFT	20
@@ -74,25 +58,55 @@ extern struct dentry *pm_dbg_main_dir;
 #define NVALUERECIPROCAL_RNSENN_SHIFT	0
 
 /* ERRCONFIG */
-#define SR_CLKACTIVITY_MASK		(0x03 << 20)
+#define ERRCONFIG_ERRWEIGHT_SHIFT	16
+#define ERRCONFIG_ERRMAXLIMIT_SHIFT	8
+#define ERRCONFIG_ERRMINLIMIT_SHIFT	0
+
 #define SR_ERRWEIGHT_MASK		(0x07 << 16)
 #define SR_ERRMAXLIMIT_MASK		(0xFF << 8)
 #define SR_ERRMINLIMIT_MASK		(0xFF << 0)
 
 #define ERRCONFIG_VPBOUNDINTEN		BIT(31)
 #define ERRCONFIG_VPBOUNDINTST		BIT(30)
+#define	ERRCONFIG_MCUACCUMINTEN		BIT(29)
+#define ERRCONFIG_MCUACCUMINTST		BIT(28)
+#define	ERRCONFIG_MCUVALIDINTEN		BIT(27)
+#define ERRCONFIG_MCUVALIDINTST		BIT(26)
+#define ERRCONFIG_MCUBOUNDINTEN		BIT(25)
+#define	ERRCONFIG_MCUBOUNDINTST		BIT(24)
+#define	ERRCONFIG_MCUDISACKINTEN	BIT(23)
+#define ERRCONFIG_MCUDISACKINTST	BIT(22)
 
-#define SR1_ERRWEIGHT			(0x07 << 16)
-#define SR1_ERRMAXLIMIT			(0x02 << 8)
-#define SR1_ERRMINLIMIT			(0xFA << 0)
+/* Common Bit values */
 
-#define SR2_ERRWEIGHT			(0x07 << 16)
-#define SR2_ERRMAXLIMIT			(0x02 << 8)
-#define SR2_ERRMINLIMIT			(0xF9 << 0)
+#define SRCLKLENGTH_12MHZ_SYSCLK	0x3C
+#define SRCLKLENGTH_13MHZ_SYSCLK	0x41
+#define SRCLKLENGTH_19MHZ_SYSCLK	0x60
+#define SRCLKLENGTH_26MHZ_SYSCLK	0x82
+#define SRCLKLENGTH_38MHZ_SYSCLK	0xC0
 
-/* Vmode control */
-#define R_DCDC_GLOBAL_CFG	PHY_TO_OFF_PM_RECIEVER(0x61)
+/*
+ * 3430 specific values. Maybe these should be passed from board file or
+ * pmic structures.
+ */
+#define OMAP3430_SR_ACCUMDATA		0x1F4
+
+#define OMAP3430_SR1_SENPAVGWEIGHT	0x03
+#define OMAP3430_SR1_SENNAVGWEIGHT	0x03
+
+#define OMAP3430_SR2_SENPAVGWEIGHT	0x01
+#define OMAP3430_SR2_SENNAVGWEIGHT	0x01
+
+#define OMAP3430_SR_ERRWEIGHT		0x07
+#define OMAP3430_SR_ERRMAXLIMIT		0x02
+#define OMAP3430_SR1_ERRMINLIMIT	0xFA
+#define OMAP3430_SR2_ERRMINLIMIT	0xF9
 
+/* TODO:3630/OMAP4 values if it has to come from this file */
+
+/* Info for enabling SR in T2/gaia. ToDo: Move it to twl4030_power.c */
+#define PHY_TO_OFF_PM_RECIEVER(p)	(p - 0x5b)
+#define R_DCDC_GLOBAL_CFG	PHY_TO_OFF_PM_RECIEVER(0x61)
 /* R_DCDC_GLOBAL_CFG register, SMARTREFLEX_ENABLE values */
 #define DCDC_GLOBAL_CFG_ENABLE_SRFLX	0x08
 
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3
  2010-04-16  9:03                         ` [PATCHv3 13/22] OMAP3: PM: Cleaning up of smartreflex header file Thara Gopinath
@ 2010-04-16  9:03                           ` Thara Gopinath
  2010-04-16  9:03                             ` [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default Thara Gopinath
  2010-04-27 19:06                             ` [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3 Kevin Hilman
  0 siblings, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

There are two separate modules in SmartReflex-AVS :
MinMaxAvg module and Error module. Class3 uses the Error module only.
In Class2 you can choose between either module since it is software based.
The registers are mapped to the modules as followed:

MinMaxAvg module: AccumData, MinMaxAvgEnable, MinMaxAvgValid,
        MinMaxAvgAccumValid, SenVal, SenMin, SenMax, SenAverage,
        AverageWeight, MCUAccum, MCUValid, MCUBounds.

Error module: SenNGain, SenPGain, SenPRN, SenNRN, AvgError,
        SenError, VPBounds, ErrWeight, ErrMaxLimit, ErrMinLimit.

Shared between both: SRClkLength, SREnable, SenEnable, SenNEnable,
        SenPEnable, DelayCtrl, MCUDisableAck, ClkActivity.

This patch generates separate API's to configure the two modules
which can be used by the smartreflex class driver as per its
requirement. This patch allows allows for registering for smartreflex
interrupt handler and notification of interrupts in case requested by
the smartreflex class driver.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex-class3.c |    7 +
 arch/arm/mach-omap2/smartreflex.c        |  253 +++++++++++++++++++++++-------
 arch/arm/mach-omap2/smartreflex.h        |   14 ++
 3 files changed, 219 insertions(+), 55 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index 66696be..53bfd05 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -39,10 +39,17 @@ static int sr_class3_disable(int id)
 	return true;
 }
 
+static void sr_class3_configure(int id)
+{
+	sr_configure_errgen(id);
+}
+
 /* SR class3 structure */
 struct omap_smartreflex_class_data class3_data = {
 	.enable = sr_class3_enable,
 	.disable = sr_class3_disable,
+	.configure = sr_class3_configure,
+	.class_type = SR_CLASS3,
 };
 
 int __init sr_class3_init(void)
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index c6942e9..d043951 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -41,6 +41,12 @@ struct omap_sr {
 	int			is_sr_reset;
 	int			is_autocomp_active;
 	u32			clk_length;
+	u32			err_weight;
+	u32			err_minlimit;
+	u32			err_maxlimit;
+	u32			accum_data;
+	u32			senn_avgweight;
+	u32			senp_avgweight;
 	unsigned int		irq;
 	struct platform_device	*pdev;
 	struct list_head	node;
@@ -111,6 +117,24 @@ static void sr_clk_disable(struct omap_sr *sr)
 	sr->is_sr_reset = 1;
 }
 
+static irqreturn_t sr_omap_isr(int irq, void *data)
+{
+	struct omap_sr *sr_info = (struct omap_sr *)data;
+	u32 status;
+
+	/* Read the status bits */
+	status = sr_read_reg(sr_info, ERRCONFIG);
+
+	/* Clear them by writing back */
+	sr_write_reg(sr_info, ERRCONFIG, status);
+
+	/* Call the class driver notify function if registered*/
+	if (sr_class->class_type == SR_CLASS2 && sr_class->notify)
+		sr_class->notify(sr_info->srid, status);
+
+	return IRQ_HANDLED;
+}
+
 static void sr_set_clk_length(struct omap_sr *sr)
 {
 	struct clk *sys_ck;
@@ -142,64 +166,41 @@ static void sr_set_clk_length(struct omap_sr *sr)
 	}
 }
 
-static void sr_configure(struct omap_sr *sr)
+static void sr_set_regfields(struct omap_sr *sr)
 {
-	u32 sr_config;
-	u32 senp_en , senn_en;
-	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
-
-	if (sr->clk_length == 0)
-		sr_set_clk_length(sr);
-
-	senp_en = pdata->senp_mod;
-	senn_en = pdata->senn_mod;
-	if (sr->srid == VDD1) {
-		sr_config = SR1_SRCONFIG_ACCUMDATA |
-			(sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
-			SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
-			SRCONFIG_MINMAXAVG_EN |
-			(senn_en << SRCONFIG_SENNENABLE_SHIFT) |
-			(senp_en << SRCONFIG_SENPENABLE_SHIFT) |
-			SRCONFIG_DELAYCTRL;
-
-		sr_write_reg(sr, SRCONFIG, sr_config);
-		sr_write_reg(sr, AVGWEIGHT, SR1_AVGWEIGHT_SENPAVGWEIGHT |
-					SR1_AVGWEIGHT_SENNAVGWEIGHT);
-
-		sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
-			SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
-			(SR1_ERRWEIGHT | SR1_ERRMAXLIMIT | SR1_ERRMINLIMIT));
-
-	} else if (sr->srid == VDD2) {
-		sr_config = SR2_SRCONFIG_ACCUMDATA |
-			(sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
-			SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
-			SRCONFIG_MINMAXAVG_EN |
-			(senn_en << SRCONFIG_SENNENABLE_SHIFT) |
-			(senp_en << SRCONFIG_SENPENABLE_SHIFT) |
-			SRCONFIG_DELAYCTRL;
-
-		sr_write_reg(sr, SRCONFIG, sr_config);
-		sr_write_reg(sr, AVGWEIGHT, SR2_AVGWEIGHT_SENPAVGWEIGHT |
-					SR2_AVGWEIGHT_SENNAVGWEIGHT);
-		sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
-			SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
-			(SR2_ERRWEIGHT | SR2_ERRMAXLIMIT | SR2_ERRMINLIMIT));
-
+	/*
+	 * For time being these values are defined in smartreflex.h
+	 * and populated during init. May be they can be moved to board
+	 * file or pmic specific data structure. In that case these structure
+	 * fields will have to be populated using the pdata or pmic structure.
+	 */
+	if (cpu_is_omap343x()) {
+		sr->err_weight = OMAP3430_SR_ERRWEIGHT;
+		sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
+		sr->accum_data = OMAP3430_SR_ACCUMDATA;
+		if (sr->srid == VDD1) {
+			sr->err_minlimit = OMAP3430_SR1_ERRMINLIMIT;
+			sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
+			sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
+		} else {
+			sr->err_minlimit = OMAP3430_SR2_ERRMINLIMIT;
+			sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
+			sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
+		}
 	}
-	sr->is_sr_reset = 0;
+	/* TODO: 3630 and Omap4 specific bit field values */
 }
 
 static void sr_start_vddautocomp(struct omap_sr *sr)
 {
-	if (!sr_class || !(sr_class->enable)) {
+	if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
 		pr_warning("smartreflex class driver not registered\n");
 		return;
 	}
 
 	if (sr->is_sr_reset == 1) {
 		sr_clk_enable(sr);
-		sr_configure(sr);
+		sr_class->configure(sr->srid);
 	}
 
 	sr->is_autocomp_active = 1;
@@ -224,9 +225,139 @@ static void  sr_stop_vddautocomp(struct omap_sr *sr)
 	}
 }
 
+/*
+ * This function handles the intializations which have to be done
+ * only when both sr device and class driver regiter has
+ * completed. This will be attempted to be called from both sr class
+ * driver register and sr device intializtion API's. Only one call
+ * will ultimately succeed.
+ *
+ * Currenly this function registers interrrupt handler for a particular SR
+ * if smartreflex class driver is already registered and has
+ * requested for interrupts and the SR interrupt line in present.
+ */
+static int sr_late_init(struct omap_sr *sr_info)
+{
+	char name[SMARTREFLEX_NAME_LEN];
+	int ret = 0;
+
+	if (sr_class->class_type == SR_CLASS2 &&
+		sr_class->notify_flags && sr_info->irq) {
+
+		sprintf(name, "sr%d", sr_info->srid);
+		ret = request_irq(sr_info->irq, sr_omap_isr,
+				IRQF_DISABLED, name, (void *)sr_info);
+		if (ret < 0)
+			pr_warning("ERROR in registering interrupt \
+				handler for SR%d. Smartreflex will \
+				not function as desired\n", sr_info->srid);
+	}
+	return ret;
+}
+
 /* Public Functions */
 
 /**
+ * sr_configure_errgen : Configures the smrtreflex to perform AVS using the
+ *			 error generator module.
+ * @srid - The id of the sr module to be configured.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * configure the error generator module inside the smartreflex module.
+ * SR settings if using the ERROR module inside Smartreflex.
+ * SR CLASS 3 by default uses only the ERROR module where as
+ * SR CLASS 2 can choose between ERROR module and MINMAXAVG
+ * module.
+ */
+void sr_configure_errgen(int srid)
+{
+	u32 sr_config, sr_errconfig;
+	u32 senp_en , senn_en;
+	struct omap_sr *sr = _sr_lookup(srid);
+	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
+
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid + 1);
+		return;
+	}
+
+	if (sr->clk_length == 0)
+		sr_set_clk_length(sr);
+
+	senp_en = pdata->senp_mod;
+	senn_en = pdata->senn_mod;
+	sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
+		SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
+		(senn_en << SRCONFIG_SENNENABLE_SHIFT) |
+		(senp_en << SRCONFIG_SENPENABLE_SHIFT) | SRCONFIG_DELAYCTRL;
+	sr_write_reg(sr, SRCONFIG, sr_config);
+	sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) |
+		(sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) |
+		(sr->err_minlimit <<  ERRCONFIG_ERRMINLIMIT_SHIFT);
+	sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
+		SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
+		sr_errconfig);
+	/* Enabling the interrupts if the ERROR module is used */
+	sr_modify_reg(sr, ERRCONFIG,
+		(ERRCONFIG_VPBOUNDINTEN),
+		(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
+	sr->is_sr_reset = 0;
+}
+
+/**
+ * sr_configure_minmax : Configures the smrtreflex to perform AVS using the
+ *			 minmaxavg module.
+ * @srid - The id of the sr module to be configured.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * configure the minmaxavg module inside the smartreflex module.
+ * SR settings if using the ERROR module inside Smartreflex.
+ * SR CLASS 3 by default uses only the ERROR module where as
+ * SR CLASS 2 can choose between ERROR module and MINMAXAVG
+ * module.
+ */
+void sr_configure_minmax(int srid)
+{
+	u32 sr_config, sr_avgwt;
+	u32 senp_en , senn_en;
+	struct omap_sr *sr = _sr_lookup(srid);
+	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
+
+	if (!sr) {
+		pr_warning("omap_sr struct corresponding to SR%d not found\n",
+								srid + 1);
+		return;
+	}
+
+	if (sr->clk_length == 0)
+		sr_set_clk_length(sr);
+
+	senp_en = pdata->senp_mod;
+	senn_en = pdata->senn_mod;
+	sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
+		SRCONFIG_SENENABLE | (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
+		(senp_en << SRCONFIG_SENPENABLE_SHIFT) |
+		(sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT) |
+		SRCONFIG_DELAYCTRL;
+	sr_write_reg(sr, SRCONFIG, sr_config);
+	sr_avgwt = (sr->senp_avgweight << AVGWEIGHT_SENPAVGWEIGHT_SHIFT) |
+		(sr->senn_avgweight << AVGWEIGHT_SENNAVGWEIGHT_SHIFT);
+	sr_write_reg(sr, AVGWEIGHT, sr_avgwt);
+	/*
+	 * Enabling the interrupts if MINMAXAVG module is used.
+	 * TODO: check if all the interrupts are mandatory
+	 */
+	sr_modify_reg(sr, ERRCONFIG,
+		(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
+		ERRCONFIG_MCUBOUNDINTEN),
+		(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
+		 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
+		 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
+	sr->is_sr_reset = 0;
+}
+
+/**
  * sr_enable : Enables the smartreflex module.
  * @srid - The id of the sr module to be enabled.
  * @volt - The voltage at which the Voltage domain associated with
@@ -261,12 +392,6 @@ int sr_enable(int srid, unsigned long volt)
 	}
 
 	sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
-
-	/* Enable the interrupt */
-	sr_modify_reg(sr, ERRCONFIG,
-			(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
-			(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
-
 	/* SRCONFIG - enable SR */
 	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
 	return true;
@@ -315,7 +440,7 @@ void omap_smartreflex_enable(int srid)
 		return;
 	}
 
-	if (!sr_class || !(sr_class->enable)) {
+	if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
 		pr_warning("smartreflex class driver not registered\n");
 		return;
 	}
@@ -324,7 +449,7 @@ void omap_smartreflex_enable(int srid)
 		if (sr->is_sr_reset == 1) {
 			/* Enable SR clks */
 			sr_clk_enable(sr);
-			sr_configure(sr);
+			sr_class->configure(srid);
 			if (!sr_class->enable(srid))
 				sr_clk_disable(sr);
 		}
@@ -373,6 +498,8 @@ void omap_smartreflex_disable(int srid)
  */
 void omap_sr_register_class(struct omap_smartreflex_class_data *class_data)
 {
+	struct omap_sr *sr_info;
+
 	if (!class_data) {
 		pr_warning("Smartreflex class data passed is NULL\n");
 		return;
@@ -382,7 +509,15 @@ void omap_sr_register_class(struct omap_smartreflex_class_data *class_data)
 		pr_warning("Smartreflex class driver already registered\n");
 		return;
 	}
+
 	sr_class = class_data;
+
+	/*
+	 * Call into late init to do intializations that require
+	 * both sr driver and sr class driver to be initiallized.
+	 */
+	list_for_each_entry(sr_info, &sr_list, node)
+		sr_late_init(sr_info);
 }
 
 /* PM Debug Fs enteries to enable disable smartreflex.*/
@@ -436,6 +571,7 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 	if (odev->hwmods[0]->mpu_irqs)
 		sr_info->irq = odev->hwmods[0]->mpu_irqs[0].irq;
 	sr_set_clk_length(sr_info);
+	sr_set_regfields(sr_info);
 
 	/* Create the debug fs enteries */
 	sprintf(name, "sr%d_autocomp", sr_info->srid + 1);
@@ -443,8 +579,15 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 				(void *)sr_info, &pm_sr_fops);
 
 	list_add(&sr_info->node, &sr_list);
-	pr_info("SmartReflex driver initialized\n");
 
+	/*
+	 * Call into late init to do intializations that require
+	 * both sr driver and sr class driver to be initiallized.
+	 */
+	if (sr_class)
+		ret = sr_late_init(sr_info);
+
+	pr_info("SmartReflex driver initialized\n");
 	return ret;
 }
 
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 85cfbe3..0cdee6e 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -151,12 +151,23 @@ struct omap_smartreflex_dev_data {
 };
 
 #ifdef CONFIG_OMAP_SMARTREFLEX
+/*
+ * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
+ * The smartreflex class driver should pass the class type.
+ * Should be used to populate the class_type field of the
+ * omap_smartreflex_class_data structure.
+ */
+#define SR_CLASS1	0x1
+#define SR_CLASS2	0x2
+#define SR_CLASS3	0x3
+
 /**
  * omap_smartreflex_class_data : Structure to be populated by
  * Smartreflex class driver with corresponding class enable disable API's
  *
  * @enable - API to enable a particular class smaartreflex.
  * @disable - API to disable a particular class smartreflex.
+ * @configure - API to configure a particular class smartreflex.
  * @notify - API to notify the class driver about an event in SR. Not needed
  *		for class3.
  * @notify_flags - specify the events to be notified to the class driver
@@ -166,6 +177,7 @@ struct omap_smartreflex_dev_data {
 struct omap_smartreflex_class_data {
 	int (*enable)(int sr_id);
 	int (*disable)(int sr_id);
+	void (*configure)(int sr_id);
 	int (*notify)(int sr_id, u32 status);
 	u8 notify_flags;
 	u8 class_type;
@@ -207,6 +219,8 @@ void omap_smartreflex_disable(int srid);
  */
 int sr_enable(int srid, unsigned long volt);
 void sr_disable(int srid);
+void sr_configure_errgen(int srid);
+void sr_configure_minmax(int srid);
 
 /*
  * API to register the smartreflex class driver with the smartreflex driver
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default.
  2010-04-16  9:03                           ` [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3 Thara Gopinath
@ 2010-04-16  9:03                             ` Thara Gopinath
  2010-04-16  9:03                               ` [PATCHv3 16/22] OMAP3: PM: Correcting accessing of ERRCONFIG register in smartreflex.c Thara Gopinath
  2010-04-27 19:10                               ` [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default Kevin Hilman
  2010-04-27 19:06                             ` [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3 Kevin Hilman
  1 sibling, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch adds support to pdata enable smartreflex autocompenstion
during init based on enable_on_init flag passed as pdata.

This patch also adds enabling of autocompensation by
default (setting enable_on_init  flag to true) in case of ES3.1
OMAP3430 chip. In the current implementation
this step is kept in smartreflex.c itself.Later an API can be added
so that the decision to enable autocompensation by default
can be passed from the corresponding board files.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |    5 +++++
 arch/arm/mach-omap2/sr_device.c   |   16 +++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index d043951..56a8005 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -239,6 +239,7 @@ static void  sr_stop_vddautocomp(struct omap_sr *sr)
 static int sr_late_init(struct omap_sr *sr_info)
 {
 	char name[SMARTREFLEX_NAME_LEN];
+	struct omap_smartreflex_data *pdata = sr_info->pdev->dev.platform_data;
 	int ret = 0;
 
 	if (sr_class->class_type == SR_CLASS2 &&
@@ -252,6 +253,10 @@ static int sr_late_init(struct omap_sr *sr_info)
 				handler for SR%d. Smartreflex will \
 				not function as desired\n", sr_info->srid);
 	}
+
+	if (pdata->enable_on_init)
+		sr_start_vddautocomp(sr_info);
+
 	return ret;
 }
 
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index c9b6533..7cb1fc7 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -117,7 +117,21 @@ static int __init omap_devinit_smartreflex(void)
 		if (WARN_ON(!sr_data))
 			return -ENOMEM;
 
-		sr_data->enable_on_init = false;
+		/*
+		 * OMAP3430 ES3.1 chips by default come with Efuse burnt
+		 * with parameters required for full functionality of
+		 * smartreflex AVS feature like ntarget values , sennenable
+		 * and senpenable. So enable the SR AVS feature during boot up
+		 * itself if it is a OMAP3430 ES3.1 chip.
+		 */
+		if (cpu_is_omap343x()) {
+			if (omap_rev() == OMAP3430_REV_ES3_1)
+				sr_data->enable_on_init = true;
+			else
+				sr_data->enable_on_init = false;
+		} else {
+			sr_data->enable_on_init = false;
+		}
 		sr_data->device_enable = omap_device_enable;
 		sr_data->device_shutdown = omap_device_shutdown;
 		sr_data->device_idle = omap_device_idle;
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 16/22] OMAP3: PM: Correcting accessing of ERRCONFIG register in smartreflex.c
  2010-04-16  9:03                             ` [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default Thara Gopinath
@ 2010-04-16  9:03                               ` Thara Gopinath
  2010-04-16  9:03                                 ` [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence Thara Gopinath
  2010-04-27 19:10                               ` [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default Kevin Hilman
  1 sibling, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

Smartreflex error config register is special as it contains
certain status bits which if written a 1 into means a clear
of those bits. This patch takes special care during modify of
this register that no status bits in this register are accidently
set to 1.

This issue was first reported by Nishanth Menon.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |   11 +++++++++++
 arch/arm/mach-omap2/smartreflex.h |    6 ++++++
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 56a8005..da7f534 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -71,6 +71,17 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
 
 	reg_val = omap_hwmod_readl(odev->hwmods[0], offset);
 	reg_val &= ~mask;
+	/*
+	 * Smartreflex error config register is special as it contains
+	 * certain status bits which if written a 1 into means a clear
+	 * of those bits. So in order to make sure no accidental write of
+	 * 1 happens to those status bits, do a clear of them in the read
+	 * value. Now if there is an actual reguest to write to these bits
+	 * they will be set in the nex step.
+	 */
+	if (offset == ERRCONFIG)
+		reg_val &= ~ERRCONFIG_STATUS_MASK;
+
 	reg_val |= value;
 
 	omap_hwmod_writel(reg_val, odev->hwmods[0], offset);
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 0cdee6e..823aea0 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -77,6 +77,12 @@ extern struct dentry *pm_dbg_main_dir;
 #define	ERRCONFIG_MCUDISACKINTEN	BIT(23)
 #define ERRCONFIG_MCUDISACKINTST	BIT(22)
 
+#define ERRCONFIG_STATUS_MASK		(ERRCONFIG_VPBOUNDINTST | \
+					ERRCONFIG_MCUACCUMINTST | \
+					ERRCONFIG_MCUVALIDINTST | \
+					ERRCONFIG_MCUBOUNDINTST | \
+					ERRCONFIG_MCUDISACKINTST)
+
 /* Common Bit values */
 
 #define SRCLKLENGTH_12MHZ_SYSCLK	0x3C
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence.
  2010-04-16  9:03                               ` [PATCHv3 16/22] OMAP3: PM: Correcting accessing of ERRCONFIG register in smartreflex.c Thara Gopinath
@ 2010-04-16  9:03                                 ` Thara Gopinath
  2010-04-16  9:03                                   ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Thara Gopinath
  2010-04-27 19:12                                   ` [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence Kevin Hilman
  0 siblings, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch introduces OMAP3 specific values for Smartreflex and
Voltage processor registers as per the latest TI recommendations.
This patch adds smartreflex errminlimit and voltage processor
errorgain into the voltage tables as they vary with different
voltages. This patch also improves the smartreflex and voltage
processor enable disable sequences as per the latest recommendations.

These recommendations were first formed based on experimentations
on N900 platform  and were implemented in the N900 codebase
base first by Nishanth Menon and Paul Walmsley.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |   54 +++++++++++++++----
 arch/arm/mach-omap2/smartreflex.h |    4 +-
 arch/arm/mach-omap2/voltage.c     |  103 +++++++++++++++++++++++++++++-------
 arch/arm/mach-omap2/voltage.h     |   25 ++++++---
 4 files changed, 142 insertions(+), 44 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index da7f534..eed7f9b 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -27,14 +27,17 @@
 #include <linux/io.h>
 #include <linux/list.h>
 #include <linux/debugfs.h>
+#include <linux/delay.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
+#include <plat/common.h>
 
 #include "voltage.h"
 #include "smartreflex.h"
 
 #define SMARTREFLEX_NAME_LEN	16
+#define SR_DISABLE_TIMEOUT	200
 
 struct omap_sr {
 	int			srid;
@@ -190,11 +193,9 @@ static void sr_set_regfields(struct omap_sr *sr)
 		sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
 		sr->accum_data = OMAP3430_SR_ACCUMDATA;
 		if (sr->srid == VDD1) {
-			sr->err_minlimit = OMAP3430_SR1_ERRMINLIMIT;
 			sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
 			sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
 		} else {
-			sr->err_minlimit = OMAP3430_SR2_ERRMINLIMIT;
 			sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
 			sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
 		}
@@ -209,11 +210,6 @@ static void sr_start_vddautocomp(struct omap_sr *sr)
 		return;
 	}
 
-	if (sr->is_sr_reset == 1) {
-		sr_clk_enable(sr);
-		sr_class->configure(sr->srid);
-	}
-
 	sr->is_autocomp_active = 1;
 	if (!sr_class->enable(sr->srid)) {
 		sr->is_autocomp_active = 0;
@@ -407,6 +403,13 @@ int sr_enable(int srid, unsigned long volt)
 		return false;
 	}
 
+	/* errminlimit is opp dependent and hence linked to voltage */
+	sr->err_minlimit = volt_data.sr_errminlimit;
+
+	/* Enable the clocks and configure SR */
+	sr_clk_enable(sr);
+	sr_class->configure(sr->srid);
+
 	sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
 	/* SRCONFIG - enable SR */
 	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
@@ -423,6 +426,7 @@ int sr_enable(int srid, unsigned long volt)
 void sr_disable(int srid)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
+	int timeout = 0;
 
 	if (!sr) {
 		pr_warning("omap_sr struct corresponding to SR%d not found\n",
@@ -430,10 +434,39 @@ void sr_disable(int srid)
 		return;
 	}
 
-	sr->is_sr_reset = 1;
+	/* Check if SR is already disabled. If yes do nothing */
+	if (!(sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE))
+		return;
+
+	/* Enable MCUDisableAcknowledge interrupt */
+	sr_modify_reg(sr, ERRCONFIG,
+			ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
+
 	/* SRCONFIG - disable SR */
-	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
+	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
+
+	/* Disable all other SR interrupts and clear the status */
+	sr_modify_reg(sr, ERRCONFIG,
+			(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
+			ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN),
+			(ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
+			ERRCONFIG_MCUBOUNDINTST | ERRCONFIG_VPBOUNDINTST));
 
+	/* Wait for SR to be disabled.
+	 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
+	 */
+	omap_test_timeout((sr_read_reg(sr, ERRCONFIG) &
+			ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
+			timeout);
+
+	if (timeout >= SR_DISABLE_TIMEOUT)
+		pr_warning("SR%d disable timedout\n", srid);
+
+	/* Disable MCUDisableAcknowledge interrupt & clear pending interrupt
+	 * Also enable VPBOUND interrrupt
+	 */
+	sr_modify_reg(sr, ERRCONFIG, ERRCONFIG_MCUDISACKINTEN,
+			ERRCONFIG_MCUDISACKINTST);
 }
 
 /**
@@ -463,9 +496,6 @@ void omap_smartreflex_enable(int srid)
 
 	if (sr->is_autocomp_active == 1) {
 		if (sr->is_sr_reset == 1) {
-			/* Enable SR clks */
-			sr_clk_enable(sr);
-			sr_class->configure(srid);
 			if (!sr_class->enable(srid))
 				sr_clk_disable(sr);
 		}
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 823aea0..9cc3204 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -103,10 +103,8 @@ extern struct dentry *pm_dbg_main_dir;
 #define OMAP3430_SR2_SENPAVGWEIGHT	0x01
 #define OMAP3430_SR2_SENNAVGWEIGHT	0x01
 
-#define OMAP3430_SR_ERRWEIGHT		0x07
+#define OMAP3430_SR_ERRWEIGHT		0x04
 #define OMAP3430_SR_ERRMAXLIMIT		0x02
-#define OMAP3430_SR1_ERRMINLIMIT	0xFA
-#define OMAP3430_SR2_ERRMINLIMIT	0xF9
 
 /* TODO:3630/OMAP4 values if it has to come from this file */
 
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 7777e28..05b0b78 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -29,11 +29,12 @@
 #include <plat/opp.h>
 #include <plat/opp_twl_tps.h>
 #include <plat/clock.h>
+#include <plat/common.h>
 
 #include "prm-regbits-34xx.h"
 #include "voltage.h"
 
-#define MAX_TRIES 100
+#define VP_IDLE_TIMEOUT		200
 
 /**
  * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
@@ -151,18 +152,18 @@ static struct prm_setup_vc vc_config = {
 
 /* VDD1 */
 static struct omap_volt_data omap34xx_vdd1_volt_data[] = {
-	{975000, 0},
-	{1075000, 0},
-	{1200000, 0},
-	{1270000, 0},
-	{1350000, 0},
+	{975000, 0, 0xF4, 0x0C},
+	{1075000, 0, 0xF4, 0x0C},
+	{1200000, 0, 0xF9, 0x18},
+	{1270000, 0, 0xF9, 0x18},
+	{1350000, 0, 0xF9, 0x18},
 };
 
 /* VDD2 */
 static struct omap_volt_data omap34xx_vdd2_volt_data[] = {
-	{975000, 0},
-	{1050000, 0},
-	{1150000, 0},
+	{975000, 0, 0xF4, 0x0C},
+	{1050000, 0, 0xF4, 0x0C},
+	{1150000, 0, 0xF9, 0x18},
 };
 
 static inline u32 voltage_read_reg(u8 offset)
@@ -309,11 +310,17 @@ static void __init vp_configure(int vp_id)
 static void __init vp_data_configure(int vp_id)
 {
 	if (cpu_is_omap34xx()) {
+		unsigned long curr_volt;
+		struct omap_volt_data volt_data;
+		struct clk *sys_ck;
+		u32 sys_clk_speed, timeout_val;
+
 		vp_reg[vp_id].vp_offs = omap3_vp_offs[vp_id];
 		if (vp_id == VDD1) {
 			vp_reg[vp_id].volt_data = omap34xx_vdd1_volt_data;
 			vp_reg[vp_id].volt_data_count =
 					ARRAY_SIZE(omap34xx_vdd1_volt_data);
+			curr_volt = get_curr_vdd1_voltage();
 			vp_reg[vp_id].vp_vddmin = (OMAP3_VP1_VLIMITTO_VDDMIN <<
 					OMAP3430_VDDMIN_SHIFT);
 			vp_reg[vp_id].vp_vddmax = (OMAP3_VP1_VLIMITTO_VDDMAX <<
@@ -322,6 +329,7 @@ static void __init vp_data_configure(int vp_id)
 			vp_reg[vp_id].volt_data = omap34xx_vdd2_volt_data;
 			vp_reg[vp_id].volt_data_count =
 					ARRAY_SIZE(omap34xx_vdd2_volt_data);
+			curr_volt = get_curr_vdd2_voltage();
 			vp_reg[vp_id].vp_vddmin = (OMAP3_VP2_VLIMITTO_VDDMIN <<
 					OMAP3430_VDDMIN_SHIFT);
 			vp_reg[vp_id].vp_vddmax = (OMAP3_VP2_VLIMITTO_VDDMAX <<
@@ -331,9 +339,16 @@ static void __init vp_data_configure(int vp_id)
 					in OMAP3 \n", vp_id);
 			return;
 		}
+
+		if (omap_match_volt(vp_id, curr_volt, &volt_data)) {
+			pr_err("Unable to get voltage table for VDD%d during \
+				vp configure. Some really Wrong !", vp_id + 1);
+			return;
+		}
+
 		vp_reg[vp_id].vp_erroroffset = (OMAP3_VP_CONFIG_ERROROFFSET <<
 					OMAP3430_INITVOLTAGE_SHIFT);
-		vp_reg[vp_id].vp_errorgain = (OMAP3_VP_CONFIG_ERRORGAIN <<
+		vp_reg[vp_id].vp_errorgain = (volt_data.vp_errorgain <<
 					OMAP3430_ERRORGAIN_SHIFT);
 		vp_reg[vp_id].vp_smpswaittimemin =
 					(OMAP3_VP_VSTEPMIN_SMPSWAITTIMEMIN <<
@@ -345,7 +360,23 @@ static void __init vp_data_configure(int vp_id)
 					OMAP3430_VSTEPMIN_SHIFT);
 		vp_reg[vp_id].vp_stepmax = (OMAP3_VP_VSTEPMAX_VSTEPMAX <<
 					OMAP3430_VSTEPMAX_SHIFT);
-		vp_reg[vp_id].vp_timeout = (OMAP3_VP_VLIMITTO_TIMEOUT <<
+		/*
+		 * Use sys clk speed to convert the VP timeout in us to
+		 * number of clock cycles
+		 */
+		sys_ck = clk_get(NULL, "sys_ck");
+		if (IS_ERR(sys_ck)) {
+			pr_warning("Could not get the sys clk to calculate \
+					timeout value for VP %d\n", vp_id + 1);
+			return;
+		}
+		sys_clk_speed = clk_get_rate(sys_ck);
+		clk_put(sys_ck);
+		/* Divide to avoid overflow */
+		sys_clk_speed /= 1000;
+		timeout_val = (sys_clk_speed * OMAP3_VP_VLIMITTO_TIMEOUT_US) /
+					1000;
+		vp_reg[vp_id].vp_timeout = (timeout_val <<
 					OMAP3430_TIMEOUT_SHIFT);
 	}
 	/* TODO Extend this for OMAP4 ?? Or need a separate file  */
@@ -391,6 +422,26 @@ static int vc_bypass_scale_voltage(u32 vdd, unsigned long target_volt,
 		return false;
 	}
 
+	/* OMAP3430 has errorgain varying btw various opp's */
+	if (cpu_is_omap34xx()) {
+		struct omap_volt_data volt_data;
+		u32 errorgain = voltage_read_reg(vp_reg[vdd].vp_offs.
+					vpconfig_reg);
+
+		if (omap_match_volt(vdd, target_volt, &volt_data)) {
+			pr_warning("Unable to get voltage table for VDD%d \
+				during voltage scaling. Some really Wrong!",
+				vdd + 1);
+			return false;
+		}
+		vp_reg[vdd].vp_errorgain = volt_data.vp_errorgain <<
+			OMAP3430_ERRORGAIN_SHIFT;
+		errorgain &= ~VP_ERRORGAIN_MASK;
+		errorgain |= vp_reg[vdd].vp_errorgain;
+		voltage_write_reg(vp_reg[vdd].vp_offs.vpconfig_reg,
+				errorgain);
+	}
+
 	vc_bypass_value = (target_vsel << VC_DATA_SHIFT) |
 			(reg_addr << VC_REGADDR_SHIFT) |
 			(R_SRI2C_SLAVE_ADDR << VC_SLAVEADDR_SHIFT);
@@ -527,6 +578,10 @@ void omap_voltageprocessor_enable(int vp_id)
 {
 	u32 vpconfig;
 
+	/* If VP is already enabled, do nothing. Return */
+	if (voltage_read_reg(vp_reg[vp_id].vp_offs.vpconfig_reg) &
+				VP_CONFIG_VPENABLE)
+		return;
 	/*
 	 * This latching is required only if VC bypass method is used for
 	 * voltage scaling during dvfs.
@@ -547,21 +602,29 @@ void omap_voltageprocessor_enable(int vp_id)
  */
 void omap_voltageprocessor_disable(int vp_id)
 {
-	int i = 0;
 	u32 vpconfig;
+	int timeout;
 
-	/* Wait for VP idle before disabling VP */
-	while ((!voltage_read_reg(vp_reg[vp_id].vp_offs.status_reg)) &&
-				i++ < MAX_TRIES)
-		udelay(1);
+	/* If VP is already disabled, do nothing. Return */
+	if (!(voltage_read_reg(vp_reg[vp_id].vp_offs.vpconfig_reg) &
+				VP_CONFIG_VPENABLE))
+		return;
 
-	if (i >= MAX_TRIES)
-		pr_warning("VP1 not idle, still going ahead with \
-						VP1 disable\n");
-	/* Disable VP1 */
+	/* Disable VP */
 	vpconfig = voltage_read_reg(vp_reg[vp_id].vp_offs.vpconfig_reg);
 	vpconfig &= ~VP_CONFIG_VPENABLE;
 	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg, vpconfig);
+
+	/*
+	 * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
+	 */
+	omap_test_timeout((voltage_read_reg
+			(vp_reg[vp_id].vp_offs.status_reg)),
+			VP_IDLE_TIMEOUT, timeout);
+
+	if (timeout >= VP_IDLE_TIMEOUT)
+		pr_warning("VP%d idle timedout\n", vp_id);
+	return;
 }
 
 /**
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 2effa3e..8800369 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -20,6 +20,7 @@
 #define VP_CONFIG_INITVDD	OMAP3430_INITVDD
 #define VP_FORCEUPDATE		OMAP3430_FORCEUPDATE
 #define VP_CONFIG_VPENABLE	OMAP3430_VPENABLE
+#define VP_ERRORGAIN_MASK	OMAP3430_ERRORGAIN_MASK
 #define VP_INITVOLTAGE_MASK	OMAP3430_INITVOLTAGE_MASK
 #define VP_INITVOLTAGE_SHIFT	OMAP3430_INITVOLTAGE_SHIFT
 
@@ -50,28 +51,34 @@
  * board file or PMIC data structure
  */
 #define OMAP3_VP_CONFIG_ERROROFFSET		0x00
-#define OMAP3_VP_CONFIG_ERRORGAIN		0x20
-#define	OMAP3_VP_VSTEPMIN_SMPSWAITTIMEMIN	0x01F4
+#define	OMAP3_VP_VSTEPMIN_SMPSWAITTIMEMIN	0x3C
 #define OMAP3_VP_VSTEPMIN_VSTEPMIN		0x1
-#define OMAP3_VP_VSTEPMAX_SMPSWAITTIMEMAX	0x01F4
+#define OMAP3_VP_VSTEPMAX_SMPSWAITTIMEMAX	0x3C
 #define OMAP3_VP_VSTEPMAX_VSTEPMAX		0x04
-#define OMAP3_VP1_VLIMITTO_VDDMIN		0x0
-#define OMAP3_VP1_VLIMITTO_VDDMAX		0x3C
+#define OMAP3_VP1_VLIMITTO_VDDMIN		0x14
+#define OMAP3_VP1_VLIMITTO_VDDMAX		0x42
 #define OMAP3_VP2_VLIMITTO_VDDMAX		0x2C
-#define OMAP3_VP2_VLIMITTO_VDDMIN		0x0
-#define OMAP3_VP_VLIMITTO_TIMEOUT		0xFFFF
+#define OMAP3_VP2_VLIMITTO_VDDMIN		0x18
+#define OMAP3_VP_VLIMITTO_TIMEOUT_US		0x200
 
 /* TODO OMAP4 VP register values if the same file is used for OMAP4*/
 
 /**
  * omap_volt_data - Omap voltage specific data.
  *
- * @voltage	: The possible voltage value
- * @sr_nvalue	: Smartreflex N target value at voltage <voltage>
+ * @voltage		: The possible voltage value
+ * @sr_nvalue		: Smartreflex N target value at voltage <voltage>
+ * @sr_errminlimit	: Error min limit value for smartreflex. This value
+ *			  differs at differnet opp and thus is linked
+ *			  with voltage.
+ * @vp_errorgain	: Error gain value for the voltage processor. This
+ *			  field also differs according to the voltage/opp.
  */
 struct omap_volt_data {
 	unsigned long	voltage;
 	u32		sr_nvalue;
+	u8		sr_errminlimit;
+	u8		vp_errorgain;
 };
 
 void omap_voltageprocessor_enable(int vp_id);
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable.
  2010-04-16  9:03                                 ` [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence Thara Gopinath
@ 2010-04-16  9:03                                   ` Thara Gopinath
  2010-04-16  9:03                                     ` [PATCHv3 19/22] OMAP3: PM: Disabling Smartreflex across both frequency and voltage scaling during DVFS Thara Gopinath
  2010-04-27 19:14                                     ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Kevin Hilman
  2010-04-27 19:12                                   ` [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence Kevin Hilman
  1 sibling, 2 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

Currently whenever smartreflex is disabled the voltage for the
particular VDD is reset to the non-smartreflex compensated level.
This step is unnecessary during dvfs because anyways in the next couple
of steps before re-enabling smartreflex , the voltage level is changed.

This patch adds the flexibility in the smartreflex framework for the user
to specify whether or not a voltage reset is required after disabling
of smartrefelx. The smartreflex driver just passes on this info
to the smartreflex class driver, which ultimately takes the
decision to reset the voltage or not.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c             |    4 ++--
 arch/arm/mach-omap2/smartreflex-class3.c |    5 +++--
 arch/arm/mach-omap2/smartreflex.c        |   10 +++++++---
 arch/arm/mach-omap2/smartreflex.h        |    4 ++--
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index f3994c0..f6c1df3 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -415,9 +415,9 @@ void omap_sram_idle(void)
 	 * Only needed if we are going to enter retention or off.
 	 */
 	if (mpu_next_state <= PWRDM_POWER_RET)
-		omap_smartreflex_disable(VDD1);
+		omap_smartreflex_disable(VDD1, 1);
 	if (core_next_state <= PWRDM_POWER_RET)
-		omap_smartreflex_disable(VDD2);
+		omap_smartreflex_disable(VDD2, 1);
 
 	/* CORE */
 	if (core_next_state < PWRDM_POWER_ON) {
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index 53bfd05..f1d6027 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -30,11 +30,12 @@ static int sr_class3_enable(int id)
 	return sr_enable(id, volt);
 }
 
-static int sr_class3_disable(int id)
+static int sr_class3_disable(int id, int is_volt_reset)
 {
 	omap_voltageprocessor_disable(id);
 	sr_disable(id);
-	omap_reset_voltage(id);
+	if (is_volt_reset)
+		omap_reset_voltage(id);
 
 	return true;
 }
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index eed7f9b..6b7d9aa 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -226,7 +226,7 @@ static void  sr_stop_vddautocomp(struct omap_sr *sr)
 	}
 
 	if (sr->is_autocomp_active == 1) {
-		sr_class->disable(sr->srid);
+		sr_class->disable(sr->srid, 1);
 		sr_clk_disable(sr);
 		sr->is_autocomp_active = 0;
 	}
@@ -506,12 +506,16 @@ void omap_smartreflex_enable(int srid)
  * omap_smartreflex_disable : API to disable SR clocks and to call into the
  * registered smartreflex class disable API.
  * @srid - The id of the sr module to be disabled.
+ * @is_volt_reset - Whether the voltage needs to be reset after disabling
+ *		    smartreflex module or not. This parameter is directly
+ *		    passed on to the smartreflex class disable which takes the
+ *		    appropriate action.
  *
  * This API is to be called from the kernel in order to disable
  * a particular smartreflex module. This API will in turn call
  * into the registered smartreflex class disable API.
  */
-void omap_smartreflex_disable(int srid)
+void omap_smartreflex_disable(int srid, int is_volt_reset)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
 
@@ -528,7 +532,7 @@ void omap_smartreflex_disable(int srid)
 
 	if (sr->is_autocomp_active == 1) {
 		if (sr->is_sr_reset == 0) {
-			sr_class->disable(srid);
+			sr_class->disable(srid, is_volt_reset);
 			/* Disable SR clk */
 			sr_clk_disable(sr);
 		}
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index 9cc3204..476a3b6 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -180,7 +180,7 @@ struct omap_smartreflex_dev_data {
  */
 struct omap_smartreflex_class_data {
 	int (*enable)(int sr_id);
-	int (*disable)(int sr_id);
+	int (*disable)(int sr_id, int is_volt_reset);
 	void (*configure)(int sr_id);
 	int (*notify)(int sr_id, u32 status);
 	u8 notify_flags;
@@ -216,7 +216,7 @@ struct omap_smartreflex_data {
  * do anything.
  */
 void omap_smartreflex_enable(int srid);
-void omap_smartreflex_disable(int srid);
+void omap_smartreflex_disable(int srid, int is_volt_reset);
 
 /*
  * Smartreflex driver hooks to be called from Smartreflex class driver
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 19/22] OMAP3: PM: Disabling Smartreflex across both frequency and voltage scaling during DVFS.
  2010-04-16  9:03                                   ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Thara Gopinath
@ 2010-04-16  9:03                                     ` Thara Gopinath
  2010-04-16  9:03                                       ` [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling Thara Gopinath
  2010-04-27 19:14                                     ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Kevin Hilman
  1 sibling, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch disables smartreflex across both frequency and voltage
scaling instead of just across voltage scaling as before.
This is the hardware recommended practice.
This bug was first reported and solved on Nokia N900
code base by Nishanth Menon and Paul Walmsley.

This patch also does some changes in SRF to adapt to the new smartreflex
and voltage driver.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/resource34xx.c |   27 ++++++++++-----------------
 arch/arm/mach-omap2/resource34xx.h |    1 -
 2 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index c6cce8b..853c563 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -28,6 +28,7 @@
 #include <plat/opp_twl_tps.h>
 
 #include "smartreflex.h"
+#include "voltage.h"
 #include "resource34xx.h"
 #include "pm.h"
 #include "cm.h"
@@ -331,12 +332,6 @@ static int program_opp(int res, enum opp_t opp_type, int target_level,
 {
 	int i, ret = 0, raise;
 	unsigned long freq;
-#ifdef CONFIG_OMAP_SMARTREFLEX
-	unsigned long t_opp, c_opp;
-
-	t_opp = ID_VDD(res) | ID_OPP_NO(target_level);
-	c_opp = ID_VDD(res) | ID_OPP_NO(current_level);
-#endif
 
 	/* See if have a freq associated, if not, invalid opp */
 	ret = opp_to_freq(&freq, opp_type, target_level);
@@ -348,15 +343,15 @@ static int program_opp(int res, enum opp_t opp_type, int target_level,
 	else
 		raise = 0;
 
+	omap_smartreflex_disable(res - 1, 0);
+
 	for (i = 0; i < 2; i++) {
-		if (i == raise)
+		if (i == raise) {
 			ret = program_opp_freq(res, target_level,
 					current_level);
-#ifdef CONFIG_OMAP_SMARTREFLEX
-		else {
-			u8 vc, vt;
+		} else {
 			struct omap_opp *oppx;
-			unsigned long uvdc;
+			unsigned long uvdc_current, uvdc_target;
 
 			/*
 			 * transitioning from good to good OPP
@@ -364,21 +359,19 @@ static int program_opp(int res, enum opp_t opp_type, int target_level,
 			 */
 			oppx = opp_find_freq_exact(opp_type, freq, true);
 			BUG_ON(IS_ERR(oppx));
-			uvdc = opp_get_voltage(oppx);
-			vt = omap_twl_uv_to_vsel(uvdc);
+			uvdc_target = opp_get_voltage(oppx);
 
 			BUG_ON(opp_to_freq(&freq, opp_type, current_level));
 			oppx = opp_find_freq_exact(opp_type, freq, true);
 			BUG_ON(IS_ERR(oppx));
-			uvdc = opp_get_voltage(oppx);
-			vc = omap_twl_uv_to_vsel(uvdc);
+			uvdc_current = opp_get_voltage(oppx);
 
 			/* ok to scale.. */
-			sr_voltagescale_vcbypass(t_opp, c_opp, vt, vc);
+			omap_voltage_scale(res - 1, uvdc_target, uvdc_current);
 		}
-#endif
 	}
 
+	omap_smartreflex_enable(res - 1);
 	return ret;
 }
 
diff --git a/arch/arm/mach-omap2/resource34xx.h b/arch/arm/mach-omap2/resource34xx.h
index 0b4e76e..b56d2df 100644
--- a/arch/arm/mach-omap2/resource34xx.h
+++ b/arch/arm/mach-omap2/resource34xx.h
@@ -30,7 +30,6 @@
 #include <plat/opp.h>
 #include <plat/omap34xx.h>
 
-extern int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
 extern void lock_scratchpad_sem(void);
 extern void unlock_scratchpad_sem(void);
 
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling
  2010-04-16  9:03                                     ` [PATCHv3 19/22] OMAP3: PM: Disabling Smartreflex across both frequency and voltage scaling during DVFS Thara Gopinath
@ 2010-04-16  9:03                                       ` Thara Gopinath
  2010-04-16  9:03                                         ` [PATCHv3 21/22] OMAP3: PM: Enabling Smartreflex Class 3 driver by default in pm defconfig Thara Gopinath
                                                           ` (2 more replies)
  0 siblings, 3 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch introduces VP force update method of voltage scaling
and enables it by default. The older method of vc bypass is now
configuratble through a menu config option. VP force update is the
hardware recommended method of voltage scaling.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/voltage.c |  175 +++++++++++++++++++++++++++++++++++++++--
 arch/arm/mach-omap2/voltage.h |    3 +
 2 files changed, 172 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 05b0b78..554f137 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -35,6 +35,7 @@
 #include "voltage.h"
 
 #define VP_IDLE_TIMEOUT		200
+#define VP_TRANXDONE_TIMEOUT	300
 
 /**
  * OMAP3 Voltage controller SR parameters. TODO: Pass this info as part of
@@ -80,6 +81,7 @@ struct vp_info {
 	u32 vp_vddmin;
 	u32 vp_vddmax;
 	u32 vp_timeout;
+	u32 vp_tranxdone_status;
 };
 static struct vp_info *vp_reg;
 /*
@@ -166,6 +168,9 @@ static struct omap_volt_data omap34xx_vdd2_volt_data[] = {
 	{1150000, 0, 0xF9, 0x18},
 };
 
+/* By default VPFORCEUPDATE is the chosen method of voltage scaling */
+static bool voltscale_vpforceupdate = true;
+
 static inline u32 voltage_read_reg(u8 offset)
 {
 	return prm_read_mod_reg(volt_mod, offset);
@@ -325,6 +330,8 @@ static void __init vp_data_configure(int vp_id)
 					OMAP3430_VDDMIN_SHIFT);
 			vp_reg[vp_id].vp_vddmax = (OMAP3_VP1_VLIMITTO_VDDMAX <<
 					OMAP3430_VDDMAX_SHIFT);
+			vp_reg[vp_id].vp_tranxdone_status =
+					OMAP3430_VP1_TRANXDONE_ST;
 		} else if (vp_id == VDD2) {
 			vp_reg[vp_id].volt_data = omap34xx_vdd2_volt_data;
 			vp_reg[vp_id].volt_data_count =
@@ -334,6 +341,8 @@ static void __init vp_data_configure(int vp_id)
 					OMAP3430_VDDMIN_SHIFT);
 			vp_reg[vp_id].vp_vddmax = (OMAP3_VP2_VLIMITTO_VDDMAX <<
 					OMAP3430_VDDMAX_SHIFT);
+			vp_reg[vp_id].vp_tranxdone_status =
+					OMAP3430_VP2_TRANXDONE_ST;
 		} else {
 			pr_warning("Voltage processor%d does not exisit\
 					in OMAP3 \n", vp_id);
@@ -476,6 +485,134 @@ static int vc_bypass_scale_voltage(u32 vdd, unsigned long target_volt,
 	return true;
 }
 
+/* VP force update method of voltage scaling */
+static int vp_forceupdate_scale_voltage(u32 vdd, unsigned long target_volt,
+						unsigned long current_volt)
+{
+	u32 smps_steps = 0, smps_delay = 0;
+	u32 vpconfig;
+	int timeout = 0;
+	u8 target_vsel, current_vsel;
+
+	if (!((vdd == VDD1) || (vdd == VDD2))) {
+		pr_warning("Wrong vdd id passed to vp forceupdate\n");
+		return false;
+	}
+
+	target_vsel = omap_twl_uv_to_vsel(target_volt);
+	current_vsel = omap_twl_uv_to_vsel(current_volt);
+	smps_steps = abs(target_vsel - current_vsel);
+
+	if (vdd == VDD1) {
+		u32 vc_cmdval0;
+
+		vc_cmdval0 = voltage_read_reg(vc_reg.cmdval0_reg);
+		vc_cmdval0 &= ~VC_CMD_ON_MASK;
+		vc_cmdval0 |= (target_vsel << VC_CMD_ON_SHIFT);
+		voltage_write_reg(vc_reg.cmdval0_reg, vc_cmdval0);
+	} else if (vdd == VDD2) {
+		u32 vc_cmdval1;
+
+		vc_cmdval1 = voltage_read_reg(vc_reg.cmdval1_reg);
+		vc_cmdval1 &= ~VC_CMD_ON_MASK;
+		vc_cmdval1 |= (target_vsel << VC_CMD_ON_SHIFT);
+		voltage_write_reg(vc_reg.cmdval1_reg, vc_cmdval1);
+	}
+
+	/*
+	 * Clear all pending TransactionDone interrupt/status. Typical latency
+	 * is <3us
+	 */
+	while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+		prm_write_mod_reg(vp_reg[vdd].vp_tranxdone_status,
+				OCP_MOD, PRM_IRQSTATUS_REG_OFFSET);
+		if (!(prm_read_mod_reg(OCP_MOD, PRM_IRQSTATUS_REG_OFFSET) &
+				vp_reg[vdd].vp_tranxdone_status))
+				break;
+		udelay(1);
+	}
+
+	if (timeout >= VP_TRANXDONE_TIMEOUT) {
+		pr_warning("VP%d TRANXDONE timeout exceeded. Voltage change \
+				aborted", vdd);
+		return false;
+	}
+
+	/* OMAP3430 has errorgain varying btw higher and lower opp's */
+	if (cpu_is_omap34xx()) {
+		struct omap_volt_data volt_data;
+
+		if (omap_match_volt(vdd, target_volt, &volt_data)) {
+			pr_warning("Unable to get voltage table for VDD%d \
+				during voltage scaling. Some really Wrong!",
+				vdd + 1);
+			return false;
+		}
+		vp_reg[vdd].vp_errorgain = (volt_data.vp_errorgain <<
+				OMAP3430_ERRORGAIN_SHIFT);
+	}
+
+	/* Configure for VP-Force Update */
+	vpconfig = voltage_read_reg(vp_reg[vdd].vp_offs.vpconfig_reg);
+	vpconfig &= ~(VP_CONFIG_INITVDD | VP_FORCEUPDATE |
+			VP_INITVOLTAGE_MASK | VP_ERRORGAIN_MASK);
+	vpconfig |= ((target_vsel << VP_INITVOLTAGE_SHIFT) |
+			vp_reg[vdd].vp_errorgain);
+	voltage_write_reg(vp_reg[vdd].vp_offs.vpconfig_reg, vpconfig);
+
+	/* Trigger initVDD value copy to voltage processor */
+	vpconfig |= VP_CONFIG_INITVDD;
+	voltage_write_reg(vp_reg[vdd].vp_offs.vpconfig_reg, vpconfig);
+
+	/* Force update of voltage */
+	vpconfig |= VP_FORCEUPDATE;
+	voltage_write_reg(vp_reg[vdd].vp_offs.vpconfig_reg, vpconfig);
+
+	timeout = 0;
+	/*
+	 * Wait for TransactionDone. Typical latency is <200us.
+	 * Depends on SMPSWAITTIMEMIN/MAX and voltage change
+	 */
+	omap_test_timeout((prm_read_mod_reg(OCP_MOD, PRM_IRQSTATUS_REG_OFFSET) &
+			vp_reg[vdd].vp_tranxdone_status),
+			VP_TRANXDONE_TIMEOUT, timeout);
+
+	if (timeout >= VP_TRANXDONE_TIMEOUT)
+		pr_warning("VP%d TRANXDONE timeout exceeded. TRANXDONE never \
+			got set after the voltage update.Serious error!!!!\n",
+			vdd);
+
+	/* Wait for voltage to settle with SW wait-loop */
+	smps_delay = ((smps_steps * 125) / 40) + 2;
+	udelay(smps_delay);
+
+	/*
+	 * Disable TransactionDone interrupt , clear all status, clear
+	 * control registers
+	 */
+	timeout = 0;
+	while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+		prm_write_mod_reg(vp_reg[vdd].vp_tranxdone_status,
+				OCP_MOD, PRM_IRQSTATUS_REG_OFFSET);
+		if (!(prm_read_mod_reg(OCP_MOD, PRM_IRQSTATUS_REG_OFFSET) &
+				vp_reg[vdd].vp_tranxdone_status))
+				break;
+		udelay(1);
+	}
+	if (timeout >= VP_TRANXDONE_TIMEOUT)
+		pr_warning("VP%d TRANXDONE timeout exceeded while trying to \
+			clear the TRANXDONE status\n", vdd);
+
+	vpconfig = voltage_read_reg(vp_reg[vdd].vp_offs.vpconfig_reg);
+	/* Clear initVDD copy trigger bit */
+	vpconfig &= ~VP_CONFIG_INITVDD;
+	voltage_write_reg(vp_reg[vdd].vp_offs.vpconfig_reg, vpconfig);
+	/* Clear force bit */
+	vpconfig &= ~VP_FORCEUPDATE;
+	voltage_write_reg(vp_reg[vdd].vp_offs.vpconfig_reg, vpconfig);
+
+	return true;
+}
 
 static void __init init_voltageprocessors(void)
 {
@@ -586,7 +723,9 @@ void omap_voltageprocessor_enable(int vp_id)
 	 * This latching is required only if VC bypass method is used for
 	 * voltage scaling during dvfs.
 	 */
-	vp_latch_vsel(vp_id);
+	if (!voltscale_vpforceupdate)
+		vp_latch_vsel(vp_id);
+
 	vpconfig = voltage_read_reg(vp_reg[vp_id].vp_offs.vpconfig_reg);
 	/* Enable VP */
 	voltage_write_reg(vp_reg[vp_id].vp_offs.vpconfig_reg,
@@ -638,11 +777,12 @@ void omap_voltageprocessor_disable(int vp_id)
  */
 int omap_voltage_scale(int vdd, unsigned long target_volt,
 					unsigned long current_volt)
-{	/*
-	 * TODO add VP force update method of voltage scaling
-	 * and choose btw the two
-	 */
-	return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
+{
+	if (voltscale_vpforceupdate)
+		return vp_forceupdate_scale_voltage(vdd, target_volt,
+								current_volt);
+	else
+		return vc_bypass_scale_voltage(vdd, target_volt, current_volt);
 }
 
 /**
@@ -679,6 +819,29 @@ void omap_reset_voltage(int vdd)
 }
 
 /**
+ * omap_change_voltscale_method : API to change the voltage scaling method.
+ * @voltscale_method : the method to be used for voltage scaling.
+ *
+ * This API can be used by the board files to change the method of voltage
+ * scaling between vpforceupdate and vcbypass. The parameter values are
+ * defined in voltage.h
+ */
+void omap_change_voltscale_method(int voltscale_method)
+{
+	switch (voltscale_method) {
+	case VOLTSCALE_VPFORCEUPDATE:
+		voltscale_vpforceupdate = true;
+		return;
+	case VOLTSCALE_VCBYPASS:
+		voltscale_vpforceupdate = false;
+		return;
+	default:
+		pr_warning("Trying to change the method of voltage scaling \
+				to an unsupported one!\n");
+	}
+}
+
+/**
  * omap3_pm_init_vc - polpulates vc_config with values specified in board file
  * @setup_vc - the structure with various vc parameters
  *
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 8800369..473a953 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -14,7 +14,10 @@
 #define VDD1	0
 #define VDD2	1
 
+#define VOLTSCALE_VPFORCEUPDATE		1
+#define VOLTSCALE_VCBYPASS		2
 
+#define PRM_IRQSTATUS_REG_OFFSET	OMAP3_PRM_IRQSTATUS_MPU_OFFSET
 /* Generic VP definitions. Need to be redefined for OMAP4 */
 #define VP_CONFIG_TIMEOUTEN	OMAP3430_TIMEOUTEN
 #define VP_CONFIG_INITVDD	OMAP3430_INITVDD
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 21/22] OMAP3: PM: Enabling Smartreflex Class 3 driver by default in pm defconfig
  2010-04-16  9:03                                       ` [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling Thara Gopinath
@ 2010-04-16  9:03                                         ` Thara Gopinath
  2010-04-16  9:03                                           ` [PATCHv3 22/22] OMAP3: PM: Fix crash when enabling SmartReflex on non-supported OMAPs Thara Gopinath
  2010-04-27 16:23                                         ` [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling Kevin Hilman
  2010-04-27 19:16                                         ` Kevin Hilman
  2 siblings, 1 reply; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch enables smartreflex class 3 driver in omap3_pm_defconfig.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/configs/omap3_pm_defconfig |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/configs/omap3_pm_defconfig b/arch/arm/configs/omap3_pm_defconfig
index 6e86a06..300ac48 100644
--- a/arch/arm/configs/omap3_pm_defconfig
+++ b/arch/arm/configs/omap3_pm_defconfig
@@ -246,6 +246,7 @@ CONFIG_ARCH_OMAP4=y
 # OMAP Feature Selections
 #
 CONFIG_OMAP_SMARTREFLEX=y
+CONFIG_OMAP_SMARTREFLEX_CLASS3=y
 # CONFIG_OMAP_SMARTREFLEX_TESTING is not set
 CONFIG_OMAP_RESET_CLOCKS=y
 CONFIG_OMAP_MUX=y
-- 
1.7.0.rc1.33.g07cf0f


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

* [PATCHv3 22/22] OMAP3: PM: Fix crash when enabling SmartReflex on non-supported OMAPs.
  2010-04-16  9:03                                         ` [PATCHv3 21/22] OMAP3: PM: Enabling Smartreflex Class 3 driver by default in pm defconfig Thara Gopinath
@ 2010-04-16  9:03                                           ` Thara Gopinath
  0 siblings, 0 replies; 43+ messages in thread
From: Thara Gopinath @ 2010-04-16  9:03 UTC (permalink / raw)
  To: linux-omap
  Cc: khilman, paul, b-cousson, vishwanath.bs, sawant, Thara Gopinath

This patch renames is_sr_reset to is_sr_enable and  sets and unsets
this flag in appropriate places so that trying to enable smart reflex in a
non-supported OMAP chip does not lead to unnecessary crash.
Basically today if sr_enable fails, sr_disable will crash due to accessing
sr registers when sr clocks are not turned on.
By checking on is_sr_reset flag and setting and
unsetting this flag appropriately this crash is fixed in this
patch.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/smartreflex.c |   93 +++++++++++++++++++------------------
 1 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 6b7d9aa..4dccfd1 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -41,7 +41,7 @@
 
 struct omap_sr {
 	int			srid;
-	int			is_sr_reset;
+	int			is_sr_enable;
 	int			is_autocomp_active;
 	u32			clk_length;
 	u32			err_weight;
@@ -111,26 +111,6 @@ static struct omap_sr *_sr_lookup(int srid)
 	return sr_info;
 }
 
-static int sr_clk_enable(struct omap_sr *sr)
-{
-	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
-
-	if (pdata->device_enable)
-		pdata->device_enable(sr->pdev);
-
-	return 0;
-}
-
-static void sr_clk_disable(struct omap_sr *sr)
-{
-	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
-
-	if (pdata->device_idle)
-		pdata->device_idle(sr->pdev);
-
-	sr->is_sr_reset = 1;
-}
-
 static irqreturn_t sr_omap_isr(int irq, void *data)
 {
 	struct omap_sr *sr_info = (struct omap_sr *)data;
@@ -211,11 +191,8 @@ static void sr_start_vddautocomp(struct omap_sr *sr)
 	}
 
 	sr->is_autocomp_active = 1;
-	if (!sr_class->enable(sr->srid)) {
+	if (!sr_class->enable(sr->srid))
 		sr->is_autocomp_active = 0;
-		if (sr->is_sr_reset == 1)
-			sr_clk_disable(sr);
-	}
 }
 
 static void  sr_stop_vddautocomp(struct omap_sr *sr)
@@ -227,7 +204,6 @@ static void  sr_stop_vddautocomp(struct omap_sr *sr)
 
 	if (sr->is_autocomp_active == 1) {
 		sr_class->disable(sr->srid, 1);
-		sr_clk_disable(sr);
 		sr->is_autocomp_active = 0;
 	}
 }
@@ -314,7 +290,6 @@ void sr_configure_errgen(int srid)
 	sr_modify_reg(sr, ERRCONFIG,
 		(ERRCONFIG_VPBOUNDINTEN),
 		(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
-	sr->is_sr_reset = 0;
 }
 
 /**
@@ -366,7 +341,6 @@ void sr_configure_minmax(int srid)
 		(ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
 		 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
 		 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
-	sr->is_sr_reset = 0;
 }
 
 /**
@@ -406,8 +380,25 @@ int sr_enable(int srid, unsigned long volt)
 	/* errminlimit is opp dependent and hence linked to voltage */
 	sr->err_minlimit = volt_data.sr_errminlimit;
 
-	/* Enable the clocks and configure SR */
-	sr_clk_enable(sr);
+	/* Enable the clocks */
+	if (!sr->is_sr_enable) {
+		struct omap_smartreflex_data *pdata =
+				sr->pdev->dev.platform_data;
+		if (pdata->device_enable) {
+			pdata->device_enable(sr->pdev);
+		} else {
+			pr_warning("Not able to turn on SR%d clocks during \
+					enable. So returning", sr->srid + 1);
+			return false;
+		}
+		sr->is_sr_enable = 1;
+	}
+
+	/* Check if SR is already enabled. If yes do nothing */
+	if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE)
+		return true;
+
+	/* Configure SR */
 	sr_class->configure(sr->srid);
 
 	sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
@@ -426,6 +417,7 @@ int sr_enable(int srid, unsigned long volt)
 void sr_disable(int srid)
 {
 	struct omap_sr *sr = _sr_lookup(srid);
+	struct omap_smartreflex_data *pdata;
 	int timeout = 0;
 
 	if (!sr) {
@@ -434,10 +426,14 @@ void sr_disable(int srid)
 		return;
 	}
 
-	/* Check if SR is already disabled. If yes do nothing */
-	if (!(sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE))
+	/* Check if SR clocks are already disabled. If yes do nothing */
+	if (!sr->is_sr_enable)
 		return;
 
+	/* Check if SR is already disabled. If yes just disable the clocks */
+	if (!(sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE))
+		goto disable_clocks;
+
 	/* Enable MCUDisableAcknowledge interrupt */
 	sr_modify_reg(sr, ERRCONFIG,
 			ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
@@ -467,6 +463,17 @@ void sr_disable(int srid)
 	 */
 	sr_modify_reg(sr, ERRCONFIG, ERRCONFIG_MCUDISACKINTEN,
 			ERRCONFIG_MCUDISACKINTST);
+
+disable_clocks:
+	pdata = sr->pdev->dev.platform_data;
+	if (pdata->device_idle) {
+		pdata->device_idle(sr->pdev);
+	} else {
+		pr_warning("Unable to turn off SR%d clocks during SR disable",
+				srid);
+		return;
+	}
+	sr->is_sr_enable = 0;
 }
 
 /**
@@ -489,17 +496,15 @@ void omap_smartreflex_enable(int srid)
 		return;
 	}
 
+	if (!sr->is_autocomp_active)
+		return;
+
 	if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
 		pr_warning("smartreflex class driver not registered\n");
 		return;
 	}
 
-	if (sr->is_autocomp_active == 1) {
-		if (sr->is_sr_reset == 1) {
-			if (!sr_class->enable(srid))
-				sr_clk_disable(sr);
-		}
-	}
+	sr_class->enable(srid);
 }
 
 /**
@@ -525,18 +530,15 @@ void omap_smartreflex_disable(int srid, int is_volt_reset)
 		return;
 	}
 
+	if (!sr->is_autocomp_active)
+		return;
+
 	if (!sr_class || !(sr_class->disable)) {
 		pr_warning("smartreflex class driver not registered\n");
 		return;
 	}
 
-	if (sr->is_autocomp_active == 1) {
-		if (sr->is_sr_reset == 0) {
-			sr_class->disable(srid, is_volt_reset);
-			/* Disable SR clk */
-			sr_clk_disable(sr);
-		}
-	}
+	sr_class->disable(srid, is_volt_reset);
 }
 
 /**
@@ -615,7 +617,6 @@ static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	sr_info->pdev = pdev;
 	sr_info->srid = pdev->id;
-	sr_info->is_sr_reset = 1,
 	sr_info->is_autocomp_active = 0;
 	sr_info->clk_length = 0;
 	if (odev->hwmods[0]->mpu_irqs)
-- 
1.7.0.rc1.33.g07cf0f


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

* Re: [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp
  2010-04-16  9:02 [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp Thara Gopinath
  2010-04-16  9:02 ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Thara Gopinath
@ 2010-04-20 23:49 ` Kevin Hilman
  2010-04-27 19:18 ` Kevin Hilman
  2 siblings, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-20 23:49 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> The main motivations behind this patch series are the following
> 1. Making smartreflex a platform driver with omap-device layer.
> 2. Separating voltage specific code from smartreflex.c and other
>    locations and consolidating them into voltage.c and voltage.h.
> 3. Smartreflex module can have Class 1 Class 2 or Class 3 implementations
>    depending on the PMIC in use. Making smartreflex.c capable
>    of handling both the Class 2 and 3  implementaions and separating out
>    class specific code into a separate class driver.
> 4. Remove dependencies on opp id in the smartreflex and
>    voltage drivers
> 5. Implementating  latest TI recommended register settings for
>   Smartreflex and Voltage processor module as well as recommended
>   sequences for enabling and disabling of Smartreflex and Voltage
>   processor modules.
> 6. Implementing VP force update method of voltage scaling which is
>    again TI hardware recommended.
>
> What this patch series does not address are
> 1. Separating PMIC specific portions from smartreflex and voltage code.
> 2. OMAP3630 and OMP4 smartreflex support.
>
> This patch series is based on Kevin's PM tree origin/pm-wip-opp branch
> and is dependent on the following patches not yet applied onto this branch.
>
>         http://patchwork.kernel.org/patch/81504/
>         http://patchwork.kernel.org/patch/81606/
>
> This patch series has been tested on OMAP3430 SDP with basic power
> management tests including the dvfs scripts.

Will get to reviewing this later this week.  In the mean time, I 
pushed a new pm-wip-sr branch with this version of the series.

Thanks,

Kevin

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

* Re: [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling
  2010-04-16  9:03                                       ` [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling Thara Gopinath
  2010-04-16  9:03                                         ` [PATCHv3 21/22] OMAP3: PM: Enabling Smartreflex Class 3 driver by default in pm defconfig Thara Gopinath
@ 2010-04-27 16:23                                         ` Kevin Hilman
  2010-04-27 19:16                                         ` Kevin Hilman
  2 siblings, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 16:23 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch introduces VP force update method of voltage scaling
> and enables it by default. The older method of vc bypass is now
> configuratble through a menu config option. VP force update is the
> hardware recommended method of voltage scaling.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>

Hi Thara,

Could you (re) test this along with my changes to the PRCM IRQ handler:

  https://patchwork.kernel.org/patch/95450/

I made a change (suggested by Mike Turquette) that affects how that
ISR clears PRCM interrupts.  Previously, it would possibly interfere
with events you're polling for here, but it may never have seen.

[...]

> diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> index 8800369..473a953 100644
> --- a/arch/arm/mach-omap2/voltage.h
> +++ b/arch/arm/mach-omap2/voltage.h
> @@ -14,7 +14,10 @@
>  #define VDD1	0
>  #define VDD2	1
>  
> +#define VOLTSCALE_VPFORCEUPDATE		1
> +#define VOLTSCALE_VCBYPASS		2
>  
> +#define PRM_IRQSTATUS_REG_OFFSET	OMAP3_PRM_IRQSTATUS_MPU_OFFSET

Don't use another #define, just use OMAP3_PRM_IRQSTATUS_MPU_OFFSET in
code directly Please.

Kevin

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

* Re: [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex
  2010-04-16  9:02 ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Thara Gopinath
  2010-04-16  9:02   ` [PATCHv3 02/22] OMAP3: PM: Create list to keep track of various smartreflex instances Thara Gopinath
@ 2010-04-27 17:34   ` Kevin Hilman
  1 sibling, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 17:34 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch adds the hwmod strucutres and other hwmod data for
> OMAP3 Smartreflex IP's.

Should also comment about the additional data used in dev_attr as well.

> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
>  arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  135 ++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/smartreflex.h          |   33 +++++++
>  2 files changed, 168 insertions(+), 0 deletions(-)
>

[...]

> diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
> index 2a0e823..d239eb2 100644
> --- a/arch/arm/mach-omap2/smartreflex.h
> +++ b/arch/arm/mach-omap2/smartreflex.h
> @@ -237,6 +237,39 @@ extern u32 current_vdd2_opp;
>  #define SR_TESTING_NVALUES 	0
>  #endif
>  
> +/**
> + * omap_smartreflex_dev_data - Smartreflex device specific data
> + *
> + * @volts_supported	: Number of distinct voltages possible for the VDD
> + *			  associated with this smartreflex module.
> + * @efuse_sr_control	: The regisrter offset of control_fuse_sr efuse
> + *			  register from which sennenable and senpenable values
> + *			  are obtained.
> + * @sennenable_shift	: The shift in the control_fuse_sr register for
> + *			  obtaining the sennenable value for this smartreflex
> + *			  module.
> + * @senpenable_shift	: The shift in the control_fuse_sr register for
> + *			  obtaining the senpenable value for this smartreflex
> + *			  module.
> + * @efuse_nvalues_offs	: Array of efuse offsets from which ntarget values can
> + *			  be retrieved. Number of efuse offsets in this arrray
> + *			  is equal to the volts_supported value ie one efuse
> + *			  register per supported voltage.
> + * @test_sennenable	: SENNENABLE test value
> + * @test_senpenable	: SENPENABLE test value.
> + * @test_nvalues	: Array of test ntarget values.
> + */
> +struct omap_smartreflex_dev_data {

Minor nit here, but this could be named omap_sr_dev_data to
keep the name shorter and avoid some of the wrapping that has to
be done in other code because of this.

Kevin

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

* Re: [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer
  2010-04-16  9:02     ` [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer Thara Gopinath
  2010-04-16  9:02       ` [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs Thara Gopinath
@ 2010-04-27 17:47       ` Kevin Hilman
  1 sibling, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 17:47 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch converts the exisitng smartreflex library into a
> platform driver with device , driver registrations using hardware mods.
> As part of this Ntarget values are passed as platform data.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
>
> ---
>  arch/arm/mach-omap2/Makefile      |    2 +-
>  arch/arm/mach-omap2/smartreflex.c |  325 +++++++++++++------------------------
>  arch/arm/mach-omap2/smartreflex.h |   26 +++
>  arch/arm/mach-omap2/sr_device.c   |  139 ++++++++++++++++
>  4 files changed, 278 insertions(+), 214 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/sr_device.c
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index ab47043..62accd2 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -48,7 +48,7 @@ obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
>  obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
>  obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o
>  obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
> -obj-$(CONFIG_OMAP_SMARTREFLEX)	+= smartreflex.o
> +obj-$(CONFIG_OMAP_SMARTREFLEX)		+= sr_device.o smartreflex.o
>  
>  AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
>  AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a
> diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
> index dc8d6e1..b4e98e5 100644
> --- a/arch/arm/mach-omap2/smartreflex.c
> +++ b/arch/arm/mach-omap2/smartreflex.c
> @@ -3,6 +3,9 @@
>   *
>   * OMAP34XX SmartReflex Voltage Control
>   *
> + * Copyright (C) 2010 Texas Instruments, Inc.
> + * Thara Gopinath <thara@ti.com>
> + *
>   * Copyright (C) 2008 Nokia Corporation
>   * Kalle Jokiniemi
>   *
> @@ -14,7 +17,6 @@
>   * published by the Free Software Foundation.
>   */
>  
> -
>  #include <linux/kernel.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
> @@ -29,10 +31,11 @@
>  #include <linux/list.h>
>  
>  #include <plat/omap34xx.h>
> -#include <plat/control.h>
>  #include <plat/clock.h>
>  #include <plat/opp.h>
>  #include <plat/opp_twl_tps.h>
> +#include <plat/omap_hwmod.h>
> +#include <plat/omap_device.h>
>  
>  #include "prm.h"
>  #include "smartreflex.h"
> @@ -41,45 +44,44 @@
>  #define MAX_TRIES 100
>  
>  struct omap_sr {
> -	int		srid;
> -	int		is_sr_reset;
> -	int		is_autocomp_active;
> -	struct clk	*clk;
> -	struct clk	*vdd_opp_clk;
> -	u32		clk_length;
> -	u32		req_opp_no;
> -	u32		opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue;
> -	u32		opp5_nvalue;
> -	u32		senp_mod, senn_mod;
> -	void __iomem	*srbase_addr;

I think you should leave the srbase_addr here and keep the register
access the way it is (using __raw_[read|write]*) My preference for
general drivers is to keep the omap_hwmod/omap_device usage in the
driver to a minimum.  More on this below in comments on the _probe
function. 

I would just rename it from 'srbase_addr' to 'base'.

> +	int			srid;
> +	int			is_sr_reset;
> +	int			is_autocomp_active;
> +	struct clk		*vdd_opp_clk;
> +	u32			clk_length;
> +	unsigned int		irq;
> +	struct platform_device	*pdev;
>  	struct list_head	node;
>  };
>  
>  /* sr_list contains all the instances of smartreflex module */
>  static LIST_HEAD(sr_list);
>  
> -#define SR_REGADDR(offs)	(sr->srbase_addr + offset)
> -
>  static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
>  {
> -	__raw_writel(value, SR_REGADDR(offset));
> +	struct omap_device *odev = to_omap_device(sr->pdev);
> +
> +	omap_hwmod_writel(value, odev->hwmods[0], offset);
>  }
>  
>  static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
>  					u32 value)
>  {
> +	struct omap_device *odev = to_omap_device(sr->pdev);
>  	u32 reg_val;
>  
> -	reg_val = __raw_readl(SR_REGADDR(offset));
> +	reg_val = omap_hwmod_readl(odev->hwmods[0], offset);
>  	reg_val &= ~mask;
>  	reg_val |= value;
>  
> -	__raw_writel(reg_val, SR_REGADDR(offset));
> +	omap_hwmod_writel(reg_val, odev->hwmods[0], offset);
>  }
>  
>  static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset)
>  {
> -	return __raw_readl(SR_REGADDR(offset));
> +	struct omap_device *odev = to_omap_device(sr->pdev);
> +
> +	return omap_hwmod_readl(odev->hwmods[0], offset);
>  }
>  
>  static struct omap_sr *_sr_lookup(int srid)
> @@ -98,71 +100,22 @@ static struct omap_sr *_sr_lookup(int srid)
>  
>  static int sr_clk_enable(struct omap_sr *sr)
>  {
> -	if (clk_enable(sr->clk) != 0) {
> -		pr_err("Could not enable %s\n", sr->clk->name);
> -		return -1;
> -	}
> +	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
>  
> -	/* set fclk- active , iclk- idle */
> -	sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
> -		      SR_CLKACTIVITY_IOFF_FON);
> +	if (pdata->device_enable)
> +		pdata->device_enable(sr->pdev);
>  
>  	return 0;
>  }
>  
>  static void sr_clk_disable(struct omap_sr *sr)
>  {
> -	/* set fclk, iclk- idle */
> -	sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
> -		      SR_CLKACTIVITY_IOFF_FOFF);
> -
> -	clk_disable(sr->clk);
> -	sr->is_sr_reset = 1;
> -}
> -
> -static struct omap_sr sr1 = {
> -	.srid			= SR1,
> -	.is_sr_reset		= 1,
> -	.is_autocomp_active	= 0,
> -	.clk_length		= 0,
> -	.srbase_addr		= OMAP2_L4_IO_ADDRESS(OMAP34XX_SR1_BASE),
> -};
> -
> -static struct omap_sr sr2 = {
> -	.srid			= SR2,
> -	.is_sr_reset		= 1,
> -	.is_autocomp_active	= 0,
> -	.clk_length		= 0,
> -	.srbase_addr		= OMAP2_L4_IO_ADDRESS(OMAP34XX_SR2_BASE),
> -};
> -
> -static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
> -{
> -	u32 gn, rn, mul;
> -
> -	for (gn = 0; gn < GAIN_MAXLIMIT; gn++) {
> -		mul = 1 << (gn + 8);
> -		rn = mul / sensor;
> -		if (rn < R_MAXLIMIT) {
> -			*sengain = gn;
> -			*rnsen = rn;
> -		}
> -	}
> -}
> -
> -static u32 cal_test_nvalue(u32 sennval, u32 senpval)
> -{
> -	u32 senpgain, senngain;
> -	u32 rnsenp, rnsenn;
> +	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
>  
> -	/* Calculating the gain and reciprocal of the SenN and SenP values */
> -	cal_reciprocal(senpval, &senpgain, &rnsenp);
> -	cal_reciprocal(sennval, &senngain, &rnsenn);
> +	if (pdata->device_idle)
> +		pdata->device_idle(sr->pdev);
>  
> -	return (senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
> -		(senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
> -		(rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
> -		(rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT);
> +	sr->is_sr_reset = 1;
>  }
>  
>  static u8 get_vdd1_opp(void)
> @@ -255,76 +208,6 @@ static void sr_set_clk_length(struct omap_sr *sr)
>  	}
>  }
>  
> -static void sr_set_efuse_nvalues(struct omap_sr *sr)
> -{
> -	if (sr->srid == SR1) {
> -		sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
> -					OMAP343X_SR1_SENNENABLE_MASK) >>
> -					OMAP343X_SR1_SENNENABLE_SHIFT;
> -		sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
> -					OMAP343X_SR1_SENPENABLE_MASK) >>
> -					OMAP343X_SR1_SENPENABLE_SHIFT;
> -
> -		sr->opp5_nvalue = omap_ctrl_readl(
> -					OMAP343X_CONTROL_FUSE_OPP5_VDD1);
> -		sr->opp4_nvalue = omap_ctrl_readl(
> -					OMAP343X_CONTROL_FUSE_OPP4_VDD1);
> -		sr->opp3_nvalue = omap_ctrl_readl(
> -					OMAP343X_CONTROL_FUSE_OPP3_VDD1);
> -		sr->opp2_nvalue = omap_ctrl_readl(
> -					OMAP343X_CONTROL_FUSE_OPP2_VDD1);
> -		sr->opp1_nvalue = omap_ctrl_readl(
> -					OMAP343X_CONTROL_FUSE_OPP1_VDD1);
> -	} else if (sr->srid == SR2) {
> -		sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
> -					OMAP343X_SR2_SENNENABLE_MASK) >>
> -					OMAP343X_SR2_SENNENABLE_SHIFT;
> -
> -		sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
> -					OMAP343X_SR2_SENPENABLE_MASK) >>
> -					OMAP343X_SR2_SENPENABLE_SHIFT;
> -
> -		sr->opp3_nvalue = omap_ctrl_readl(
> -					OMAP343X_CONTROL_FUSE_OPP3_VDD2);
> -		sr->opp2_nvalue = omap_ctrl_readl(
> -					OMAP343X_CONTROL_FUSE_OPP2_VDD2);
> -		sr->opp1_nvalue = omap_ctrl_readl(
> -					OMAP343X_CONTROL_FUSE_OPP1_VDD2);
> -	}
> -}
> -
> -/* Hard coded nvalues for testing purposes, may cause device to hang! */
> -static void sr_set_testing_nvalues(struct omap_sr *sr)
> -{
> -	if (sr->srid == SR1) {
> -		sr->senp_mod = 0x03;	/* SenN-M5 enabled */
> -		sr->senn_mod = 0x03;
> -
> -		/* calculate nvalues for each opp */
> -		sr->opp5_nvalue = cal_test_nvalue(0xacd + 0x330, 0x848 + 0x330);
> -		sr->opp4_nvalue = cal_test_nvalue(0x964 + 0x2a0, 0x727 + 0x2a0);
> -		sr->opp3_nvalue = cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200);
> -		sr->opp2_nvalue = cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0);
> -		sr->opp1_nvalue = cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100);
> -	} else if (sr->srid == SR2) {
> -		sr->senp_mod = 0x03;
> -		sr->senn_mod = 0x03;
> -
> -		sr->opp3_nvalue = cal_test_nvalue(0x76f + 0x200, 0x579 + 0x200);
> -		sr->opp2_nvalue = cal_test_nvalue(0x4f5 + 0x1c0, 0x390 + 0x1c0);
> -		sr->opp1_nvalue = cal_test_nvalue(0x359, 0x25d);
> -	}
> -
> -}
> -
> -static void sr_set_nvalues(struct omap_sr *sr)
> -{
> -	if (SR_TESTING_NVALUES)
> -		sr_set_testing_nvalues(sr);
> -	else
> -		sr_set_efuse_nvalues(sr);
> -}
> -
>  static void sr_configure_vp(int srid)
>  {
>  	u32 vpconfig;
> @@ -438,12 +321,13 @@ static void sr_configure(struct omap_sr *sr)
>  {
>  	u32 sr_config;
>  	u32 senp_en , senn_en;
> +	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
>  
>  	if (sr->clk_length == 0)
>  		sr_set_clk_length(sr);
>  
> -	senp_en = sr->senp_mod;
> -	senn_en = sr->senn_mod;
> +	senp_en = pdata->senp_mod;
> +	senn_en = pdata->senn_mod;
>  	if (sr->srid == SR1) {
>  		sr_config = SR1_SRCONFIG_ACCUMDATA |
>  			(sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
> @@ -571,57 +455,28 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
>  {
>  	u32 nvalue_reciprocal, v;
>  	struct omap_opp *opp;
> +	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
>  	int uvdc;
>  	char vsel;
>  
> -	sr->req_opp_no = target_opp_no;
> -
>  	if (sr->srid == SR1) {
> -		switch (target_opp_no) {
> -		case 5:
> -			nvalue_reciprocal = sr->opp5_nvalue;
> -			break;
> -		case 4:
> -			nvalue_reciprocal = sr->opp4_nvalue;
> -			break;
> -		case 3:
> -			nvalue_reciprocal = sr->opp3_nvalue;
> -			break;
> -		case 2:
> -			nvalue_reciprocal = sr->opp2_nvalue;
> -			break;
> -		case 1:
> -			nvalue_reciprocal = sr->opp1_nvalue;
> -			break;
> -		default:
> -			nvalue_reciprocal = sr->opp3_nvalue;
> -			break;
> -		}
> -
>  		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
>  		if (!opp)
>  			return false;
>  	} else {
> -		switch (target_opp_no) {
> -		case 3:
> -			nvalue_reciprocal = sr->opp3_nvalue;
> -			break;
> -		case 2:
> -			nvalue_reciprocal = sr->opp2_nvalue;
> -			break;
> -		case 1:
> -			nvalue_reciprocal = sr->opp1_nvalue;
> -			break;
> -		default:
> -			nvalue_reciprocal = sr->opp3_nvalue;
> -			break;
> -		}
> -
>  		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
>  		if (!opp)
>  			return false;
>  	}
>  
> +	if (!pdata->sr_nvalue) {
> +		pr_notice("N target values does not exist for SR%d\n",
> +								sr->srid);
> +		return false;
> +	}
> +
> +	nvalue_reciprocal = pdata->sr_nvalue[target_opp_no - 1];
> +
>  	if (nvalue_reciprocal == 0) {
>  		pr_notice("OPP%d doesn't support SmartReflex\n",
>  								target_opp_no);
> @@ -1033,49 +888,93 @@ static struct kobj_attribute sr_vdd2_autocomp = {
>  	.store = omap_sr_vdd2_autocomp_store,
>  };
>  
> +static int __devinit omap_smartreflex_probe(struct platform_device *pdev)
> +{
> +	struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
> +	struct omap_device *odev = to_omap_device(pdev);
> +	int ret = 0;
> +
> +	if (WARN_ON(!sr_info))
> +		return -ENOMEM;
> +	sr_info->pdev = pdev;
> +	sr_info->srid = pdev->id + 1;
> +	sr_info->is_sr_reset = 1,
> +	sr_info->is_autocomp_active = 0;
> +	sr_info->clk_length = 0;
> +	if (odev->hwmods[0]->mpu_irqs)
> +		sr_info->irq = odev->hwmods[0]->mpu_irqs[0].irq;

You should use platform_get_resource(..., IORESOURCE_IRQ) here instead
of accessing the hwmod. (or better, platform_get_irq().)

Remember that omap_device_build() builds a platform_device as well
with all the resources (base addresses, IRQs, DMA channels) so the
standard platform_get_resource() calls should be used to get all
those.

And, for the base address, use 

  sr_info->base = platform_get_resource(pdev, IORESOURCE_MEM);

Ideally, as generic driver here should have no (or minimal) knowledge of 
omap_device/omap_hwmod internals.

> +	sr_set_clk_length(sr_info);
> +
> +	if (sr_info->srid == SR1) {
> +		sr_info->vdd_opp_clk = clk_get(NULL, "dpll1_ck");
> +		ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
> +		if (ret)
> +			pr_err("sysfs_create_file failed: %d\n", ret);
> +	} else {
> +		sr_info->vdd_opp_clk = clk_get(NULL, "l3_ick");
> +		ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
> +		if (ret)
> +			pr_err("sysfs_create_file failed: %d\n", ret);
> +	}
> +
> +	/* Call the VPConfig */
> +	sr_configure_vp(sr_info->srid);
> +	list_add(&sr_info->node, &sr_list);
> +	pr_info("SmartReflex driver initialized\n");
> +
> +	return ret;
> +}
> +
> +static int __devexit omap_smartreflex_remove(struct platform_device *pdev)
> +{
> +	struct omap_sr *sr_info = _sr_lookup(pdev->id + 1);
>  
> +	/* Disable Autocompensation if enabled before removing the module */
> +	if (sr_info->is_autocomp_active == 1)
> +		sr_stop_vddautocomap(sr_info->srid);
> +	list_del(&sr_info->node);
> +	kfree(sr_info);
>  
> -static int __init omap3_sr_init(void)
> +	return 0;
> +}
> +
> +static struct platform_driver smartreflex_driver = {
> +	.probe          = omap_smartreflex_probe,

minor nit... since you're using platform_device_probe(), you don't
need a .probe function here, and you can make omap_smartreflex_probe()
__init.

> +	.remove         = omap_smartreflex_remove,
> +	.driver		= {
> +		.name	= "smartreflex",
> +	},
> +};
> +
> +static int __init sr_init(void)
>  {
>  	int ret = 0;
>  	u8 RdReg;
>  
> +	/* TODO: Find an appropriate place for this */
>  	/* Enable SR on T2 */
>  	ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
>  			      R_DCDC_GLOBAL_CFG);
> -
>  	RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
>  	ret |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, RdReg,
>  				R_DCDC_GLOBAL_CFG);
> -	if (cpu_is_omap34xx()) {
> -		sr1.clk = clk_get(NULL, "sr1_fck");
> -		sr2.clk = clk_get(NULL, "sr2_fck");
> -	}
> -	sr1.vdd_opp_clk = clk_get(NULL, "dpll1_ck");
> -	sr2.vdd_opp_clk = clk_get(NULL, "l3_ick");
> -	sr_set_clk_length(&sr1);
> -	sr_set_clk_length(&sr2);
> -
> -	/* Call the VPConfig, VCConfig, set N Values. */
> -	sr_set_nvalues(&sr1);
> -	sr_configure_vp(SR1);
> -
> -	sr_set_nvalues(&sr2);
> -	sr_configure_vp(SR2);
> -
> -	pr_info("SmartReflex driver initialized\n");
>  
> -	ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
> -	if (ret)
> -		pr_err("sysfs_create_file failed: %d\n", ret);
> +	ret = platform_driver_probe(&smartreflex_driver,
> +				omap_smartreflex_probe);
>  
> -	ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
>  	if (ret)
> -		pr_err("sysfs_create_file failed: %d\n", ret);
> -	list_add(&sr1.node, &sr_list);
> -	list_add(&sr2.node, &sr_list);
> -
> +		pr_err("platform driver register failed for smartreflex");
>  	return 0;
>  }
>  
> -late_initcall(omap3_sr_init);
> +void __exit sr_exit(void)
> +{
> +	platform_driver_unregister(&smartreflex_driver);
> +}
> +late_initcall(sr_init);
> +module_exit(sr_exit);
> +
> +MODULE_DESCRIPTION("OMAP SMARTREFLEX DRIVER");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:" DRIVER_NAME);
> +MODULE_AUTHOR("Texas Instruments Inc");
> diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
> index d239eb2..5eb8846 100644
> --- a/arch/arm/mach-omap2/smartreflex.h
> +++ b/arch/arm/mach-omap2/smartreflex.h
> @@ -14,6 +14,8 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/platform_device.h>
> +
>  #define PHY_TO_OFF_PM_MASTER(p)		(p - 0x36)
>  #define PHY_TO_OFF_PM_RECIEVER(p)	(p - 0x5b)
>  #define PHY_TO_OFF_PM_INT(p)		(p - 0x2e)
> @@ -276,6 +278,30 @@ struct omap_smartreflex_dev_data {
>   * do anything.
>   */
>  #ifdef CONFIG_OMAP_SMARTREFLEX
> +/**
> + * omap_smartreflex_data - Smartreflex platform data
> + *
> + * @senp_mod		: SENPENABLE value for the sr
> + * @senn_mod		: SENNENABLE value for sr
> + * @sr_nvalue		: array of n target values for sr
> + * @enable_on_init	: whether this sr module needs to enabled at
> + *			  boot up or not
> + * @device_enable	: fn pointer to be populated with omap_device
> + *			enable API
> + * @device_shutdown	: fn pointer to be populated with omap_device
> + *			shutdown API
> + * @device_idle		: fn pointer to be pouplated with omap_device idle API

You can drop the comments about omap_device API.  These are intended to
be generic pointers.  The device part is free to fill those out

> + */
> +struct omap_smartreflex_data {

Also, how about a rename to omap_sr_data;

> +	u32		senp_mod;
> +	u32		senn_mod;
> +	u32		*sr_nvalue;
> +	bool		enable_on_init;
> +	int (*device_enable)(struct platform_device *pdev);
> +	int (*device_shutdown)(struct platform_device *pdev);
> +	int (*device_idle)(struct platform_device *pdev);
> +};
> +
>  void enable_smartreflex(int srid);
>  void disable_smartreflex(int srid);
>  int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
> diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
> new file mode 100644
> index 0000000..a9c1ef0
> --- /dev/null
> +++ b/arch/arm/mach-omap2/sr_device.c
> @@ -0,0 +1,139 @@
> +/*
> + * linux/arch/arm/mach-omap2/sr_device.c

Please drop the filename from the header.

> + * OMAP3/OMAP4 smartreflex device file
> + *
> + * Author: Thara Gopinath	<thara@ti.com>
> + *
> + * Based originally on code from smartreflex.c
> + * Copyright (C) 2010 Texas Instruments, Inc.
> + * Thara Gopinath <thara@ti.com>
> + *
> + * Copyright (C) 2008 Nokia Corporation
> + * Kalle Jokiniemi
> + *
> + * Copyright (C) 2007 Texas Instruments, Inc.
> + * Lesly A M <x0080970@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/err.h>
> +
> +#include <plat/control.h>
> +#include <plat/omap_hwmod.h>
> +#include <plat/omap_device.h>
> +#include <plat/opp.h>
> +
> +#include "smartreflex.h"
> +
> +#define MAX_HWMOD_NAME_LEN	16
> +
> +struct omap_device_pm_latency omap_sr_latency[] = {
> +	{
> +		.deactivate_func = omap_device_idle_hwmods,
> +		.activate_func	 = omap_device_enable_hwmods,
> +		.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST
> +	},
> +};
> +
> +/* Read EFUSE values from control registers for OMAP3430 */
> +static void __init sr_read_efuse(
> +				struct omap_smartreflex_dev_data *dev_data,
> +				struct omap_smartreflex_data *sr_data)
> +{
> +	int i;
> +
> +	if (WARN_ON(!dev_data || !dev_data->volts_supported ||
> +			!dev_data->efuse_sr_control ||
> +			!dev_data->efuse_nvalues_offs))
> +		return;
> +
> +	sr_data->sr_nvalue = kzalloc(sizeof(sr_data->sr_nvalue) *
> +			dev_data->volts_supported , GFP_KERNEL);
> +	sr_data->senn_mod = (omap_ctrl_readl(dev_data->efuse_sr_control) &
> +				(0x3 << dev_data->sennenable_shift) >>
> +				dev_data->sennenable_shift);
> +	sr_data->senp_mod = (omap_ctrl_readl(dev_data->efuse_sr_control) &
> +				(0x3 << dev_data->senpenable_shift) >>
> +				dev_data->senpenable_shift);
> +	for (i = 0; i < dev_data->volts_supported; i++)
> +		sr_data->sr_nvalue[i] = omap_ctrl_readl(
> +				dev_data->efuse_nvalues_offs[i]);
> +}
> +
> +/*
> + * Hard coded nvalues for testing purposes for OMAP3430,
> + * may cause device to hang!
> + */
> +static void __init sr_set_testing_nvalues(
> +				struct omap_smartreflex_dev_data *dev_data,
> +				struct omap_smartreflex_data *sr_data)
> +{
> +	int i;
> +
> +	if (WARN_ON(!dev_data || !dev_data->volts_supported ||
> +			!dev_data->test_nvalues))
> +		return;
> +
> +	sr_data->sr_nvalue = kzalloc(sizeof(sr_data->sr_nvalue) *
> +			dev_data->volts_supported , GFP_KERNEL);
> +	sr_data->senn_mod = dev_data->test_sennenable;
> +	sr_data->senp_mod = dev_data->test_senpenable;
> +	for (i = 0; i < dev_data->volts_supported; i++)
> +		sr_data->sr_nvalue[i] = dev_data->test_nvalues[i];
> +}
> +
> +static void __init sr_set_nvalues(struct omap_smartreflex_dev_data *dev_data,
> +		struct omap_smartreflex_data *sr_data)
> +{
> +	if (cpu_is_omap34xx()) {

Why this check?  Looks like the called functions already check for
valid data.  Also, I don't see this changed/updated in the 3630 patches.

> +		if (SR_TESTING_NVALUES)
> +			sr_set_testing_nvalues(dev_data, sr_data);
> +		else
> +			sr_read_efuse(dev_data, sr_data);
> +	}
> +}
> +
> +static int __init omap_devinit_smartreflex(void)
> +{
> +	int i = 0;
> +	char *name = "smartreflex";
> +
> +	do {
> +		struct omap_smartreflex_data *sr_data;
> +		struct omap_smartreflex_dev_data *sr_dev_data;
> +		struct omap_device *od;
> +		struct omap_hwmod *oh;
> +		char oh_name[MAX_HWMOD_NAME_LEN + 1];
> +
> +		snprintf(oh_name, MAX_HWMOD_NAME_LEN, "sr%d_hwmod", i + 1);
> +		oh = omap_hwmod_lookup(oh_name);

Should be using the hwmod_class to iterate: omap_hwmod_for_each_by_class()

> +		if (!oh)
> +			break;
> +
> +		sr_data = kzalloc(sizeof(struct omap_smartreflex_data),
> +								GFP_KERNEL);
> +		sr_dev_data = (struct omap_smartreflex_dev_data *)oh->dev_attr;
> +		if (WARN_ON(!sr_data))
> +			return -ENOMEM;
> +
> +		sr_data->enable_on_init = false;
> +		sr_data->device_enable = omap_device_enable;
> +		sr_data->device_shutdown = omap_device_shutdown;
> +		sr_data->device_idle = omap_device_idle;
> +		sr_set_nvalues(sr_dev_data, sr_data);
> +
> +		od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
> +				       omap_sr_latency,
> +				       ARRAY_SIZE(omap_sr_latency), 0);
> +		WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
> +		     name, oh->name);
> +		i++;
> +	} while (1);
> +
> +	return 0;
> +}
> +arch_initcall(omap_devinit_smartreflex);

Kevin

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

* Re: [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs.
  2010-04-16  9:02       ` [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs Thara Gopinath
  2010-04-16  9:03         ` [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver Thara Gopinath
@ 2010-04-27 17:57         ` Kevin Hilman
  1 sibling, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 17:57 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch moves the hooks to enable disable smartreflex
> autocompensation to pm debugfs from the /sys/power/.
>
> To enable autocompensation for smartreflex SR<n> do
>         echo 1 > <path>/pm_debug/sr<n>_autocomp
> To disable autocompensation for smartreflex SR<n> do
>         echo 0 > <path>/pm_debug/sr<n>_autocomp
>
> Signed-off-by: Thara Gopinath <thara@ti.com>

some minor comments...

> ---
>  arch/arm/mach-omap2/pm-debug.c    |    4 +-
>  arch/arm/mach-omap2/smartreflex.c |  114 ++++++++++--------------------------
>  arch/arm/mach-omap2/smartreflex.h |    2 +
>  3 files changed, 36 insertions(+), 84 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
> index 8aafd71..ce46059 100644
> --- a/arch/arm/mach-omap2/pm-debug.c
> +++ b/arch/arm/mach-omap2/pm-debug.c
> @@ -162,7 +162,7 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
>  
>  static void pm_dbg_regset_store(u32 *ptr);
>  
> -struct dentry *pm_dbg_dir;
> +struct dentry *pm_dbg_dir, *pm_dbg_main_dir;
>  
>  static int pm_dbg_init_done;
>  
> @@ -613,7 +613,7 @@ static int __init pm_dbg_init(void)
>  					   S_IRUGO | S_IWUGO, d,
>  					   &voltage_off_while_idle,
>  					   &pm_dbg_option_fops);
> -
> +	pm_dbg_main_dir = d;
>  	pm_dbg_init_done = 1;
>  
>  	return 0;
> diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
> index b4e98e5..2f89d79 100644
> --- a/arch/arm/mach-omap2/smartreflex.c
> +++ b/arch/arm/mach-omap2/smartreflex.c
> @@ -24,11 +24,11 @@
>  #include <linux/delay.h>
>  #include <linux/err.h>
>  #include <linux/clk.h>
> -#include <linux/sysfs.h>
>  #include <linux/kobject.h>
>  #include <linux/i2c/twl.h>
>  #include <linux/io.h>
>  #include <linux/list.h>
> +#include <linux/debugfs.h>
>  
>  #include <plat/omap34xx.h>
>  #include <plat/clock.h>
> @@ -42,6 +42,7 @@
>  #include "prm-regbits-34xx.h"
>  
>  #define MAX_TRIES 100
> +#define SMARTREFLEX_NAME_LEN	16
>  
>  struct omap_sr {
>  	int			srid;
> @@ -796,103 +797,53 @@ int sr_voltagescale_vcbypass(u32 target_opp, u32 current_opp,
>  	return 0;
>  }
>  
> -/* Sysfs interface to select SR VDD1 auto compensation */
> -static ssize_t omap_sr_vdd1_autocomp_show(struct kobject *kobj,
> -					struct kobj_attribute *attr, char *buf)
> +/* PM Debug Fs enteries to enable disable smartreflex.*/
                                                         ^
need a space before the */

> +

stray blank line

> +static int omap_sr_autocomp_show(void *data, u64 *val)
>  {
> -	struct omap_sr *sr_info = _sr_lookup(SR1);
> +	struct omap_sr *sr_info = (struct omap_sr *) data;

        struct device *dev = &sr_info->pdev->dev;

>  	if (!sr_info) {
> -		pr_warning("omap_sr struct corresponding to SR1 not found\n");
> +		pr_warning("omap_sr struct corresponding to SR%d not found\n",
> +							sr_info->srid);

                dev_err(dev, "struct for SR%d not found\n",
                        sr_info->srid);

>  		return 0;
>  	}
> -	return sprintf(buf, "%d\n", sr_info->is_autocomp_active);
> +	*val = sr_info->is_autocomp_active;
> +	return 0;
>  }
>  
> -static ssize_t omap_sr_vdd1_autocomp_store(struct kobject *kobj,
> -					struct kobj_attribute *attr,
> -					const char *buf, size_t n)
> +static int omap_sr_autocomp_store(void *data, u64 val)
>  {
> -	unsigned short value;
> -
> -	if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
> -		pr_err("sr_vdd1_autocomp: Invalid value\n");
> -		return -EINVAL;
> -	}
> -
> -	if (value == 0) {
> -		sr_stop_vddautocomap(SR1);
> -	} else {
> -		u32 current_vdd1opp_no = get_vdd1_opp();
> -		if (!current_vdd1opp_no) {
> -			pr_err("sr_vdd1_autocomp: Current VDD1 opp unknown\n");
> -			return -EINVAL;
> -		}
> -		sr_start_vddautocomap(SR1, current_vdd1opp_no);
> -	}
> -	return n;
> -}
> -
> -static struct kobj_attribute sr_vdd1_autocomp = {
> -	.attr = {
> -	.name = __stringify(sr_vdd1_autocomp),
> -	.mode = 0644,
> -	},
> -	.show = omap_sr_vdd1_autocomp_show,
> -	.store = omap_sr_vdd1_autocomp_store,
> -};
> -
> -/* Sysfs interface to select SR VDD2 auto compensation */
> -static ssize_t omap_sr_vdd2_autocomp_show(struct kobject *kobj,
> -					struct kobj_attribute *attr, char *buf)
> -{
> -	struct omap_sr *sr_info = _sr_lookup(SR2);
> +	struct omap_sr *sr_info = (struct omap_sr *) data;
>  
>  	if (!sr_info) {
> -		pr_warning("omap_sr struct corresponding to SR2 not found\n");
> +		pr_warning("omap_sr struct corresponding to SR%d not found\n",
> +							sr_info->srid);

dev_warn()

>  		return 0;
>  	}
> -	return sprintf(buf, "%d\n", sr_info->is_autocomp_active);
> -}
> -

[...]

Kevin

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

* Re: [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver
  2010-04-16  9:03         ` [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver Thara Gopinath
  2010-04-16  9:03           ` [PATCHv3 06/22] OMAP3: PM: Correcting API names in samrtreflex driver Thara Gopinath
@ 2010-04-27 18:43           ` Kevin Hilman
  1 sibling, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 18:43 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch removes get_vdd1_opp and get_vdd2_opp API's and replaces
> them with get_curr_vdd1_voltage and get_curr_vdd2_voltage API's.
> N-target values are now linked to voltages and the link bewtween
> voltage and n-target values is managed internally in smartreflex
> driver and sr_devices.c.
>
> get_curr_vdd1_voltage and get_curr_vdd2_voltage are added in
> smartreflex driver in this patch. These API's will be moved to the
> voltage driver in a later patch when voltage specific code is separated
> out of smartreflex. The link between various voltages and n-target
> values will also be separated out later.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
>  arch/arm/mach-omap2/smartreflex.c |  201 +++++++++++++++----------------------
>  arch/arm/mach-omap2/smartreflex.h |   21 +++-
>  arch/arm/mach-omap2/sr_device.c   |   39 ++++++-
>  3 files changed, 129 insertions(+), 132 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
> index 2f89d79..669f1bb 100644
> --- a/arch/arm/mach-omap2/smartreflex.c
> +++ b/arch/arm/mach-omap2/smartreflex.c
> @@ -48,7 +48,6 @@ struct omap_sr {
>  	int			srid;
>  	int			is_sr_reset;
>  	int			is_autocomp_active;
> -	struct clk		*vdd_opp_clk;
>  	u32			clk_length;
>  	unsigned int		irq;
>  	struct platform_device	*pdev;
> @@ -119,64 +118,65 @@ static void sr_clk_disable(struct omap_sr *sr)
>  	sr->is_sr_reset = 1;
>  }
>  
> -static u8 get_vdd1_opp(void)
> +static unsigned long get_curr_vdd1_voltage(void)
>  {
>  	struct omap_opp *opp;
>  	unsigned long freq;
> -	struct omap_sr *sr_info = _sr_lookup(SR1);
> +	struct clk *dpll1_clk;
>  

> -	if (!sr_info) {
> -		pr_warning("omap_sr struct corresponding to SR1 not found\n");
> -		return 0;
> -	}
> -
> -	if (sr_info->vdd_opp_clk == NULL || IS_ERR(sr_info->vdd_opp_clk))
> +	dpll1_clk = clk_get(NULL, "dpll1_ck");
> +	if (IS_ERR(dpll1_clk))
>  		return 0;
>  
> -	freq = sr_info->vdd_opp_clk->rate;
> -	opp = opp_find_freq_ceil(OPP_MPU, &freq);
> +	freq = dpll1_clk->rate;;
> +	opp = opp_find_freq_exact(OPP_MPU, freq, 1);
>  	if (IS_ERR(opp))
>  		return 0;

I mentioned this in an earlier review, but I think it's best to leave
the clock as part of sr_info.  If you also add the OPP enum value
to sr_info, you could have a single, common function to get current
voltage intstead of a separate one per-VDD.  Otherwise, as additional
voltage domains are added, we need to add another function.

What should result is just a single get_curr_voltage() or similar
which takes an sr_info ptr and doesn't need to sr_lookup()

> -	/*
> -	 * Use higher freq voltage even if an exact match is not available
> -	 * we are probably masking a clock framework bug, so warn
> -	 */
> -	if (unlikely(freq != sr_info->vdd_opp_clk->rate))
> -		pr_warning("%s: Available freq %ld != dpll freq %ld.\n",
> -			   __func__, freq, sr_info->vdd_opp_clk->rate);
>  

Removed here, but added back in subsequent patch.  Should be combined.
Another reason to start condensing this series and reworking against
mainline.

> -	return opp_get_opp_id(opp);
> +	return opp_get_voltage(opp);
>  }
>  
> -static u8 get_vdd2_opp(void)
> +static unsigned long get_curr_vdd2_voltage(void)
>  {
>  	struct omap_opp *opp;
>  	unsigned long freq;
> -	struct omap_sr *sr_info = _sr_lookup(SR2);
> +	struct clk *l3_clk;
>  
> -	if (!sr_info) {
> -		pr_warning("omap_sr struct corresponding to SR2 not found\n");
> -		return 0;
> -	}
> -
> -	if (sr_info->vdd_opp_clk == NULL || IS_ERR(sr_info->vdd_opp_clk))
> +	l3_clk = clk_get(NULL, "l3_ick");
> +	if (IS_ERR(l3_clk))
>  		return 0;
>  
> -	freq = sr_info->vdd_opp_clk->rate;
> -	opp = opp_find_freq_ceil(OPP_L3, &freq);
> +	freq = l3_clk->rate;
> +	opp = opp_find_freq_exact(OPP_L3, freq, 1);
>  	if (IS_ERR(opp))
>  		return 0;
>  
> -	/*
> -	 * Use higher freq voltage even if an exact match is not available
> -	 * we are probably masking a clock framework bug, so warn
> -	 */
> -	if (unlikely(freq != sr_info->vdd_opp_clk->rate))
> -		pr_warning("%s: Available freq %ld != dpll freq %ld.\n",
> -			   __func__, freq, sr_info->vdd_opp_clk->rate);
> -	return opp_get_opp_id(opp);
> +	return opp_get_voltage(opp);
>  }
>  
> +static int sr_match_volt(struct omap_sr *sr, unsigned long volt,
> +				struct omap_volt_data *volt_data)
> +{
> +	struct omap_smartreflex_data *pdata = sr->pdev->dev.platform_data;
> +	struct omap_device *odev = to_omap_device(sr->pdev);
> +	struct omap_smartreflex_dev_data *sr_dev_data =
> +					odev->hwmods[0]->dev_attr;
> +	int i;
> +
> +	if (!pdata->sr_volt_data) {
> +		pr_notice("voltage table does not exist for SR %d\n", sr->srid);

dev_notice()

> +		return false;
> +	}
> +	for (i = 0; i < sr_dev_data->volts_supported; i++) {
> +		if (pdata->sr_volt_data[i].voltage == volt) {
> +			*volt_data = pdata->sr_volt_data[i];
> +			return true;
> +		}
> +	}
> +	pr_notice("Unable to match the current voltage with \
> +				the voltage table for SR %d\n", sr->srid);

dev_notice()

> +	return false;
> +}
>  

[...]

> diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
> index ea0ddd3..b14ba50 100644
> --- a/arch/arm/mach-omap2/smartreflex.h
> +++ b/arch/arm/mach-omap2/smartreflex.h
> @@ -242,6 +242,17 @@ extern u32 current_vdd2_opp;
>  #endif
>  
>  /**
> + * omap_volt_data - Omap voltage specific data.
> + *
> + * @voltage	: The possible voltage value
> + * @sr_nvalue	: Smartreflex N target value at voltage <voltage>
> + */
> +struct omap_volt_data {
> +	unsigned long	voltage;
> +	u32		sr_nvalue;
> +};
> +
> +/**
>   * omap_smartreflex_dev_data - Smartreflex device specific data
>   *
>   * @volts_supported	: Number of distinct voltages possible for the VDD
> @@ -295,10 +306,10 @@ struct omap_smartreflex_dev_data {
>   * @device_idle		: fn pointer to be pouplated with omap_device idle API
>   */
>  struct omap_smartreflex_data {
> -	u32		senp_mod;
> -	u32		senn_mod;
> -	u32		*sr_nvalue;
> -	bool		enable_on_init;
> +	u32				senp_mod;
> +	u32				senn_mod;
> +	struct omap_volt_data		*sr_volt_data;

minor nit: drop the sr_ prefix

> +	bool				enable_on_init;
>  	int (*device_enable)(struct platform_device *pdev);
>  	int (*device_shutdown)(struct platform_device *pdev);
>  	int (*device_idle)(struct platform_device *pdev);
> @@ -307,7 +318,7 @@ struct omap_smartreflex_data {
>  void enable_smartreflex(int srid);
>  void disable_smartreflex(int srid);
>  int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
> -void sr_start_vddautocomap(int srid, u32 target_opp_no);
> +void sr_start_vddautocomap(int srid, unsigned long volt);
>  int sr_stop_vddautocomap(int srid);
>  #else
>  static inline void enable_smartreflex(int srid) {}
> diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
> index a9c1ef0..544d575 100644
> --- a/arch/arm/mach-omap2/sr_device.c
> +++ b/arch/arm/mach-omap2/sr_device.c
> @@ -51,8 +51,9 @@ static void __init sr_read_efuse(
>  			!dev_data->efuse_nvalues_offs))
>  		return;
>  
> -	sr_data->sr_nvalue = kzalloc(sizeof(sr_data->sr_nvalue) *
> -			dev_data->volts_supported , GFP_KERNEL);
> +	if (WARN_ON(!sr_data->sr_volt_data))
> +		return;
> +
>  	sr_data->senn_mod = (omap_ctrl_readl(dev_data->efuse_sr_control) &
>  				(0x3 << dev_data->sennenable_shift) >>
>  				dev_data->sennenable_shift);
> @@ -60,7 +61,7 @@ static void __init sr_read_efuse(
>  				(0x3 << dev_data->senpenable_shift) >>
>  				dev_data->senpenable_shift);
>  	for (i = 0; i < dev_data->volts_supported; i++)
> -		sr_data->sr_nvalue[i] = omap_ctrl_readl(
> +		sr_data->sr_volt_data[i].sr_nvalue = omap_ctrl_readl(
>  				dev_data->efuse_nvalues_offs[i]);
>  }
>  
> @@ -78,12 +79,13 @@ static void __init sr_set_testing_nvalues(
>  			!dev_data->test_nvalues))
>  		return;
>  
> -	sr_data->sr_nvalue = kzalloc(sizeof(sr_data->sr_nvalue) *
> -			dev_data->volts_supported , GFP_KERNEL);
> +	if (WARN_ON(!sr_data->sr_volt_data))
> +		return;
> +
>  	sr_data->senn_mod = dev_data->test_sennenable;
>  	sr_data->senp_mod = dev_data->test_senpenable;
>  	for (i = 0; i < dev_data->volts_supported; i++)
> -		sr_data->sr_nvalue[i] = dev_data->test_nvalues[i];
> +		sr_data->sr_volt_data[i].sr_nvalue = dev_data->test_nvalues[i];
>  }
>  
>  static void __init sr_set_nvalues(struct omap_smartreflex_dev_data *dev_data,
> @@ -97,6 +99,28 @@ static void __init sr_set_nvalues(struct omap_smartreflex_dev_data *dev_data,
>  	}
>  }
>  
> +static void __init omap34xx_sr_volt_details(struct omap_smartreflex_data
> +						*sr_data, int srid,
> +						int volt_count)
> +{
> +	sr_data->sr_volt_data = kzalloc(sizeof(sr_data->sr_volt_data) *
> +				volt_count , GFP_KERNEL);
> +	if (WARN_ON(!sr_data->sr_volt_data))
> +		return;
> +
> +	if (srid == SR1) {
> +		sr_data->sr_volt_data[0].voltage = 975000;
> +		sr_data->sr_volt_data[1].voltage = 1075000;
> +		sr_data->sr_volt_data[2].voltage = 1200000;
> +		sr_data->sr_volt_data[3].voltage = 1270000;
> +		sr_data->sr_volt_data[4].voltage = 1350000;
> +	} else if (srid == SR2) {
> +		sr_data->sr_volt_data[0].voltage = 975000;
> +		sr_data->sr_volt_data[1].voltage = 1050000;
> +		sr_data->sr_volt_data[2].voltage = 1150000;
> +	}
> +}
> +

again, more stuff added that is removed later.  Time to start condensing
as it's getting hard to keep track of.

[...]

Kevin


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

* Re: [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver.
  2010-04-16  9:03                   ` [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver Thara Gopinath
  2010-04-16  9:03                     ` [PATCHv3 11/22] OMAP3: PM: Removing VP1, VP2, SR1 and SR2 defintions Thara Gopinath
@ 2010-04-27 18:58                     ` Kevin Hilman
  1 sibling, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 18:58 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch introduces the framework to create voltage table per
> VDD basis in voltage driver. Each VDD will have one voltage table,
> which in turn will contain one entry per voltage supported and
> other data associated with the voltage like smartreflex N-target
> values. This patch also generates voltage tables for VDD1 and VDD2 of
> OMAP3430 and passes them as dev_attr to sr_device.c in order
> to populate the smartreflex n-target values.
>
> These voltage tables are extended in a later patch to contain more
> voltage specific information like errminlimt and errorgain values.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
>  arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |    7 +-
>  arch/arm/mach-omap2/smartreflex.c          |   27 +--------
>  arch/arm/mach-omap2/smartreflex.h          |   13 +----
>  arch/arm/mach-omap2/sr_device.c            |   42 ++----------
>  arch/arm/mach-omap2/voltage.c              |   93 +++++++++++++++++++++++++++-
>  arch/arm/mach-omap2/voltage.h              |   15 +++++
>  6 files changed, 118 insertions(+), 79 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> index 049e4e2..1f41310 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -23,6 +23,7 @@
>  
>  #include "prm-regbits-34xx.h"
>  #include "smartreflex.h"
> +#include "voltage.h"
>  
>  /*
>   * OMAP3xxx hardware module integration data
> @@ -240,14 +241,13 @@ static u32 omap34xx_sr1_test_nvalues[] = {
>  };
>  
>  static struct omap_smartreflex_dev_data omap34xx_sr1_dev_attr = {
> -	.volts_supported	= 5,
>  	.efuse_sr_control	= OMAP343X_CONTROL_FUSE_SR,
>  	.sennenable_shift	= OMAP343X_SR1_SENNENABLE_SHIFT,
>  	.senpenable_shift	= OMAP343X_SR1_SENPENABLE_SHIFT,
>  	.efuse_nvalues_offs	= omap34xx_sr1_efuse_offs,
>  	.test_sennenable	= 0x3,
>  	.test_senpenable	= 0x3,
> -	.test_nvalues		= omap34xx_sr1_test_nvalues
> +	.test_nvalues		= omap34xx_sr1_test_nvalues,

unrelated change, should be in original patch that adds this struct.

>  };
>  
>  static struct omap_hwmod omap34xx_sr1_hwmod = {
> @@ -276,14 +276,13 @@ static u32 omap34xx_sr2_test_nvalues[] = {
>  };
>  
>  static struct omap_smartreflex_dev_data omap34xx_sr2_dev_attr = {
> -	.volts_supported	= 3,
>  	.efuse_sr_control	= OMAP343X_CONTROL_FUSE_SR,
>  	.sennenable_shift	= OMAP343X_SR2_SENNENABLE_SHIFT,
>  	.senpenable_shift	= OMAP343X_SR2_SENPENABLE_SHIFT,
>  	.efuse_nvalues_offs	= omap34xx_sr2_efuse_offs,
>  	.test_sennenable	= 0x3,
>  	.test_senpenable	= 0x3,
> -	.test_nvalues		= omap34xx_sr2_test_nvalues
> +	.test_nvalues		= omap34xx_sr2_test_nvalues,

ditto

>  };
>  

[...]

>  /**
> + * omap_get_voltage_table : API to get the voltage table associated with a
> + *			    particular voltage domain.
> + *
> + * @vdd : the voltage domain id for which the voltage table is required
> + * @volt_data : the voltage table for the particular vdd which is to be
> + *		populated by this API
> + * @volt_count : number of distinct voltages supported by this vdd which
> + *		is to be populated by this API.
> + *
> + * This API populates the voltage table associated with a VDD and the count
> + * of number of voltages supported into the passed parameter pointers.
> + */
> +void omap_get_voltage_table(int vdd, struct omap_volt_data **volt_data,
> +						int *volt_count)
> +{
> +	*volt_data = vp_reg[vdd].volt_data;
> +	*volt_count = vp_reg[vdd].volt_data_count;
> +}

How about returning the count instad of in another pointer.

> +/**
> + * omap_match_volt : API to get the voltage table entry for a particular
> + *		     voltage
> + * @vdd : the voltage domain id for whose voltage table has to be searched
> + * @volt : the voltage to be searched in the voltage table
> + * @volt_data : the matching voltage table entry which has to be populate
> + *		by this API.
> + *
> + * This API searches through the voltage table for the required voltage
> + * domain and tries to find a matching entry for the passed voltage volt.
> + * If a matching entry is found volt_data is populated with that entry.
> + * Returns -ENXIO if not voltage table exisits for the passed voltage
> + * domain or if there is no matching entry. On success returns true.
> + */
> +int omap_match_volt(int vdd, unsigned long volt,
> +				struct omap_volt_data *volt_data)
> +{
> +	int i;
> +
> +	if (!vp_reg[vdd].volt_data) {
> +		pr_notice("voltage table does not exist for VDD %d\n", vdd + 1);
> +		return -ENXIO;
> +	}
> +
> +	for (i = 0; i < vp_reg[vdd].volt_data_count; i++) {
> +		if (vp_reg[vdd].volt_data[i].voltage == volt) {
> +			*volt_data = vp_reg[vdd].volt_data[i];
> +			return 0;
> +		}
> +	}
> +	pr_notice("Unable to match the current voltage with \
> +				the voltage table for VDD %d\n", vdd + 1);
> +	return -ENXIO;
> +}
> +
> +/**
>   * omap_voltage_init : Volatage init API which does VP and VC init.
>   */
>  void __init omap_voltage_init(void)
> diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
> index 663c6fe..cc3308e 100644
> --- a/arch/arm/mach-omap2/voltage.h
> +++ b/arch/arm/mach-omap2/voltage.h
> @@ -63,6 +63,17 @@
>  
>  /* TODO OMAP4 VP register values if the same file is used for OMAP4*/
>  
> +/**
> + * omap_volt_data - Omap voltage specific data.
> + *
> + * @voltage	: The possible voltage value
> + * @sr_nvalue	: Smartreflex N target value at voltage <voltage>
> + */
> +struct omap_volt_data {
> +	unsigned long	voltage;
> +	u32		sr_nvalue;

both could be unsigned long (or u32)

> +};
> +
>  void omap_voltageprocessor_enable(int vp_id);
>  void omap_voltageprocessor_disable(int vp_id);
>  void omap_voltage_init_vc(struct prm_setup_vc *setup_vc);
> @@ -70,5 +81,9 @@ void omap_voltage_init(void);
>  int omap_voltage_scale(int vdd, unsigned long target_volt,
>  					unsigned long current_volt);
>  void omap_reset_voltage(int vdd);
> +void omap_get_voltage_table(int vdd, struct omap_volt_data **volt_data,
> +						int *volt_count);
> +int omap_match_volt(int vdd, unsigned long volt,
> +				struct omap_volt_data *volt_data);
>  unsigned long get_curr_vdd1_voltage(void);
>  unsigned long get_curr_vdd2_voltage(void);

Kevin

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

* Re: [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c
  2010-04-16  9:03                       ` [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c Thara Gopinath
  2010-04-16  9:03                         ` [PATCHv3 13/22] OMAP3: PM: Cleaning up of smartreflex header file Thara Gopinath
@ 2010-04-27 19:02                         ` Kevin Hilman
  2010-05-13  7:13                           ` Gopinath, Thara
  1 sibling, 1 reply; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 19:02 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch ensures that sr id is passed as a parameter only to
> public APIs in smartreflex.c and other APIs in smartreflex.c
> uses the omap_sr strucutres.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>

Good change, but...

> ---
>  arch/arm/mach-omap2/smartreflex.c |   36 +++++++++++++-----------------------
>  1 files changed, 13 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
> index fffd5f7..c6942e9 100644
> --- a/arch/arm/mach-omap2/smartreflex.c
> +++ b/arch/arm/mach-omap2/smartreflex.c
> @@ -190,16 +190,8 @@ static void sr_configure(struct omap_sr *sr)
>  	sr->is_sr_reset = 0;
>  }
>  
> -static void sr_start_vddautocomp(int srid)
> +static void sr_start_vddautocomp(struct omap_sr *sr)
>  {
> -	struct omap_sr *sr = _sr_lookup(srid);
> -
> -	if (!sr) {
> -		pr_warning("omap_sr struct corresponding to SR%d not found\n",
> -								srid + 1);
> -		return;
> -	}
> -
>  	if (!sr_class || !(sr_class->enable)) {
>  		pr_warning("smartreflex class driver not registered\n");
>  		return;
> @@ -211,30 +203,22 @@ static void sr_start_vddautocomp(int srid)
>  	}
>  
>  	sr->is_autocomp_active = 1;
> -	if (!sr_class->enable(srid)) {
> +	if (!sr_class->enable(sr->srid)) {

... the class3 layer is still taking SR ID as a parameter and it
should also just take an sr_info ptr.

Kevin

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

* Re: [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3
  2010-04-16  9:03                           ` [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3 Thara Gopinath
  2010-04-16  9:03                             ` [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default Thara Gopinath
@ 2010-04-27 19:06                             ` Kevin Hilman
  1 sibling, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 19:06 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> There are two separate modules in SmartReflex-AVS :
> MinMaxAvg module and Error module. Class3 uses the Error module only.
> In Class2 you can choose between either module since it is software based.
> The registers are mapped to the modules as followed:
>
> MinMaxAvg module: AccumData, MinMaxAvgEnable, MinMaxAvgValid,
>         MinMaxAvgAccumValid, SenVal, SenMin, SenMax, SenAverage,
>         AverageWeight, MCUAccum, MCUValid, MCUBounds.
>
> Error module: SenNGain, SenPGain, SenPRN, SenNRN, AvgError,
>         SenError, VPBounds, ErrWeight, ErrMaxLimit, ErrMinLimit.
>
> Shared between both: SRClkLength, SREnable, SenEnable, SenNEnable,
>         SenPEnable, DelayCtrl, MCUDisableAck, ClkActivity.
>
> This patch generates separate API's to configure the two modules
> which can be used by the smartreflex class driver as per its
> requirement. This patch allows allows for registering for smartreflex
> interrupt handler and notification of interrupts in case requested by
> the smartreflex class driver.

After just removing functions that take SR IDs, here new functions are added 
that take SR IDs and do _sr_lookup() instead of passing sr pointer.

Kevin

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

* Re: [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default.
  2010-04-16  9:03                             ` [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default Thara Gopinath
  2010-04-16  9:03                               ` [PATCHv3 16/22] OMAP3: PM: Correcting accessing of ERRCONFIG register in smartreflex.c Thara Gopinath
@ 2010-04-27 19:10                               ` Kevin Hilman
  1 sibling, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 19:10 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch adds support to pdata enable smartreflex autocompenstion
> during init based on enable_on_init flag passed as pdata.

-ENOPARSE.  Removing the first 'pdata' makes it understandable, I think.

> This patch also adds enabling of autocompensation by
> default (setting enable_on_init  flag to true) in case of ES3.1
> OMAP3430 chip. In the current implementation
> this step is kept in smartreflex.c itself.Later an API can be added
> so that the decision to enable autocompensation by default
> can be passed from the corresponding board files.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>

otherwise, ok.

Kevin

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

* Re: [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence.
  2010-04-16  9:03                                 ` [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence Thara Gopinath
  2010-04-16  9:03                                   ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Thara Gopinath
@ 2010-04-27 19:12                                   ` Kevin Hilman
  1 sibling, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 19:12 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch introduces OMAP3 specific values for Smartreflex and
> Voltage processor registers as per the latest TI recommendations.
> This patch adds smartreflex errminlimit and voltage processor
> errorgain into the voltage tables as they vary with different
> voltages. This patch also improves the smartreflex and voltage
> processor enable disable sequences as per the latest recommendations.
>
> These recommendations were first formed based on experimentations
> on N900 platform  and were implemented in the N900 codebase
> base first by Nishanth Menon and Paul Walmsley.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>

Some minor CodingStyle issues.  Please check the multi-line comment
style in this patch.

Kevin

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

* Re: [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable.
  2010-04-16  9:03                                   ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Thara Gopinath
  2010-04-16  9:03                                     ` [PATCHv3 19/22] OMAP3: PM: Disabling Smartreflex across both frequency and voltage scaling during DVFS Thara Gopinath
@ 2010-04-27 19:14                                     ` Kevin Hilman
  2010-05-05 11:03                                       ` Gopinath, Thara
  1 sibling, 1 reply; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 19:14 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> Currently whenever smartreflex is disabled the voltage for the
> particular VDD is reset to the non-smartreflex compensated level.
> This step is unnecessary during dvfs because anyways in the next couple
> of steps before re-enabling smartreflex , the voltage level is changed.
>
> This patch adds the flexibility in the smartreflex framework for the user
> to specify whether or not a voltage reset is required after disabling
> of smartrefelx. The smartreflex driver just passes on this info
> to the smartreflex class driver, which ultimately takes the
> decision to reset the voltage or not.
>
> Signed-off-by: Thara Gopinath <thara@ti.com>

I don't think this option should be a decision made for each call to
omap_smartreflex_[en|dis]able().  Rather it should be an init time
option.

Kevin

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

* Re: [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling
  2010-04-16  9:03                                       ` [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling Thara Gopinath
  2010-04-16  9:03                                         ` [PATCHv3 21/22] OMAP3: PM: Enabling Smartreflex Class 3 driver by default in pm defconfig Thara Gopinath
  2010-04-27 16:23                                         ` [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling Kevin Hilman
@ 2010-04-27 19:16                                         ` Kevin Hilman
  2 siblings, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 19:16 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> This patch introduces VP force update method of voltage scaling
> and enables it by default. The older method of vc bypass is now
> configuratble through a menu config option. VP force update is the
> hardware recommended method of voltage scaling.

changelog needs update.  It is no longer a menuconfig option.

Kevin


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

* Re: [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp
  2010-04-16  9:02 [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp Thara Gopinath
  2010-04-16  9:02 ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Thara Gopinath
  2010-04-20 23:49 ` [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp Kevin Hilman
@ 2010-04-27 19:18 ` Kevin Hilman
  2010-04-30  6:09   ` Gopinath, Thara
  2 siblings, 1 reply; 43+ messages in thread
From: Kevin Hilman @ 2010-04-27 19:18 UTC (permalink / raw)
  To: Thara Gopinath; +Cc: linux-omap, paul, b-cousson, vishwanath.bs, sawant

Thara Gopinath <thara@ti.com> writes:

> The main motivations behind this patch series are the following
> 1. Making smartreflex a platform driver with omap-device layer.
> 2. Separating voltage specific code from smartreflex.c and other
>    locations and consolidating them into voltage.c and voltage.h.
> 3. Smartreflex module can have Class 1 Class 2 or Class 3 implementations
>    depending on the PMIC in use. Making smartreflex.c capable
>    of handling both the Class 2 and 3  implementaions and separating out
>    class specific code into a separate class driver.
> 4. Remove dependencies on opp id in the smartreflex and
>    voltage drivers
> 5. Implementating  latest TI recommended register settings for
>   Smartreflex and Voltage processor module as well as recommended
>   sequences for enabling and disabling of Smartreflex and Voltage
>   processor modules.
> 6. Implementing VP force update method of voltage scaling which is
>    again TI hardware recommended.
>
> What this patch series does not address are
> 1. Separating PMIC specific portions from smartreflex and voltage code.
> 2. OMAP3630 and OMP4 smartreflex support.
>
> This patch series is based on Kevin's PM tree origin/pm-wip-opp branch
> and is dependent on the following patches not yet applied onto this branch.
>
>         http://patchwork.kernel.org/patch/81504/
>         http://patchwork.kernel.org/patch/81606/
>
> This patch series has been tested on OMAP3430 SDP with basic power
> management tests including the dvfs scripts.

First some general comments...

- check multi-line comment style

- use of dev_err() instead of pr_err() (or dev_* instead of pr_*)
  wherever you have a valid platform_device.  This will print messages
  with the specific SR device name so you get more detailed messages.
  It will also avoid you having to use sr_info->srid since that
  number is already part of the device name.
  
And now, IMHO, this is getting close enough, where I think it's
getting mostly ready for submission upstream.  To that end, I think
it's time to start creating this series against mainline, instead of
against the PM branch.

This is basically a rewrite, so I think it makes sense to breifly
summarize the history in the first patch, but then build from scratch
against mainline (except for SRF changes which will have to be a
separate series based on the PM branch.)

As it is, the series is getting hard to follow as there are several
things that are cleaned up from the old code and then removed later in
the series etc.  For that reason, I'd now like to see this as a fresh
series against mainline.

Actually, currnely it will have to be based on my pm-vc branch which
is a small series of VC init/setup patches that I'll be queueing for
2.6.35, but itself is based on mainline.

The SR series could broken up as follows (only a suggestion)

- Creation of voltage layer: current pm-vc branch + voltage.c

- Creation of device/platform init: hwmods, sr_device.c

- Creation of driver: smartreflex*.[ch], sr_device.c

These should each have a brief summary of history and main
contributors, but you as primary author.

Kevin

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

* RE: [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp
  2010-04-27 19:18 ` Kevin Hilman
@ 2010-04-30  6:09   ` Gopinath, Thara
  2010-04-30 14:22     ` Kevin Hilman
  0 siblings, 1 reply; 43+ messages in thread
From: Gopinath, Thara @ 2010-04-30  6:09 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant, Anand



>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Wednesday, April 28, 2010 12:48 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand
>>Subject: Re: [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp
>>
>>Thara Gopinath <thara@ti.com> writes:
>>
>>> The main motivations behind this patch series are the following
>>> 1. Making smartreflex a platform driver with omap-device layer.
>>> 2. Separating voltage specific code from smartreflex.c and other
>>>    locations and consolidating them into voltage.c and voltage.h.
>>> 3. Smartreflex module can have Class 1 Class 2 or Class 3 implementations
>>>    depending on the PMIC in use. Making smartreflex.c capable
>>>    of handling both the Class 2 and 3  implementaions and separating out
>>>    class specific code into a separate class driver.
>>> 4. Remove dependencies on opp id in the smartreflex and
>>>    voltage drivers
>>> 5. Implementating  latest TI recommended register settings for
>>>   Smartreflex and Voltage processor module as well as recommended
>>>   sequences for enabling and disabling of Smartreflex and Voltage
>>>   processor modules.
>>> 6. Implementing VP force update method of voltage scaling which is
>>>    again TI hardware recommended.
>>>
>>> What this patch series does not address are
>>> 1. Separating PMIC specific portions from smartreflex and voltage code.
>>> 2. OMAP3630 and OMP4 smartreflex support.
>>>
>>> This patch series is based on Kevin's PM tree origin/pm-wip-opp branch
>>> and is dependent on the following patches not yet applied onto this branch.
>>>
>>>         http://patchwork.kernel.org/patch/81504/
>>>         http://patchwork.kernel.org/patch/81606/
>>>
>>> This patch series has been tested on OMAP3430 SDP with basic power
>>> management tests including the dvfs scripts.
>>
>>First some general comments...
>>
>>- check multi-line comment style
>>
>>- use of dev_err() instead of pr_err() (or dev_* instead of pr_*)
>>  wherever you have a valid platform_device.  This will print messages
>>  with the specific SR device name so you get more detailed messages.
>>  It will also avoid you having to use sr_info->srid since that
>>  number is already part of the device name.
>>
>>And now, IMHO, this is getting close enough, where I think it's
>>getting mostly ready for submission upstream.  To that end, I think
>>it's time to start creating this series against mainline, instead of
>>against the PM branch.
>>
>>This is basically a rewrite, so I think it makes sense to breifly
>>summarize the history in the first patch, but then build from scratch
>>against mainline (except for SRF changes which will have to be a
>>separate series based on the PM branch.)
>>
>>As it is, the series is getting hard to follow as there are several
>>things that are cleaned up from the old code and then removed later in
>>the series etc.  For that reason, I'd now like to see this as a fresh
>>series against mainline.
>>
>>Actually, currnely it will have to be based on my pm-vc branch which
>>is a small series of VC init/setup patches that I'll be queueing for
>>2.6.35, but itself is based on mainline.
>>
>>The SR series could broken up as follows (only a suggestion)
>>
>>- Creation of voltage layer: current pm-vc branch + voltage.c
>>
>>- Creation of device/platform init: hwmods, sr_device.c
>>
>>- Creation of driver: smartreflex*.[ch], sr_device.c

Kevin,

I could create this series against mainline but I need OPP layer for voltage layer.. 

Regards,
Thara

>>These should each have a brief summary of history and main
>>contributors, but you as primary author.
>>
>>Kevin

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

* Re: [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp
  2010-04-30  6:09   ` Gopinath, Thara
@ 2010-04-30 14:22     ` Kevin Hilman
  0 siblings, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-04-30 14:22 UTC (permalink / raw)
  To: Gopinath, Thara
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant, Anand

"Gopinath, Thara" <thara@ti.com> writes:

>>>-----Original Message-----
>>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>>Sent: Wednesday, April 28, 2010 12:48 AM
>>>To: Gopinath, Thara
>>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand
>>>Subject: Re: [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp
>>>
>>>Thara Gopinath <thara@ti.com> writes:
>>>
>>>> The main motivations behind this patch series are the following
>>>> 1. Making smartreflex a platform driver with omap-device layer.
>>>> 2. Separating voltage specific code from smartreflex.c and other
>>>>    locations and consolidating them into voltage.c and voltage.h.
>>>> 3. Smartreflex module can have Class 1 Class 2 or Class 3 implementations
>>>>    depending on the PMIC in use. Making smartreflex.c capable
>>>>    of handling both the Class 2 and 3  implementaions and separating out
>>>>    class specific code into a separate class driver.
>>>> 4. Remove dependencies on opp id in the smartreflex and
>>>>    voltage drivers
>>>> 5. Implementating  latest TI recommended register settings for
>>>>   Smartreflex and Voltage processor module as well as recommended
>>>>   sequences for enabling and disabling of Smartreflex and Voltage
>>>>   processor modules.
>>>> 6. Implementing VP force update method of voltage scaling which is
>>>>    again TI hardware recommended.
>>>>
>>>> What this patch series does not address are
>>>> 1. Separating PMIC specific portions from smartreflex and voltage code.
>>>> 2. OMAP3630 and OMP4 smartreflex support.
>>>>
>>>> This patch series is based on Kevin's PM tree origin/pm-wip-opp branch
>>>> and is dependent on the following patches not yet applied onto this branch.
>>>>
>>>>         http://patchwork.kernel.org/patch/81504/
>>>>         http://patchwork.kernel.org/patch/81606/
>>>>
>>>> This patch series has been tested on OMAP3430 SDP with basic power
>>>> management tests including the dvfs scripts.
>>>
>>>First some general comments...
>>>
>>>- check multi-line comment style
>>>
>>>- use of dev_err() instead of pr_err() (or dev_* instead of pr_*)
>>>  wherever you have a valid platform_device.  This will print messages
>>>  with the specific SR device name so you get more detailed messages.
>>>  It will also avoid you having to use sr_info->srid since that
>>>  number is already part of the device name.
>>>
>>>And now, IMHO, this is getting close enough, where I think it's
>>>getting mostly ready for submission upstream.  To that end, I think
>>>it's time to start creating this series against mainline, instead of
>>>against the PM branch.
>>>
>>>This is basically a rewrite, so I think it makes sense to breifly
>>>summarize the history in the first patch, but then build from scratch
>>>against mainline (except for SRF changes which will have to be a
>>>separate series based on the PM branch.)
>>>
>>>As it is, the series is getting hard to follow as there are several
>>>things that are cleaned up from the old code and then removed later in
>>>the series etc.  For that reason, I'd now like to see this as a fresh
>>>series against mainline.
>>>
>>>Actually, currnely it will have to be based on my pm-vc branch which
>>>is a small series of VC init/setup patches that I'll be queueing for
>>>2.6.35, but itself is based on mainline.
>>>
>>>The SR series could broken up as follows (only a suggestion)
>>>
>>>- Creation of voltage layer: current pm-vc branch + voltage.c
>>>
>>>- Creation of device/platform init: hwmods, sr_device.c
>>>
>>>- Creation of driver: smartreflex*.[ch], sr_device.c
>
> Kevin,
>
> I could create this series against mainline but I need OPP layer for voltage layer.. 
>

Ah, yes.  Sorry.  Please create against pm-opp, which is based on
mainline.  I am working on reorganizing pm-opp for upstream.

Kevin


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

* RE: [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable.
  2010-04-27 19:14                                     ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Kevin Hilman
@ 2010-05-05 11:03                                       ` Gopinath, Thara
  2010-05-05 21:39                                         ` Kevin Hilman
  0 siblings, 1 reply; 43+ messages in thread
From: Gopinath, Thara @ 2010-05-05 11:03 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant, Anand



>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Wednesday, April 28, 2010 12:45 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand
>>Subject: Re: [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable.
>>
>>Thara Gopinath <thara@ti.com> writes:
>>
>>> Currently whenever smartreflex is disabled the voltage for the
>>> particular VDD is reset to the non-smartreflex compensated level.
>>> This step is unnecessary during dvfs because anyways in the next couple
>>> of steps before re-enabling smartreflex , the voltage level is changed.
>>>
>>> This patch adds the flexibility in the smartreflex framework for the user
>>> to specify whether or not a voltage reset is required after disabling
>>> of smartrefelx. The smartreflex driver just passes on this info
>>> to the smartreflex class driver, which ultimately takes the
>>> decision to reset the voltage or not.
>>>
>>> Signed-off-by: Thara Gopinath <thara@ti.com>
>>
>>I don't think this option should be a decision made for each call to
>>omap_smartreflex_[en|dis]able().  Rather it should be an init time
>>option.
Hello Kevin,

Why do you say this? Anytime we do a disable of smartreflex auto compensation  from user space we need a reset of the voltage is required. During dvfs during smartreflex disable a reset of the voltage is not required. And in both these scenarios it is the same class API that gets called. So the only way for the API to know whether to reset the voltage or not is through this parameter. Also IMHO keeping it parameter based allows more flexibility in the framework for voltage reset. 

Regards
Thara

>>
>>Kevin

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

* Re: [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable.
  2010-05-05 11:03                                       ` Gopinath, Thara
@ 2010-05-05 21:39                                         ` Kevin Hilman
  0 siblings, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-05-05 21:39 UTC (permalink / raw)
  To: Gopinath, Thara
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant, Anand

"Gopinath, Thara" <thara@ti.com> writes:

>>>-----Original Message-----
>>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>>Sent: Wednesday, April 28, 2010 12:45 AM
>>>To: Gopinath, Thara
>>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand
>>>Subject: Re: [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable.
>>>
>>>Thara Gopinath <thara@ti.com> writes:
>>>
>>>> Currently whenever smartreflex is disabled the voltage for the
>>>> particular VDD is reset to the non-smartreflex compensated level.
>>>> This step is unnecessary during dvfs because anyways in the next couple
>>>> of steps before re-enabling smartreflex , the voltage level is changed.
>>>>
>>>> This patch adds the flexibility in the smartreflex framework for the user
>>>> to specify whether or not a voltage reset is required after disabling
>>>> of smartrefelx. The smartreflex driver just passes on this info
>>>> to the smartreflex class driver, which ultimately takes the
>>>> decision to reset the voltage or not.
>>>>
>>>> Signed-off-by: Thara Gopinath <thara@ti.com>
>>>
>>>I don't think this option should be a decision made for each call to
>>>omap_smartreflex_[en|dis]able().  Rather it should be an init time
>>>option.
>
> Why do you say this? Anytime we do a disable of smartreflex auto
>compensation from user space we need a reset of the voltage is
>required.  During dvfs during smartreflex disable a reset of the
>voltage is not required.  And in both these scenarios it is the same
>class API that gets called. So the only way for the API to know
>whether to reset the voltage or not is through this parameter. Also
>IMHO keeping it parameter based allows more flexibility in the
>framework for voltage reset.

OK,  I see now.

I was looking at this patch in isolation and didn't notice the usage
of it in the next DVFS patch where the ->disable is done without
reset.

Also, since this new flag is a bool, change it from int to bool.

Or better yet add a new function.  One thing I'm not a fan of for
readability sake is the use of bool flags.  It makes me have to go
look at the function to see what the flag is used for.  I'd rather
just see a new function added.  Something like
omap_smartreflex_disable_noreset() would make the code a bit more
readable.

Thanks,

Kevin




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

* RE: [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c
  2010-04-27 19:02                         ` [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c Kevin Hilman
@ 2010-05-13  7:13                           ` Gopinath, Thara
  2010-05-14 17:14                             ` Kevin Hilman
  0 siblings, 1 reply; 43+ messages in thread
From: Gopinath, Thara @ 2010-05-13  7:13 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant, Anand



>>-----Original Message-----
>>From: Kevin Hilman [mailto:khilman@deeprootsystems.com]
>>Sent: Wednesday, April 28, 2010 12:32 AM
>>To: Gopinath, Thara
>>Cc: linux-omap@vger.kernel.org; paul@pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand
>>Subject: Re: [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c
>>
>>Thara Gopinath <thara@ti.com> writes:
>>
>>> This patch ensures that sr id is passed as a parameter only to
>>> public APIs in smartreflex.c and other APIs in smartreflex.c
>>> uses the omap_sr strucutres.
>>>
>>> Signed-off-by: Thara Gopinath <thara@ti.com>
>>
>>Good change, but...
>>
>>> ---
>>>  arch/arm/mach-omap2/smartreflex.c |   36 +++++++++++++-----------------------
>>>  1 files changed, 13 insertions(+), 23 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
>>> index fffd5f7..c6942e9 100644
>>> --- a/arch/arm/mach-omap2/smartreflex.c
>>> +++ b/arch/arm/mach-omap2/smartreflex.c
>>> @@ -190,16 +190,8 @@ static void sr_configure(struct omap_sr *sr)
>>>  	sr->is_sr_reset = 0;
>>>  }
>>>
>>> -static void sr_start_vddautocomp(int srid)
>>> +static void sr_start_vddautocomp(struct omap_sr *sr)
>>>  {
>>> -	struct omap_sr *sr = _sr_lookup(srid);
>>> -
>>> -	if (!sr) {
>>> -		pr_warning("omap_sr struct corresponding to SR%d not found\n",
>>> -								srid + 1);
>>> -		return;
>>> -	}
>>> -
>>>  	if (!sr_class || !(sr_class->enable)) {
>>>  		pr_warning("smartreflex class driver not registered\n");
>>>  		return;
>>> @@ -211,30 +203,22 @@ static void sr_start_vddautocomp(int srid)
>>>  	}
>>>
>>>  	sr->is_autocomp_active = 1;
>>> -	if (!sr_class->enable(srid)) {
>>> +	if (!sr_class->enable(sr->srid)) {
>>
>>... the class3 layer is still taking SR ID as a parameter and it
>>should also just take an sr_info ptr.

Hi Kevin,

sr_info is an internal structure for smartreflex driver. The intention behind this patch is all external API's pass the srid and internally the driver static APIs take sr_info as parameter. I did not realize this point till now when I was doing the actual changes and hence the late reply :-)

Regards
Thara

>>
>>Kevin

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

* Re: [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c
  2010-05-13  7:13                           ` Gopinath, Thara
@ 2010-05-14 17:14                             ` Kevin Hilman
  0 siblings, 0 replies; 43+ messages in thread
From: Kevin Hilman @ 2010-05-14 17:14 UTC (permalink / raw)
  To: Gopinath, Thara
  Cc: linux-omap, paul, Cousson, Benoit, Sripathy, Vishwanath, Sawant, Anand

"Gopinath, Thara" <thara@ti.com> writes:

>>>
>>>Thara Gopinath <thara@ti.com> writes:
>>>
>>>> This patch ensures that sr id is passed as a parameter only to
>>>> public APIs in smartreflex.c and other APIs in smartreflex.c
>>>> uses the omap_sr strucutres.
>>>>
>>>> Signed-off-by: Thara Gopinath <thara@ti.com>
>>>
>>>Good change, but...
>>>

[...]

>>>
>>>... the class3 layer is still taking SR ID as a parameter and it
>>>should also just take an sr_info ptr.
>
> sr_info is an internal structure for smartreflex driver. The
> intention behind this patch is all external API's pass the srid and
> internally the driver static APIs take sr_info as parameter. 

OK, that makes sense.  I though I saw the usage of _sr_lookup() inside
the class driver which made me think it should just take sr_info.  But
looking again now, I see it's only using the id.

> I did not realize this point till now when I was doing the actual
> changes and hence the late reply :-)

no worries, thanks for clarifying.

Kevin

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

end of thread, other threads:[~2010-05-14 17:14 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-16  9:02 [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp Thara Gopinath
2010-04-16  9:02 ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Thara Gopinath
2010-04-16  9:02   ` [PATCHv3 02/22] OMAP3: PM: Create list to keep track of various smartreflex instances Thara Gopinath
2010-04-16  9:02     ` [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer Thara Gopinath
2010-04-16  9:02       ` [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs Thara Gopinath
2010-04-16  9:03         ` [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver Thara Gopinath
2010-04-16  9:03           ` [PATCHv3 06/22] OMAP3: PM: Correcting API names in samrtreflex driver Thara Gopinath
2010-04-16  9:03             ` [PATCHv3 07/22] OMAP3: PM: Smartreflex class related changes for smartreflex.c Thara Gopinath
2010-04-16  9:03               ` [PATCHv3 08/22] OMAP3: PM: Adding smartreflex class 3 driver Thara Gopinath
2010-04-16  9:03                 ` [PATCHv3 09/22] OMAP3: PM: Creating separate files for handling OMAP3 voltage related operations Thara Gopinath
2010-04-16  9:03                   ` [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver Thara Gopinath
2010-04-16  9:03                     ` [PATCHv3 11/22] OMAP3: PM: Removing VP1, VP2, SR1 and SR2 defintions Thara Gopinath
2010-04-16  9:03                       ` [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c Thara Gopinath
2010-04-16  9:03                         ` [PATCHv3 13/22] OMAP3: PM: Cleaning up of smartreflex header file Thara Gopinath
2010-04-16  9:03                           ` [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3 Thara Gopinath
2010-04-16  9:03                             ` [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default Thara Gopinath
2010-04-16  9:03                               ` [PATCHv3 16/22] OMAP3: PM: Correcting accessing of ERRCONFIG register in smartreflex.c Thara Gopinath
2010-04-16  9:03                                 ` [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence Thara Gopinath
2010-04-16  9:03                                   ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Thara Gopinath
2010-04-16  9:03                                     ` [PATCHv3 19/22] OMAP3: PM: Disabling Smartreflex across both frequency and voltage scaling during DVFS Thara Gopinath
2010-04-16  9:03                                       ` [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling Thara Gopinath
2010-04-16  9:03                                         ` [PATCHv3 21/22] OMAP3: PM: Enabling Smartreflex Class 3 driver by default in pm defconfig Thara Gopinath
2010-04-16  9:03                                           ` [PATCHv3 22/22] OMAP3: PM: Fix crash when enabling SmartReflex on non-supported OMAPs Thara Gopinath
2010-04-27 16:23                                         ` [PATCHv3 20/22] OMAP3: PM: VP force update method of voltage scaling Kevin Hilman
2010-04-27 19:16                                         ` Kevin Hilman
2010-04-27 19:14                                     ` [PATCHv3 18/22] OMAP3: PM: Optional reset of voltage during Smartreflex disable Kevin Hilman
2010-05-05 11:03                                       ` Gopinath, Thara
2010-05-05 21:39                                         ` Kevin Hilman
2010-04-27 19:12                                   ` [PATCHv3 17/22] OMAP3: PM: Implement latest h/w recommendations for SR and VP registers and SR VP enable disable sequence Kevin Hilman
2010-04-27 19:10                               ` [PATCHv3 15/22] OMAP3: PM: Support for enabling smartreflex autocompensation by default Kevin Hilman
2010-04-27 19:06                             ` [PATCHv3 14/22] OMAP3: PM: Configurations for Smartreflex Class 2 and Smartreflex Class 3 Kevin Hilman
2010-04-27 19:02                         ` [PATCHv3 12/22] OMAP3: PM: Minimizing the passing around of sr id in smartreflex.c Kevin Hilman
2010-05-13  7:13                           ` Gopinath, Thara
2010-05-14 17:14                             ` Kevin Hilman
2010-04-27 18:58                     ` [PATCHv3 10/22] OMAP3: PM: Adding voltage table support in voltage driver Kevin Hilman
2010-04-27 18:43           ` [PATCHv3 05/22] OMAP3: PM: Remove OPP id dependency from smartreflex driver Kevin Hilman
2010-04-27 17:57         ` [PATCHv3 04/22] OMAP3: PM: Move smartreflex autocompensation enable disable hooks to PM debugfs Kevin Hilman
2010-04-27 17:47       ` [PATCHv3 03/22] OMAP3: PM: Convert smartreflex driver into a platform driver using hwmods and omap-device layer Kevin Hilman
2010-04-27 17:34   ` [PATCHv3 01/22] OMAP3: PM: Adding hwmod data for Smartreflex Kevin Hilman
2010-04-20 23:49 ` [PATCHv3 00/22] OMAP3: PM: Smartreflex and voltage revamp Kevin Hilman
2010-04-27 19:18 ` Kevin Hilman
2010-04-30  6:09   ` Gopinath, Thara
2010-04-30 14:22     ` Kevin Hilman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.