u8500: Enabling power to MMC device on AB8500 V2
authorMathieu J. Poirier <mathieu.poirier@linaro.org>
Tue, 31 Jul 2012 08:59:30 +0000 (08:59 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Sat, 1 Sep 2012 12:58:20 +0000 (14:58 +0200)
Register mapping has changed on power control chip between
the first and second revision.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: John Rigby <john.rigby@linaro.org>
Signed-off-by: Tom Rini <trini@ti.com>
arch/arm/cpu/armv7/u8500/cpu.c
arch/arm/include/asm/arch-u8500/hardware.h
board/st-ericsson/snowball/snowball.c

index 7126d9472c069342f710ea2defb021f316a284f8..02bb332097a8b8c61b6acaa01b88d49375cadd6f 100644 (file)
 #include <asm/arch/hardware.h>
 
 #define CPUID_DB8500V1         0x411fc091
+#define CPUID_DB8500V2         0x412fc091
 #define ASICID_DB8500V11       0x008500A1
 
-static unsigned int read_asicid(void)
+static unsigned int read_asicid(void);
+
+static inline unsigned int read_cpuid(void)
 {
-       unsigned int *address = (void *)U8500_BOOTROM_BASE
-                               + U8500_BOOTROM_ASIC_ID_OFFSET;
-       return readl(address);
+       unsigned int val;
+
+       /* Main ID register (MIDR) */
+       asm("mrc        p15, 0, %0, c0, c0, 0"
+          : "=r" (val)
+          :
+          : "cc");
+
+       return val;
 }
 
 static int cpu_is_u8500v11(void)
@@ -47,6 +56,23 @@ static int cpu_is_u8500v11(void)
        return read_asicid() == ASICID_DB8500V11;
 }
 
+static int cpu_is_u8500v2(void)
+{
+       return read_cpuid() == CPUID_DB8500V2;
+}
+
+static unsigned int read_asicid(void)
+{
+       unsigned int *address;
+
+       if (cpu_is_u8500v2())
+               address = (void *) U8500_ASIC_ID_LOC_V2;
+       else
+               address = (void *) U8500_ASIC_ID_LOC_ED_V1;
+
+       return readl(address);
+}
+
 #ifdef CONFIG_ARCH_CPU_INIT
 /*
  * SOC specific cpu init
@@ -62,22 +88,22 @@ int arch_cpu_init(void)
 
 #ifdef CONFIG_MMC
 
-#define LDO_VAUX3_MASK         0x3
-#define LDO_VAUX3_ENABLE       0x1
-#define VAUX3_VOLTAGE_2_9V     0xd
-
-#define AB8500_REGU_CTRL2      0x4
-#define AB8500_REGU_VRF1VAUX3_REGU_REG 0x040A
-#define AB8500_REGU_VRF1VAUX3_SEL_REG  0x0421
-
 int u8500_mmc_power_init(void)
 {
        int ret;
-       int val;
+       int enable, voltage;
+       int ab8500_revision;
 
-       if (!cpu_is_u8500v11())
+       if (!cpu_is_u8500v11() && !cpu_is_u8500v2())
                return 0;
 
+       /* Get AB8500 revision */
+       ret = ab8500_read(AB8500_MISC, AB8500_REV_REG);
+       if (ret < 0)
+               goto out;
+
+       ab8500_revision = ret;
+
        /*
         * On v1.1 HREF boards (HREF+), Vaux3 needs to be enabled for the SD
         * card to work.  This is done by enabling the regulators in the AB8500
@@ -89,33 +115,50 @@ int u8500_mmc_power_init(void)
         * Turn off and delay is required to have it work across soft reboots.
         */
 
-       ret = prcmu_i2c_read(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG);
+       /* Turn off (read-modify-write) */
+       ret = ab8500_read(AB8500_REGU_CTRL2,
+                               AB8500_REGU_VRF1VAUX3_REGU_REG);
        if (ret < 0)
                goto out;
 
-       val = ret;
+       enable = ret;
 
        /* Turn off */
-       ret = prcmu_i2c_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG,
-                                                       val & ~LDO_VAUX3_MASK);
+       ret = ab8500_write(AB8500_REGU_CTRL2,
+                       AB8500_REGU_VRF1VAUX3_REGU_REG,
+                       enable & ~LDO_VAUX3_ENABLE_MASK);
        if (ret < 0)
                goto out;
 
        udelay(10 * 1000);
 
