Merge git://git.denx.de/u-boot-marvell

- Sync DDR training with Marvell code for Armada 38x by Chris
- Misc updates to Armada 38x Helios4 board by Aditya
diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c
index 5d91d7e..dea42de 100644
--- a/arch/arm/mach-sunxi/pmic_bus.c
+++ b/arch/arm/mach-sunxi/pmic_bus.c
@@ -101,6 +101,9 @@
 	if (ret)
 		return ret;
 
+	if ((val & bits) == bits)
+		return 0;
+
 	val |= bits;
 	return pmic_bus_write(reg, val);
 }
@@ -114,6 +117,9 @@
 	if (ret)
 		return ret;
 
+	if (!(val & bits))
+		return 0;
+
 	val &= ~bits;
 	return pmic_bus_write(reg, val);
 }
diff --git a/board/8dtech/eco5pk/eco5pk.c b/board/8dtech/eco5pk/eco5pk.c
index e05928f..dcbd483 100644
--- a/board/8dtech/eco5pk/eco5pk.c
+++ b/board/8dtech/eco5pk/eco5pk.c
@@ -16,7 +16,7 @@
 #include <asm/arch/emac_defs.h>
 #include <asm/gpio.h>
 #include <i2c.h>
-#include <crc.h>
+#include <u-boot/crc.h>
 #include <asm/mach-types.h>
 #include "eco5pk.h"
 
diff --git a/board/armadeus/apf27/apf27.c b/board/armadeus/apf27/apf27.c
index 0f0c8a4..bf2586d 100644
--- a/board/armadeus/apf27/apf27.c
+++ b/board/armadeus/apf27/apf27.c
@@ -16,8 +16,8 @@
 #include <asm/arch/gpio.h>
 #include <asm/gpio.h>
 #include <linux/errno.h>
+#include <u-boot/crc.h>
 #include "apf27.h"
-#include "crc.h"
 #include "fpga.h"
 
 DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/sunxi/README.sunxi64 b/board/sunxi/README.sunxi64
index bba2e01..258921a 100644
--- a/board/sunxi/README.sunxi64
+++ b/board/sunxi/README.sunxi64
@@ -12,8 +12,13 @@
 Quick Start / Overview
 ======================
 - Build the ARM Trusted Firmware binary (see "ARM Trusted Firmware (ATF)" below)
+  $ cd /src/arm-trusted-firmware
+  $ make PLAT=sun50i_a64 DEBUG=1 bl31
 - Build U-Boot (see "SPL/U-Boot" below)
+  $ export BL31=/path/to/bl31.bin
+  $ make pine64_plus_defconfig && make -j5
 - Transfer to an uSD card (see "microSD card" below)
+  $ dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=8k seek=1
 - Boot and enjoy!
 
 Building the firmware
@@ -29,14 +34,18 @@
 
  ARM Trusted Firmware (ATF)
 ----------------------------
-Checkout the "allwinner" branch from the github repository [1] and build it:
+Checkout the latest master branch from the official ATF repository [1] and
+build it:
 $ export CROSS_COMPILE=aarch64-linux-gnu-
-$ make PLAT=sun50iw1p1 DEBUG=1 bl31
-The resulting binary is build/sun50iw1p1/debug/bl31.bin. Either put the
+$ make PLAT=sun50i_a64 DEBUG=1 bl31
+The resulting binary is build/sun50i_a64/debug/bl31.bin. Either put the
 location of this file into the BL31 environment variable or copy this to
 the root of your U-Boot build directory (or create a symbolic link).
-$ export BL31=/src/arm-trusted-firmware/build/sun50iw1p1/debug/bl31.bin
+$ export BL31=/src/arm-trusted-firmware/build/sun50i_a64/debug/bl31.bin
   (adjust the actual path accordingly)
+The platform target "sun50i_a64" covers all boards with either an Allwinner
+A64 or H5 SoC (since they are very similar). For boards with an Allwinner H6
+SoC use "sun50i_h6".
 
 If you run into size issues with the resulting U-Boot image file, it might
 help to use a release build, by using "DEBUG=0" when building bl31.bin.
