mirror of
https://git.yoctoproject.org/poky
synced 2026-02-07 17:26:36 +01:00
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@4869 311d38ba-8fff-0310-9ca6-ca027cbcb966
1003 lines
26 KiB
Diff
1003 lines
26 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 1/3] ARM: OMAP: SmartReflex driver, reference source and header files
|
|
Date: Mon, 2 Jun 2008 14:30:12 +0300
|
|
|
|
The following patch set integrates TI's SmartReflex driver. SmartReflex is a
|
|
module that adjusts OMAP3 VDD1 and VDD2 operating voltages around the nominal
|
|
values of current operating point depending on silicon characteristics and
|
|
operating conditions.
|
|
|
|
The driver creates two sysfs entries into /sys/power/ named "sr_vdd1_autocomp"
|
|
and "sr_vdd2_autocomp" which can be used to activate SmartReflex modules 1 and
|
|
2.
|
|
|
|
Use the following commands to enable SmartReflex:
|
|
|
|
echo -n 1 > /sys/power/sr_vdd1_autocomp
|
|
echo -n 1 > /sys/power/sr_vdd2_autocomp
|
|
|
|
To disable:
|
|
|
|
echo -n 0 > /sys/power/sr_vdd1_autocomp
|
|
echo -n 0 > /sys/power/sr_vdd2_autocomp
|
|
|
|
This particular patch adds the TI reference source and header files for
|
|
SmartReflex. Only modifications include minor styling to pass checkpatch.pl
|
|
test.
|
|
|
|
Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
|
|
---
|
|
arch/arm/mach-omap2/smartreflex.c | 815 +++++++++++++++++++++++++++++++++++++
|
|
arch/arm/mach-omap2/smartreflex.h | 136 ++++++
|
|
2 files changed, 951 insertions(+), 0 deletions(-)
|
|
create mode 100644 arch/arm/mach-omap2/smartreflex.c
|
|
create mode 100644 arch/arm/mach-omap2/smartreflex.h
|
|
|
|
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
|
|
new file mode 100644
|
|
index 0000000..dae7460
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-omap2/smartreflex.c
|
|
@@ -0,0 +1,815 @@
|
|
+/*
|
|
+ * linux/arch/arm/mach-omap3/smartreflex.c
|
|
+ *
|
|
+ * OMAP34XX SmartReflex Voltage Control
|
|
+ *
|
|
+ * 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/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/sysfs.h>
|
|
+
|
|
+#include <asm/arch/prcm.h>
|
|
+#include <asm/arch/power_companion.h>
|
|
+#include <linux/io.h>
|
|
+
|
|
+#include "prcm-regs.h"
|
|
+#include "smartreflex.h"
|
|
+
|
|
+
|
|
+/* #define DEBUG_SR 1 */
|
|
+#ifdef DEBUG_SR
|
|
+# define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__ ,\
|
|
+ ## args)
|
|
+#else
|
|
+# define DPRINTK(fmt, args...)
|
|
+#endif
|
|
+
|
|
+struct omap_sr{
|
|
+ int srid;
|
|
+ int is_sr_reset;
|
|
+ int is_autocomp_active;
|
|
+ struct clk *fck;
|
|
+ u32 req_opp_no;
|
|
+ u32 opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue, opp5_nvalue;
|
|
+ u32 senp_mod, senn_mod;
|
|
+ u32 srbase_addr;
|
|
+ u32 vpbase_addr;
|
|
+};
|
|
+
|
|
+static struct omap_sr sr1 = {
|
|
+ .srid = SR1,
|
|
+ .is_sr_reset = 1,
|
|
+ .is_autocomp_active = 0,
|
|
+ .srbase_addr = OMAP34XX_SR1_BASE,
|
|
+};
|
|
+
|
|
+static struct omap_sr sr2 = {
|
|
+ .srid = SR2,
|
|
+ .is_sr_reset = 1,
|
|
+ .is_autocomp_active = 0,
|
|
+ .srbase_addr = OMAP34XX_SR2_BASE,
|
|
+};
|
|
+
|
|
+static inline void sr_write_reg(struct omap_sr *sr, int offset, u32 value)
|
|
+{
|
|
+ omap_writel(value, sr->srbase_addr + offset);
|
|
+}
|
|
+
|
|
+static inline void sr_modify_reg(struct omap_sr *sr, int offset, u32 mask,
|
|
+ u32 value)
|
|
+{
|
|
+ u32 reg_val;
|
|
+
|
|
+ reg_val = omap_readl(sr->srbase_addr + offset);
|
|
+ reg_val &= ~mask;
|
|
+ reg_val |= value;
|
|
+
|
|
+ omap_writel(reg_val, sr->srbase_addr + offset);
|
|
+}
|
|
+
|
|
+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;
|
|
+
|
|
+ for (gn = 0; gn < GAIN_MAXLIMIT; gn++) {
|
|
+ mul = 1 << (gn + 8);
|
|
+ rn = mul / sensor;
|
|
+ if (rn < R_MAXLIMIT) {
|
|
+ *sengain = gn;
|
|
+ *rnsen = rn;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+static int sr_clk_enable(struct omap_sr *sr)
|
|
+{
|
|
+ if (clk_enable(sr->fck) != 0) {
|
|
+ printk(KERN_ERR "Could not enable sr%d_fck\n", sr->srid);
|
|
+ goto clk_enable_err;
|
|
+ }
|
|
+
|
|
+ /* set fclk- active , iclk- idle */
|
|
+ sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
|
|
+ SR_CLKACTIVITY_IOFF_FON);
|
|
+
|
|
+ return 0;
|
|
+
|
|
+clk_enable_err:
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+static int 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->fck);
|
|
+ sr->is_sr_reset = 1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void sr_set_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
|
|
+ */
|
|
+ sr->senp_mod = 0x03; /* SenN-M5 enabled */
|
|
+ sr->senn_mod = 0x03;
|
|
+
|
|
+ /* for OPP5 */
|
|
+ senpval = 0x848 + 0x330;
|
|
+ sennval = 0xacd + 0x330;
|
|
+
|
|
+ cal_reciprocal(senpval, &senpgain, &rnsenp);
|
|
+ cal_reciprocal(sennval, &senngain, &rnsenn);
|
|
+
|
|
+ sr->opp5_nvalue =
|
|
+ ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
|
|
+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
+
|
|
+ /* for OPP4 */
|
|
+ senpval = 0x727 + 0x2a0;
|
|
+ sennval = 0x964 + 0x2a0;
|
|
+
|
|
+ cal_reciprocal(senpval, &senpgain, &rnsenp);
|
|
+ cal_reciprocal(sennval, &senngain, &rnsenn);
|
|
+
|
|
+ sr->opp4_nvalue =
|
|
+ ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
|
|
+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
+
|
|
+ /* for OPP3 */
|
|
+ senpval = 0x655 + 0x200;
|
|
+ sennval = 0x85b + 0x200;
|
|
+
|
|
+ cal_reciprocal(senpval, &senpgain, &rnsenp);
|
|
+ cal_reciprocal(sennval, &senngain, &rnsenn);
|
|
+
|
|
+ sr->opp3_nvalue =
|
|
+ ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
|
|
+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
+
|
|
+ /* for OPP2 */
|
|
+ senpval = 0x3be + 0x1a0;
|
|
+ sennval = 0x506 + 0x1a0;
|
|
+
|
|
+ cal_reciprocal(senpval, &senpgain, &rnsenp);
|
|
+ cal_reciprocal(sennval, &senngain, &rnsenn);
|
|
+
|
|
+ sr->opp2_nvalue =
|
|
+ ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
|
|
+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
+
|
|
+ /* for OPP1 */
|
|
+ senpval = 0x28c + 0x100;
|
|
+ sennval = 0x373 + 0x100;
|
|
+
|
|
+ cal_reciprocal(senpval, &senpgain, &rnsenp);
|
|
+ cal_reciprocal(sennval, &senngain, &rnsenn);
|
|
+
|
|
+ sr->opp1_nvalue =
|
|
+ ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
|
|
+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
+
|
|
+ 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
|
|
+ */
|
|
+ sr->senp_mod = 0x03;
|
|
+ sr->senn_mod = 0x03;
|
|
+
|
|
+ /* for OPP3 */
|
|
+ senpval = 0x579 + 0x200;
|
|
+ sennval = 0x76f + 0x200;
|
|
+
|
|
+ cal_reciprocal(senpval, &senpgain, &rnsenp);
|
|
+ cal_reciprocal(sennval, &senngain, &rnsenn);
|
|
+
|
|
+ sr->opp3_nvalue =
|
|
+ ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
|
|
+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
+
|
|
+ /* for OPP2 */
|
|
+ senpval = 0x390 + 0x1c0;
|
|
+ sennval = 0x4f5 + 0x1c0;
|
|
+
|
|
+ cal_reciprocal(senpval, &senpgain, &rnsenp);
|
|
+ cal_reciprocal(sennval, &senngain, &rnsenn);
|
|
+
|
|
+ sr->opp2_nvalue =
|
|
+ ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
|
|
+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
+
|
|
+ /* for OPP1 */
|
|
+ senpval = 0x25d;
|
|
+ sennval = 0x359;
|
|
+
|
|
+ cal_reciprocal(senpval, &senpgain, &rnsenp);
|
|
+ cal_reciprocal(sennval, &senngain, &rnsenn);
|
|
+
|
|
+ sr->opp1_nvalue =
|
|
+ ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
|
|
+ (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
|
|
+ (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
|
|
+ (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
|
|
+
|
|
+#endif
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+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;
|
|
+
|
|
+ } 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;
|
|
+
|
|
+ }
|
|
+}
|
|
+
|
|
+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;
|
|
+
|
|
+ /* Setup voltctrl and other setup times */
|
|
+#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;
|
|
+#else
|
|
+ PRM_VOLTCTRL |= PRM_VOLTCTRL_AUTO_RET;
|
|
+#endif
|
|
+
|
|
+}
|
|
+
|
|
+
|
|
+static void sr_configure(struct omap_sr *sr)
|
|
+{
|
|
+ u32 sys_clk, sr_clk_length = 0;
|
|
+ u32 sr_config;
|
|
+ u32 senp_en , senn_en;
|
|
+
|
|
+ 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) |
|
|
+ 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 == SR2) {
|
|
+ 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));
|
|
+
|
|
+ }
|
|
+ sr->is_sr_reset = 0;
|
|
+}
|
|
+
|
|
+static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
|
|
+{
|
|
+ u32 nvalue_reciprocal, current_nvalue;
|
|
+
|
|
+ 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;
|
|
+ }
|
|
+ } 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;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ current_nvalue = sr_read_reg(sr, NVALUERECIPROCAL);
|
|
+
|
|
+ if (current_nvalue == nvalue_reciprocal) {
|
|
+ DPRINTK("System is already at the desired voltage level\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
|
|
+
|
|
+ /* Enable the interrupt */
|
|
+ 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;
|
|
+ } else if (sr->srid == SR2) {
|
|
+ /* Enable VP2 */
|
|
+ PRM_VP2_CONFIG |= PRM_VP2_CONFIG_VPENABLE;
|
|
+ }
|
|
+
|
|
+ /* SRCONFIG - enable SR */
|
|
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
|
|
+
|
|
+}
|
|
+
|
|
+static void sr_disable(struct omap_sr *sr)
|
|
+{
|
|
+ sr->is_sr_reset = 1;
|
|
+
|
|
+ /* SRCONFIG - disable SR */
|
|
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
|
|
+
|
|
+ if (sr->srid == SR1) {
|
|
+ /* Enable VP1 */
|
|
+ PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
|
|
+ } else if (sr->srid == SR2) {
|
|
+ /* Enable VP2 */
|
|
+ PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+void sr_start_vddautocomap(int srid, u32 target_opp_no)
|
|
+{
|
|
+ struct omap_sr *sr = NULL;
|
|
+
|
|
+ if (srid == SR1)
|
|
+ sr = &sr1;
|
|
+ else if (srid == SR2)
|
|
+ sr = &sr2;
|
|
+
|
|
+ if (sr->is_sr_reset == 1) {
|
|
+ sr_clk_enable(sr);
|
|
+ sr_configure(sr);
|
|
+ }
|
|
+
|
|
+ if (sr->is_autocomp_active == 1)
|
|
+ DPRINTK(KERN_WARNING "SR%d: VDD autocomp is already active\n",
|
|
+ srid);
|
|
+
|
|
+ sr->is_autocomp_active = 1;
|
|
+ sr_enable(sr, target_opp_no);
|
|
+}
|
|
+EXPORT_SYMBOL(sr_start_vddautocomap);
|
|
+
|
|
+int sr_stop_vddautocomap(int srid)
|
|
+{
|
|
+ struct omap_sr *sr = NULL;
|
|
+
|
|
+ if (srid == SR1)
|
|
+ sr = &sr1;
|
|
+ else if (srid == SR2)
|
|
+ sr = &sr2;
|
|
+
|
|
+ if (sr->is_autocomp_active == 1) {
|
|
+ sr_disable(sr);
|
|
+ sr_clk_disable(sr);
|
|
+ sr->is_autocomp_active = 0;
|
|
+ return SR_TRUE;
|
|
+ } else {
|
|
+ DPRINTK(KERN_WARNING "SR%d: VDD autocomp is not active\n",
|
|
+ srid);
|
|
+ return SR_FALSE;
|
|
+ }
|
|
+
|
|
+}
|
|
+EXPORT_SYMBOL(sr_stop_vddautocomap);
|
|
+
|
|
+void enable_smartreflex(int srid)
|
|
+{
|
|
+ u32 target_opp_no = 0;
|
|
+ struct omap_sr *sr = NULL;
|
|
+
|
|
+ if (srid == SR1)
|
|
+ sr = &sr1;
|
|
+ else if (srid == SR2)
|
|
+ sr = &sr2;
|
|
+
|
|
+ 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);
|
|
+
|
|
+ } else if (srid == SR2) {
|
|
+ /* Enable SR clks */
|
|
+ CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
|
|
+ target_opp_no = get_opp_no(current_vdd2_opp);
|
|
+ }
|
|
+
|
|
+ sr_configure(sr);
|
|
+
|
|
+ sr_enable(sr, target_opp_no);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void disable_smartreflex(int srid)
|
|
+{
|
|
+ struct omap_sr *sr = NULL;
|
|
+
|
|
+ if (srid == SR1)
|
|
+ sr = &sr1;
|
|
+ else if (srid == SR2)
|
|
+ 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;
|
|
+ /* SRCONFIG - disable SR */
|
|
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
|
|
+ ~SRCONFIG_SRENABLE);
|
|
+
|
|
+ if (sr->srid == SR1) {
|
|
+ /* Disable SR clk */
|
|
+ CM_FCLKEN_WKUP &= ~SR1_CLK_ENABLE;
|
|
+ /* Enable VP1 */
|
|
+ PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
|
|
+
|
|
+ } else if (sr->srid == SR2) {
|
|
+ /* Disable SR clk */
|
|
+ CM_FCLKEN_WKUP &= ~SR2_CLK_ENABLE;
|
|
+ /* Enable VP2 */
|
|
+ PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+/* 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;
|
|
+ u32 reg_addr = 0;
|
|
+ u32 loop_cnt = 0, retries_cnt = 0;
|
|
+
|
|
+ vdd = get_vdd(target_opp);
|
|
+ target_opp_no = get_opp_no(target_opp);
|
|
+
|
|
+ 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);
|
|
+ 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);
|
|
+ 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);
|
|
+
|
|
+ PRM_VC_BYPASS_VAL = vc_bypass_value;
|
|
+
|
|
+ PRM_VC_BYPASS_VAL |= PRM_VC_BYPASS_VALID;
|
|
+
|
|
+ DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, PRM_VC_BYPASS_VAL);
|
|
+ DPRINTK("PRM_IRQST_MPU %X\n", PRM_IRQSTATUS_MPU);
|
|
+
|
|
+ while ((PRM_VC_BYPASS_VAL & PRM_VC_BYPASS_VALID) != 0x0) {
|
|
+ ret = loop_wait(&loop_cnt, &retries_cnt, 10);
|
|
+ if (ret != PRCM_PASS) {
|
|
+ printk(KERN_INFO "Loop count exceeded in check SR I2C"
|
|
+ "write\n");
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ omap_udelay(T2_SMPS_UPDATE_DELAY);
|
|
+
|
|
+ if (sr_status) {
|
|
+ if (vdd == PRCM_VDD1)
|
|
+ sr_start_vddautocomap(SR1, target_opp_no);
|
|
+ else if (vdd == PRCM_VDD2)
|
|
+ sr_start_vddautocomap(SR2, target_opp_no);
|
|
+ }
|
|
+
|
|
+ return SR_PASS;
|
|
+}
|
|
+
|
|
+/* Sysfs interface to select SR VDD1 auto compensation */
|
|
+static ssize_t omap_sr_vdd1_autocomp_show(struct kset *subsys, 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)
|
|
+{
|
|
+ u32 current_vdd1opp_no;
|
|
+ unsigned short value;
|
|
+
|
|
+ if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
|
|
+ printk(KERN_ERR "sr_vdd1_autocomp: Invalid value\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ current_vdd1opp_no = get_opp_no(current_vdd1_opp);
|
|
+
|
|
+ if (value == 0)
|
|
+ sr_stop_vddautocomap(SR1);
|
|
+ else
|
|
+ sr_start_vddautocomap(SR1, current_vdd1opp_no);
|
|
+
|
|
+ return n;
|
|
+}
|
|
+
|
|
+static struct subsys_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 kset *subsys, 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)
|
|
+{
|
|
+ u32 current_vdd2opp_no;
|
|
+ unsigned short value;
|
|
+
|
|
+ if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
|
|
+ printk(KERN_ERR "sr_vdd2_autocomp: Invalid value\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ current_vdd2opp_no = get_opp_no(current_vdd2_opp);
|
|
+
|
|
+ if (value == 0)
|
|
+ sr_stop_vddautocomap(SR2);
|
|
+ else
|
|
+ sr_start_vddautocomap(SR2, current_vdd2opp_no);
|
|
+
|
|
+ return n;
|
|
+}
|
|
+
|
|
+static struct subsys_attribute sr_vdd2_autocomp = {
|
|
+ .attr = {
|
|
+ .name = __stringify(sr_vdd2_autocomp),
|
|
+ .mode = 0644,
|
|
+ },
|
|
+ .show = omap_sr_vdd2_autocomp_show,
|
|
+ .store = omap_sr_vdd2_autocomp_store,
|
|
+};
|
|
+
|
|
+
|
|
+
|
|
+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 */
|
|
+
|
|
+ /* Call the VPConfig, VCConfig, set N Values. */
|
|
+ sr_set_nvalues(&sr1);
|
|
+ sr_configure_vp(SR1);
|
|
+
|
|
+ sr_set_nvalues(&sr2);
|
|
+ sr_configure_vp(SR2);
|
|
+
|
|
+ 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);
|
|
+
|
|
+
|
|
+ printk(KERN_INFO "SmartReflex driver initialized\n");
|
|
+
|
|
+ ret = subsys_create_file(&power_subsys, &sr_vdd1_autocomp);
|
|
+ if (ret)
|
|
+ printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
|
|
+
|
|
+ ret = subsys_create_file(&power_subsys, &sr_vdd2_autocomp);
|
|
+ if (ret)
|
|
+ printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+arch_initcall(omap3_sr_init);
|
|
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
|
|
new file mode 100644
|
|
index 0000000..62907ef
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-omap2/smartreflex.h
|
|
@@ -0,0 +1,136 @@
|
|
+/*
|
|
+ * linux/arch/arm/mach-omap3/smartreflex.h
|
|
+ *
|
|
+ * 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.
|
|
+ */
|
|
+
|
|
+
|
|
+/* SR Modules */
|
|
+#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 (0x1 << 6)
|
|
+#define SR2_CLK_ENABLE (0x1 << 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 (0x1 << 3)
|
|
+#define PRM_VP1_CONFIG_INITVDD (0x1 << 2)
|
|
+#define PRM_VP1_CONFIG_FORCEUPDATE (0x1 << 1)
|
|
+#define PRM_VP1_CONFIG_VPENABLE (0x1 << 0)
|
|
+
|
|
+/* PRM_VP1_VSTEPMIN */
|
|
+#define PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN (0x01F4 << 8)
|
|
+#define PRM_VP1_VSTEPMIN_VSTEPMIN (0x01 << 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 (0x1 << 3)
|
|
+#define PRM_VP2_CONFIG_INITVDD (0x1 << 2)
|
|
+#define PRM_VP2_CONFIG_FORCEUPDATE (0x1 << 1)
|
|
+#define PRM_VP2_CONFIG_VPENABLE (0x1 << 0)
|
|
+
|
|
+/* PRM_VP2_VSTEPMIN */
|
|
+#define PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN (0x01F4 << 8)
|
|
+#define PRM_VP2_VSTEPMIN_VSTEPMIN (0x01 << 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)
|
|
+
|
|
+#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_SRCLKLENGTH_SHIFT 12
|
|
+#define SRCONFIG_SENNENABLE_SHIFT 5
|
|
+#define SRCONFIG_SENPENABLE_SHIFT 3
|
|
+
|
|
+#define SRCONFIG_SRENABLE (0x01 << 11)
|
|
+#define SRCONFIG_SENENABLE (0x01 << 10)
|
|
+#define SRCONFIG_ERRGEN_EN (0x01 << 9)
|
|
+#define SRCONFIG_MINMAXAVG_EN (0x01 << 8)
|
|
+
|
|
+#define SRCONFIG_DELAYCTRL (0x01 << 2)
|
|
+#define SRCONFIG_CLKCTRL (0x00 << 0)
|
|
+
|
|
+/* AVGWEIGHT */
|
|
+#define SR1_AVGWEIGHT_SENPAVGWEIGHT (0x03 << 2)
|
|
+#define SR1_AVGWEIGHT_SENNAVGWEIGHT (0x03 << 0)
|
|
+
|
|
+#define SR2_AVGWEIGHT_SENPAVGWEIGHT (0x01 << 2)
|
|
+#define SR2_AVGWEIGHT_SENNAVGWEIGHT (0x01 << 0)
|
|
+
|
|
+/* NVALUERECIPROCAL */
|
|
+#define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
|
|
+#define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
|
|
+#define NVALUERECIPROCAL_RNSENP_SHIFT 8
|
|
+#define NVALUERECIPROCAL_RNSENN_SHIFT 0
|
|
+
|
|
+/* ERRCONFIG */
|
|
+#define SR_CLKACTIVITY_MASK (0x03 << 20)
|
|
+#define SR_ERRWEIGHT_MASK (0x07 << 16)
|
|
+#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 (0x1 << 31)
|
|
+#define ERRCONFIG_VPBOUNDINTST (0x1 << 30)
|
|
+
|
|
+#define SR1_ERRWEIGHT (0x07 << 16)
|
|
+#define SR1_ERRMAXLIMIT (0x02 << 8)
|
|
+#define SR1_ERRMINLIMIT (0xFA << 0)
|
|
+
|
|
+#define SR2_ERRWEIGHT (0x07 << 16)
|
|
+#define SR2_ERRMAXLIMIT (0x02 << 8)
|
|
+#define SR2_ERRMINLIMIT (0xF9 << 0)
|
|
+
|
|
+extern u32 current_vdd1_opp;
|
|
+extern u32 current_vdd2_opp;
|
|
+extern struct kset power_subsys;
|
|
+
|
|
+extern inline int loop_wait(u32 *lcnt, u32 *rcnt, u32 delay);
|
|
+extern void omap_udelay(u32 udelay);
|
|
+
|
|
--
|
|
1.5.4.3
|