-       /* Set the voltage to 2.9V */
-       ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
-                               AB8500_REGU_VRF1VAUX3_SEL_REG,
-                               VAUX3_VOLTAGE_2_9V);
+       /* Set the voltage to 2.91 V or 2.9 V without overriding VRF1 value */
+       ret = ab8500_read(AB8500_REGU_CTRL2,
+                       AB8500_REGU_VRF1VAUX3_SEL_REG);
        if (ret < 0)
                goto out;
 
-       val = val & ~LDO_VAUX3_MASK;
-       val = val | LDO_VAUX3_ENABLE;
+       voltage = ret;
+
+       if (ab8500_revision < 0x20) {
+               voltage &= ~LDO_VAUX3_SEL_MASK;
+               voltage |= LDO_VAUX3_SEL_2V9;
+       } else {
+               voltage &= ~LDO_VAUX3_V2_SEL_MASK;
+               voltage |= LDO_VAUX3_V2_SEL_2V91;
+       }
+
+       ret = ab8500_write(AB8500_REGU_CTRL2,
+                       AB8500_REGU_VRF1VAUX3_SEL_REG, voltage);
+       if (ret < 0)
+               goto out;
 
        /* Turn on the supply */
-       ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
-                               AB8500_REGU_VRF1VAUX3_REGU_REG, val);
+       enable &= ~LDO_VAUX3_ENABLE_MASK;
+       enable |= LDO_VAUX3_ENABLE_VAL;
+
+       ret = ab8500_write(AB8500_REGU_CTRL2,
+                       AB8500_REGU_VRF1VAUX3_REGU_REG, enable);
 
 out:
        return ret;
index 8044ac3af4e9233581477be5d6ddb433f884325f..ee0341932cc97f2869d9bda3166f829b44bf4624 100644 (file)
 #define U8500_CLKRST1_BASE     (U8500_PER1_BASE + 0xf000)
 
 /* Last page of Boot ROM */
-#define U8500_BOOTROM_BASE      0x9001f000
-#define U8500_BOOTROM_ASIC_ID_OFFSET    0x0ff4
+#define U8500_BOOTROM_BASE      0x90000000
+#define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOTROM_BASE + 0x1FFF4)
+#define U8500_ASIC_ID_LOC_V2    (U8500_BOOTROM_BASE + 0x1DBF4)
 
 /* AB8500 specifics */
+
+/* address bank */
+#define AB8500_REGU_CTRL2      0x0004
 #define AB8500_MISC            0x0010
+
+/* registers */
+#define AB8500_REGU_VRF1VAUX3_REGU_REG 0x040A
+#define AB8500_REGU_VRF1VAUX3_SEL_REG  0x0421
+#define AB8500_REV_REG                 0x1080
+
 #define AB8500_GPIO_SEL2_REG   0x1001
 #define AB8500_GPIO_DIR2_REG   0x1011
 #define AB8500_GPIO_DIR4_REG   0x1013
 #define AB8500_GPIO_OUT2_REG   0x1021
 #define AB8500_GPIO_OUT4_REG   0x1023
 
+#define LDO_VAUX3_ENABLE_MASK  0x3
+#define LDO_VAUX3_ENABLE_VAL   0x1
+#define LDO_VAUX3_SEL_MASK     0xf
+#define LDO_VAUX3_SEL_2V9      0xd
+#define LDO_VAUX3_V2_SEL_MASK  0x7
+#define LDO_VAUX3_V2_SEL_2V91  0x7
+
+
 #endif /* __ASM_ARCH_HARDWARE_H */
index 7c3e08ce3f5602e7b3d3fc58e804030002fea9f4..67fc5dfff1e5c1dd6588dba6d34bc71380d10d73 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/arch/db8500_pincfg.h>
 #include <asm/arch/prcmu.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
 
 #include "db8500_pins.h"
 
@@ -249,5 +250,9 @@ int board_late_init(void)
        if ((raise_ab8500_gpio16() < 0))
                printf("error: cant' raise GPIO16\n");
 
+#ifdef CONFIG_MMC
+       u8500_mmc_power_init();
+#endif /* CONFIG_MMC */
+
        return 0;
 }