diff -ur gnexus_kernel2/arch/arm/mach-omap2/omap_opp_data.h gnexus_kernel/arch/arm/mach-omap2/omap_opp_data.h --- gnexus_kernel2/arch/arm/mach-omap2/omap_opp_data.h 2012-03-11 13:11:56.540324278 +0100 +++ gnexus_kernel/arch/arm/mach-omap2/omap_opp_data.h 2012-03-11 12:56:49.043824254 +0100 @@ -75,9 +75,10 @@ * Initialization wrapper used to define SmartReflex process data * XXX Is this needed? Just use C99 initializers in data files? */ -#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain, _abb_type) \ +#define VOLT_DATA_DEFINE(_v_nom, _v_margin, _efuse_offs, _errminlimit, _errgain, _abb_type) \ { \ .volt_nominal = _v_nom, \ + .volt_margin = _v_margin, \ .sr_efuse_offs = _efuse_offs, \ .sr_errminlimit = _errminlimit, \ .vp_errgain = _errgain, \ diff -ur gnexus_kernel2/arch/arm/mach-omap2/opp3xxx_data.c gnexus_kernel/arch/arm/mach-omap2/opp3xxx_data.c --- gnexus_kernel2/arch/arm/mach-omap2/opp3xxx_data.c 2012-03-11 13:11:56.532324238 +0100 +++ gnexus_kernel/arch/arm/mach-omap2/opp3xxx_data.c 2012-03-11 12:56:04.963605654 +0100 @@ -36,12 +36,12 @@ #define OMAP3430_VDD_MPU_OPP5_UV 1350000 struct omap_volt_data omap34xx_vddmpu_volt_data[] = { - VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, 0, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, 0, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, 0, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, 0, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, 0, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; /* VDD2 */ @@ -51,10 +51,10 @@ #define OMAP3430_VDD_CORE_OPP3_UV 1150000 struct omap_volt_data omap34xx_vddcore_volt_data[] = { - VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, 0, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, 0, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, 0, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; /* OMAP 3430 MPU Core VDD dependency table */ @@ -85,11 +85,11 @@ #define OMAP3630_VDD_MPU_OPP1G_UV 1375000 struct omap_volt_data omap36xx_vddmpu_volt_data[] = { - VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27, OMAP_ABB_FAST_OPP), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, 0, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, 0, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, 0, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, 0, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27, OMAP_ABB_FAST_OPP), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; /* VDD2 */ @@ -98,9 +98,9 @@ #define OMAP3630_VDD_CORE_OPP100_UV 1200000 struct omap_volt_data omap36xx_vddcore_volt_data[] = { - VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, 0, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, 0, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; /* OPP data */ diff -ur gnexus_kernel2/arch/arm/mach-omap2/opp4xxx_data.c gnexus_kernel/arch/arm/mach-omap2/opp4xxx_data.c --- gnexus_kernel2/arch/arm/mach-omap2/opp4xxx_data.c 2012-03-11 13:11:56.532324238 +0100 +++ gnexus_kernel/arch/arm/mach-omap2/opp4xxx_data.c 2012-03-11 13:05:29.242403770 +0100 @@ -29,6 +29,18 @@ #include "pm.h" /* + * STD_FUSE_OPP_DPLL_1 contains info about ABB trim type for MPU/IVA. + * This bit field definition is specific for OMAP4460 TURBO alone. + * For future OMAP4 silicon it is possible that other efuse offsets might + * be used in addition to controlling other OPPs as well. + * This probably is an ugly location to put the DPLL trim details.. but, + * alternatives are even less attractive :( shrug.. + */ +#define OMAP4460_MPU_OPP_DPLL_TRIM BIT(18) +#define OMAP4460_MPU_OPP_DPLL_TURBO_RBB BIT(20) +#define OMAP4460_IVA_OPP_DPLL_TURBO_RBB BIT(21) + +/* * Structures containing OMAP4430 voltage supported and various * voltage dependent data for each VDD. */ @@ -39,11 +51,11 @@ #define OMAP4430_VDD_MPU_OPPNITRO_UV 1388000 struct omap_volt_data omap443x_vdd_mpu_volt_data[] = { - VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27, OMAP_ABB_FAST_OPP), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, 0, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, 0, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, 0, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, 0, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27, OMAP_ABB_FAST_OPP), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; #define OMAP4430_VDD_IVA_OPP50_UV 950000 @@ -51,19 +63,19 @@ #define OMAP4430_VDD_IVA_OPPTURBO_UV 1291000 struct omap_volt_data omap443x_vdd_iva_volt_data[] = { - VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, 0, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, 0, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, 0, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; #define OMAP4430_VDD_CORE_OPP50_UV 962000 #define OMAP4430_VDD_CORE_OPP100_UV 1127000 struct omap_volt_data omap443x_vdd_core_volt_data[] = { - VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, 0, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, 0, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; /* Dependency of domains are as follows for OMAP4430 (OPP based): @@ -159,11 +171,11 @@ #define OMAP4460_VDD_MPU_OPPNITRO_UV 1380000 struct omap_volt_data omap446x_vdd_mpu_volt_data[] = { - VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27, OMAP_ABB_FAST_OPP), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, 0, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, 0, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, 0, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, 0, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27, OMAP_ABB_FAST_OPP), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; #define OMAP4460_VDD_IVA_OPP50_UV 950000 @@ -172,11 +184,11 @@ #define OMAP4460_VDD_IVA_OPPNITRO_UV 1375000 struct omap_volt_data omap446x_vdd_iva_volt_data[] = { - VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), - VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23, OMAP_ABB_FAST_OPP), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, 13000, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, 0, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, 0, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23, OMAP_ABB_NOMINAL_OPP), + VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, 0, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23, OMAP_ABB_FAST_OPP), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; #define OMAP4460_VDD_CORE_OPP50_UV 962000 @@ -184,10 +196,10 @@ #define OMAP4460_VDD_CORE_OPP100_OV_UV 1250000 struct omap_volt_data omap446x_vdd_core_volt_data[] = { - VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16, OMAP_ABB_NONE), - VOLT_DATA_DEFINE(0, 0, 0, 0, 0), + VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, 38000, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, 13000, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, 13000, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16, OMAP_ABB_NONE), + VOLT_DATA_DEFINE(0, 0, 0, 0, 0, 0), }; /* OMAP 4460 MPU Core VDD dependency table */ @@ -284,28 +296,125 @@ }; /** - * omap4_mpu_opp_enable() - helper to enable the OPP + * omap4_opp_enable() - helper to enable the OPP + * @oh_name: name of the hwmod device * @freq: frequency to enable */ -static void __init omap4_mpu_opp_enable(unsigned long freq) +static void __init omap4_opp_enable(const char *oh_name, unsigned long freq) { - struct device *mpu_dev; + struct device *dev; int r; - mpu_dev = omap2_get_mpuss_device(); - if (!mpu_dev) { - pr_err("%s: no mpu_dev, did not enable f=%ld\n", __func__, - freq); + dev = omap_hwmod_name_get_dev(oh_name); + if (IS_ERR(dev)) { + pr_err("%s: no %s device, did not enable f=%ld\n", __func__, + oh_name, freq); return; } - r = opp_enable(mpu_dev, freq); + r = opp_enable(dev, freq); if (r < 0) - dev_err(mpu_dev, "%s: opp_enable failed(%d) f=%ld\n", __func__, + dev_err(dev, "%s: opp_enable failed(%d) f=%ld\n", __func__, r, freq); } /** + * omap4_abb_update() - update the ABB map for a specific voltage in table + * @vtable: voltage table to update + * @voltage: voltage whose voltage data needs update + * @abb_type: what ABB type should we update it to? + */ +static void __init omap4_abb_update(struct omap_volt_data *vtable, + unsigned long voltage, int abb_type) +{ + /* scan through and update the voltage table */ + while (vtable->volt_nominal) { + if (vtable->volt_nominal == voltage) { + vtable->abb_type = abb_type; + return; + } + vtable++; + } + /* WARN noticably to get the developer to fix */ + WARN(1, "%s: voltage %ld could not be set to ABB %d\n", + __func__, voltage, abb_type); +} + +/** + * omap4460_abb_update() - update the abb mapping quirks for OMAP4460 + */ +static void __init omap4460_abb_update(void) +{ + u32 reg, trim, rbb; + char *abb_msg; + int abb_type; + + /* + * Determine MPU ABB state at OPP_TURBO on 4460 + * + * On 4460 all OPPs have preset states for the MPU's ABB LDO, except + * for OPP_TURBO. OPP_TURBO may require bypass, FBB or RBB depending + * on a combination of characterisation data blown into eFuse register + * CONTROL_STD_FUSE_OPP_DPLL_1. + * + * Bits 18 & 19 of that register signify DPLL_MPU trim (see + * arch/arm/mach-omap2/omap4-trim-quirks.c). OPP_TURBO might put MPU's + * ABB LDO into bypass or FBB based on this value. + * + * Bit 20 siginifies if RBB should be enabled. If set it will always + * override the values from bits 18 & 19. + * + * The table below captures the valid combinations: + * trim rbb + * Bit 18|Bit 19|Bit 20|ABB type + * 0 0 0 bypass + * 0 1 0 bypass (invalid combination) + * 1 0 0 FBB (2.4GHz DPLL_MPU) + * 1 1 0 FBB (3GHz DPLL_MPU) + * 0 0 1 RBB + * 0 1 1 RBB (invalid combination) + * 1 0 1 RBB (2.4GHz DPLL_MPU) + * 1 1 1 RBB (3GHz DPLL_MPU) + */ + reg = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_1); + trim = reg & OMAP4460_MPU_OPP_DPLL_TRIM; + rbb = reg & OMAP4460_MPU_OPP_DPLL_TURBO_RBB; + + if (rbb) { + abb_type = OMAP_ABB_SLOW_OPP; + abb_msg = "Slow"; + } else if (!trim) { + abb_type = OMAP_ABB_NOMINAL_OPP; + abb_msg = "un-trimmed Nominal"; + } else { + abb_type = OMAP_ABB_FAST_OPP; + abb_msg = "Fast"; + } + + omap4_abb_update(omap446x_vdd_mpu_volt_data, + OMAP4460_VDD_MPU_OPPTURBO_UV, + abb_type); + pr_info("%s: MPU OPP Turbo: %s OPP ABB type\n", __func__, abb_msg); + + /* + * OMAP4460 IVA OPP Turbo configuration: + * if bit 21 is set, enable RBB + */ + rbb = reg & OMAP4460_IVA_OPP_DPLL_TURBO_RBB; + if (rbb) { + abb_type = OMAP_ABB_SLOW_OPP; + abb_msg = "Slow"; + } else { + abb_type = OMAP_ABB_NOMINAL_OPP; + abb_msg = "Nominal"; + } + omap4_abb_update(omap446x_vdd_iva_volt_data, + OMAP4460_VDD_IVA_OPPTURBO_UV, + abb_type); + pr_info("%s: IVA OPP Turbo: %s OPP ABB type\n", __func__, abb_msg); +} + +/** * omap4_opp_init() - initialize omap4 opp table */ int __init omap4_opp_init(void) @@ -323,12 +432,17 @@ if (!r) { if (omap4_has_mpu_1_2ghz()) - omap4_mpu_opp_enable(1300000000); + //omap4_mpu_opp_enable(1300000000); + omap4_opp_enable("mpu", 1300000000); /* The tuna PCB doesn't support 1.5GHz, so disable it for now */ /*if (omap4_has_mpu_1_5ghz()) omap4_mpu_opp_enable(1500000000);*/ } + /* Update ABB settings */ + if (cpu_is_omap446x()) + omap4460_abb_update(); + return r; } device_initcall(omap4_opp_init); diff -ur gnexus_kernel2/arch/arm/mach-omap2/smartreflex-class1p5.c gnexus_kernel/arch/arm/mach-omap2/smartreflex-class1p5.c --- gnexus_kernel2/arch/arm/mach-omap2/smartreflex-class1p5.c 2012-03-11 13:11:56.532324238 +0100 +++ gnexus_kernel/arch/arm/mach-omap2/smartreflex-class1p5.c 2012-03-11 12:35:35.821510672 +0100 @@ -69,8 +69,6 @@ static struct delayed_work recal_work; #endif -static unsigned long class1p5_margin; - /** * sr_class1p5_notify() - isr notifier for status events * @voltdm: voltage domain for which we were triggered @@ -274,7 +272,7 @@ sr_disable(voltdm); /* Add margin if needed */ - if (class1p5_margin) { + if (volt_data->volt_margin) { struct omap_voltdm_pmic *pmic = voltdm->pmic; /* Convert to rounded to PMIC step level if available */ if (pmic && pmic->vsel_to_uv && pmic->uv_to_vsel) { @@ -284,21 +282,21 @@ * then convert it with pmic routine to vsel and back * to voltage, and finally remove the base voltage */ - u_volt_margin = u_volt_current + class1p5_margin; + u_volt_margin = u_volt_current + volt_data->volt_margin; u_volt_margin = pmic->uv_to_vsel(u_volt_margin); u_volt_margin = pmic->vsel_to_uv(u_volt_margin); u_volt_margin -= u_volt_current; } else { - u_volt_margin = class1p5_margin; + u_volt_margin = volt_data->volt_margin; } /* Add margin IF we are lower than nominal */ if ((u_volt_safe + u_volt_margin) < volt_data->volt_nominal) { u_volt_safe += u_volt_margin; } else { - pr_err("%s: %s could not add %ld[%ld] margin" + pr_err("%s: %s could not add %ld[%d] margin" "to vnom %d curr_v=%ld\n", __func__, voltdm->name, u_volt_margin, - class1p5_margin, volt_data->volt_nominal, + volt_data->volt_margin, volt_data->volt_nominal, u_volt_current); } } @@ -317,9 +315,10 @@ voltdm_scale(voltdm, volt_data); } - pr_info("%s: %s: Calibration complete: Voltage Nominal=%d Calib=%d\n", + pr_info("%s: %s: Calibration complete: Voltage:Nominal=%d," + "Calib=%d,margin=%d\n", __func__, voltdm->name, volt_data->volt_nominal, - volt_data->volt_calibrated); + volt_data->volt_calibrated, volt_data->volt_margin); /* * TODO: Setup my wakeup voltage to allow immediate going to OFF and * on - Pending twl and voltage layer cleanups. @@ -650,18 +649,6 @@ }; /** - * sr_class1p5_margin_set() - add a margin on top of calibrated voltage - * @margin: add margin in uVolts - * - * Some platforms may need a margin, so provide an api which board files - * need to call and update internal data structure. - */ -void __init sr_class1p5_margin_set(unsigned int margin) -{ - class1p5_margin = margin; -} - -/** * sr_class1p5_driver_init() - register class 1p5 as default * * board files call this function to use class 1p5, we register with the @@ -675,13 +662,6 @@ if (!(cpu_is_omap3630() || cpu_is_omap44xx())) return -EINVAL; - /* Add 10mV margin as 4460 has Class3 ntarget values */ - if (!class1p5_margin && cpu_is_omap446x()) { - pr_info("%s: OMAP4460: add 10mV margin for class 1.5\n", - __func__); - class1p5_margin = 10000; - } - r = sr_register_class(&class1p5_data); if (r) { pr_err("SmartReflex class 1.5 driver: " diff -ur gnexus_kernel2/arch/arm/mach-omap2/smartreflex.h gnexus_kernel/arch/arm/mach-omap2/smartreflex.h --- gnexus_kernel2/arch/arm/mach-omap2/smartreflex.h 2012-03-11 13:11:56.532324238 +0100 +++ gnexus_kernel/arch/arm/mach-omap2/smartreflex.h 2012-03-11 12:57:38.924071590 +0100 @@ -286,9 +286,4 @@ } #endif -#ifdef CONFIG_OMAP_SMARTREFLEX_CLASS1P5 -extern void sr_class1p5_margin_set(unsigned int margin); -#else -static inline void sr_class1p5_margin_set(unsigned int margin) { } -#endif #endif diff -ur gnexus_kernel2/arch/arm/mach-omap2/voltage.c gnexus_kernel/arch/arm/mach-omap2/voltage.c --- gnexus_kernel2/arch/arm/mach-omap2/voltage.c 2012-03-11 13:11:56.532324238 +0100 +++ gnexus_kernel/arch/arm/mach-omap2/voltage.c 2012-03-11 12:43:16.539795261 +0100 @@ -385,6 +385,28 @@ } DEFINE_SIMPLE_ATTRIBUTE(calib_volt_debug_fops, calib_volt_debug_get, NULL, "%llu\n"); +static int margin_volt_debug_get(void *data, u64 *val) +{ + struct voltagedomain *voltdm = (struct voltagedomain *) data; + struct omap_volt_data *vdata; + + if (!voltdm) { + pr_warning("Wrong paramater passed\n"); + return -EINVAL; + } + + vdata = omap_voltage_get_curr_vdata(voltdm); + if (IS_ERR_OR_NULL(vdata)) { + pr_warning("%s: unable to get volt for vdd_%s\n", + __func__, voltdm->name); + return -ENODEV; + } + *val = vdata->volt_margin; + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(margin_volt_debug_fops, margin_volt_debug_get, NULL, + "%llu\n"); static int nom_volt_debug_get(void *data, u64 *val) { @@ -441,6 +463,9 @@ (void) debugfs_create_file("curr_calibrated_volt", S_IRUGO, voltdm->debug_dir, (void *) voltdm, &calib_volt_debug_fops); + (void) debugfs_create_file("curr_margin_volt", S_IRUGO, + voltdm->debug_dir, (void *) voltdm, + &margin_volt_debug_fops); } /** diff -ur gnexus_kernel2/arch/arm/mach-omap2/voltage.h gnexus_kernel/arch/arm/mach-omap2/voltage.h --- gnexus_kernel2/arch/arm/mach-omap2/voltage.h 2012-03-11 13:11:56.536324253 +0100 +++ gnexus_kernel/arch/arm/mach-omap2/voltage.h 2012-03-11 12:46:22.556717656 +0100 @@ -125,7 +125,8 @@ /* Flags for various ABB options */ #define OMAP_ABB_NONE -1 #define OMAP_ABB_NOMINAL_OPP 0 -#define OMAP_ABB_FAST_OPP 1 +#define OMAP_ABB_SLOW_OPP 1 +#define OMAP_ABB_FAST_OPP 2 /** * struct omap_volt_data - Omap voltage specific data. @@ -134,6 +135,8 @@ * @voltage_dynamic_nominal: The run time optimized nominal voltage for * the device. Dynamic nominal is the nominal voltage * specialized for that OPP on the device in uV. + * @volt_margin: Additional sofware margin in uV to add to OPP calibrated + * voltage * @sr_efuse_offs: The offset of the efuse register(from system * control module base address) from where to read * the n-target value for the smartreflex module. @@ -151,6 +154,7 @@ u32 volt_nominal; u32 volt_calibrated; u32 volt_dynamic_nominal; + u32 volt_margin; u32 sr_efuse_offs; u8 sr_errminlimit; u8 vp_errgain;