@@ -59,7 +68,8 @@
 $ make
 
 This will build the SPL in spl/sunxi-spl.bin and a FIT image called u-boot.itb,
-which contains the rest of the firmware.
+which contains the rest of the firmware. u-boot-sunxi-with-spl.bin joins those
+two components in one convenient image file.
 
 
 Boot process
@@ -91,6 +101,9 @@
 As the FEL mode is controlled by the boot ROM, it expects to be running in
 AArch32. For now the AArch64 SPL cannot properly return into FEL mode, so the
 feature is disabled in the configuration at the moment.
+The repository in [3] contains FEL capable SPL binaries, built using an
+off-tree branch to generate 32-bit ARM code (along with instructions
+how to re-create them).
 
 microSD card
 ------------
@@ -165,6 +178,6 @@
 device file (see above):
 $ dd if=firmware.img of=/dev/sdx bs=8k seek=1
 
-[1] https://github.com/apritzel/arm-trusted-firmware.git
+[1] https://github.com/ARM-software/arm-trusted-firmware.git
 [2] git://github.com/linux-sunxi/sunxi-tools.git
 [3] https://github.com/apritzel/pine64/
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 64ccbc7..8e20dc7 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -28,7 +28,7 @@
 #endif
 #include <asm/gpio.h>
 #include <asm/io.h>
-#include <crc.h>
+#include <u-boot/crc.h>
 #include <environment.h>
 #include <linux/libfdt.h>
 #include <nand.h>
@@ -637,13 +637,6 @@
 	power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON));
 #endif
 #endif
-	printf("DRAM:");
-	gd->ram_size = sunxi_dram_init();
-	printf(" %d MiB\n", (int)(gd->ram_size >> 20));
-	if (!gd->ram_size)
-		hang();
-
-	sunxi_spl_store_dram_size(gd->ram_size);
 
 	/*
 	 * Only clock up the CPU to full speed if we are reasonably
@@ -652,7 +645,16 @@
 	if (!power_failed)
 		clock_set_pll1(CONFIG_SYS_CLK_FREQ);
 	else
-		printf("Failed to set core voltage! Can't set CPU frequency\n");
+		printf("Error setting up the power controller.\n"
+		       "CPU frequency not set.\n");
+
+	printf("DRAM:");
+	gd->ram_size = sunxi_dram_init();
+	printf(" %d MiB\n", (int)(gd->ram_size >> 20));
+	if (!gd->ram_size)
+		hang();
+
+	sunxi_spl_store_dram_size(gd->ram_size);
 }
 #endif
 
diff --git a/common/hash.c b/common/hash.c
index ef14651..413a5bf 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -85,6 +85,33 @@
 }
 #endif
 
+static int hash_init_crc16_ccitt(struct hash_algo *algo, void **ctxp)
+{
+	uint16_t *ctx = malloc(sizeof(uint16_t));
+	*ctx = 0;
+	*ctxp = ctx;
+	return 0;
+}
+
+static int hash_update_crc16_ccitt(struct hash_algo *algo, void *ctx,
+				   const void *buf, unsigned int size,
+				   int is_last)
+{
+	*((uint16_t *)ctx) = crc16_ccitt(*((uint16_t *)ctx), buf, size);
+	return 0;
+}
+
+static int hash_finish_crc16_ccitt(struct hash_algo *algo, void *ctx,
+				   void *dest_buf, int size)
+{
+	if (size < algo->digest_size)
+		return -1;
+
+	*((uint16_t *)dest_buf) = *((uint16_t *)ctx);
+	free(ctx);
+	return 0;
+}
+
 static int hash_init_crc32(struct hash_algo *algo, void **ctxp)
 {
 	uint32_t *ctx = malloc(sizeof(uint32_t));
@@ -160,6 +187,15 @@
 	},
 #endif
 	{
+		.name		= "crc16-ccitt",
+		.digest_size	= 2,
+		.chunk_size	= CHUNKSZ,
+		.hash_func_ws	= crc16_ccitt_wd_buf,
+		.hash_init	= hash_init_crc16_ccitt,
+		.hash_update	= hash_update_crc16_ccitt,
+		.hash_finish	= hash_finish_crc16_ccitt,
+	},
+	{
 		.name		= "crc32",
 		.digest_size	= 4,
 		.chunk_size	= CHUNKSZ_CRC32,
diff --git a/common/xyzModem.c b/common/xyzModem.c
index 830fca8..e5c65b4 100644
--- a/common/xyzModem.c
+++ b/common/xyzModem.c
@@ -24,7 +24,7 @@
 #include <common.h>
 #include <xyzModem.h>
 #include <stdarg.h>
-#include <crc.h>
+#include <u-boot/crc.h>
 
 /* Assumption - run xyzModem protocol over the console port */
 
