[U-Boot] [PATCH 01/10] sunxi: make SoC variant choice mandatory

The user should always select an SoC variant to support. Not choosing one doesn't make sense for a bootloader.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- board/sunxi/Kconfig | 1 - 1 file changed, 1 deletion(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index fa7872031b9d..95500a1bcdb0 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -18,7 +18,6 @@ config SUNXI_GEN_SUN6I
choice prompt "Sunxi SoC Variant" - optional
config MACH_SUN4I bool "sun4i (Allwinner A10)"

In most other places, we sort SoC descriptions by family (sunXi) first, then by the chip name (A20).
Signed-off-by: Chen-Yu Tsai wens@csie.org --- board/sunxi/Kconfig | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 95500a1bcdb0..49a937a8b61a 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -67,6 +67,12 @@ config MACH_SUN8I_A33 select SUPPORT_SPL select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
+config MACH_SUN8I_A83T + bool "sun8i (Allwinner A83T)" + select CPU_V7 + select SUNXI_GEN_SUN6I + select SUPPORT_SPL + config MACH_SUN8I_H3 bool "sun8i (Allwinner H3)" select CPU_V7 @@ -76,22 +82,16 @@ config MACH_SUN8I_H3 select SUPPORT_SPL select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT
-config MACH_SUN50I - bool "sun50i (Allwinner A64)" - select ARM64 - select SUNXI_GEN_SUN6I - -config MACH_SUN8I_A83T - bool "sun8i (Allwinner A83T)" - select CPU_V7 - select SUNXI_GEN_SUN6I - select SUPPORT_SPL - config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7 select SUNXI_GEN_SUN6I
+config MACH_SUN50I + bool "sun50i (Allwinner A64)" + select ARM64 + select SUNXI_GEN_SUN6I + endchoice
# The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33"

A83T, H3, and A64 have a dedicated pin for card detect on the PF pingroup. This is used in all designs. Set it as the default.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- board/sunxi/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 49a937a8b61a..a24d5c238da9 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -260,6 +260,7 @@ config MMC
config MMC0_CD_PIN string "Card detect pin for mmc0" + default "PF6" if MACH_SUN8I_A83T || MACH_SUN8I_H3 || MACH_SUN50I default "" ---help--- Set the card detect pin for mmc0, leave empty to not use cd. This

The newer chips use a newer display pipeline, which is not supported.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- board/sunxi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index a24d5c238da9..059e9146cc5c 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -419,7 +419,7 @@ config AXP_GPIO
config VIDEO boolean "Enable graphical uboot console on HDMI, LCD or VGA" - depends on !MACH_SUN8I_A83T + depends on !MACH_SUN8I_A83T && !MACH_SUN8I_H3 && !MACH_SUN9I && !MACH_SUN50I_A64 default y ---help--- Say Y here to add support for using a cfb console on the HDMI, LCD

The ELDO enable bits and registers are contiguous for axp221. Instead of a switch case testing against the index, just use the index to shift the bit or register offset.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- drivers/power/axp221.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-)
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c index cb1f88b185cc..727ab098068f 100644 --- a/drivers/power/axp221.c +++ b/drivers/power/axp221.c @@ -191,33 +191,20 @@ int axp_set_eldo(int eldo_num, unsigned int mvolt) { int ret; u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100); - u8 addr, bits; - - switch (eldo_num) { - case 3: - addr = AXP221_ELDO3_CTRL; - bits = AXP221_OUTPUT_CTRL2_ELDO3_EN; - break; - case 2: - addr = AXP221_ELDO2_CTRL; - bits = AXP221_OUTPUT_CTRL2_ELDO2_EN; - break; - case 1: - addr = AXP221_ELDO1_CTRL; - bits = AXP221_OUTPUT_CTRL2_ELDO1_EN; - break; - default: + + if (eldo_num < 1 || eldo_num > 3) return -EINVAL; - }
if (mvolt == 0) - return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, bits); + return pmic_bus_clrbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1));
- ret = pmic_bus_write(addr, cfg); + ret = pmic_bus_write(AXP221_ELDO1_CTRL + (eldo_num - 1), cfg); if (ret) return ret;
- return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, bits); + return pmic_bus_setbits(AXP221_OUTPUT_CTRL2, + AXP221_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1)); }
int axp_init(void)

