[U-Boot] [PATCH v2 08/12] sunxi: Add axp209 pmic support
Hans de Goede
hdegoede at redhat.com
Tue Jun 3 21:41:58 CEST 2014
From: Henrik Nordstrom <henrik at henriknordstrom.net>
Add support for the x-powers axp209 pmic which is found on most A10, A13 and
A20 boards.
And enable AXP209 support for the Cubietruck and Cubieboard boards.
While changing the boards.cfg lines for the Cubietruck, add Ian and me as board
maintainers for the Cubietruck.
Signed-off-by: Henrik Nordstrom <henrik at henriknordstrom.net>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
board/sunxi/board.c | 22 +++++
boards.cfg | 6 +-
drivers/power/Makefile | 1 +
drivers/power/axp209.c | 180 +++++++++++++++++++++++++++++++++++++++++
include/axp209.h | 15 ++++
include/configs/sun4i.h | 1 +
include/configs/sun5i.h | 1 +
include/configs/sun7i.h | 1 +
include/configs/sunxi-common.h | 5 ++
9 files changed, 229 insertions(+), 3 deletions(-)
create mode 100644 drivers/power/axp209.c
create mode 100644 include/axp209.h
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 543b809..8375711 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -12,6 +12,9 @@
*/
#include <common.h>
+#ifdef CONFIG_AXP209_POWER
+#include <axp209.h>
+#endif
#include <asm/arch/clock.h>
#include <asm/arch/dram.h>
#include <asm/arch/gpio.h>
@@ -116,12 +119,31 @@ void i2c_init_board(void)
#ifdef CONFIG_SPL_BUILD
void sunxi_board_init(void)
{
+ int power_failed = 0;
unsigned long ramsize;
+#ifdef CONFIG_AXP209_POWER
+ power_failed |= axp209_init();
+ power_failed |= axp209_set_dcdc2(1400);
+ power_failed |= axp209_set_dcdc3(1250);
+ power_failed |= axp209_set_ldo2(3000);
+ power_failed |= axp209_set_ldo3(2800);
+ power_failed |= axp209_set_ldo4(2800);
+#endif
+
printf("DRAM:");
ramsize = sunxi_dram_init();
printf(" %lu MiB\n", ramsize >> 20);
if (!ramsize)
hang();
+
+ /*
+ * Only clock up the CPU to full speed if we are reasonably
+ * assured it's being powered with suitable core voltage
+ */
+ if (!power_failed)
+ clock_set_pll1(CONFIG_CLK_FULL_SPEED);
+ else
+ printf("Failed to set core voltage! Can't set CPU frequency\n");
}
#endif
diff --git a/boards.cfg b/boards.cfg
index f2da564..151c443 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -382,9 +382,9 @@ Active arm armv7 s5pc1xx samsung goni
Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang <mk7.kang at samsung.com>
Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - -
Active arm armv7 sunxi - sunxi A13-OLinuXinoM sun5i:A13_OLINUXINOM,SPL,CONS_INDEX=2 Hans de Goede <hdegoede at redhat.com>
-Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL Hans de Goede <hdegoede at redhat.com>
-Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII -
-Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII -
+Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL,AXP209_POWER Hans de Goede <hdegoede at redhat.com>
+Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,AXP209_POWER,SUNXI_GMAC,RGMII Ian Campbell <ijc at hellion.org.uk>:Hans de Goede <hdegoede at redhat.com>
+Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,AXP209_POWER,SUNXI_GMAC,RGMII Ian Campbell <ijc at hellion.org.uk>:Hans de Goede <hdegoede at redhat.com>
Active arm armv7 sunxi - sunxi r7-tv-dongle sun5i:R7DONGLE,SPL Hans de Goede <hdegoede at redhat.com>
Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier <mathieu.poirier at linaro.org>
Active arm armv7 u8500 st-ericsson u8500 u8500_href - -
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 53ff97d..063ac8f 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -5,6 +5,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
+obj-$(CONFIG_AXP209_POWER) += axp209.o
obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o
obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o
obj-$(CONFIG_TPS6586X_POWER) += tps6586x.o
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
new file mode 100644
index 0000000..fc1befa
--- /dev/null
+++ b/drivers/power/axp209.c
@@ -0,0 +1,180 @@
+/*
+ * (C) Copyright 2012
+ * Henrik Nordstrom <henrik at henriknordstrom.net>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <axp209.h>
+
+enum axp209_reg {
+ AXP209_POWER_STATUS = 0x00,
+ AXP209_CHIP_VERSION = 0x03,
+ AXP209_DCDC2_VOLTAGE = 0x23,
+ AXP209_DCDC3_VOLTAGE = 0x27,
+ AXP209_LDO24_VOLTAGE = 0x28,
+ AXP209_LDO3_VOLTAGE = 0x29,
+ AXP209_IRQ_STATUS5 = 0x4c,
+ AXP209_SHUTDOWN = 0x32,
+};
+
+#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0)
+
+#define AXP209_IRQ5_PEK_UP (1 << 6)
+#define AXP209_IRQ5_PEK_DOWN (1 << 5)
+
+#define AXP209_POWEROFF (1 << 7)
+
+static int axp209_write(enum axp209_reg reg, u8 val)
+{
+ return i2c_write(0x34, reg, 1, &val, 1);
+}
+
+static int axp209_read(enum axp209_reg reg, u8 *val)
+{
+ return i2c_read(0x34, reg, 1, val, 1);
+}
+
+static int axp209_mvolt_to_cfg(int mvolt, int min, int max, int div)
+{
+ if (mvolt < min)
+ mvolt = min;
+ else if (mvolt > max)
+ mvolt = max;
+
+ return (mvolt - min) / div;
+}
+
+int axp209_set_dcdc2(int mvolt)
+{
+ int cfg, rc;
+ u8 current;
+
+ cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25);
+
+ /* Do we really need to be this gentle? It has built-in voltage slope */
+ while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, ¤t)) == 0 &&
+ current != cfg) {
+ if (current < cfg)
+ current++;
+ else
+ current--;
+
+ rc = axp209_write(AXP209_DCDC2_VOLTAGE, current);
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+
+int axp209_set_dcdc3(int mvolt)
+{
+ int cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25);
+
+ return axp209_write(AXP209_DCDC3_VOLTAGE, cfg);
+}
+
+int axp209_set_ldo2(int mvolt)
+{
+ int rc, cfg;
+ u8 reg;
+
+ cfg = axp209_mvolt_to_cfg(mvolt, 1800, 3300, 100);
+
+ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®);
+ if (rc)
+ return rc;
+
+ /* LDO2 configuration is in upper 4 bits */
+ reg = (reg & 0x0f) | (cfg << 4);
+ return axp209_write(AXP209_LDO24_VOLTAGE, reg);
+}
+
+int axp209_set_ldo3(int mvolt)
+{
+ int cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25);
+
+ if (mvolt == -1)
+ cfg = 0x80; /* determined by LDO3IN pin */
+
+ return axp209_write(AXP209_LDO3_VOLTAGE, cfg);
+}
+
+int axp209_set_ldo4(int mvolt)
+{
+ int cfg, rc;
+ static const int vindex[] = {
+ 1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2500,
+ 2700, 2800, 3000, 3100, 3200, 3300
+ };
+ u8 reg;
+
+ /* Translate mvolt to register cfg value, requested <= selected */
+ for (cfg = 15; vindex[cfg] > mvolt && cfg > 0; cfg--);
+
+ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®);
+ if (rc)
+ return rc;
+
+ /* LDO4 configuration is in lower 4 bits */
+ reg = (reg & 0xf0) | (cfg << 0);
+ return axp209_write(AXP209_LDO24_VOLTAGE, reg);
+}
+
+void axp209_poweroff(void)
+{
+ u8 val;
+
+ if (axp209_read(AXP209_SHUTDOWN, &val) != 0)
+ return;
+
+ val |= AXP209_POWEROFF;
+
+ if (axp209_write(AXP209_SHUTDOWN, val) != 0)
+ return;
+
+ udelay(10000); /* wait for power to drain */
+}
+
+int axp209_init(void)
+{
+ u8 ver;
+ int rc;
+
+ rc = axp209_read(AXP209_CHIP_VERSION, &ver);
+ if (rc)
+ return rc;
+
+ /* Low 4 bits is chip version */
+ ver &= 0x0f;
+
+ if (ver != 0x1)
+ return -1;
+
+ return 0;
+}
+
+int axp209_poweron_by_dc(void)
+{
+ u8 v;
+
+ if (axp209_read(AXP209_POWER_STATUS, &v))
+ return 0;
+
+ return (v & AXP209_POWER_STATUS_ON_BY_DC);
+}
+
+int axp209_power_button(void)
+{
+ u8 v;
+
+ if (axp209_read(AXP209_IRQ_STATUS5, &v))
+ return 0;
+
+ axp209_write(AXP209_IRQ_STATUS5, AXP209_IRQ5_PEK_DOWN);
+
+ return v & AXP209_IRQ5_PEK_DOWN;
+}
diff --git a/include/axp209.h b/include/axp209.h
new file mode 100644
index 0000000..9edfa3f
--- /dev/null
+++ b/include/axp209.h
@@ -0,0 +1,15 @@
+/*
+ * (C) Copyright 2012 Henrik Nordstrom <henrik at henriknordstrom.net>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+extern int axp209_set_dcdc2(int mvolt);
+extern int axp209_set_dcdc3(int mvolt);
+extern int axp209_set_ldo2(int mvolt);
+extern int axp209_set_ldo3(int mvolt);
+extern int axp209_set_ldo4(int mvolt);
+extern void axp209_poweroff(void);
+extern int axp209_init(void);
+extern int axp209_poweron_by_dc(void);
+extern int axp209_power_button(void);
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
index 6560b65..037f995 100644
--- a/include/configs/sun4i.h
+++ b/include/configs/sun4i.h
@@ -12,6 +12,7 @@
* A10 specific configuration
*/
#define CONFIG_SUN4I /* sun4i SoC generation */
+#define CONFIG_CLK_FULL_SPEED 1008000000
#define CONFIG_SYS_PROMPT "sun4i# "
diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
index 43f0d67..c6138b7 100644
--- a/include/configs/sun5i.h
+++ b/include/configs/sun5i.h
@@ -12,6 +12,7 @@
* High Level Configuration Options
*/
#define CONFIG_SUN5I /* sun5i SoC generation */
+#define CONFIG_CLK_FULL_SPEED 1008000000
#define CONFIG_SYS_PROMPT "sun5i# "
diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h
index 9b693f7..d9be104 100644
--- a/include/configs/sun7i.h
+++ b/include/configs/sun7i.h
@@ -13,6 +13,7 @@
* A20 specific configuration
*/
#define CONFIG_SUN7I /* sun7i SoC generation */
+#define CONFIG_CLK_FULL_SPEED 912000000
#define CONFIG_SYS_PROMPT "sun7i# "
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 2db083c..b76227e 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -170,6 +170,11 @@
#define CONFIG_SYS_I2C_SLAVE 0x7f
#define CONFIG_CMD_I2C
+/* PMU */
+#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || defined CONFIG_AXP221_POWER
+#define CONFIG_SPL_POWER_SUPPORT
+#endif
+
#ifndef CONFIG_CONS_INDEX
#define CONFIG_CONS_INDEX 1 /* UART0 */
#endif
--
1.9.0
More information about the U-Boot
mailing list