On 19:49-20130513, Andrii Tseglytskyi wrote:
[...]
> +void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 control,
> +            u32 txdone, u32 txdone_mask, u32 opp)
> +{
> +     u32 abb_type_mask, opp_sel_mask;
> +
> +     /* sanity check */
> +     if (!setup || !control || !txdone)
> +             return;
> +
> +     /* setup ABB only in case of Fast or Slow OPP */
> +     switch (opp) {
> +     case OMAP_ABB_FAST_OPP:
> +             abb_type_mask = OMAP_ABB_SETUP_ACTIVE_FBB_SEL_MASK;
> +             opp_sel_mask = OMAP_ABB_CONTROL_FAST_OPP_SEL_MASK;
> +             break;
> +     case OMAP_ABB_SLOW_OPP:
> +             abb_type_mask = OMAP_ABB_SETUP_ACTIVE_RBB_SEL_MASK;
> +             opp_sel_mask = OMAP_ABB_CONTROL_SLOW_OPP_SEL_MASK;
> +             break;
> +     default:
> +            return;
> +     }
> +
> +     /*
> +      * For some OMAP silicons additional setup for LDOVBB register is
> +      * required. This is determined by data retrieved from corresponding
> +      * OPP EFUSE register. Data, which is retrieved from EFUSE - is
> +      * ABB enable/disable flag and VSET value, which must be copied
> +      * to LDOVBB register. If function call fails - return quietly,
> +      * it means no ABB is required for such silicon.
> +      *
> +      * For silicons, which don't require LDOVBB setup "fuse" and
> +      * "ldovbb" offsets are not defined. ABB will be initialized in
> +      * the common way for them.
> +      */
> +     if (fuse && ldovbb) {
> +             if (abb_setup_ldovbb(fuse, ldovbb))
> +                     return;
> +     }
> +
> +     /* configure timings, based on oscillator value */
> +     abb_setup_timings(setup);
Still missing txdone clear..
If txdone was set on entry, you'd escape a bit waiting for transition
completion bit in SR2, However, by clearing TXDONE here, you can just wait
for TXDONE.
> +
> +     /* select ABB type */
> +     clrsetbits_le32(setup,
> +                     abb_type_mask | OMAP_ABB_SETUP_SR2EN_MASK,
> +                     abb_type_mask | OMAP_ABB_SETUP_SR2EN_MASK);
This is no better than set_bits! clearbits (addr, clr, set) -> the clr
bits should clear *all* bits of the field. in this example ABB_TYPE
should both be cleared, same in OPP_SEL.
See the following change on top of this series:
diff --git a/arch/arm/cpu/armv7/omap-common/abb.c 
b/arch/arm/cpu/armv7/omap-common/abb.c
index 73eadb2..31332fb 100644
--- a/arch/arm/cpu/armv7/omap-common/abb.c
+++ b/arch/arm/cpu/armv7/omap-common/abb.c
@@ -115,14 +115,22 @@ void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 
control,
        /* configure timings, based on oscillator value */
        abb_setup_timings(setup);
 
+       /*
+        * Clear any pending ABB tranxdones before we wait for txdone.
+        * We do not know the mode in which we have been handed over
+        * the system (warm/cold reboot), ROM code operations etc..
+        * on a cold boot, we do not expect to see this set.
+        */
+       setbits_le32(txdone, OMAP_ABB_MPU_TXDONE_MASK);
+
        /* select ABB type */
-       clrsetbits_le32(setup,
-                       abb_type_mask | OMAP_ABB_SETUP_SR2EN_MASK,
+       clrsetbits_le32(setup, OMAP_ABB_SETUP_ABB_SEL_MASK |
+                       OMAP_ABB_SETUP_SR2EN_MASK,
                        abb_type_mask | OMAP_ABB_SETUP_SR2EN_MASK);
 
        /* initiate ABB ldo change */
-       clrsetbits_le32(control,
-                       opp_sel_mask | OMAP_ABB_CONTROL_OPP_CHANGE_MASK,
+       clrsetbits_le32(control, OMAP_ABB_CONTROL_OPP_SEL_MASK |
+                       OMAP_ABB_CONTROL_OPP_CHANGE_MASK,
                        opp_sel_mask | OMAP_ABB_CONTROL_OPP_CHANGE_MASK);
 
        /* wait until transition complete */
diff --git a/arch/arm/include/asm/omap_common.h 
b/arch/arm/include/asm/omap_common.h
index 4892c0a..c2fc180 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -565,13 +565,17 @@ s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb);
 #define OMAP_ABB_NOMINAL_OPP           0
 #define OMAP_ABB_FAST_OPP              1
 #define OMAP_ABB_SLOW_OPP              3
+#define OMAP_ABB_CONTROL_OPP_SEL_MASK                  (0x3 << 0)
 #define OMAP_ABB_CONTROL_FAST_OPP_SEL_MASK             (0x1 << 0)
-#define OMAP_ABB_CONTROL_SLOW_OPP_SEL_MASK             (0x1 << 1)
+#define OMAP_ABB_CONTROL_SLOW_OPP_SEL_MASK             (0x3 << 0)
+#define OMAP_ABB_CONTROL_NOMINAL_OPP_SEL_MASK          (0x0 << 0)
 #define OMAP_ABB_CONTROL_OPP_CHANGE_MASK               (0x1 << 2)
 #define OMAP_ABB_CONTROL_SR2_IN_TRANSITION_MASK                (0x1 << 6)
 #define OMAP_ABB_SETUP_SR2EN_MASK                      (0x1 << 0)
 #define OMAP_ABB_SETUP_ACTIVE_FBB_SEL_MASK             (0x1 << 2)
 #define OMAP_ABB_SETUP_ACTIVE_RBB_SEL_MASK             (0x1 << 1)
+#define OMAP_ABB_SETUP_ABB_SEL_MASK                    
(OMAP_ABB_SETUP_ACTIVE_RBB_SEL_MASK | \
+                                                        
OMAP_ABB_SETUP_ACTIVE_FBB_SEL_MASK)
 #define OMAP_ABB_SETUP_SR2_WTCNT_VALUE_MASK            (0xff << 8)
 
 static inline u32 omap_revision(void)

> +
> +     /* initiate ABB ldo change */
> +     clrsetbits_le32(control,
> +                     opp_sel_mask | OMAP_ABB_CONTROL_OPP_CHANGE_MASK,
> +                     opp_sel_mask | OMAP_ABB_CONTROL_OPP_CHANGE_MASK);
> +
> +     /* wait until transition complete */
> +     if (!wait_on_value(OMAP_ABB_CONTROL_SR2_IN_TRANSITION_MASK, 0,
> +                        (void *)control, LDELAY))
> +             puts("Error: ABB is in transition\n");
superfluous if you wait for txdone.
> +
> +     if (!wait_on_value(OMAP_ABB_MPU_TXDONE_MASK, OMAP_ABB_MPU_TXDONE_MASK,
> +                        (void *)txdone, LDELAY))
> +             puts("Error: ABB txdone is not set\n");
> +
> +     /* clear ABB tranxdone */
> +     setbits_le32(txdone, OMAP_ABB_MPU_TXDONE_MASK);
> +}
> diff --git a/arch/arm/cpu/armv7/omap5/Makefile 
> b/arch/arm/cpu/armv7/omap5/Makefile
> index ce00e2c..6ff8dbb 100644
> --- a/arch/arm/cpu/armv7/omap5/Makefile
> +++ b/arch/arm/cpu/armv7/omap5/Makefile
> @@ -30,6 +30,7 @@ COBJS       += emif.o
>  COBJS        += sdram.o
>  COBJS        += prcm-regs.o
>  COBJS        += hw_data.o
> +COBJS        += abb.o
>  
>  SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
>  OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
> diff --git a/arch/arm/cpu/armv7/omap5/abb.c b/arch/arm/cpu/armv7/omap5/abb.c
> new file mode 100644
> index 0000000..cb33cb8
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/omap5/abb.c
> @@ -0,0 +1,67 @@
> +/*
> + *
> + * Adaptive Body Bias programming sequence for OMAP5 family
> + *
> + * (C) Copyright 2013
> + * Texas Instruments, <www.ti.com>
> + *
> + * Andrii Tseglytskyi <[email protected]>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/omap_common.h>
> +#include <asm/io.h>
> +
> +/*
> + * Setup LDOVBB for OMAP5.
> + * On OMAP5+ some ABB settings are fused. They are handled
> + * in the following way:
> + *
> + * 1. corresponding EFUSE register contains ABB enable bit
> + *    and VSET value
> + * 2. If ABB enable bit is set to 1, than ABB should be
> + *    enabled, otherwise ABB should be disabled
> + * 3. If ABB is enabled, than VSET value should be copied
> + *    to corresponding MUX control register
> + */
> +s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb)
> +{
> +     u32 vset;
> +
> +     /*
> +      * ABB parameters must be properly fused
> +      * otherwise ABB should be disabled
> +      */
> +     vset = readl(fuse);
> +     if (!(vset & OMAP5_ABB_FUSE_ENABLE_MASK))
> +             return -1;
> +
> +     /* prepare VSET value for LDOVBB mux register */
> +     vset &= OMAP5_ABB_FUSE_VSET_MASK;
> +     vset >>= ffs(OMAP5_ABB_FUSE_VSET_MASK) - 1;
> +     vset <<= ffs(OMAP5_ABB_LDOVBBMPU_VSET_OUT_MASK) - 1;
> +     vset |= OMAP5_ABB_LDOVBBMPU_MUX_CTRL_MASK;
> +
> +     /* setup LDOVBB using fused value */
> +     clrsetbits_le32(ldovbb, vset, vset);
here as well -> please why clrbits need to be clearing all field -
suggest looking in all usages.
> +
> +     return 0;
> +}
> diff --git a/arch/arm/include/asm/arch-omap3/omap3.h 
> b/arch/arm/include/asm/arch-omap3/omap3.h
> index 2b5e9ae..c57599a 100644
> --- a/arch/arm/include/asm/arch-omap3/omap3.h
> +++ b/arch/arm/include/asm/arch-omap3/omap3.h
> @@ -253,4 +253,11 @@ struct gpio {
>  
>  #define OMAP3_EMU_HAL_START_HAL_CRITICAL     4
>  
> +/* ABB settings */
> +#define OMAP_ABB_SETTLING_TIME               30
> +#define OMAP_ABB_CLOCK_CYCLES                8
> +
> +/* ABB tranxdone mask */
> +#define OMAP_ABB_MPU_TXDONE_MASK     (0x1 << 26)
> +
>  #endif
> diff --git a/arch/arm/include/asm/arch-omap4/omap.h 
> b/arch/arm/include/asm/arch-omap4/omap.h
> index ad984da..559ad26 100644
> --- a/arch/arm/include/asm/arch-omap4/omap.h
> +++ b/arch/arm/include/asm/arch-omap4/omap.h
> @@ -170,6 +170,13 @@ struct s32ktimer {
>  #define CH_FLAGS_CHFLASH     (0x1 << 2)
>  #define CH_FLAGS_CHMMCSD     (0x1 << 3)
>  
> +/* ABB settings */
> +#define OMAP_ABB_SETTLING_TIME               50
> +#define OMAP_ABB_CLOCK_CYCLES                16
> +
> +/* ABB tranxdone mask */
> +#define OMAP_ABB_MPU_TXDONE_MASK     (0x1 << 7)
> +
>  #ifndef __ASSEMBLY__
>  struct omap_boot_parameters {
>       char *boot_message;
> diff --git a/arch/arm/include/asm/arch-omap5/omap.h 
> b/arch/arm/include/asm/arch-omap5/omap.h
> index 887fcaa..caa1234 100644
> --- a/arch/arm/include/asm/arch-omap5/omap.h
> +++ b/arch/arm/include/asm/arch-omap5/omap.h
> @@ -243,6 +243,19 @@ struct s32ktimer {
>  #define SRCODE_OVERRIDE_SEL_XS_SHIFT 0
>  #define SRCODE_OVERRIDE_SEL_XS_MASK  (1 << 0)
>  
> +/* ABB settings */
> +#define OMAP_ABB_SETTLING_TIME               50
> +#define OMAP_ABB_CLOCK_CYCLES                16
> +
> +/* ABB tranxdone mask */
> +#define OMAP_ABB_MPU_TXDONE_MASK             (0x1 << 7)
> +
> +/* ABB efuse masks */
> +#define OMAP5_ABB_FUSE_VSET_MASK             (0x1F << 24)
> +#define OMAP5_ABB_FUSE_ENABLE_MASK           (0x1 << 29)
> +#define OMAP5_ABB_LDOVBBMPU_MUX_CTRL_MASK    (0x1 << 10)
> +#define OMAP5_ABB_LDOVBBMPU_VSET_OUT_MASK    (0x1f << 0)
> +
>  #ifndef __ASSEMBLY__
>  struct srcomp_params {
>       s8 divide_factor;
> diff --git a/arch/arm/include/asm/omap_common.h 
> b/arch/arm/include/asm/omap_common.h
> index 091ddb5..4892c0a 100644
> --- a/arch/arm/include/asm/omap_common.h
> +++ b/arch/arm/include/asm/omap_common.h
> @@ -240,6 +240,8 @@ struct prcm_regs {
>       u32 cm_l3init_fsusb_clkctrl;
>       u32 cm_l3init_ocp2scp1_clkctrl;
>  
> +     u32 prm_irqstatus_mpu_2;
> +
>       /* cm2.l4per */
>       u32 cm_l4per_clkstctrl;
>       u32 cm_l4per_dynamicdep;
> @@ -325,6 +327,8 @@ struct prcm_regs {
>       u32 prm_sldo_mpu_ctrl;
>       u32 prm_sldo_mm_setup;
>       u32 prm_sldo_mm_ctrl;
> +     u32 prm_abbldo_mpu_setup;
> +     u32 prm_abbldo_mpu_ctrl;
>  
>       u32 cm_div_m4_dpll_core;
>       u32 cm_div_m5_dpll_core;
> @@ -347,6 +351,7 @@ struct prcm_regs {
>  
>  struct omap_sys_ctrl_regs {
>       u32 control_status;
> +     u32 control_std_fuse_opp_vdd_mpu_2;
>       u32 control_core_mmr_lock1;
>       u32 control_core_mmr_lock2;
>       u32 control_core_mmr_lock3;
> @@ -416,6 +421,7 @@ struct omap_sys_ctrl_regs {
>       u32 control_port_emif2_sdram_config;
>       u32 control_emif1_sdram_config_ext;
>       u32 control_emif2_sdram_config_ext;
> +     u32 control_wkup_ldovbb_mpu_voltage_ctrl;
>       u32 control_smart1nopmio_padconf_0;
>       u32 control_smart1nopmio_padconf_1;
>       u32 control_padconf_mode;
> @@ -542,6 +548,9 @@ void enable_non_essential_clocks(void);
>  void scale_vcores(struct vcores_data const *);
>  u32 get_offset_code(u32 volt_offset, struct pmic_data *pmic);
>  void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic);
> +void abb_setup(u32 fuse, u32 ldovbb, u32 setup, u32 control,
> +            u32 txdone, u32 txdone_mask, u32 opp);
> +s8 abb_setup_ldovbb(u32 fuse, u32 ldovbb);
>  
>  /* Max value for DPLL multiplier M */
>  #define OMAP_DPLL_MAX_N      127
> @@ -552,6 +561,19 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct 
> pmic_data *pmic);
>  #define OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL    2
>  #define OMAP_INIT_CONTEXT_UBOOT_AFTER_CH     3
>  
> +/* ABB */
> +#define OMAP_ABB_NOMINAL_OPP         0
> +#define OMAP_ABB_FAST_OPP            1
> +#define OMAP_ABB_SLOW_OPP            3
> +#define OMAP_ABB_CONTROL_FAST_OPP_SEL_MASK           (0x1 << 0)
> +#define OMAP_ABB_CONTROL_SLOW_OPP_SEL_MASK           (0x1 << 1)
> +#define OMAP_ABB_CONTROL_OPP_CHANGE_MASK             (0x1 << 2)
> +#define OMAP_ABB_CONTROL_SR2_IN_TRANSITION_MASK              (0x1 << 6)
> +#define OMAP_ABB_SETUP_SR2EN_MASK                    (0x1 << 0)
> +#define OMAP_ABB_SETUP_ACTIVE_FBB_SEL_MASK           (0x1 << 2)
> +#define OMAP_ABB_SETUP_ACTIVE_RBB_SEL_MASK           (0x1 << 1)
> +#define OMAP_ABB_SETUP_SR2_WTCNT_VALUE_MASK          (0xff << 8)
> +
>  static inline u32 omap_revision(void)
>  {
>       extern u32 *const omap_si_rev;
> -- 
> 1.7.9.5
> 
> _______________________________________________
> U-Boot mailing list
> [email protected]
> http://lists.denx.de/mailman/listinfo/u-boot

-- 
Regards,
Nishanth Menon
_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to