Description said eldo2 instead of fldo2, a copy-paste error.
Fixes: 38491d9c6515 ("power: axp818: Add support for FLDOs") Signed-off-by: Chen-Yu Tsai wens@csie.org --- drivers/power/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 3c41bca32acd..b365fd46fa71 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -249,7 +249,7 @@ config AXP_FLDO1_VOLT used.
config AXP_FLDO2_VOLT - int "axp pmic eldo2 voltage" + int "axp pmic fldo2 voltage" depends on AXP818_POWER default 900 if MACH_SUN8I_A83T ---help---

The AXP818 has a switchable output, SW. This is commonly used for controlling power to the LCD backlight.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- board/sunxi/board.c | 1 + drivers/power/Kconfig | 7 +++++++ drivers/power/axp818.c | 10 ++++++++++ include/axp818.h | 1 + include/axp_pmic.h | 1 + 5 files changed, 20 insertions(+)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 3cf36147b241..6a0a8dbc4f5e 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -523,6 +523,7 @@ void sunxi_board_init(void) power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT); power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT); power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT); + power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON)); #endif #endif printf("DRAM:"); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index b365fd46fa71..02cb8e7ba687 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -265,6 +265,13 @@ config AXP_FLDO3_VOLT Set the voltage (mV) to program the axp pmic fldo3 at, set to 0 to disable fldo3.
+config AXP_SW_ON + bool "axp pmic sw on" + depends on AXP818_POWER + default n + ---help--- + Enable to turn on axp pmic sw. + config SY8106A_VOUT1_VOLT int "SY8106A pmic VOUT1 voltage" depends on SY8106A_POWER diff --git a/drivers/power/axp818.c b/drivers/power/axp818.c index 3ac05ffefe01..bf6ecd6be597 100644 --- a/drivers/power/axp818.c +++ b/drivers/power/axp818.c @@ -225,6 +225,16 @@ int axp_set_fldo(int fldo_num, unsigned int mvolt) AXP818_OUTPUT_CTRL3_FLDO1_EN << (fldo_num - 1)); }
+int axp_set_sw(bool on) +{ + if (on) + return pmic_bus_setbits(AXP818_OUTPUT_CTRL2, + AXP818_OUTPUT_CTRL2_SW_EN); + + return pmic_bus_clrbits(AXP818_OUTPUT_CTRL2, + AXP818_OUTPUT_CTRL2_SW_EN); +} + int axp_init(void) { u8 axp_chip_id; diff --git a/include/axp818.h b/include/axp818.h index 5630eed04d8f..f7f343a194ab 100644 --- a/include/axp818.h +++ b/include/axp818.h @@ -24,6 +24,7 @@ #define AXP818_OUTPUT_CTRL2_DLDO2_EN (1 << 4) #define AXP818_OUTPUT_CTRL2_DLDO3_EN (1 << 5) #define AXP818_OUTPUT_CTRL2_DLDO4_EN (1 << 6) +#define AXP818_OUTPUT_CTRL2_SW_EN (1 << 7) #define AXP818_OUTPUT_CTRL3 0x13 #define AXP818_OUTPUT_CTRL3_FLDO1_EN (1 << 2) #define AXP818_OUTPUT_CTRL3_FLDO2_EN (1 << 3) diff --git a/include/axp_pmic.h b/include/axp_pmic.h index b203cc88ddbc..2ed5196354e9 100644 --- a/include/axp_pmic.h +++ b/include/axp_pmic.h @@ -32,6 +32,7 @@ int axp_set_aldo4(unsigned int mvolt); int axp_set_dldo(int dldo_num, unsigned int mvolt); int axp_set_eldo(int eldo_num, unsigned int mvolt); int axp_set_fldo(int fldo_num, unsigned int mvolt); +int axp_set_sw(bool on); int axp_init(void); int axp_get_sid(unsigned int *sid);

The SW output of the PMIC supplies the ethernet PHY with power.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- configs/Sinovoip_BPI_M3_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/Sinovoip_BPI_M3_defconfig b/configs/Sinovoip_BPI_M3_defconfig index 13dbb98689e3..29694ce1ef73 100644 --- a/configs/Sinovoip_BPI_M3_defconfig +++ b/configs/Sinovoip_BPI_M3_defconfig @@ -30,5 +30,6 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_AXP_DCDC5_VOLT=1200 CONFIG_AXP_DLDO3_VOLT=2500 +CONFIG_AXP_SW_ON=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_MUSB_HOST=y

Adds poweroff support for axp818 pmic.
Signed-off-by: Chen-Yu Tsai wens@csie.org --- drivers/power/Kconfig | 1 + drivers/power/axp818.c | 11 +++++++++++ include/axp818.h | 3 +++ 3 files changed, 15 insertions(+)
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 02cb8e7ba687..d1375369c195 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -44,6 +44,7 @@ config AXP221_POWER config AXP818_POWER boolean "axp818 pmic support" depends on MACH_SUN8I_A83T + select CMD_POWEROFF ---help--- Say y here to enable support for the axp818 pmic found on A83T dev board. diff --git a/drivers/power/axp818.c b/drivers/power/axp818.c index bf6ecd6be597..af4d7a69032a 100644 --- a/drivers/power/axp818.c +++ b/drivers/power/axp818.c @@ -255,3 +255,14 @@ int axp_init(void)
return 0; } + +int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + pmic_bus_write(AXP818_SHUTDOWN, AXP818_SHUTDOWN_POWEROFF); + + /* infinite loop during shutdown */ + while (1) {} + + /* not reached */ + return 0; +} diff --git a/include/axp818.h b/include/axp818.h index f7f343a194ab..959774c76fa6 100644 --- a/include/axp818.h +++ b/include/axp818.h @@ -55,6 +55,9 @@ #define AXP818_ALDO2_CTRL 0x29 #define AXP818_ALDO3_CTRL 0x2a
+#define AXP818_SHUTDOWN 0x32 +#define AXP818_SHUTDOWN_POWEROFF (1 << 7) + /* For axp_gpio.c */ #define AXP_POWER_STATUS 0x00 #define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5)