diff --git a/configs/A20-OLinuXino-Lime2-eMMC_defconfig b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
index 467ca4e..dee8d02 100644
--- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
@@ -26,7 +26,9 @@
 CONFIG_RGMII=y
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
+CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
 CONFIG_AXP_ALDO3_VOLT=2800
+CONFIG_AXP_ALDO3_VOLT_SLOPE_08=y
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
index fa58a6d..0c04ae6 100644
--- a/configs/A20-OLinuXino-Lime2_defconfig
+++ b/configs/A20-OLinuXino-Lime2_defconfig
@@ -25,7 +25,9 @@
 CONFIG_RGMII=y
 CONFIG_MII=y
 CONFIG_SUN7I_GMAC=y
+CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
 CONFIG_AXP_ALDO3_VOLT=2800
+CONFIG_AXP_ALDO3_VOLT_SLOPE_08=y
 CONFIG_AXP_ALDO4_VOLT=2800
 CONFIG_SCSI=y
 CONFIG_USB_EHCI_HCD=y
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
index a9d95fb..4f57990 100644
--- a/drivers/mmc/mmc_spi.c
+++ b/drivers/mmc/mmc_spi.c
@@ -10,7 +10,7 @@
 #include <part.h>
 #include <mmc.h>
 #include <spi.h>
-#include <crc.h>
+#include <u-boot/crc.h>
 #include <linux/crc7.h>
 #include <asm/byteorder.h>
 
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
index 37749e0..a0abb23 100644
--- a/drivers/net/phy/aquantia.c
+++ b/drivers/net/phy/aquantia.c
@@ -8,7 +8,7 @@
 #include <common.h>
 #include <dm.h>
 #include <phy.h>
-#include <crc.h>
+#include <u-boot/crc.h>
 #include <malloc.h>
 #include <asm/byteorder.h>
 #include <fs.h>
diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.c b/drivers/pinctrl/meson/pinctrl-meson-axg.c
index a54fbce..3bbbe81 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-axg.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-axg.c
@@ -14,7 +14,7 @@
 
 #include "pinctrl-meson-axg.h"
 
-#define EE_OFF	14
+#define EE_OFF	15
 
 /* emmc */
 static const unsigned int emmc_nand_d0_pins[] = {BOOT_0};
