Merge changes from topic "allwinner_pmic" into integration

* changes:
  allwinner: h6: power: Switch to using the AXP driver
  drivers: allwinner: axp: Add AXP805 support
diff --git a/drivers/allwinner/axp/axp805.c b/drivers/allwinner/axp/axp805.c
new file mode 100644
index 0000000..8d029c0
--- /dev/null
+++ b/drivers/allwinner/axp/axp805.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/allwinner/axp.h>
+
+const uint8_t axp_chip_id = AXP805_CHIP_ID;
+const char *const axp_compatible = "x-powers,axp805";
+
+/*
+ * The "dcdcd" split changes the step size by a factor of 5, not 2;
+ * disallow values above the split to maintain accuracy.
+ */
+const struct axp_regulator axp_regulators[] = {
+	{"dcdca",  600, 1520,  10, 50, 0x12, 0x10, 0},
+	{"dcdcb", 1000, 2550,  50, NA, 0x13, 0x10, 1},
+	{"dcdcc",  600, 1520,  10, 50, 0x14, 0x10, 2},
+	{"dcdcd",  600, 1500,  20, NA, 0x15, 0x10, 3},
+	{"dcdce", 1100, 3400, 100, NA, 0x16, 0x10, 4},
+	{"aldo1",  700, 3300, 100, NA, 0x17, 0x10, 5},
+	{"aldo2",  700, 3300, 100, NA, 0x18, 0x10, 6},
+	{"aldo3",  700, 3300, 100, NA, 0x19, 0x10, 7},
+	{"bldo1",  700, 1900, 100, NA, 0x20, 0x11, 0},
+	{"bldo2",  700, 1900, 100, NA, 0x21, 0x11, 1},
+	{"bldo3",  700, 1900, 100, NA, 0x22, 0x11, 2},
+	{"bldo4",  700, 1900, 100, NA, 0x23, 0x11, 3},
+	{"cldo1",  700, 3300, 100, NA, 0x24, 0x11, 4},
+	{"cldo2",  700, 4200, 100, 27, 0x25, 0x11, 5},
+	{"cldo3",  700, 3300, 100, NA, 0x26, 0x11, 6},
+	{}
+};
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
index a021e1c..13437fe 100644
--- a/drivers/allwinner/axp/common.c
+++ b/drivers/allwinner/axp/common.c
@@ -108,7 +108,7 @@
 void axp_setup_regulators(const void *fdt)
 {
 	int node;
-	bool dc1sw = false;
+	bool sw = false;
 
 	if (fdt == NULL)
 		return;
@@ -120,6 +120,7 @@
 		return;
 	}
 
+	/* This applies to AXP803 only. */
 	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
 		axp_clrbits(0x8f, BIT(4));
 		axp_setbits(0x30, BIT(2));
@@ -144,26 +145,31 @@
 			continue;
 
 		name = fdt_get_name(fdt, node, &length);
+
+		/* Enable the switch last to avoid overheating. */
+		if (!strncmp(name, "dc1sw", length) ||
+		    !strncmp(name, "sw", length)) {
+			sw = true;
+			continue;
+		}
+
 		for (reg = axp_regulators; reg->dt_name; reg++) {
 			if (!strncmp(name, reg->dt_name, length)) {
 				setup_regulator(fdt, node, reg);
 				break;
 			}
 		}
-
-		if (!strncmp(name, "dc1sw", length)) {
-			/* Delay DC1SW enablement to avoid overheating. */
-			dc1sw = true;
-			continue;
-		}
 	}
 
 	/*
-	 * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts
-	 * down. So always enable DC1SW as the very last regulator.
+	 * On the AXP803, if DLDO2 is enabled after DC1SW, the PMIC overheats
+	 * and shuts down. So always enable DC1SW as the very last regulator.
 	 */
-	if (dc1sw) {
-		INFO("PMIC: Enabling DC1SW\n");
-		axp_setbits(0x12, BIT(7));
+	if (sw) {
+		INFO("PMIC: Enabling DC SW\n");
+		if (axp_chip_id == AXP803_CHIP_ID)
+			axp_setbits(0x12, BIT(7));
+		if (axp_chip_id == AXP805_CHIP_ID)
+			axp_setbits(0x11, BIT(7));
 	}
 }
