allwinner: H5: Implement power down for H5 reference design boards

Allwinner produces reference board designs, which apparently most board
vendors copy from. So every H5 board I checked uses regulators which are
controlled by the same PortL GPIO pins to power the ARM CPU cores, the
DRAM and the I/O ports.
Add a SoC specific power down routine, which turns those regulators off
when ATF detects running on an H5 SoC and the rich OS triggers a
SYSTEM_POWEROFF PSCI call.

NOTE: It sounds very tempting to turn the CPU power off, but this is not
working as expected, instead the system is rebooting. Most probably this
is due to VCC-SYS also being controlled by the same GPIO line, and
turning this off requires an elaborate and not fully understood setup.
Apparently not even Allwinner reference code is turning this regulator
off. So for now we refrain to pulling down PL8, the power consumption is
quite low anyway, so we are as close to poweroff as reasonably possible.
Many thanks to Samuel for doing some research on that topic.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
Andre Przywara 2018-10-02 00:21:53 +01:00
parent 7020dca0bd
commit 3d22228fe9
1 changed files with 22 additions and 1 deletions

View File

@ -18,6 +18,7 @@
static enum pmic_type {
GENERIC_H5,
GENERIC_A64,
REF_DESIGN_H5, /* regulators controlled by GPIO pins on port L */
} pmic;
/*
@ -79,7 +80,8 @@ int sunxi_pmic_setup(uint16_t socid)
{
switch (socid) {
case SUNXI_SOC_H5:
pmic = GENERIC_H5;
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;
@ -105,6 +107,25 @@ void __dead2 sunxi_power_down(void)
sunxi_turn_off_soc(SUNXI_SOC_A64);
/* Turn off the pin controller now. */
mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
break;
case REF_DESIGN_H5:
sunxi_turn_off_soc(SUNXI_SOC_H5);
/*
* Switch PL pins to power off the board:
* - PL5 (VCC_IO) -> high
* - PL8 (PWR-STB = CPU power supply) -> low
* - PL9 (PWR-DRAM) ->low
* - PL10 (power LED) -> low
* Note: Clearing PL8 will reset the board, so keep it up.
*/
sunxi_set_gpio_out('L', 5, 1);
sunxi_set_gpio_out('L', 9, 0);
sunxi_set_gpio_out('L', 10, 0);
/* Turn off pin controller now. */
mmio_write_32(SUNXI_CCU_BASE + 0x68, 0);
break;
default:
break;