From 75dfe964cbe01ec089e4e3d470a86835776fe248 Mon Sep 17 00:00:00 2001 From: "Mathieu J. Poirier" Date: Tue, 31 Jul 2012 08:59:30 +0000 Subject: [PATCH] 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 Signed-off-by: John Rigby Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/u8500/cpu.c | 95 ++++++++++++++++------ arch/arm/include/asm/arch-u8500/hardware.h | 22 ++++- board/st-ericsson/snowball/snowball.c | 5 ++ 3 files changed, 94 insertions(+), 28 deletions(-) diff --git a/arch/arm/cpu/armv7/u8500/cpu.c b/arch/arm/cpu/armv7/u8500/cpu.c index 7126d9472c..02bb332097 100644 --- a/arch/arm/cpu/armv7/u8500/cpu.c +++ b/arch/arm/cpu/armv7/u8500/cpu.c @@ -33,13 +33,22 @@ #include #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 8044ac3af4..ee0341932c 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 */ diff --git a/board/st-ericsson/snowball/snowball.c b/board/st-ericsson/snowball/snowball.c index 7c3e08ce3f..67fc5dfff1 100644 --- a/board/st-ericsson/snowball/snowball.c +++ b/board/st-ericsson/snowball/snowball.c @@ -27,6 +27,7 @@ #include #include #include +#include #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; }