2.6.36 kernel BB-xM patch for 1 GHz (VDD1 voltage adjusting)

Affichage de 12 messages sur 2
2.6.36 kernel BB-xM patch for 1 GHz (VDD1 voltage adjusting) Max Galemin 17/11/10 15:53
Hi all,

I made a patch for 2.6.36 kernel (git://git.kernel.org/pub/scm/linux/
kernel/git/tmlind/linux-omap-2.6.git
) that makes it possible to run
Beagleboard-xM on 1 GHz frequency. The main idea is adjusting
processor voltage VDD1 to the level of OPP1G (1.28..1.38V). Please
note that default processor voltage after boot is 1.2V according to
BOOT0 (=1) and BOOT1 (=0) pins on TPS65950 (see "Table 5-2. Boot
Modes" in SWCU050F, p.238). You can see processor voltage values for
different frequencies in "Table 4-20. Processor Clocks" in SPRS685B
document (p.144). In order to increase voltage there are three
options:

1) SmartReflex technology (implemented in kernel 2.6.32 from Arago,
also used in TI VDSDK and Beagleboard validation, I have no time for
merging all PM related functionality to the new kernel);

2) Setting voltage directly using VDDx_VSEL register in TPS65950;

3) Play with VFLOOR/VROOF registers in TPS65950 and toggling VMODE
input (which is grounded in BB-xM A3).

I implemented adjusting by changing VDD1_VSEL register value (VDDx =
VDDx_VSEL x 12.5mV + 0.6V, thus, for VDD1 = 1.35V VDD1_VSEL = 0x3C -
see "5.4.10.1.1 Direct Control" in SWCU050F, p.259).

It would be great if someone check this workaround by reviewing the
code. Thanks!

P.S. I made a couple of tests - the temperature of the chip is
slightly higher than with mpurate=800.

=====
diff -U20 -r a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-
omap2/board-omap3beagle.c
--- a/arch/arm/mach-omap2/board-omap3beagle.c   2010-11-10
16:59:39.000000000 +1100
+++ b/arch/arm/mach-omap2/board-omap3beagle.c   2010-11-18
09:35:16.634918998 +1100
@@ -315,40 +315,52 @@

 static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
        {
                I2C_BOARD_INFO("twl4030", 0x48),
                .flags = I2C_CLIENT_WAKE,
                .irq = INT_34XX_SYS_NIRQ,
                .platform_data = &beagle_twldata,
        },
 };

 static int __init omap3_beagle_i2c_init(void)
 {
        omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
                        ARRAY_SIZE(beagle_i2c_boardinfo));
        /* Bus 3 is attached to the DVI port where devices like the
pico DLP
         * projector don't work reliably with 400kHz */
        omap_register_i2c_bus(3, 100, NULL, 0);
        return 0;
 }

+int beagle_set_opp1g_voltage(void)
+{
+#define SET_VDD1_VSEL_1_35_V    0x3C
+
+       /* See TPS65950 TRM (SWCU050F) "5.4.10.1.1 Direct Control" for
details. */
+       twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+           SET_VDD1_VSEL_1_35_V,
+           TWL4030_VDD1_VSEL);
+
+       return 0;
+}
+
 static struct gpio_led gpio_leds[] = {
        {
                .name                   = "beagleboard::usr0",
                .default_trigger        = "heartbeat",
                .gpio                   = 150,
        },
        {
                .name                   = "beagleboard::usr1",
                .default_trigger        = "mmc0",
                .gpio                   = 149,
        },
        {
                .name                   = "beagleboard::pmu_stat",
                .gpio                   = -EINVAL,      /* gets
replaced */
                .active_low             = true,
        },
 };

 static struct gpio_led_platform_data gpio_led_info = {
        .leds           = gpio_leds,
diff -U20 -r a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/
pm34xx.c
--- a/arch/arm/mach-omap2/pm34xx.c      2010-11-10 16:59:39.000000000
+1100
+++ b/arch/arm/mach-omap2/pm34xx.c      2010-11-18 09:36:14.222916045
+1100
@@ -1043,40 +1043,54 @@
 void omap_push_sram_idle(void)
 {
        _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
                                        omap34xx_cpu_suspend_sz);
        if (omap_type() != OMAP2_DEVICE_TYPE_GP)
                _omap_save_secure_sram =
omap_sram_push(save_secure_ram_context,
                                save_secure_ram_context_sz);
 }

 static int __init omap3_pm_init(void)
 {
        struct power_state *pwrst, *tmp;
        struct clockdomain *neon_clkdm, *per_clkdm, *mpu_clkdm,
*core_clkdm;
        int ret;

        if (!cpu_is_omap34xx())
                return -ENODEV;

        printk(KERN_ERR "Power Management for TI OMAP3.\n");

+#ifdef CONFIG_MACH_OMAP3_BEAGLE
+       {
+               extern int beagle_set_opp1g_voltage(void);
+
+               if (mpurate >= 1000000000) {
+                       /**
+                        * Adjust VDD1 MPU voltage for 1GHz clock. See
DM3730 description
+                        * (SPRS685B) "Table 4-20. Processor Clocks"
for details.
+                        */
+                       beagle_set_opp1g_voltage();
+               }
+       }
+#endif /* CONFIG_MACH_OMAP3_BEAGLE */
+
        /* XXX prcm_setup_regs needs to be before enabling hw
         * supervised mode for powerdomains */
        prcm_setup_regs();

        ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
                          (irq_handler_t)prcm_interrupt_handler,
                          IRQF_DISABLED, "prcm", NULL);
        if (ret) {
                printk(KERN_ERR "request_irq failed to register for 0x
%x\n",
                       INT_34XX_PRCM_MPU_IRQ);
                goto err1;
        }

        ret = pwrdm_for_each(pwrdms_setup, NULL);
        if (ret) {
                printk(KERN_ERR "Failed to setup powerdomains\n");
                goto err2;
        }

        (void) clkdm_for_each(clkdms_setup, NULL);