@@ -893,17 +893,17 @@
 };
 
 static struct meson_bank meson_axg_periphs_banks[] = {
-	/*   name    first      last      pullen  pull    dir     out     in  */
-	BANK("Z",    GPIOZ_0,	GPIOZ_10, 3,  0,  3,  0,  9,  0,  10, 0,  11, 0),
-	BANK("BOOT", BOOT_0,	BOOT_14,  4,  0,  4,  0,  12, 0,  13, 0,  14, 0),
-	BANK("A",    GPIOA_0,	GPIOA_20, 0,  0,  0,  0,  0,  0,  1,  0,  2,  0),
-	BANK("X",    GPIOX_0,	GPIOX_22, 2,  0,  2,  0,  6,  0,  7,  0,  8,  0),
-	BANK("Y",    GPIOY_0,	GPIOY_15, 1,  0,  1,  0,  3,  0,  4,  0,  5,  0),
+	/*   name    first                      last                    pullen  pull    dir     out     in  */
+	BANK("Z",    PIN(GPIOZ_0, EE_OFF),	PIN(GPIOZ_10, EE_OFF), 3,  0,  3,  0,  9,  0,  10, 0,  11, 0),
+	BANK("BOOT", PIN(BOOT_0, EE_OFF),	PIN(BOOT_14, EE_OFF),  4,  0,  4,  0,  12, 0,  13, 0,  14, 0),
+	BANK("A",    PIN(GPIOA_0, EE_OFF),	PIN(GPIOA_20, EE_OFF), 0,  0,  0,  0,  0,  0,  1,  0,  2,  0),
+	BANK("X",    PIN(GPIOX_0, EE_OFF),	PIN(GPIOX_22, EE_OFF), 2,  0,  2,  0,  6,  0,  7,  0,  8,  0),
+	BANK("Y",    PIN(GPIOY_0, EE_OFF),	PIN(GPIOY_15, EE_OFF), 1,  0,  1,  0,  3,  0,  4,  0,  5,  0),
 };
 
 static struct meson_bank meson_axg_aobus_banks[] = {
-	/*   name    first      last       pullen  pull    dir     out     in  */
-	BANK("AO",   GPIOAO_0,  GPIOAO_13, 0,  16,  0, 0,  0,  0,  0, 16,  1,  0),
+	/*   name    first              last              pullen  pull    dir     out     in  */
+	BANK("AO",   PIN(GPIOAO_0, 0),  PIN(GPIOAO_13, 0), 0,  16,  0, 0,  0,  0,  0, 16,  1,  0),
 };
 
 static struct meson_pmx_bank meson_axg_periphs_pmx_banks[] = {
@@ -931,11 +931,11 @@
 
 struct meson_pinctrl_data meson_axg_periphs_pinctrl_data = {
 	.name		= "periphs-banks",
-	.pin_base	= 11,
+	.pin_base	= 15,
 	.groups		= meson_axg_periphs_groups,
 	.funcs		= meson_axg_periphs_functions,
 	.banks		= meson_axg_periphs_banks,
-	.num_pins	= 100,
+	.num_pins	= 86,
 	.num_groups	= ARRAY_SIZE(meson_axg_periphs_groups),
 	.num_funcs	= ARRAY_SIZE(meson_axg_periphs_functions),
 	.num_banks	= ARRAY_SIZE(meson_axg_periphs_banks),
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 0bd6152..b539749 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -136,7 +136,7 @@
 	if (ret)
 		return ret;
 
-	clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), 1);
+	setbits_le32(priv->reg_gpio + reg, BIT(bit));
 
 	return 0;
 }
@@ -152,7 +152,7 @@
 	if (ret)
 		return ret;
 
-	clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), 0);
+	clrbits_le32(priv->reg_gpio + reg, BIT(bit));
 
 	ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_OUT, &reg, &bit);
 	if (ret)
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 1a38524..9495dca 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -197,6 +197,49 @@
 	On A83T / H8 boards aldo3 is AVCC, VCC-PL, and VCC-LED, and should be
 	3.0V.
 