diff --git a/include/drivers/allwinner/axp.h b/include/drivers/allwinner/axp.h
index f3d6277..9c0035f 100644
--- a/include/drivers/allwinner/axp.h
+++ b/include/drivers/allwinner/axp.h
@@ -13,6 +13,7 @@
 
 enum {
 	AXP803_CHIP_ID = 0x41,
+	AXP805_CHIP_ID = 0x40,
 };
 
 struct axp_regulator {
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 6866bd6..5e8885d 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -20,7 +20,8 @@
 				${AW_PLAT}/common/plat_helpers.S	\
 				${AW_PLAT}/common/sunxi_common.c
 
-BL31_SOURCES		+=	drivers/arm/gic/common/gic_common.c	\
+BL31_SOURCES		+=	drivers/allwinner/axp/common.c		\
+				drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v2/gicv2_helpers.c	\
 				drivers/arm/gic/v2/gicv2_main.c		\
 				drivers/delay_timer/delay_timer.c	\
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index a76a679..f6d5aa9 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -8,5 +8,4 @@
 include plat/allwinner/common/allwinner-common.mk
 
 BL31_SOURCES		+=	drivers/allwinner/axp/axp803.c		\
-				drivers/allwinner/axp/common.c		\
 				drivers/allwinner/sunxi_rsb.c
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index fa1b0e5..4ecc57c 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.mk
@@ -7,4 +7,5 @@
 # The differences between the platform are covered by the include files.
 include plat/allwinner/common/allwinner-common.mk
 
-BL31_SOURCES		+=	drivers/mentor/i2c/mi2cv.c
+BL31_SOURCES		+=	drivers/allwinner/axp/axp805.c		\
+				drivers/mentor/i2c/mi2cv.c
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 7bb266b..443015b 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -10,6 +10,7 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/allwinner/axp.h>
 #include <drivers/delay_timer.h>
 #include <drivers/mentor/mi2cv.h>
 #include <lib/mmio.h>
@@ -19,31 +20,33 @@
 #include <sunxi_private.h>
 
 #define AXP805_ADDR	0x36
-#define AXP805_ID	0x03
 
 static enum pmic_type {
 	UNKNOWN,
 	AXP805,
 } pmic;
 
-int axp_i2c_read(uint8_t chip, uint8_t reg, uint8_t *val)
+int axp_read(uint8_t reg)
 {
+	uint8_t val;
 	int ret;
 
-	ret = i2c_write(chip, 0, 0, &reg, 1);
+	ret = i2c_write(AXP805_ADDR, 0, 0, &reg, 1);
 	if (ret == 0)
-		ret = i2c_read(chip, 0, 0, val, 1);
-	if (ret)
+		ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1);
+	if (ret) {
 		ERROR("PMIC: Cannot read AXP805 register %02x\n", reg);
+		return ret;
+	}
 
-	return ret;
+	return val;
 }
 
-int axp_i2c_write(uint8_t chip, uint8_t reg, uint8_t val)
+int axp_write(uint8_t reg, uint8_t val)
 {
 	int ret;
 
-	ret = i2c_write(chip, reg, 1, &val, 1);
+	ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1);
 	if (ret)
 		ERROR("PMIC: Cannot write AXP805 register %02x\n", reg);
 
@@ -53,23 +56,16 @@
 static int axp805_probe(void)
 {
 	int ret;
-	uint8_t val;
 
 	/* Switch the AXP805 to master/single-PMIC mode. */
-	ret = axp_i2c_write(AXP805_ADDR, 0xff, 0x0);
+	ret = axp_write(0xff, 0x0);
 	if (ret)
 		return ret;
 
-	ret = axp_i2c_read(AXP805_ADDR, AXP805_ID, &val);
+	ret = axp_check_id();
 	if (ret)
 		return ret;
 
-	val &= 0xcf;
-	if (val != 0x40) {
-		ERROR("PMIC: Found unknown PMIC %02x\n", val);
-		return -EINVAL;
-	}
-
 	return 0;
 }
 
@@ -91,22 +87,20 @@
 		return ret;
 
 	pmic = AXP805;
+	axp_setup_regulators(fdt);
 
 	return 0;
 }
 
 void sunxi_power_down(void)
 {
-	uint8_t val;
-
 	switch (pmic) {
 	case AXP805:
 		/* Re-initialise after rich OS might have used it. */
 		sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
 		/* initialise mi2cv driver */
 		i2c_init((void *)SUNXI_R_I2C_BASE);
-		axp_i2c_read(AXP805_ADDR, 0x32, &val);
-		axp_i2c_write(AXP805_ADDR, 0x32, val | 0x80);
+		axp_power_off();
 		break;
 	default:
 		break;