diff -U20 -r a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
--- a/arch/arm/plat-omap/clock.c        2010-05-25 13:52:41.000000000
+1000
+++ b/arch/arm/plat-omap/clock.c        2010-11-18 09:19:18.203016004
+1100
@@ -164,41 +164,41 @@
 }
 EXPORT_SYMBOL(clk_get_parent);

 /*
  * OMAP specific clock functions shared between omap1 and omap2
  */

 int __initdata mpurate;

 /*
  * By default we use the rate set by the bootloader.
  * You can override this with mpurate= cmdline option.
  */
 static int __init omap_clk_setup(char *str)
 {
        get_option(&str, &mpurate);

        if (!mpurate)
                return 1;

-       if (mpurate < 1000)
+       if (mpurate < 2000)
                mpurate *= 1000000;

        return 1;
 }
 __setup("mpurate=", omap_clk_setup);

 /* Used for clocks that always have same value as the parent clock */
 unsigned long followparent_recalc(struct clk *clk)
 {
        return clk->parent->rate;
 }

 /*
  * Used for clocks that have the same value as the parent clock,
  * divided by some factor
  */
 unsigned long omap_fixed_divisor_recalc(struct clk *clk)
 {
        WARN_ON(!clk->fixed_div);

diff -U20 -r a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
--- a/include/linux/i2c/twl.h   2010-11-10 17:00:14.000000000 +1100
+++ b/include/linux/i2c/twl.h   2010-11-18 09:19:09.954896444 +1100
@@ -608,40 +608,42 @@
        struct regulator_init_data              *vpp;
        struct regulator_init_data              *vusim;
        struct regulator_init_data              *vana;
        struct regulator_init_data              *vcxio;
        struct regulator_init_data              *vusb;
 };

 /
*----------------------------------------------------------------------
*/

 int twl4030_sih_setup(int module);

 /* Offsets to Power Registers */
 #define TWL4030_VDAC_DEV_GRP           0x3B
 #define TWL4030_VDAC_DEDICATED         0x3E
 #define TWL4030_VAUX1_DEV_GRP          0x17
 #define TWL4030_VAUX1_DEDICATED                0x1A
 #define TWL4030_VAUX2_DEV_GRP          0x1B
 #define TWL4030_VAUX2_DEDICATED                0x1E
 #define TWL4030_VAUX3_DEV_GRP          0x1F
 #define TWL4030_VAUX3_DEDICATED                0x22
+#define TWL4030_VDD1_VSEL              0x5E
+#define TWL4030_VDD2_VSEL              0x6C

 static inline int twl4030charger_usb_en(int enable) { return 0; }

 /
*----------------------------------------------------------------------
*/

 /* Linux-specific regulator identifiers ... for now, we only support
  * the LDOs, and leave the three buck converters alone.  VDD1 and
VDD2
  * need to tie into hardware based voltage scaling (cpufreq etc),
while
  * VIO is generally fixed.
  */

 /* TWL4030 SMPS/LDO's */
 /* EXTERNAL dc-to-dc buck converters */
 #define TWL4030_REG_VDD1       0
 #define TWL4030_REG_VDD2       1
 #define TWL4030_REG_VIO                2

 /* EXTERNAL LDOs */
 #define TWL4030_REG_VDAC       3
 #define TWL4030_REG_VPLL1      4

=====


Cheers,
Max.
Re: [beagleboard] 2.6.36 kernel BB-xM patch for 1 GHz (VDD1 voltage adjusting) aos...@gmail.com 17/11/10 16:29
Very cool, well done I'll have a look at the code when I get home.

-Alex
--
You received this message because you are subscribed to the Google Groups "Beagle Board" group.
To post to this group, send email to beagl...@googlegroups.com.
To unsubscribe from this group, send email to beagleboard...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/beagleboard?hl=en.