+choice
+	prompt "axp pmic (a)ldo3 voltage rate control"
+	depends on AXP209_POWER
+	default AXP_ALDO3_VOLT_SLOPE_NONE
+	---help---
+	The AXP can slowly ramp up voltage to reduce the inrush current when
+	changing voltages.
+	Note, this does not apply when enabling/disabling LDO3. See
+	"axp pmic (a)ldo3 inrush quirk" below to enable a slew rate to limit
+	inrush current on broken board designs.
+
+config AXP_ALDO3_VOLT_SLOPE_NONE
+	bool "No voltage slope"
+	---help---
+	Tries to reach the next voltage setting near instantaneously. Measurements
+	indicate that this is about 0.0167 V/uS.
+
+config AXP_ALDO3_VOLT_SLOPE_16
+	bool "1.6 mV per uS"
+	---help---
+	Increases the voltage by 1.6 mV per uS until the final voltage has
+	been reached. Note that the scaling is in 25 mV steps and thus
+	the slew rate in reality is about 25 mV/31.250 uS.
+
+config AXP_ALDO3_VOLT_SLOPE_08
+	bool "0.8 mV per uS"
+	---help---
+	Increases the voltage by 0.8 mV per uS until the final voltage has
+	been reached. Note that the scaling is in 25 mV steps however and thus
+	the slew rate in reality is about 25 mV/15.625 uS.
+	This is the slowest supported rate.
+
+endchoice
+
+config AXP_ALDO3_INRUSH_QUIRK
+	bool "axp pmic (a)ldo3 inrush quirk"
+	depends on AXP209_POWER
+	default n
+	---help---
+	The reference design denotes a value of 4.7 uF for the output capacitor
+	of LDO3. Some boards have too high capacitance causing 	an inrush current
+	and resulting an AXP209 shutdown.
+
 config AXP_ALDO4_VOLT
 	int "axp pmic (a)ldo4 voltage"
 	depends on AXP209_POWER
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
index 6de5ec6..67b4209 100644
--- a/drivers/power/axp209.c
+++ b/drivers/power/axp209.c
@@ -9,6 +9,16 @@
 #include <asm/arch/pmic_bus.h>
 #include <axp_pmic.h>
 
+#ifdef CONFIG_AXP_ALDO3_VOLT_SLOPE_08
+#  define AXP209_VRC_SLOPE AXP209_VRC_LDO3_800uV_uS
+#endif
+#ifdef CONFIG_AXP_ALDO3_VOLT_SLOPE_16
+#  define AXP209_VRC_SLOPE AXP209_VRC_LDO3_1600uV_uS
+#endif
+#if defined CONFIG_AXP_ALDO3_VOLT_SLOPE_NONE || !defined AXP209_VRC_SLOPE
+#  define AXP209_VRC_SLOPE 0x00
+#endif
+
 static u8 axp209_mvolt_to_cfg(int mvolt, int min, int max, int div)
 {
 	if (mvolt < min)
@@ -81,8 +91,7 @@
 	if (rc)
 		return rc;
 
-	/* LDO2 configuration is in upper 4 bits */
-	reg = (reg & 0x0f) | (cfg << 4);
+	reg |= AXP209_LDO24_LDO2_SET(reg, cfg);
 	rc = pmic_bus_write(AXP209_LDO24_VOLTAGE, reg);
 	if (rc)
 		return rc;
@@ -99,10 +108,49 @@
 		return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
 					AXP209_OUTPUT_CTRL_LDO3);
 
+	/*
+	 * Some boards have trouble reaching the target voltage without causing
+	 * great inrush currents. To prevent this, boards can enable a certain
+	 * slope to ramp up voltage. Note, this only works when changing an
+	 * already active power rail. When toggling power on, the AXP ramps up
+	 * steeply at 0.0167 V/uS.
+	 */
+	rc = pmic_bus_read(AXP209_VRC_DCDC2_LDO3, &cfg);
+	cfg = AXP209_VRC_LDO3_SLOPE_SET(cfg, AXP209_VRC_SLOPE);
+	rc |= pmic_bus_write(AXP209_VRC_DCDC2_LDO3, cfg);
+
+	if (rc)
+		return rc;
+
+#ifdef CONFIG_AXP_ALDO3_INRUSH_QUIRK
+	/*
+	 * On some boards, LDO3 has a too big capacitor installed. When
+	 * turning on LDO3, this causes the AXP209 to shutdown on
+	 * voltages over 1.9 volt. As a workaround, we enable LDO3
+	 * first with the lowest possible voltage. If this still causes
+	 * high inrush currents, the voltage slope should be increased.
+	 */
+	rc = pmic_bus_read(AXP209_OUTPUT_CTRL, &cfg);
+	if (rc)
+		return rc;
+
+	if (!(cfg & AXP209_OUTPUT_CTRL_LDO3)) {
+		rc = pmic_bus_write(AXP209_LDO3_VOLTAGE, 0x0); /* 0.7 Volt */
+		mdelay(1);
+		rc |= pmic_bus_setbits(AXP209_OUTPUT_CTRL,
+				       AXP209_OUTPUT_CTRL_LDO3);
+
-	if (mvolt == -1)
-		cfg = 0x80;	/* determined by LDO3IN pin */
-	else
+		if (rc)
+			return rc;
+	}
+#endif
+
+	if (mvolt == -1) {
+		cfg = AXP209_LDO3_VOLTAGE_FROM_LDO3IN;
+	} else {
 		cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25);
