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>
master
Mathieu J. Poirier 12 years ago committed by Albert ARIBAUD
parent 1e37322e5a
commit 75dfe964cb
  1. 95
      arch/arm/cpu/armv7/u8500/cpu.c
  2. 22
      arch/arm/include/asm/arch-u8500/hardware.h
  3. 5
      board/st-ericsson/snowball/snowball.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;

@ -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 */

@ -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;
}

Loading…
Cancel
Save