Merge changes from topic "rockchip-secure-ddr" into integration
* changes:
rockchip: make miniloader ddr_parameter handling optional
rockchip: px30: cleanup securing of ddr regions
rockchip: px30: move secure init to separate file
rockchip: really use base+size for secure ddr regions
rockchip: bring TZRAM_SIZE values in line
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 68f84ea..d9d7f84 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -17,10 +17,18 @@
:G: `sandrine-bailleux-arm`_
:M: Alexei Fedorov <alexei.fedorov@arm.com>
:G: `AlexeiFedorov`_
-:M: Paul Beesley <paul.beesley@arm.com>
-:G: `pbeesley-arm`_
:M: György Szing <gyorgy.szing@arm.com>
:G: `gyuri-szing`_
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:M: Mark Dykes <mark.dykes@arm.com>
+:G: `mardyk01`_
+:M: Olivier Deprez <olivier.deprez@arm.com>
+:G: `odeprez`_
+:M: Bipin Ravi <bipin.ravi@arm.com>
+:G: `bipinravi-arm`_
+:M: Joanna Farley <joanna.farley@arm.com>
+:G: `joannafarley-arm`_
Allwinner ARMv8 platform port
-----------------------------
@@ -300,7 +308,6 @@
.. _mtk09422: https://github.com/mtk09422
.. _niej: https://github.com/niej
.. _npoushin: https://github.com/npoushin
-.. _pbeesley-arm: https://github.com/pbeesley-arm
.. _qoriq-open-source: https://github.com/qoriq-open-source
.. _remi-triplefault: https://github.com/repk
.. _rockchip-linux: https://github.com/rockchip-linux
@@ -314,3 +321,8 @@
.. _TonyXie06: https://github.com/TonyXie06
.. _vwadekar: https://github.com/vwadekar
.. _Yann-lms: https://github.com/Yann-lms
+.. _manish-pandey-arm: https://github.com/manish-pandey-arm
+.. _mardyk01: https://github.com/mardyk01
+.. _odeprez: https://github.com/odeprez
+.. _bipinravi-arm: https://github.com/bipinravi-arm
+.. _joannafarley-arm: https://github.com/joannafarley-arm
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 8985e49..731b876 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -196,7 +196,7 @@
builds, but this behaviour can be overridden in each platform's Makefile or
in the build command line.
- - ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
+- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
support in GCC for TF-A. This option is currently only supported for
AArch64. Default is 0.
diff --git a/drivers/allwinner/axp/axp803.c b/drivers/allwinner/axp/axp803.c
new file mode 100644
index 0000000..53b11c1
--- /dev/null
+++ b/drivers/allwinner/axp/axp803.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017-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 = AXP803_CHIP_ID;
+const char *const axp_compatible = "x-powers,axp803";
+
+const struct axp_regulator axp_regulators[] = {
+ {"dcdc1", 1600, 3400, 100, NA, 0x20, 0x10, 0},
+ {"dcdc5", 800, 1840, 10, 32, 0x24, 0x10, 4},
+ {"dcdc6", 600, 1520, 10, 50, 0x25, 0x10, 5},
+ {"dldo1", 700, 3300, 100, NA, 0x15, 0x12, 3},
+ {"dldo2", 700, 4200, 100, 27, 0x16, 0x12, 4},
+ {"dldo3", 700, 3300, 100, NA, 0x17, 0x12, 5},
+ {"dldo4", 700, 3300, 100, NA, 0x18, 0x12, 6},
+ {"fldo1", 700, 1450, 50, NA, 0x1c, 0x13, 2},
+ {}
+};
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
new file mode 100644
index 0000000..a021e1c
--- /dev/null
+++ b/drivers/allwinner/axp/common.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <libfdt.h>
+
+#include <common/debug.h>
+#include <drivers/allwinner/axp.h>
+
+int axp_check_id(void)
+{
+ int ret;
+
+ ret = axp_read(0x03);
+ if (ret < 0)
+ return ret;
+
+ ret &= 0xcf;
+ if (ret != axp_chip_id) {
+ ERROR("PMIC: Found unknown PMIC %02x\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
+{
+ uint8_t val;
+ int ret;
+
+ ret = axp_read(reg);
+ if (ret < 0)
+ return ret;
+
+ val = (ret & ~clr_mask) | set_mask;
+
+ return axp_write(reg, val);
+}
+
+void axp_power_off(void)
+{
+ /* Set "power disable control" bit */
+ axp_setbits(0x32, BIT(7));
+}
+
+/*
+ * Retrieve the voltage from a given regulator DTB node.
+ * Both the regulator-{min,max}-microvolt properties must be present and
+ * have the same value. Return that value in millivolts.
+ */
+static int fdt_get_regulator_millivolt(const void *fdt, int node)
+{
+ const fdt32_t *prop;
+ uint32_t min_volt;
+
+ prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ min_volt = fdt32_to_cpu(*prop);
+
+ prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+
+ if (fdt32_to_cpu(*prop) != min_volt)
+ return -EINVAL;
+
+ return min_volt / 1000;
+}
+
+static int setup_regulator(const void *fdt, int node,
+ const struct axp_regulator *reg)
+{
+ uint8_t val;
+ int mvolt;
+
+ mvolt = fdt_get_regulator_millivolt(fdt, node);
+ if (mvolt < reg->min_volt || mvolt > reg->max_volt)
+ return -EINVAL;
+
+ val = (mvolt / reg->step) - (reg->min_volt / reg->step);
+ if (val > reg->split)
+ val = ((val - reg->split) / 2) + reg->split;
+
+ axp_write(reg->volt_reg, val);
+ axp_setbits(reg->switch_reg, BIT(reg->switch_bit));
+
+ INFO("PMIC: %s voltage: %d.%03dV\n", reg->dt_name,
+ mvolt / 1000, mvolt % 1000);
+
+ return 0;
+}
+
+static bool should_enable_regulator(const void *fdt, int node)
+{
+ if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
+ return true;
+ if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
+ return true;
+ return false;
+}
+
+void axp_setup_regulators(const void *fdt)
+{
+ int node;
+ bool dc1sw = false;
+
+ if (fdt == NULL)
+ return;
+
+ /* locate the PMIC DT node, bail out if not found */
+ node = fdt_node_offset_by_compatible(fdt, -1, axp_compatible);
+ if (node < 0) {
+ WARN("PMIC: No PMIC DT node, skipping setup\n");
+ return;
+ }
+
+ if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
+ axp_clrbits(0x8f, BIT(4));
+ axp_setbits(0x30, BIT(2));
+ INFO("PMIC: Enabling DRIVEVBUS\n");
+ }
+
+ /* descend into the "regulators" subnode */
+ node = fdt_subnode_offset(fdt, node, "regulators");
+ if (node < 0) {
+ WARN("PMIC: No regulators DT node, skipping setup\n");
+ return;
+ }
+
+ /* iterate over all regulators to find used ones */
+ fdt_for_each_subnode(node, fdt, node) {
+ const struct axp_regulator *reg;
+ const char *name;
+ int length;
+
+ /* We only care if it's always on or referenced. */
+ if (!should_enable_regulator(fdt, node))
+ continue;
+
+ name = fdt_get_name(fdt, node, &length);
+ 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.
+ */
+ if (dc1sw) {
+ INFO("PMIC: Enabling DC1SW\n");
+ axp_setbits(0x12, BIT(7));
+ }
+}
diff --git a/include/drivers/allwinner/axp.h b/include/drivers/allwinner/axp.h
new file mode 100644
index 0000000..f3d6277
--- /dev/null
+++ b/include/drivers/allwinner/axp.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AXP_H
+#define AXP_H
+
+#include <stdint.h>
+
+#define NA 0xff
+
+enum {
+ AXP803_CHIP_ID = 0x41,
+};
+
+struct axp_regulator {
+ const char *dt_name;
+ uint16_t min_volt;
+ uint16_t max_volt;
+ uint16_t step;
+ unsigned char split;
+ unsigned char volt_reg;
+ unsigned char switch_reg;
+ unsigned char switch_bit;
+};
+
+extern const uint8_t axp_chip_id;
+extern const char *const axp_compatible;
+extern const struct axp_regulator axp_regulators[];
+
+/*
+ * Since the PMIC can be connected to multiple bus types,
+ * low-level read/write functions must be provided by the platform
+ */
+int axp_read(uint8_t reg);
+int axp_write(uint8_t reg, uint8_t val);
+int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask);
+#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
+#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
+
+int axp_check_id(void);
+void axp_power_off(void);
+void axp_setup_regulators(const void *fdt);
+
+#endif /* AXP_H */
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 1f41055..dcf3dc9 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -12,7 +12,7 @@
void sunxi_cpu_on(u_register_t mpidr);
void sunxi_cpu_off(u_register_t mpidr);
void sunxi_disable_secondary_cpus(u_register_t primary_mpidr);
-void __dead2 sunxi_power_down(void);
+void sunxi_power_down(void);
int sunxi_pmic_setup(uint16_t socid, const void *fdt);
void sunxi_security_setup(void);
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 0797452..1e21a42 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -150,16 +150,16 @@
/* set both pins to pull-up */
mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U);
- /* assert, then de-assert reset of I2C/RSB controller */
- mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
- mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
-
/* un-gate clock */
if (socid != SUNXI_SOC_H6)
mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
else
mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0));
+ /* assert, then de-assert reset of I2C/RSB controller */
+ mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+
return 0;
}
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 13e1353..9b074d2 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -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
*/
@@ -65,6 +65,11 @@
sunxi_disable_secondary_cpus(read_mpidr());
sunxi_power_down();
+
+ udelay(1000);
+ ERROR("PSCI: Cannot turn off system, halting\n");
+ wfi();
+ panic();
}
static void __dead2 sunxi_system_reset(void)
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index b46fbc2..a76a679 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.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
#
@@ -7,4 +7,6 @@
# The differences between the platform are covered by the include files.
include plat/allwinner/common/allwinner-common.mk
-PLAT_BL_COMMON_SOURCES += drivers/allwinner/sunxi_rsb.c
+BL31_SOURCES += drivers/allwinner/axp/axp803.c \
+ drivers/allwinner/axp/common.c \
+ drivers/allwinner/sunxi_rsb.c
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index d48ff56..5b7d76a 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -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.
* Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -7,14 +7,11 @@
#include <errno.h>
-#include <libfdt.h>
-
#include <platform_def.h>
-#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/allwinner/axp.h>
#include <drivers/allwinner/sunxi_rsb.h>
-#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <sunxi_def.h>
@@ -22,6 +19,7 @@
#include <sunxi_private.h>
static enum pmic_type {
+ UNKNOWN,
GENERIC_H5,
GENERIC_A64,
REF_DESIGN_H5, /* regulators controlled by GPIO pins on port L */
@@ -38,7 +36,7 @@
* disabled.
* This function only cares about peripherals.
*/
-void sunxi_turn_off_soc(uint16_t socid)
+static void sunxi_turn_off_soc(uint16_t socid)
{
int i;
@@ -113,175 +111,22 @@
return ret;
/* Associate the 8-bit runtime address with the 12-bit bus address. */
- return rsb_assign_runtime_address(AXP803_HW_ADDR,
- AXP803_RT_ADDR);
-}
-
-static int axp_write(uint8_t reg, uint8_t val)
-{
- return rsb_write(AXP803_RT_ADDR, reg, val);
-}
-
-static int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
-{
- uint8_t regval;
- int ret;
-
- ret = rsb_read(AXP803_RT_ADDR, reg);
- if (ret < 0)
+ ret = rsb_assign_runtime_address(AXP803_HW_ADDR,
+ AXP803_RT_ADDR);
+ if (ret)
return ret;
- regval = (ret & ~clr_mask) | set_mask;
-
- return rsb_write(AXP803_RT_ADDR, reg, regval);
-}
-
-#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
-#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
-
-static bool should_enable_regulator(const void *fdt, int node)
-{
- if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
- return true;
- if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
- return true;
- return false;
+ return axp_check_id();
}
-/*
- * Retrieve the voltage from a given regulator DTB node.
- * Both the regulator-{min,max}-microvolt properties must be present and
- * have the same value. Return that value in millivolts.
- */
-static int fdt_get_regulator_millivolt(const void *fdt, int node)
+int axp_read(uint8_t reg)
{
- const fdt32_t *prop;
- uint32_t min_volt;
-
- prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
- if (prop == NULL)
- return -EINVAL;
- min_volt = fdt32_to_cpu(*prop);
-
- prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
- if (prop == NULL)
- return -EINVAL;
-
- if (fdt32_to_cpu(*prop) != min_volt)
- return -EINVAL;
-
- return min_volt / 1000;
+ return rsb_read(AXP803_RT_ADDR, reg);
}
-#define NO_SPLIT 0xff
-
-static const struct axp_regulator {
- char *dt_name;
- uint16_t min_volt;
- uint16_t max_volt;
- uint16_t step;
- unsigned char split;
- unsigned char volt_reg;
- unsigned char switch_reg;
- unsigned char switch_bit;
-} regulators[] = {
- {"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0x10, 0},
- {"dcdc5", 800, 1840, 10, 32, 0x24, 0x10, 4},
- {"dcdc6", 600, 1520, 10, 50, 0x25, 0x10, 5},
- {"dldo1", 700, 3300, 100, NO_SPLIT, 0x15, 0x12, 3},
- {"dldo2", 700, 4200, 100, 27, 0x16, 0x12, 4},
- {"dldo3", 700, 3300, 100, NO_SPLIT, 0x17, 0x12, 5},
- {"dldo4", 700, 3300, 100, NO_SPLIT, 0x18, 0x12, 6},
- {"fldo1", 700, 1450, 50, NO_SPLIT, 0x1c, 0x13, 2},
- {}
-};
-
-static int setup_regulator(const void *fdt, int node,
- const struct axp_regulator *reg)
+int axp_write(uint8_t reg, uint8_t val)
{
- int mvolt;
- uint8_t regval;
-
- if (!should_enable_regulator(fdt, node))
- return -ENOENT;
-
- mvolt = fdt_get_regulator_millivolt(fdt, node);
- if (mvolt < reg->min_volt || mvolt > reg->max_volt)
- return -EINVAL;
-
- regval = (mvolt / reg->step) - (reg->min_volt / reg->step);
- if (regval > reg->split)
- regval = ((regval - reg->split) / 2) + reg->split;
-
- axp_write(reg->volt_reg, regval);
- if (reg->switch_reg < 0xff)
- axp_setbits(reg->switch_reg, BIT(reg->switch_bit));
-
- INFO("PMIC: AXP803: %s voltage: %d.%03dV\n", reg->dt_name,
- mvolt / 1000, mvolt % 1000);
-
- return 0;
-}
-
-static void setup_axp803_rails(const void *fdt)
-{
- int node;
- bool dc1sw = false;
-
- /* locate the PMIC DT node, bail out if not found */
- node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803");
- if (node < 0) {
- WARN("BL31: PMIC: Cannot find AXP803 DT node, skipping initial setup.\n");
- return;
- }
-
- if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
- axp_clrbits(0x8f, BIT(4));
- axp_setbits(0x30, BIT(2));
- INFO("PMIC: AXP803: Enabling DRIVEVBUS\n");
- }
-
- /* descend into the "regulators" subnode */
- node = fdt_subnode_offset(fdt, node, "regulators");
- if (node < 0) {
- WARN("BL31: PMIC: Cannot find regulators subnode, skipping initial setup.\n");
- return;
- }
-
- /* iterate over all regulators to find used ones */
- for (node = fdt_first_subnode(fdt, node);
- node >= 0;
- node = fdt_next_subnode(fdt, node)) {
- const struct axp_regulator *reg;
- const char *name;
- int length;
-
- /* We only care if it's always on or referenced. */
- if (!should_enable_regulator(fdt, node))
- continue;
-
- name = fdt_get_name(fdt, node, &length);
- for (reg = 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.
- */
- if (dc1sw) {
- INFO("PMIC: AXP803: Enabling DC1SW\n");
- axp_setbits(0x12, BIT(7));
- }
+ return rsb_write(AXP803_RT_ADDR, reg, val);
}
int sunxi_pmic_setup(uint16_t socid, const void *fdt)
@@ -290,11 +135,16 @@
switch (socid) {
case SUNXI_SOC_H5:
+ NOTICE("PMIC: Assuming H5 reference regulator design\n");
+
pmic = REF_DESIGN_H5;
- NOTICE("BL31: PMIC: Defaulting to PortL GPIO according to H5 reference design.\n");
+
break;
case SUNXI_SOC_A64:
pmic = GENERIC_A64;
+
+ INFO("PMIC: Probing AXP803 on RSB\n");
+
ret = sunxi_init_platform_r_twi(socid, true);
if (ret)
return ret;
@@ -304,20 +154,16 @@
return ret;
pmic = AXP803_RSB;
- NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n");
-
- if (fdt)
- setup_axp803_rails(fdt);
+ axp_setup_regulators(fdt);
break;
default:
- NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid);
return -ENODEV;
}
return 0;
}
-void __dead2 sunxi_power_down(void)
+void sunxi_power_down(void)
{
switch (pmic) {
case GENERIC_H5:
@@ -355,16 +201,10 @@
/* (Re-)init RSB in case the rich OS has disabled it. */
sunxi_init_platform_r_twi(SUNXI_SOC_A64, true);
rsb_init();
-
- /* Set "power disable control" bit */
- axp_setbits(0x32, BIT(7));
+ axp_power_off();
break;
default:
break;
}
- udelay(1000);
- ERROR("PSCI: Cannot turn off system, halting.\n");
- wfi();
- panic();
}
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index 5c21ead..fa1b0e5 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.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
#
@@ -7,4 +7,4 @@
# The differences between the platform are covered by the include files.
include plat/allwinner/common/allwinner-common.mk
-PLAT_BL_COMMON_SOURCES += drivers/mentor/i2c/mi2cv.c
+BL31_SOURCES += drivers/mentor/i2c/mi2cv.c
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 5b5bad1..7bb266b 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -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.
* Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -21,27 +21,33 @@
#define AXP805_ADDR 0x36
#define AXP805_ID 0x03
-enum pmic_type {
- NO_PMIC,
+static enum pmic_type {
+ UNKNOWN,
AXP805,
-};
-
-enum pmic_type pmic;
+} pmic;
int axp_i2c_read(uint8_t chip, uint8_t reg, uint8_t *val)
{
int ret;
ret = i2c_write(chip, 0, 0, ®, 1);
+ if (ret == 0)
+ ret = i2c_read(chip, 0, 0, val, 1);
if (ret)
- return ret;
+ ERROR("PMIC: Cannot read AXP805 register %02x\n", reg);
- return i2c_read(chip, 0, 0, val, 1);
+ return ret;
}
int axp_i2c_write(uint8_t chip, uint8_t reg, uint8_t val)
{
- return i2c_write(chip, reg, 1, &val, 1);
+ int ret;
+
+ ret = i2c_write(chip, reg, 1, &val, 1);
+ if (ret)
+ ERROR("PMIC: Cannot write AXP805 register %02x\n", reg);
+
+ return ret;
}
static int axp805_probe(void)
@@ -49,21 +55,18 @@
int ret;
uint8_t val;
+ /* Switch the AXP805 to master/single-PMIC mode. */
ret = axp_i2c_write(AXP805_ADDR, 0xff, 0x0);
- if (ret) {
- ERROR("PMIC: Cannot put AXP805 to master mode.\n");
- return -EPERM;
- }
+ if (ret)
+ return ret;
ret = axp_i2c_read(AXP805_ADDR, AXP805_ID, &val);
+ if (ret)
+ return ret;
- if (!ret && ((val & 0xcf) == 0x40))
- NOTICE("PMIC: AXP805 detected\n");
- else if (ret) {
- ERROR("PMIC: Cannot communicate with AXP805.\n");
- return -EPERM;
- } else {
- ERROR("PMIC: Non-AXP805 chip attached at AXP805's address.\n");
+ val &= 0xcf;
+ if (val != 0x40) {
+ ERROR("PMIC: Found unknown PMIC %02x\n", val);
return -EINVAL;
}
@@ -74,23 +77,25 @@
{
int ret;
- sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+ INFO("PMIC: Probing AXP805 on I2C\n");
+
+ ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+ if (ret)
+ return ret;
+
/* initialise mi2cv driver */
i2c_init((void *)SUNXI_R_I2C_BASE);
- NOTICE("PMIC: Probing AXP805\n");
- pmic = AXP805;
-
ret = axp805_probe();
if (ret)
- pmic = NO_PMIC;
- else
- pmic = AXP805;
+ return ret;
+
+ pmic = AXP805;
return 0;
}
-void __dead2 sunxi_power_down(void)
+void sunxi_power_down(void)
{
uint8_t val;
@@ -106,9 +111,4 @@
default:
break;
}
-
- udelay(1000);
- ERROR("PSCI: Cannot communicate with PMIC, halting\n");
- wfi();
- panic();
}