+		cfg = AXP209_LDO3_VOLTAGE_SET(cfg);
+	}
 
 	rc = pmic_bus_write(AXP209_LDO3_VOLTAGE, cfg);
 	if (rc)
@@ -131,8 +179,7 @@
 	if (rc)
 		return rc;
 
-	/* LDO4 configuration is in lower 4 bits */
-	reg = (reg & 0xf0) | (cfg << 0);
+	reg |= AXP209_LDO24_LDO4_SET(reg, cfg);
 	rc = pmic_bus_write(AXP209_LDO24_VOLTAGE, reg);
 	if (rc)
 		return rc;
@@ -153,10 +200,7 @@
 	if (rc)
 		return rc;
 
-	/* Low 4 bits is chip version */
-	ver &= 0x0f;
-
-	if (ver != 0x1)
+	if ((ver & AXP209_CHIP_VERSION_MASK) != 0x1)
 		return -EINVAL;
 
 	/* Mask all interrupts */
diff --git a/include/axp209.h b/include/axp209.h
index b7de6ed..f4f1b2f 100644
--- a/include/axp209.h
+++ b/include/axp209.h
@@ -3,11 +3,14 @@
  * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
  */
 
+#include <linux/bitops.h>
+
 enum axp209_reg {
 	AXP209_POWER_STATUS = 0x00,
 	AXP209_CHIP_VERSION = 0x03,
 	AXP209_OUTPUT_CTRL = 0x12,
 	AXP209_DCDC2_VOLTAGE = 0x23,
+	AXP209_VRC_DCDC2_LDO3 = 0x25,
 	AXP209_DCDC3_VOLTAGE = 0x27,
 	AXP209_LDO24_VOLTAGE = 0x28,
 	AXP209_LDO3_VOLTAGE = 0x29,
@@ -20,29 +23,64 @@
 	AXP209_SHUTDOWN = 0x32,
 };
 
+#define AXP209_POWER_STATUS_ON_BY_DC	BIT(0)
+#define AXP209_POWER_STATUS_VBUS_USABLE	BIT(4)
+
+#define AXP209_CHIP_VERSION_MASK	0x0f
+
-#define AXP209_POWER_STATUS_ON_BY_DC	(1 << 0)
-#define AXP209_POWER_STATUS_VBUS_USABLE	(1 << 4)
+#define AXP209_OUTPUT_CTRL_EXTEN	BIT(0)
+#define AXP209_OUTPUT_CTRL_DCDC3	BIT(1)
+#define AXP209_OUTPUT_CTRL_LDO2		BIT(2)
+#define AXP209_OUTPUT_CTRL_LDO4		BIT(3)
+#define AXP209_OUTPUT_CTRL_DCDC2	BIT(4)
+#define AXP209_OUTPUT_CTRL_LDO3		BIT(6)
 