The A80 uses the AXP809 as its primary PMIC.
Signed-off-by: Chen-Yu Tsai wens@csie.org ---
Without actual SPL support, this patch has only been compile tested.
--- arch/arm/mach-sunxi/Makefile | 1 + arch/arm/mach-sunxi/pmic_bus.c | 6 +- board/sunxi/board.c | 20 +++- drivers/power/Kconfig | 72 ++++++++----- drivers/power/Makefile | 1 + drivers/power/axp809.c | 238 +++++++++++++++++++++++++++++++++++++++++ include/axp809.h | 60 +++++++++++ include/axp_pmic.h | 3 + 8 files changed, 367 insertions(+), 34 deletions(-) create mode 100644 drivers/power/axp809.c create mode 100644 include/axp809.h
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index ad3d6c491850..25367cf38006 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o obj-$(CONFIG_AXP152_POWER) += pmic_bus.o obj-$(CONFIG_AXP209_POWER) += pmic_bus.o obj-$(CONFIG_AXP221_POWER) += pmic_bus.o +obj-$(CONFIG_AXP809_POWER) += pmic_bus.o obj-$(CONFIG_AXP818_POWER) += pmic_bus.o
ifdef CONFIG_SPL_BUILD diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c index 5b81a8d8e127..7c57f02792b9 100644 --- a/arch/arm/mach-sunxi/pmic_bus.c +++ b/arch/arm/mach-sunxi/pmic_bus.c @@ -36,7 +36,7 @@ int pmic_bus_init(void) if (!needs_init) return 0;
-#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER # ifdef CONFIG_MACH_SUN6I p2wi_init(); ret = p2wi_change_to_p2wi_mode(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, @@ -62,7 +62,7 @@ int pmic_bus_read(u8 reg, u8 *data) return i2c_read(AXP152_I2C_ADDR, reg, 1, data, 1); #elif defined CONFIG_AXP209_POWER return i2c_read(AXP209_I2C_ADDR, reg, 1, data, 1); -#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER # ifdef CONFIG_MACH_SUN6I return p2wi_read(reg, data); # else @@ -77,7 +77,7 @@ int pmic_bus_write(u8 reg, u8 data) return i2c_write(AXP152_I2C_ADDR, reg, 1, &data, 1); #elif defined CONFIG_AXP209_POWER return i2c_write(AXP209_I2C_ADDR, reg, 1, &data, 1); -#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#elif defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER # ifdef CONFIG_MACH_SUN6I return p2wi_write(reg, data); # else diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 6a0a8dbc4f5e..103aafe14d90 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -483,10 +483,12 @@ void sunxi_board_init(void) #endif
#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \ - defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER + defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ + defined CONFIG_AXP818_POWER power_failed = axp_init();
-#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ + defined CONFIG_AXP818_POWER power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT); #endif power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT); @@ -494,11 +496,13 @@ void sunxi_board_init(void) #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER) power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT); #endif -#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ + defined CONFIG_AXP818_POWER power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT); #endif
-#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP818_POWER +#if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \ + defined CONFIG_AXP818_POWER power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT); #endif power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT); @@ -509,11 +513,14 @@ void sunxi_board_init(void) power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT); #endif
-#if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP818_POWER) +#if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP809_POWER) || \ + defined(CONFIG_AXP818_POWER) power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT); power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT); +#if !defined CONFIG_AXP809_POWER power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT); power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT); +#endif power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT); power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT); power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT); @@ -523,6 +530,9 @@ void sunxi_board_init(void) power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT); power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT); power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT); +#endif + +#if defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON)); #endif #endif diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index d1375369c195..3c4416780591 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -41,6 +41,13 @@ config AXP221_POWER Select this to enable support for the axp221/axp223 pmic found on most A23 and A31 boards.
+config AXP809_POWER + boolean "axp809 pmic support" + depends on MACH_SUN9I + select CMD_POWEROFF + ---help--- + Say y here to enable support for the axp809 pmic found on A80 boards. + config AXP818_POWER boolean "axp818 pmic support" depends on MACH_SUN8I_A83T @@ -60,36 +67,39 @@ endchoice
config AXP_DCDC1_VOLT int "axp pmic dcdc1 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP809_POWER || AXP818_POWER default 3300 if AXP818_POWER - default 3000 if MACH_SUN6I || MACH_SUN8I + default 3000 if MACH_SUN6I || MACH_SUN8I || MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc1 at, set to 0 to disable dcdc1. On A23 / A31 / A33 (axp221) boards dcdc1 is used for generic 3.3V IO voltage for external devices like the lcd-panal and sdcard interfaces, etc. On most boards dcdc1 is undervolted to 3.0V to - safe battery. On A31 devices dcdc1 is also used for VCC-IO. On A83T - dcdc1 is used for VCC-IO, nand, usb0, sd , etc. + save battery. On A31 devices dcdc1 is also used for VCC-IO. On A83T + dcdc1 is used for VCC-IO, nand, usb0, sd , etc. On A80 dcdc1 normally + powers some of the pingroups, NAND/eMMC, SD/MMC, and USB OTG.
config AXP_DCDC2_VOLT int "axp pmic dcdc2 voltage" - depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER + depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER default 900 if AXP818_POWER default 1400 if AXP152_POWER || AXP209_POWER default 1200 if MACH_SUN6I default 1100 if MACH_SUN8I + default 0 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc2 at, set to 0 to disable dcdc2. On A10(s) / A13 / A20 boards dcdc2 is VDD-CPU and should be 1.4V. On A31 boards dcdc2 is used for VDD-GPU and should be 1.2V. On A23/A33 boards dcdc2 is used for VDD-SYS and should be 1.1V. + On A80 boards dcdc2 powers the GPU and can be left off. On A83T boards dcdc2 is used for VDD-CPUA(cluster 0) and should be 0.9V.
config AXP_DCDC3_VOLT int "axp pmic dcdc3 voltage" - depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER - default 900 if AXP818_POWER + depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER + default 900 if AXP809_POWER || AXP818_POWER default 1500 if AXP152_POWER default 1250 if AXP209_POWER default 1200 if MACH_SUN6I || MACH_SUN8I @@ -100,51 +110,55 @@ config AXP_DCDC3_VOLT should be 1.25V. On A10s boards with an axp152 dcdc3 is VCC-DRAM and should be 1.5V. On A23 / A31 / A33 boards dcdc3 is VDD-CPU and should be 1.2V. + On A80 boards dcdc3 is used for VDD-CPUA(cluster 0) and should be 0.9V. On A83T boards dcdc3 is used for VDD-CPUB(cluster 1) and should be 0.9V.
config AXP_DCDC4_VOLT int "axp pmic dcdc4 voltage" - depends on AXP152_POWER || AXP221_POWER || AXP818_POWER + depends on AXP152_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER default 1250 if AXP152_POWER default 1200 if MACH_SUN6I default 0 if MACH_SUN8I + default 900 if MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc4 at, set to 0 to disable dcdc4. On A10s boards with an axp152 dcdc4 is VDD-INT-DLL and should be 1.25V. On A31 boards dcdc4 is used for VDD-SYS and should be 1.2V. On A23 / A33 boards dcdc4 is unused and should be disabled. + On A80 boards dcdc4 powers VDD-SYS, HDMI, USB OTG and should be 0.9V. On A83T boards dcdc4 is used for VDD-GPU.
config AXP_DCDC5_VOLT int "axp pmic dcdc5 voltage" - depends on AXP221_POWER || AXP818_POWER - default 1500 if MACH_SUN6I || MACH_SUN8I + depends on AXP221_POWER || AXP809_POWER || AXP818_POWER + default 1500 if MACH_SUN6I || MACH_SUN8I || MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic dcdc5 at, set to 0 to disable dcdc5. - On A23 / A31 / A33 / A83T boards dcdc5 is VCC-DRAM and should be 1.5V, - 1.35V if DDR3L is used. + On A23 / A31 / A33 / A80 / A83T boards dcdc5 is VCC-DRAM and + should be 1.5V, 1.35V if DDR3L is used.
config AXP_ALDO1_VOLT int "axp pmic (a)ldo1 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP809_POWER || AXP818_POWER default 0 if MACH_SUN6I default 1800 if MACH_SUN8I_A83T - default 3000 if MACH_SUN8I + default 3000 if MACH_SUN8I || MACH_SUN9I ---help--- Set the voltage (mV) to program the axp pmic aldo1 at, set to 0 to disable aldo1. On A31 boards aldo1 is often used to power the wifi module. On A23 / A33 boards aldo1 is used for VCC-IO and should be 3.0V. + On A80 boards aldo1 powers the USB hosts and should be 3.0V. On A83T / H8 boards aldo1 is used for MIPI CSI, DSI, HDMI, EFUSE, and should be 1.8V.
config AXP_ALDO2_VOLT int "axp pmic (a)ldo2 voltage" - depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP818_POWER + depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER default 3000 if AXP152_POWER || AXP209_POWER - default 0 if MACH_SUN6I + default 0 if MACH_SUN6I || MACH_SUN9I default 1800 if MACH_SUN8I_A83T default 2500 if MACH_SUN8I ---help--- @@ -154,19 +168,21 @@ config AXP_ALDO2_VOLT On A31 boards aldo2 is typically unused and should be disabled. On A31 boards aldo2 may be used for LPDDR2 then it should be 1.8V. On A23 / A33 boards aldo2 is used for VDD-DLL and should be 2.5V. + On A80 boards aldo2 powers PB pingroup and camera IO and can be left off. On A83T / H8 boards aldo2 powers VDD-DLL, VCC18-PLL, CPVDD, VDD18-ADC, LPDDR2, and the codec. It should be 1.8V.
config AXP_ALDO3_VOLT int "axp pmic (a)ldo3 voltage" - depends on AXP209_POWER || AXP221_POWER || AXP818_POWER - default 0 if AXP209_POWER + depends on AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER + default 0 if AXP209_POWER || MACH_SUN9I default 3000 if MACH_SUN6I || MACH_SUN8I ---help--- Set the voltage (mV) to program the axp pmic aldo3 at, set to 0 to disable aldo3. On A10(s) / A13 / A20 boards aldo3 should be 2.8V. On A23 / A31 / A33 boards aldo3 is VCC-PLL and AVCC and should be 3.0V. + On A80 boards aldo3 is normally not used. On A83T / H8 boards aldo3 is AVCC, VCC-PL, and VCC-LED, and should be 3.0V.
@@ -181,21 +197,23 @@ config AXP_ALDO4_VOLT
config AXP_DLDO1_VOLT int "axp pmic dldo1 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP809_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic dldo1 at, set to 0 to disable dldo1. On sun6i (A31) boards with ethernet dldo1 is often used - to power the ethernet phy. On sun8i (A23) boards this is often used to - power the wifi. + to power the ethernet phy. On A23, A33 and A80 boards this is often + used to power the wifi.
config AXP_DLDO2_VOLT int "axp pmic dldo2 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP809_POWER || AXP818_POWER + default 3000 if MACH_SUN9I default 0 ---help--- Set the voltage (mV) to program the axp pmic dldo2 at, set to 0 to disable dldo2. + On A80 boards dldo2 normally powers the PL pins and should be 3.0V.
config AXP_DLDO3_VOLT int "axp pmic dldo3 voltage" @@ -215,7 +233,7 @@ config AXP_DLDO4_VOLT
config AXP_ELDO1_VOLT int "axp pmic eldo1 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP809_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic eldo1 at, set to 0 to @@ -223,7 +241,7 @@ config AXP_ELDO1_VOLT
config AXP_ELDO2_VOLT int "axp pmic eldo2 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP809_POWER || AXP818_POWER default 0 ---help--- Set the voltage (mV) to program the axp pmic eldo2 at, set to 0 to @@ -231,13 +249,15 @@ config AXP_ELDO2_VOLT
config AXP_ELDO3_VOLT int "axp pmic eldo3 voltage" - depends on AXP221_POWER || AXP818_POWER + depends on AXP221_POWER || AXP809_POWER || AXP818_POWER + default 3000 if MACH_SUN9I default 0 ---help--- Set the voltage (mV) to program the axp pmic eldo3 at, set to 0 to disable eldo3. On some A31(s) tablets it might be used to supply 1.2V for the SSD2828 chip (converter of parallel LCD interface into MIPI DSI). + On A80 boards it powers the PM pingroup and should be 3.0V.
config AXP_FLDO1_VOLT int "axp pmic fldo1 voltage" @@ -268,7 +288,7 @@ config AXP_FLDO3_VOLT
config AXP_SW_ON bool "axp pmic sw on" - depends on AXP818_POWER + depends on AXP809_POWER || AXP818_POWER default n ---help--- Enable to turn on axp pmic sw. diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 690faa0f5e47..b43523e6282e 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_AS3722_POWER) += as3722.o obj-$(CONFIG_AXP152_POWER) += axp152.o obj-$(CONFIG_AXP209_POWER) += axp209.o obj-$(CONFIG_AXP221_POWER) += axp221.o +obj-$(CONFIG_AXP809_POWER) += axp809.o obj-$(CONFIG_AXP818_POWER) += axp818.o obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o diff --git a/drivers/power/axp809.c b/drivers/power/axp809.c new file mode 100644 index 000000000000..c8b76cf9b7f2 --- /dev/null +++ b/drivers/power/axp809.c @@ -0,0 +1,238 @@ +/* + * AXP809 driver based on AXP221 driver + * + * + * (C) Copyright 2016 Chen-Yu Tsai wens@csie.org + * + * Based on axp221.c + * (C) Copyright 2014 Hans de Goede hdegoede@redhat.com + * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <asm/arch/gpio.h> +#include <asm/arch/pmic_bus.h> +#include <axp_pmic.h> + +static u8 axp809_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 axp_set_dcdc1(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 1600, 3400, 100); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC1_EN); + + ret = pmic_bus_write(AXP809_DCDC1_CTRL, cfg); + if (ret) + return ret; + + ret = pmic_bus_setbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_DC1SW_EN); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC1_EN); +} + +int axp_set_dcdc2(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1540, 20); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC2_EN); + + ret = pmic_bus_write(AXP809_DCDC2_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC2_EN); +} + +int axp_set_dcdc3(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1860, 20); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC3_EN); + + ret = pmic_bus_write(AXP809_DCDC3_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC3_EN); +} + +int axp_set_dcdc4(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1540, 20); + + if (mvolt >= 1540) + cfg = 0x30 + axp809_mvolt_to_cfg(mvolt, 1800, 2600, 100); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC4_EN); + + ret = pmic_bus_write(AXP809_DCDC5_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC4_EN); +} + +int axp_set_dcdc5(unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 1000, 2550, 50); + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC5_EN); + + ret = pmic_bus_write(AXP809_DCDC5_CTRL, cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_DCDC5_EN); +} + +int axp_set_aldo(int aldo_num, unsigned int mvolt) +{ + int ret; + u8 cfg; + + if (aldo_num < 1 || aldo_num > 3) + return -EINVAL; + + if (mvolt == 0 && aldo_num == 3) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_ALDO3_EN); + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_ALDO1_EN << (aldo_num - 1)); + + cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100); + ret = pmic_bus_write(AXP809_ALDO1_CTRL + (aldo_num - 1), cfg); + if (ret) + return ret; + + if (aldo_num == 3) + return pmic_bus_setbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_ALDO3_EN); + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1, + AXP809_OUTPUT_CTRL1_ALDO1_EN << (aldo_num - 1)); +} + +/* TODO: re-work other AXP drivers to consolidate ALDO functions. */ +int axp_set_aldo1(unsigned int mvolt) +{ + return axp_set_aldo(1, mvolt); +} + +int axp_set_aldo2(unsigned int mvolt) +{ + return axp_set_aldo(2, mvolt); +} + +int axp_set_aldo3(unsigned int mvolt) +{ + return axp_set_aldo(3, mvolt); +} + +int axp_set_dldo(int dldo_num, unsigned int mvolt) +{ + u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100); + int ret; + + if (dldo_num < 1 || dldo_num > 2) + return -EINVAL; + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1)); + + if (dldo_num == 1 && mvolt > 3300) + cfg += 1 + axp809_mvolt_to_cfg(mvolt, 3400, 4200, 200); + ret = pmic_bus_write(AXP809_DLDO1_CTRL + (dldo_num - 1), cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1)); +} + +int axp_set_eldo(int eldo_num, unsigned int mvolt) +{ + int ret; + u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100); + + if (eldo_num < 1 || eldo_num > 3) + return -EINVAL; + + if (mvolt == 0) + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1)); + + ret = pmic_bus_write(AXP809_ELDO1_CTRL + (eldo_num - 1), cfg); + if (ret) + return ret; + + return pmic_bus_setbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1)); +} + +int axp_set_sw(bool on) +{ + if (on) + return pmic_bus_setbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_SWOUT_EN); + + return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2, + AXP809_OUTPUT_CTRL2_SWOUT_EN); +} + +int axp_init(void) +{ + int ret; + + ret = pmic_bus_init(); + if (ret) + return ret; + + return 0; +} + +int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + pmic_bus_write(AXP809_SHUTDOWN, AXP809_SHUTDOWN_POWEROFF); + + /* infinite loop during shutdown */ + while (1) {} + + /* not reached */ + return 0; +} diff --git a/include/axp809.h b/include/axp809.h new file mode 100644 index 000000000000..d27fb978d200 --- /dev/null +++ b/include/axp809.h @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2016 Chen-Yu Tsai wens@csie.org + * + * X-Powers AXP809 Power Management IC driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define AXP809_CHIP_ID 0x03 + +#define AXP809_OUTPUT_CTRL1 0x10 +#define AXP809_OUTPUT_CTRL1_DC5LDO_EN (1 << 0) +#define AXP809_OUTPUT_CTRL1_DCDC1_EN (1 << 1) +#define AXP809_OUTPUT_CTRL1_DCDC2_EN (1 << 2) +#define AXP809_OUTPUT_CTRL1_DCDC3_EN (1 << 3) +#define AXP809_OUTPUT_CTRL1_DCDC4_EN (1 << 4) +#define AXP809_OUTPUT_CTRL1_DCDC5_EN (1 << 5) +#define AXP809_OUTPUT_CTRL1_ALDO1_EN (1 << 6) +#define AXP809_OUTPUT_CTRL1_ALDO2_EN (1 << 7) +#define AXP809_OUTPUT_CTRL2 0x12 +#define AXP809_OUTPUT_CTRL2_ELDO1_EN (1 << 0) +#define AXP809_OUTPUT_CTRL2_ELDO2_EN (1 << 1) +#define AXP809_OUTPUT_CTRL2_ELDO3_EN (1 << 2) +#define AXP809_OUTPUT_CTRL2_DLDO1_EN (1 << 3) +#define AXP809_OUTPUT_CTRL2_DLDO2_EN (1 << 4) +#define AXP809_OUTPUT_CTRL2_ALDO3_EN (1 << 5) +#define AXP809_OUTPUT_CTRL2_SWOUT_EN (1 << 6) +#define AXP809_OUTPUT_CTRL2_DC1SW_EN (1 << 7) + +#define AXP809_DLDO1_CTRL 0x15 +#define AXP809_DLDO2_CTRL 0x16 +#define AXP809_ELDO1_CTRL 0x19 +#define AXP809_ELDO2_CTRL 0x1a +#define AXP809_ELDO3_CTRL 0x1b +#define AXP809_DC5LDO_CTRL 0x1c +#define AXP809_DCDC1_CTRL 0x21 +#define AXP809_DCDC2_CTRL 0x22 +#define AXP809_DCDC3_CTRL 0x23 +#define AXP809_DCDC4_CTRL 0x24 +#define AXP809_DCDC5_CTRL 0x25 +#define AXP809_ALDO1_CTRL 0x28 +#define AXP809_ALDO2_CTRL 0x29 +#define AXP809_ALDO3_CTRL 0x2a +#define AXP809_SHUTDOWN 0x32 +#define AXP809_SHUTDOWN_POWEROFF (1 << 7) + +/* For axp_gpio.c */ +#define AXP_POWER_STATUS 0x00 +#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5) +#define AXP_VBUS_IPSOUT 0x30 +#define AXP_VBUS_IPSOUT_DRIVEBUS (1 << 2) +#define AXP_MISC_CTRL 0x8f +#define AXP_MISC_CTRL_N_VBUSEN_FUNC (1 << 4) +#define AXP_GPIO0_CTRL 0x90 +#define AXP_GPIO1_CTRL 0x92 +#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */ +#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */ +#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */ +#define AXP_GPIO_STATE 0x94 +#define AXP_GPIO_STATE_OFFSET 0 diff --git a/include/axp_pmic.h b/include/axp_pmic.h index 2ed5196354e9..d789ad808623 100644 --- a/include/axp_pmic.h +++ b/include/axp_pmic.h @@ -16,6 +16,9 @@ #ifdef CONFIG_AXP221_POWER #include <axp221.h> #endif +#ifdef CONFIG_AXP809_POWER +#include <axp809.h> +#endif #ifdef CONFIG_AXP818_POWER #include <axp818.h> #endif

Hi,
Thanks, entire series looks good to me applied to:
http://git.denx.de/?p=u-boot/u-boot-sunxi.git;a=shortlog;h=refs/heads/next
These will be part of my first pull-req for u-boot v2016.07.
Regards,
Hans
On 02-05-16 04:28, Chen-Yu Tsai wrote:
The user should always select an SoC variant to support. Not choosing one doesn't make sense for a bootloader.
Signed-off-by: Chen-Yu Tsai wens@csie.org
board/sunxi/Kconfig | 1 - 1 file changed, 1 deletion(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index fa7872031b9d..95500a1bcdb0 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -18,7 +18,6 @@ config SUNXI_GEN_SUN6I
choice prompt "Sunxi SoC Variant"
- optional
config MACH_SUN4I bool "sun4i (Allwinner A10)"
participants (2)
-
Chen-Yu Tsai
-
Hans de Goede