diff options
Diffstat (limited to 'packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch')
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch | 1002 |
1 files changed, 0 insertions, 1002 deletions
diff --git a/packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch b/packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch deleted file mode 100644 index 550a4f58be..0000000000 --- a/packages/linux/linux-omap2-git/beagleboard/0001-ARM-OMAP-SmartReflex-driver.patch +++ /dev/null @@ -1,1002 +0,0 @@ -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 |