-#define AXP209_OUTPUT_CTRL_EXTEN	(1 << 0)
-#define AXP209_OUTPUT_CTRL_DCDC3	(1 << 1)
-#define AXP209_OUTPUT_CTRL_LDO2		(1 << 2)
-#define AXP209_OUTPUT_CTRL_LDO4		(1 << 3)
-#define AXP209_OUTPUT_CTRL_DCDC2	(1 << 4)
-#define AXP209_OUTPUT_CTRL_LDO3		(1 << 6)
+/*
+ * AXP209 datasheet contains wrong information about LDO3 VRC:
+ * - VRC is actually enabled when BIT(1) is True
+ * - VRC is actually not enabled by default (BIT(3) = 0 after reset)
+ */
+#define AXP209_VRC_LDO3_EN		BIT(3)
+#define AXP209_VRC_DCDC2_EN		BIT(2)
+#define AXP209_VRC_LDO3_800uV_uS	(BIT(1) | AXP209_VRC_LDO3_EN)
+#define AXP209_VRC_LDO3_1600uV_uS	AXP209_VRC_LDO3_EN
+#define AXP209_VRC_DCDC2_800uV_uS	(BIT(0) | AXP209_VRC_DCDC2_EN)
+#define AXP209_VRC_DCDC2_1600uV_uS	AXP209_VRC_DCDC2_EN
+#define AXP209_VRC_LDO3_MASK		0xa
+#define AXP209_VRC_DCDC2_MASK		0x5
+#define AXP209_VRC_DCDC2_SLOPE_SET(reg, cfg) \
+	(((reg) & ~AXP209_VRC_DCDC2_MASK) | \
+	((cfg) & AXP209_VRC_DCDC2_MASK))
+#define AXP209_VRC_LDO3_SLOPE_SET(reg, cfg) \
+	(((reg) & ~AXP209_VRC_LDO3_MASK) | \
+	((cfg) & AXP209_VRC_LDO3_MASK))
 
-#define AXP209_IRQ5_PEK_UP		(1 << 6)
-#define AXP209_IRQ5_PEK_DOWN		(1 << 5)
+#define AXP209_LDO24_LDO2_MASK		0xf0
+#define AXP209_LDO24_LDO4_MASK		0x0f
+#define AXP209_LDO24_LDO2_SET(reg, cfg)	\
+	(((reg) & ~AXP209_LDO24_LDO2_MASK) | \
+	(((cfg) << 4) & AXP209_LDO24_LDO2_MASK))
+#define AXP209_LDO24_LDO4_SET(reg, cfg)	\
+	(((reg) & ~AXP209_LDO24_LDO4_MASK) | \
+	(((cfg) << 0) & AXP209_LDO24_LDO4_MASK))
 
-#define AXP209_POWEROFF			(1 << 7)
+#define AXP209_LDO3_VOLTAGE_FROM_LDO3IN	BIT(7)
+#define AXP209_LDO3_VOLTAGE_MASK	0x7f
+#define AXP209_LDO3_VOLTAGE_SET(x)	((x) & AXP209_LDO3_VOLTAGE_MASK)
+
+#define AXP209_IRQ5_PEK_UP		BIT(6)
+#define AXP209_IRQ5_PEK_DOWN		BIT(5)
+
+#define AXP209_POWEROFF			BIT(7)
 
 /* For axp_gpio.c */
 #define AXP_POWER_STATUS		0x00
-#define AXP_POWER_STATUS_VBUS_PRESENT		(1 << 5)
+#define AXP_POWER_STATUS_VBUS_PRESENT	BIT(5)
 #define AXP_GPIO0_CTRL			0x90
 #define AXP_GPIO1_CTRL			0x92
 #define AXP_GPIO2_CTRL			0x93
