diff options
author | Mathieu J. Poirier <mathieu.poirier@linaro.org> | 2012-07-31 08:59:30 +0000 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2012-09-01 14:58:20 +0200 |
commit | 75dfe964cbe01ec089e4e3d470a86835776fe248 (patch) | |
tree | f651948ede760fa6e0ce584c94fb9cd19231675c /arch | |
parent | 1e37322e5a2ff8b529d82a6c345d5e343f77a5fc (diff) | |
download | u-boot-imx-75dfe964cbe01ec089e4e3d470a86835776fe248.zip u-boot-imx-75dfe964cbe01ec089e4e3d470a86835776fe248.tar.gz u-boot-imx-75dfe964cbe01ec089e4e3d470a86835776fe248.tar.bz2 |
u8500: Enabling power to MMC device on AB8500 V2
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/cpu/armv7/u8500/cpu.c | 95 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-u8500/hardware.h | 22 |
2 files changed, 89 insertions, 28 deletions
diff --git a/arch/arm/cpu/armv7/u8500/cpu.c b/arch/arm/cpu/armv7/u8500/cpu.c index 7126d94..02bb332 100644 --- a/arch/arm/cpu/armv7/u8500/cpu.c +++ b/arch/arm/cpu/armv7/u8500/cpu.c @@ -33,13 +33,22 @@ #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; diff --git a/arch/arm/include/asm/arch-u8500/hardware.h b/arch/arm/include/asm/arch-u8500/hardware.h index 8044ac3..ee03419 100644 --- a/arch/arm/include/asm/arch-u8500/hardware.h +++ b/arch/arm/include/asm/arch-u8500/hardware.h @@ -77,11 +77,21 @@ #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 @@ -89,4 +99,12 @@ #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 */ |