mirror of
https://git.yoctoproject.org/poky
synced 2026-02-08 01:36:38 +01:00
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@4869 311d38ba-8fff-0310-9ca6-ca027cbcb966
1002 lines
30 KiB
Diff
1002 lines
30 KiB
Diff
From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
|
|
To: linux-omap@vger.kernel.org
|
|
Cc: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
|
|
Subject: [PATCH 3/3] ARM: OMAP: SmartReflex driver: integration to linux-omap
|
|
Date: Fri, 6 Jun 2008 12:49:49 +0300
|
|
Message-Id: <1212745789-13926-3-git-send-email-ext-kalle.jokiniemi@nokia.com>
|
|
|
|
- Changed register accesses to use prm_{read,write}_mod_reg and
|
|
prm_{set,clear,rmw}_mod_reg_bits() functions instread of
|
|
"REG_X = REG_Y" type accesses.
|
|
|
|
- Changed direct register clock enables/disables to clockframework calls.
|
|
|
|
- replaced cpu-related #ifdefs with if (cpu_is_xxxx()) calls.
|
|
|
|
- Added E-fuse support: Use silicon characteristics parameters from E-fuse
|
|
|
|
- added smartreflex_disable/enable calls to pm34xx.c suspend function.
|
|
|
|
- Added "SmartReflex support" entry into Kconfig under "System type->TI OMAP
|
|
Implementations". It depends on ARCH_OMAP34XX and TWL4030_CORE.
|
|
|
|
- Added "SmartReflex testing support" Kconfig option for using hard coded
|
|
software parameters instead of E-fuse parameters.
|
|
|
|
Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
|
|
---
|
|
arch/arm/mach-omap2/Makefile | 3 +
|
|
arch/arm/mach-omap2/pm34xx.c | 9 +
|
|
arch/arm/mach-omap2/smartreflex.c | 531 +++++++++++++++++++++++--------------
|
|
arch/arm/mach-omap2/smartreflex.h | 9 +-
|
|
arch/arm/plat-omap/Kconfig | 31 +++
|
|
5 files changed, 385 insertions(+), 198 deletions(-)
|
|
|
|
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
|
|
index 50c6657..f645b6e 100644
|
|
--- a/arch/arm/mach-omap2/Makefile
|
|
+++ b/arch/arm/mach-omap2/Makefile
|
|
@@ -25,6 +25,9 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
|
|
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
|
|
endif
|
|
|
|
+# SmartReflex driver
|
|
+obj-$(CONFIG_OMAP_SMARTREFLEX) += smartreflex.o
|
|
+
|
|
# Clock framework
|
|
obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o
|
|
obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o
|
|
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
|
|
index 7e775cc..3da4f47 100644
|
|
--- a/arch/arm/mach-omap2/pm34xx.c
|
|
+++ b/arch/arm/mach-omap2/pm34xx.c
|
|
@@ -36,6 +36,7 @@
|
|
|
|
#include "prm.h"
|
|
#include "pm.h"
|
|
+#include "smartreflex.h"
|
|
|
|
struct power_state {
|
|
struct powerdomain *pwrdm;
|
|
@@ -256,6 +257,10 @@ static int omap3_pm_suspend(void)
|
|
struct power_state *pwrst;
|
|
int state, ret = 0;
|
|
|
|
+ /* XXX Disable smartreflex before entering suspend */
|
|
+ disable_smartreflex(SR1);
|
|
+ disable_smartreflex(SR2);
|
|
+
|
|
/* Read current next_pwrsts */
|
|
list_for_each_entry(pwrst, &pwrst_list, node)
|
|
pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
|
|
@@ -287,6 +292,10 @@ restore:
|
|
printk(KERN_INFO "Successfully put all powerdomains "
|
|
"to target state\n");
|
|
|
|
+ /* XXX Enable smartreflex after suspend */
|
|
+ enable_smartreflex(SR1);
|
|
+ enable_smartreflex(SR2);
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
|
|
index dae7460..0b10a5d 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) 2008 Nokia Corporation
|
|
+ * Kalle Jokiniemi
|
|
+ *
|
|
* Copyright (C) 2007 Texas Instruments, Inc.
|
|
* Lesly A M <x0080970@ti.com>
|
|
*
|
|
@@ -20,13 +23,16 @@
|
|
#include <linux/err.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/sysfs.h>
|
|
-
|
|
-#include <asm/arch/prcm.h>
|
|
-#include <asm/arch/power_companion.h>
|
|
+#include <linux/kobject.h>
|
|
+#include <linux/i2c/twl4030.h>
|
|
#include <linux/io.h>
|
|
|
|
-#include "prcm-regs.h"
|
|
+#include <asm/arch/omap34xx.h>
|
|
+#include <asm/arch/control.h>
|
|
+
|
|
+#include "prm.h"
|
|
#include "smartreflex.h"
|
|
+#include "prm-regbits-34xx.h"
|
|
|
|
|
|
/* #define DEBUG_SR 1 */
|
|
@@ -37,11 +43,16 @@
|
|
# define DPRINTK(fmt, args...)
|
|
#endif
|
|
|
|
+/* XXX: These should be relocated where-ever the OPP implementation will be */
|
|
+u32 current_vdd1_opp;
|
|
+u32 current_vdd2_opp;
|
|
+
|
|
struct omap_sr{
|
|
int srid;
|
|
int is_sr_reset;
|
|
int is_autocomp_active;
|
|
struct clk *fck;
|
|
+ u32 clk_length;
|
|
u32 req_opp_no;
|
|
u32 opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue, opp5_nvalue;
|
|
u32 senp_mod, senn_mod;
|
|
@@ -53,6 +64,7 @@ static struct omap_sr sr1 = {
|
|
.srid = SR1,
|
|
.is_sr_reset = 1,
|
|
.is_autocomp_active = 0,
|
|
+ .clk_length = 0,
|
|
.srbase_addr = OMAP34XX_SR1_BASE,
|
|
};
|
|
|
|
@@ -60,6 +72,7 @@ static struct omap_sr sr2 = {
|
|
.srid = SR2,
|
|
.is_sr_reset = 1,
|
|
.is_autocomp_active = 0,
|
|
+ .clk_length = 0,
|
|
.srbase_addr = OMAP34XX_SR2_BASE,
|
|
};
|
|
|
|
@@ -85,8 +98,6 @@ static inline u32 sr_read_reg(struct omap_sr *sr, int offset)
|
|
return omap_readl(sr->srbase_addr + offset);
|
|
}
|
|
|
|
-
|
|
-#ifndef USE_EFUSE_VALUES
|
|
static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
|
|
{
|
|
u32 gn, rn, mul;
|
|
@@ -100,7 +111,21 @@ static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
|
|
}
|
|
}
|
|
}
|
|
-#endif
|
|
+
|
|
+static void sr_clk_get(struct omap_sr *sr)
|
|
+{
|
|
+ if (sr->srid == SR1) {
|
|
+ sr->fck = clk_get(NULL, "sr1_fck");
|
|
+ if (IS_ERR(sr->fck))
|
|
+ printk(KERN_ERR "Could not get sr1_fck\n");
|
|
+
|
|
+ } else if (sr->srid == SR2) {
|
|
+ sr->fck = clk_get(NULL, "sr2_fck");
|
|
+ if (IS_ERR(sr->fck))
|
|
+ printk(KERN_ERR "Could not get sr2_fck\n");
|
|
+
|
|
+ }
|
|
+}
|
|
|
|
static int sr_clk_enable(struct omap_sr *sr)
|
|
{
|
|
@@ -131,22 +156,86 @@ static int sr_clk_disable(struct omap_sr *sr)
|
|
return 0;
|
|
}
|
|
|
|
-static void sr_set_nvalues(struct omap_sr *sr)
|
|
+static void sr_set_clk_length(struct omap_sr *sr)
|
|
+{
|
|
+ struct clk *osc_sys_ck;
|
|
+ u32 sys_clk = 0;
|
|
+
|
|
+ osc_sys_ck = clk_get(NULL, "osc_sys_ck");
|
|
+ sys_clk = clk_get_rate(osc_sys_ck);
|
|
+ clk_put(osc_sys_ck);
|
|
+
|
|
+ switch (sys_clk) {
|
|
+ case 12000000:
|
|
+ sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
|
|
+ break;
|
|
+ case 13000000:
|
|
+ sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
|
|
+ break;
|
|
+ case 19200000:
|
|
+ sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
|
|
+ break;
|
|
+ case 26000000:
|
|
+ sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
|
|
+ break;
|
|
+ case 38400000:
|
|
+ sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
|
|
+ break;
|
|
+ default :
|
|
+ printk(KERN_ERR "Invalid sysclk value: %d\n", sys_clk);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+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)
|
|
{
|
|
-#ifdef USE_EFUSE_VALUES
|
|
- u32 n1, n2;
|
|
-#else
|
|
u32 senpval, sennval;
|
|
u32 senpgain, senngain;
|
|
u32 rnsenp, rnsenn;
|
|
-#endif
|
|
|
|
if (sr->srid == SR1) {
|
|
-#ifdef USE_EFUSE_VALUES
|
|
- /* Read values for VDD1 from EFUSE */
|
|
-#else
|
|
- /* since E-Fuse Values are not available, calculating the
|
|
- * reciprocal of the SenN and SenP values for SR1
|
|
+ /* Calculating the reciprocal of the SenN and SenP values
|
|
+ * for SR1
|
|
*/
|
|
sr->senp_mod = 0x03; /* SenN-M5 enabled */
|
|
sr->senn_mod = 0x03;
|
|
@@ -216,15 +305,16 @@ static void sr_set_nvalues(struct omap_sr *sr)
|
|
(rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
(rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
|
|
+ /* XXX The clocks are enabled in the startup and NVALUE is
|
|
+ * set also there. Disabling this for now, but this could
|
|
+ * be related to dynamic sleep during boot */
|
|
+#if 0
|
|
sr_clk_enable(sr);
|
|
sr_write_reg(sr, NVALUERECIPROCAL, sr->opp3_nvalue);
|
|
sr_clk_disable(sr);
|
|
-
|
|
#endif
|
|
+
|
|
} else if (sr->srid == SR2) {
|
|
-#ifdef USE_EFUSE_VALUES
|
|
- /* Read values for VDD2 from EFUSE */
|
|
-#else
|
|
/* since E-Fuse Values are not available, calculating the
|
|
* reciprocal of the SenN and SenP values for SR2
|
|
*/
|
|
@@ -269,134 +359,163 @@ static void sr_set_nvalues(struct omap_sr *sr)
|
|
(senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
(rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
(rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
-
|
|
-#endif
|
|
}
|
|
|
|
}
|
|
|
|
+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;
|
|
|
|
if (srid == SR1) {
|
|
vpconfig = PRM_VP1_CONFIG_ERROROFFSET | PRM_VP1_CONFIG_ERRORGAIN
|
|
- | PRM_VP1_CONFIG_INITVOLTAGE | PRM_VP1_CONFIG_TIMEOUTEN;
|
|
-
|
|
- PRM_VP1_CONFIG = vpconfig;
|
|
- PRM_VP1_VSTEPMIN = PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
|
|
- PRM_VP1_VSTEPMIN_VSTEPMIN;
|
|
-
|
|
- PRM_VP1_VSTEPMAX = PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
|
|
- PRM_VP1_VSTEPMAX_VSTEPMAX;
|
|
-
|
|
- PRM_VP1_VLIMITTO = PRM_VP1_VLIMITTO_VDDMAX |
|
|
- PRM_VP1_VLIMITTO_VDDMIN | PRM_VP1_VLIMITTO_TIMEOUT;
|
|
-
|
|
- PRM_VP1_CONFIG |= PRM_VP1_CONFIG_INITVDD;
|
|
- PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_INITVDD;
|
|
+ | PRM_VP1_CONFIG_INITVOLTAGE
|
|
+ | PRM_VP1_CONFIG_TIMEOUTEN;
|
|
+
|
|
+ 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);
|
|
|
|
} else if (srid == SR2) {
|
|
vpconfig = PRM_VP2_CONFIG_ERROROFFSET | PRM_VP2_CONFIG_ERRORGAIN
|
|
- | PRM_VP2_CONFIG_INITVOLTAGE | PRM_VP2_CONFIG_TIMEOUTEN;
|
|
-
|
|
- PRM_VP2_CONFIG = vpconfig;
|
|
- PRM_VP2_VSTEPMIN = PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
|
|
- PRM_VP2_VSTEPMIN_VSTEPMIN;
|
|
-
|
|
- PRM_VP2_VSTEPMAX = PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
|
|
- PRM_VP2_VSTEPMAX_VSTEPMAX;
|
|
-
|
|
- PRM_VP2_VLIMITTO = PRM_VP2_VLIMITTO_VDDMAX |
|
|
- PRM_VP2_VLIMITTO_VDDMIN | PRM_VP2_VLIMITTO_TIMEOUT;
|
|
-
|
|
- PRM_VP2_CONFIG |= PRM_VP2_CONFIG_INITVDD;
|
|
- PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_INITVDD;
|
|
+ | PRM_VP2_CONFIG_INITVOLTAGE
|
|
+ | PRM_VP2_CONFIG_TIMEOUTEN;
|
|
+
|
|
+ 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_VP2_CONFIG_INITVDD, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VP2_CONFIG_OFFSET);
|
|
+ /* Reset initVDD copy trigger bit */
|
|
+ prm_clear_mod_reg_bits(PRM_VP2_CONFIG_INITVDD, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VP2_CONFIG_OFFSET);
|
|
|
|
}
|
|
}
|
|
|
|
static void sr_configure_vc(void)
|
|
{
|
|
- PRM_VC_SMPS_SA =
|
|
- (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA1_SHIFT) |
|
|
- (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA0_SHIFT);
|
|
-
|
|
- PRM_VC_SMPS_VOL_RA = (R_VDD2_SR_CONTROL << PRM_VC_SMPS_VOLRA1_SHIFT) |
|
|
- (R_VDD1_SR_CONTROL << PRM_VC_SMPS_VOLRA0_SHIFT);
|
|
-
|
|
- PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL0_ON << PRM_VC_CMD_ON_SHIFT) |
|
|
- (PRM_VC_CMD_VAL0_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
|
|
- (PRM_VC_CMD_VAL0_RET << PRM_VC_CMD_RET_SHIFT) |
|
|
- (PRM_VC_CMD_VAL0_OFF << PRM_VC_CMD_OFF_SHIFT);
|
|
-
|
|
- PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL1_ON << PRM_VC_CMD_ON_SHIFT) |
|
|
- (PRM_VC_CMD_VAL1_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
|
|
- (PRM_VC_CMD_VAL1_RET << PRM_VC_CMD_RET_SHIFT) |
|
|
- (PRM_VC_CMD_VAL1_OFF << PRM_VC_CMD_OFF_SHIFT);
|
|
-
|
|
- PRM_VC_CH_CONF = PRM_VC_CH_CONF_CMD1 | PRM_VC_CH_CONF_RAV1;
|
|
-
|
|
- PRM_VC_I2C_CFG = PRM_VC_I2C_CFG_MCODE | PRM_VC_I2C_CFG_HSEN
|
|
- | PRM_VC_I2C_CFG_SREN;
|
|
+ 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((OMAP3430_VC_CMD_VAL0_ON <<
|
|
+ OMAP3430_VC_CMD_ON_SHIFT) |
|
|
+ (OMAP3430_VC_CMD_VAL0_ONLP << OMAP3430_VC_CMD_ONLP_SHIFT) |
|
|
+ (OMAP3430_VC_CMD_VAL0_RET << OMAP3430_VC_CMD_RET_SHIFT) |
|
|
+ (OMAP3430_VC_CMD_VAL0_OFF << OMAP3430_VC_CMD_OFF_SHIFT),
|
|
+ OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
|
|
+
|
|
+ prm_write_mod_reg((OMAP3430_VC_CMD_VAL1_ON <<
|
|
+ OMAP3430_VC_CMD_ON_SHIFT) |
|
|
+ (OMAP3430_VC_CMD_VAL1_ONLP << OMAP3430_VC_CMD_ONLP_SHIFT) |
|
|
+ (OMAP3430_VC_CMD_VAL1_RET << OMAP3430_VC_CMD_RET_SHIFT) |
|
|
+ (OMAP3430_VC_CMD_VAL1_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_SREN,
|
|
+ OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VC_I2C_CFG_OFFSET);
|
|
|
|
/* Setup voltctrl and other setup times */
|
|
+ /* XXX CONFIG_SYSOFFMODE has not been implemented yet */
|
|
#ifdef CONFIG_SYSOFFMODE
|
|
- PRM_VOLTCTRL = PRM_VOLTCTRL_AUTO_OFF | PRM_VOLTCTRL_AUTO_RET;
|
|
- PRM_CLKSETUP = PRM_CLKSETUP_DURATION;
|
|
- PRM_VOLTSETUP1 = (PRM_VOLTSETUP_TIME2 << PRM_VOLTSETUP_TIME2_OFFSET) |
|
|
- (PRM_VOLTSETUP_TIME1 << PRM_VOLTSETUP_TIME1_OFFSET);
|
|
- PRM_VOLTOFFSET = PRM_VOLTOFFSET_DURATION;
|
|
- PRM_VOLTSETUP2 = PRM_VOLTSETUP2_DURATION;
|
|
+ prm_write_mod_reg(OMAP3430_AUTO_OFF | OMAP3430_AUTO_RET,
|
|
+ OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VOLTCTRL_OFFSET);
|
|
+
|
|
+ prm_write_mod_reg(OMAP3430_CLKSETUP_DURATION, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_CLKSETUP_OFFSET);
|
|
+ prm_write_mod_reg((OMAP3430_VOLTSETUP_TIME2 <<
|
|
+ OMAP3430_VOLTSETUP_TIME2_OFFSET) |
|
|
+ (OMAP3430_VOLTSETUP_TIME1 <<
|
|
+ OMAP3430_VOLTSETUP_TIME1_OFFSET),
|
|
+ OMAP3430_GR_MOD, OMAP3_PRM_VOLTSETUP1_OFFSET);
|
|
+
|
|
+ prm_write_mod_reg(OMAP3430_VOLTOFFSET_DURATION, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VOLTOFFSET_OFFSET);
|
|
+ prm_write_mod_reg(OMAP3430_VOLTSETUP2_DURATION, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VOLTSETUP2_OFFSET);
|
|
#else
|
|
- PRM_VOLTCTRL |= PRM_VOLTCTRL_AUTO_RET;
|
|
+ prm_set_mod_reg_bits(OMAP3430_AUTO_RET, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VOLTCTRL_OFFSET);
|
|
#endif
|
|
|
|
}
|
|
|
|
-
|
|
static void sr_configure(struct omap_sr *sr)
|
|
{
|
|
- u32 sys_clk, sr_clk_length = 0;
|
|
u32 sr_config;
|
|
u32 senp_en , senn_en;
|
|
|
|
+ if (sr->clk_length == 0)
|
|
+ sr_set_clk_length(sr);
|
|
+
|
|
senp_en = sr->senp_mod;
|
|
senn_en = sr->senn_mod;
|
|
-
|
|
- sys_clk = prcm_get_system_clock_speed();
|
|
-
|
|
- switch (sys_clk) {
|
|
- case 12000:
|
|
- sr_clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
|
|
- break;
|
|
- case 13000:
|
|
- sr_clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
|
|
- break;
|
|
- case 19200:
|
|
- sr_clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
|
|
- break;
|
|
- case 26000:
|
|
- sr_clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
|
|
- break;
|
|
- case 38400:
|
|
- sr_clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
|
|
- break;
|
|
- default :
|
|
- printk(KERN_ERR "Invalid sysclk value\n");
|
|
- break;
|
|
- }
|
|
-
|
|
- DPRINTK(KERN_DEBUG "SR : sys clk %lu\n", sys_clk);
|
|
if (sr->srid == SR1) {
|
|
sr_config = SR1_SRCONFIG_ACCUMDATA |
|
|
- (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
|
|
+ (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;
|
|
-
|
|
+ DPRINTK(KERN_DEBUG "setting SRCONFIG1 to 0x%08lx\n",
|
|
+ (unsigned long int) sr_config);
|
|
sr_write_reg(sr, SRCONFIG, sr_config);
|
|
|
|
sr_write_reg(sr, AVGWEIGHT, SR1_AVGWEIGHT_SENPAVGWEIGHT |
|
|
@@ -408,18 +527,18 @@ static void sr_configure(struct omap_sr *sr)
|
|
|
|
} else if (sr->srid == SR2) {
|
|
sr_config = SR2_SRCONFIG_ACCUMDATA |
|
|
- (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
|
|
+ (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;
|
|
|
|
+ DPRINTK(KERN_DEBUG "setting SRCONFIG2 to 0x%08lx\n",
|
|
+ (unsigned long int) sr_config);
|
|
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));
|
|
@@ -428,9 +547,9 @@ static void sr_configure(struct omap_sr *sr)
|
|
sr->is_sr_reset = 0;
|
|
}
|
|
|
|
-static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
|
|
+static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
|
|
{
|
|
- u32 nvalue_reciprocal, current_nvalue;
|
|
+ u32 nvalue_reciprocal;
|
|
|
|
sr->req_opp_no = target_opp_no;
|
|
|
|
@@ -472,11 +591,10 @@ static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
|
|
}
|
|
}
|
|
|
|
- current_nvalue = sr_read_reg(sr, NVALUERECIPROCAL);
|
|
-
|
|
- if (current_nvalue == nvalue_reciprocal) {
|
|
- DPRINTK("System is already at the desired voltage level\n");
|
|
- return;
|
|
+ if (nvalue_reciprocal == 0) {
|
|
+ printk(KERN_NOTICE "OPP%d doesn't support SmartReflex\n",
|
|
+ target_opp_no);
|
|
+ return SR_FALSE;
|
|
}
|
|
|
|
sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
|
|
@@ -485,18 +603,19 @@ static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
|
|
sr_modify_reg(sr, ERRCONFIG,
|
|
(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
|
|
(ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
|
|
-
|
|
if (sr->srid == SR1) {
|
|
/* Enable VP1 */
|
|
- PRM_VP1_CONFIG |= PRM_VP1_CONFIG_VPENABLE;
|
|
+ prm_set_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VP1_CONFIG_OFFSET);
|
|
} else if (sr->srid == SR2) {
|
|
/* Enable VP2 */
|
|
- PRM_VP2_CONFIG |= PRM_VP2_CONFIG_VPENABLE;
|
|
+ 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 SR_TRUE;
|
|
}
|
|
|
|
static void sr_disable(struct omap_sr *sr)
|
|
@@ -507,11 +626,13 @@ static void sr_disable(struct omap_sr *sr)
|
|
sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
|
|
|
|
if (sr->srid == SR1) {
|
|
- /* Enable VP1 */
|
|
- PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
|
|
+ /* Disable VP1 */
|
|
+ prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VP1_CONFIG_OFFSET);
|
|
} else if (sr->srid == SR2) {
|
|
- /* Enable VP2 */
|
|
- PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
|
|
+ /* Disable VP2 */
|
|
+ prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VP2_CONFIG_OFFSET);
|
|
}
|
|
}
|
|
|
|
@@ -535,7 +656,12 @@ void sr_start_vddautocomap(int srid, u32 target_opp_no)
|
|
srid);
|
|
|
|
sr->is_autocomp_active = 1;
|
|
- sr_enable(sr, target_opp_no);
|
|
+ if (!sr_enable(sr, target_opp_no)) {
|
|
+ printk(KERN_WARNING "SR%d: VDD autocomp not activated\n", srid);
|
|
+ sr->is_autocomp_active = 0;
|
|
+ if (sr->is_sr_reset == 1)
|
|
+ sr_clk_disable(sr);
|
|
+ }
|
|
}
|
|
EXPORT_SYMBOL(sr_start_vddautocomap);
|
|
|
|
@@ -574,20 +700,18 @@ void enable_smartreflex(int srid)
|
|
|
|
if (sr->is_autocomp_active == 1) {
|
|
if (sr->is_sr_reset == 1) {
|
|
- if (srid == SR1) {
|
|
- /* Enable SR clks */
|
|
- CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
|
|
- target_opp_no = get_opp_no(current_vdd1_opp);
|
|
+ /* Enable SR clks */
|
|
+ sr_clk_enable(sr);
|
|
|
|
- } else if (srid == SR2) {
|
|
- /* Enable SR clks */
|
|
- CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
|
|
+ if (srid == SR1)
|
|
+ target_opp_no = get_opp_no(current_vdd1_opp);
|
|
+ else if (srid == SR2)
|
|
target_opp_no = get_opp_no(current_vdd2_opp);
|
|
- }
|
|
|
|
sr_configure(sr);
|
|
|
|
- sr_enable(sr, target_opp_no);
|
|
+ if (!sr_enable(sr, target_opp_no))
|
|
+ sr_clk_disable(sr);
|
|
}
|
|
}
|
|
}
|
|
@@ -602,15 +726,6 @@ void disable_smartreflex(int srid)
|
|
sr = &sr2;
|
|
|
|
if (sr->is_autocomp_active == 1) {
|
|
- if (srid == SR1) {
|
|
- /* Enable SR clk */
|
|
- CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
|
|
-
|
|
- } else if (srid == SR2) {
|
|
- /* Enable SR clk */
|
|
- CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
|
|
- }
|
|
-
|
|
if (sr->is_sr_reset == 0) {
|
|
|
|
sr->is_sr_reset = 1;
|
|
@@ -618,17 +733,18 @@ void disable_smartreflex(int srid)
|
|
sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
|
|
~SRCONFIG_SRENABLE);
|
|
|
|
+ /* Disable SR clk */
|
|
+ sr_clk_disable(sr);
|
|
if (sr->srid == SR1) {
|
|
- /* Disable SR clk */
|
|
- CM_FCLKEN_WKUP &= ~SR1_CLK_ENABLE;
|
|
- /* Enable VP1 */
|
|
- PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
|
|
-
|
|
+ /* Disable VP1 */
|
|
+ prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE,
|
|
+ OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VP1_CONFIG_OFFSET);
|
|
} else if (sr->srid == SR2) {
|
|
- /* Disable SR clk */
|
|
- CM_FCLKEN_WKUP &= ~SR2_CLK_ENABLE;
|
|
- /* Enable VP2 */
|
|
- PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
|
|
+ /* Disable VP2 */
|
|
+ prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE,
|
|
+ OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VP2_CONFIG_OFFSET);
|
|
}
|
|
}
|
|
}
|
|
@@ -638,7 +754,6 @@ void disable_smartreflex(int srid)
|
|
/* Voltage Scaling using SR VCBYPASS */
|
|
int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
|
|
{
|
|
- int ret;
|
|
int sr_status = 0;
|
|
u32 vdd, target_opp_no;
|
|
u32 vc_bypass_value;
|
|
@@ -651,39 +766,53 @@ int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
|
|
if (vdd == PRCM_VDD1) {
|
|
sr_status = sr_stop_vddautocomap(SR1);
|
|
|
|
- PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL_0 & ~PRM_VC_CMD_ON_MASK) |
|
|
- (vsel << PRM_VC_CMD_ON_SHIFT);
|
|
+ prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
|
|
+ (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 == PRCM_VDD2) {
|
|
sr_status = sr_stop_vddautocomap(SR2);
|
|
|
|
- PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL_1 & ~PRM_VC_CMD_ON_MASK) |
|
|
- (vsel << PRM_VC_CMD_ON_SHIFT);
|
|
+ prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
|
|
+ (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 = (vsel << PRM_VC_BYPASS_DATA_SHIFT) |
|
|
- (reg_addr << PRM_VC_BYPASS_REGADDR_SHIFT) |
|
|
- (R_SRI2C_SLAVE_ADDR << PRM_VC_BYPASS_SLAVEADDR_SHIFT);
|
|
+ vc_bypass_value = (vsel << OMAP3430_DATA_SHIFT) |
|
|
+ (reg_addr << OMAP3430_REGADDR_SHIFT) |
|
|
+ (R_SRI2C_SLAVE_ADDR << OMAP3430_SLAVEADDR_SHIFT);
|
|
|
|
- PRM_VC_BYPASS_VAL = vc_bypass_value;
|
|
+ prm_write_mod_reg(vc_bypass_value, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
|
|
|
|
- PRM_VC_BYPASS_VAL |= PRM_VC_BYPASS_VALID;
|
|
+ vc_bypass_value = prm_set_mod_reg_bits(OMAP3430_VALID, OMAP3430_GR_MOD,
|
|
+ OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
|
|
|
|
- DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, PRM_VC_BYPASS_VAL);
|
|
- DPRINTK("PRM_IRQST_MPU %X\n", PRM_IRQSTATUS_MPU);
|
|
+ DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, vc_bypass_value);
|
|
+ DPRINTK("PRM_IRQST_MPU %X\n", prm_read_mod_reg(OCP_MOD,
|
|
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET));
|
|
|
|
- while ((PRM_VC_BYPASS_VAL & PRM_VC_BYPASS_VALID) != 0x0) {
|
|
- ret = loop_wait(&loop_cnt, &retries_cnt, 10);
|
|
- if (ret != PRCM_PASS) {
|
|
+ while ((vc_bypass_value & OMAP3430_VALID) != 0x0) {
|
|
+ loop_cnt++;
|
|
+ if (retries_cnt > 10) {
|
|
printk(KERN_INFO "Loop count exceeded in check SR I2C"
|
|
"write\n");
|
|
- return ret;
|
|
+ return SR_FAIL;
|
|
+ }
|
|
+ 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);
|
|
}
|
|
|
|
- omap_udelay(T2_SMPS_UPDATE_DELAY);
|
|
+ udelay(T2_SMPS_UPDATE_DELAY);
|
|
|
|
if (sr_status) {
|
|
if (vdd == PRCM_VDD1)
|
|
@@ -696,13 +825,15 @@ int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
|
|
}
|
|
|
|
/* Sysfs interface to select SR VDD1 auto compensation */
|
|
-static ssize_t omap_sr_vdd1_autocomp_show(struct kset *subsys, char *buf)
|
|
+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);
|
|
}
|
|
|
|
-static ssize_t omap_sr_vdd1_autocomp_store(struct kset *subsys,
|
|
- const char *buf, size_t n)
|
|
+static ssize_t omap_sr_vdd1_autocomp_store(struct kobject *kobj,
|
|
+ struct kobj_attribute *attr,
|
|
+ const char *buf, size_t n)
|
|
{
|
|
u32 current_vdd1opp_no;
|
|
unsigned short value;
|
|
@@ -722,7 +853,7 @@ static ssize_t omap_sr_vdd1_autocomp_store(struct kset *subsys,
|
|
return n;
|
|
}
|
|
|
|
-static struct subsys_attribute sr_vdd1_autocomp = {
|
|
+static struct kobj_attribute sr_vdd1_autocomp = {
|
|
.attr = {
|
|
.name = __stringify(sr_vdd1_autocomp),
|
|
.mode = 0644,
|
|
@@ -732,13 +863,15 @@ static struct subsys_attribute sr_vdd1_autocomp = {
|
|
};
|
|
|
|
/* Sysfs interface to select SR VDD2 auto compensation */
|
|
-static ssize_t omap_sr_vdd2_autocomp_show(struct kset *subsys, char *buf)
|
|
+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);
|
|
}
|
|
|
|
-static ssize_t omap_sr_vdd2_autocomp_store(struct kset *subsys,
|
|
- const char *buf, size_t n)
|
|
+static ssize_t omap_sr_vdd2_autocomp_store(struct kobject *kobj,
|
|
+ struct kobj_attribute *attr,
|
|
+ const char *buf, size_t n)
|
|
{
|
|
u32 current_vdd2opp_no;
|
|
unsigned short value;
|
|
@@ -758,7 +891,7 @@ static ssize_t omap_sr_vdd2_autocomp_store(struct kset *subsys,
|
|
return n;
|
|
}
|
|
|
|
-static struct subsys_attribute sr_vdd2_autocomp = {
|
|
+static struct kobj_attribute sr_vdd2_autocomp = {
|
|
.attr = {
|
|
.name = __stringify(sr_vdd2_autocomp),
|
|
.mode = 0644,
|
|
@@ -774,15 +907,19 @@ static int __init omap3_sr_init(void)
|
|
int ret = 0;
|
|
u8 RdReg;
|
|
|
|
-#ifdef CONFIG_ARCH_OMAP34XX
|
|
- sr1.fck = clk_get(NULL, "sr1_fck");
|
|
- if (IS_ERR(sr1.fck))
|
|
- printk(KERN_ERR "Could not get sr1_fck\n");
|
|
-
|
|
- sr2.fck = clk_get(NULL, "sr2_fck");
|
|
- if (IS_ERR(sr2.fck))
|
|
- printk(KERN_ERR "Could not get sr2_fck\n");
|
|
-#endif /* #ifdef CONFIG_ARCH_OMAP34XX */
|
|
+ if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
|
|
+ current_vdd1_opp = PRCM_VDD1_OPP3;
|
|
+ current_vdd2_opp = PRCM_VDD2_OPP3;
|
|
+ } else {
|
|
+ current_vdd1_opp = PRCM_VDD1_OPP1;
|
|
+ current_vdd2_opp = PRCM_VDD1_OPP1;
|
|
+ }
|
|
+ if (cpu_is_omap34xx()) {
|
|
+ sr_clk_get(&sr1);
|
|
+ sr_clk_get(&sr2);
|
|
+ }
|
|
+ sr_set_clk_length(&sr1);
|
|
+ sr_set_clk_length(&sr2);
|
|
|
|
/* Call the VPConfig, VCConfig, set N Values. */
|
|
sr_set_nvalues(&sr1);
|
|
@@ -794,22 +931,24 @@ static int __init omap3_sr_init(void)
|
|
sr_configure_vc();
|
|
|
|
/* Enable SR on T2 */
|
|
- ret = t2_in(PM_RECEIVER, &RdReg, R_DCDC_GLOBAL_CFG);
|
|
- RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
|
|
- ret |= t2_out(PM_RECEIVER, RdReg, R_DCDC_GLOBAL_CFG);
|
|
+ ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
|
|
+ R_DCDC_GLOBAL_CFG);
|
|
|
|
+ RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
|
|
+ ret |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, RdReg,
|
|
+ R_DCDC_GLOBAL_CFG);
|
|
|
|
printk(KERN_INFO "SmartReflex driver initialized\n");
|
|
|
|
- ret = subsys_create_file(&power_subsys, &sr_vdd1_autocomp);
|
|
+ ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
|
|
if (ret)
|
|
- printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
|
|
+ printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
|
|
|
|
- ret = subsys_create_file(&power_subsys, &sr_vdd2_autocomp);
|
|
+ ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
|
|
if (ret)
|
|
- printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
|
|
+ printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
|
|
|
|
return 0;
|
|
}
|
|
|
|
-arch_initcall(omap3_sr_init);
|
|
+late_initcall(omap3_sr_init);
|
|
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
|
|
index 2091a15..194429e 100644
|
|
--- a/arch/arm/mach-omap2/smartreflex.h
|
|
+++ b/arch/arm/mach-omap2/smartreflex.h
|
|
@@ -233,12 +233,18 @@
|
|
extern u32 current_vdd1_opp;
|
|
extern u32 current_vdd2_opp;
|
|
|
|
+#ifdef CONFIG_OMAP_SMARTREFLEX_TESTING
|
|
+#define SR_TESTING_NVALUES 1
|
|
+#else
|
|
+#define SR_TESTING_NVALUES 0
|
|
+#endif
|
|
+
|
|
/*
|
|
* Smartreflex module enable/disable interface.
|
|
* NOTE: if smartreflex is not enabled from sysfs, these functions will not
|
|
* do anything.
|
|
*/
|
|
-#if defined(CONFIG_ARCH_OMAP34XX) && defined(CONFIG_TWL4030_CORE)
|
|
+#ifdef CONFIG_OMAP_SMARTREFLEX
|
|
void enable_smartreflex(int srid);
|
|
void disable_smartreflex(int srid);
|
|
#else
|
|
@@ -246,7 +252,6 @@ static inline void enable_smartreflex(int srid) {}
|
|
static inline void disable_smartreflex(int srid) {}
|
|
#endif
|
|
|
|
-
|
|
#endif
|
|
|
|
|
|
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
|
|
index b085b07..960c13f 100644
|
|
--- a/arch/arm/plat-omap/Kconfig
|
|
+++ b/arch/arm/plat-omap/Kconfig
|
|
@@ -56,6 +56,37 @@ config OMAP_DEBUG_CLOCKDOMAIN
|
|
for every clockdomain register write. However, the
|
|
extra detail costs some memory.
|
|
|
|
+config OMAP_SMARTREFLEX
|
|
+ bool "SmartReflex support"
|
|
+ depends on ARCH_OMAP34XX && TWL4030_CORE
|
|
+ help
|
|
+ Say Y if you want to enable SmartReflex.
|
|
+
|
|
+ SmartReflex can perform continuous dynamic voltage
|
|
+ scaling around the nominal operating point voltage
|
|
+ according to silicon characteristics and operating
|
|
+ conditions. Enabling SmartReflex reduces power
|
|
+ consumption.
|
|
+
|
|
+ Please note, that by default SmartReflex is only
|
|
+ initialized. To enable the automatic voltage
|
|
+ compensation for VDD1 and VDD2, user must write 1 to
|
|
+ /sys/power/sr_vddX_autocomp, where X is 1 or 2.
|
|
+
|
|
+config OMAP_SMARTREFLEX_TESTING
|
|
+ bool "Smartreflex testing support"
|
|
+ depends on OMAP_SMARTREFLEX
|
|
+ default n
|
|
+ help
|
|
+ Say Y if you want to enable SmartReflex testing with SW hardcoded
|
|
+ NVALUES intead of E-fuse NVALUES set in factory silicon testing.
|
|
+
|
|
+ In some devices the E-fuse values have not been set, even though
|
|
+ SmartReflex modules are included. Using these hardcoded values set
|
|
+ in software, one can test the SmartReflex features without E-fuse.
|
|
+
|
|
+ WARNING: Enabling this option may cause your device to hang!
|
|
+
|
|
config OMAP_RESET_CLOCKS
|
|
bool "Reset unused clocks during boot"
|
|
depends on ARCH_OMAP
|
|
--
|
|
1.5.4.3
|