-#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_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			4
+#define AXP_GPIO_STATE_OFFSET		4
diff --git a/include/crc.h b/include/crc.h
deleted file mode 100644
index 2a00af5..0000000
--- a/include/crc.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: eCos-2.0 */
-/*
- *==========================================================================
- *
- *      crc.h
- *
- *      Interface for the CRC algorithms.
- *
- *==========================================================================
- *==========================================================================
- *#####DESCRIPTIONBEGIN####
- *
- * Author(s):    Andrew Lunn
- * Contributors: Andrew Lunn
- * Date:         2002-08-06
- * Purpose:
- * Description:
- *
- * This code is part of eCos (tm).
- *
- *####DESCRIPTIONEND####
- *
- *==========================================================================
- */
-
-#ifndef _SERVICES_CRC_CRC_H_
-#define _SERVICES_CRC_CRC_H_
-
-#include <linux/types.h>
-
-#ifndef __externC
-# ifdef __cplusplus
-#  define __externC extern "C"
-# else
-#  define __externC extern
-# endif
-#endif
-
-/* 16 bit CRC with polynomial x^16+x^12+x^5+1 (CRC-CCITT) */
-
-uint16_t crc16_ccitt(uint16_t crc_start, unsigned char *s, int len);
-
-#endif /* _SERVICES_CRC_CRC_H_ */
diff --git a/include/u-boot/crc.h b/include/u-boot/crc.h
index e98cb46..788ef29 100644
--- a/include/u-boot/crc.h
+++ b/include/u-boot/crc.h
@@ -11,6 +11,20 @@
 /* lib/crc8.c */
 unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len);
 
+/* lib/crc16.c - 16 bit CRC with polynomial x^16+x^12+x^5+1 (CRC-CCITT) */
+uint16_t crc16_ccitt(uint16_t crc_start, const unsigned char *s, int len);
+/**
+ * crc16_ccitt_wd_buf - Perform CRC16-CCIT on an input buffer and return the
+ *                      16-bit result (network byte-order) in an output buffer
+ *
+ * @in:	input buffer
+ * @len: input buffer length
+ * @out: output buffer (at least 2 bytes)
+ * @chunk_sz: ignored
+ */
+void crc16_ccitt_wd_buf(const uint8_t *in, uint len,
+			uint8_t *out, uint chunk_sz);
+
 /* lib/crc32.c */
 uint32_t crc32 (uint32_t, const unsigned char *, uint);
 uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint);
diff --git a/lib/Makefile b/lib/Makefile
index 8321355..a6dd928 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -76,6 +76,7 @@
 
 ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o
+obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
 obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
 endif
 obj-$(CONFIG_ADDR_MAP) += addr_map.o
diff --git a/lib/crc16.c b/lib/crc16.c
index 763ae33..f46ba72 100644
--- a/lib/crc16.c
+++ b/lib/crc16.c
@@ -22,7 +22,12 @@
  *==========================================================================
  */
 
-#include "crc.h"
+#ifdef USE_HOSTCC
+#include <arpa/inet.h>
+#else
+#include <common.h>
+#endif
+#include <u-boot/crc.h>
 
 /* Table of CRC constants - implements x^16+x^12+x^5+1 */
 static const uint16_t crc16_tab[] = {
@@ -60,14 +65,20 @@
 	0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
 };
 
-uint16_t crc16_ccitt(uint16_t crc_start, unsigned char *buf, int len)
+uint16_t crc16_ccitt(uint16_t cksum, const unsigned char *buf, int len)
 {
-	int i;
-	uint16_t cksum;
-
-	cksum = crc_start;
-	for (i = 0;  i < len;  i++)
+	for (int i = 0;  i < len;  i++)
 		cksum = crc16_tab[((cksum>>8) ^ *buf++) & 0xff] ^ (cksum << 8);
 
 	return cksum;
 }
+
+void crc16_ccitt_wd_buf(const uint8_t *in, uint len,
+			uint8_t *out, uint chunk_sz)
+{
+	uint16_t crc;
+
+	crc = crc16_ccitt(0, in, len);
+	crc = htons(crc);
+	memcpy(out, &crc, sizeof(crc));
+}
diff --git a/tools/Makefile b/tools/Makefile
index c93d17a..c26b631 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -106,6 +106,7 @@
 			stm32image.o \
 			$(ROCKCHIP_OBS) \
 			socfpgaimage.o \
+			lib/crc16.o \
 			lib/sha1.o \
 			lib/sha256.o \
 			common/hash.o \