Merge branch 'master' of git://git.denx.de/u-boot-sunxi

- Various axp209 fixes
- Fixes for OLinuXino-A20-Lime2 / OLinuXino-A20-Lime2-eMMC
This commit is contained in:
Tom Rini 2018-12-07 19:02:01 -05:00
commit c49aff3e66
8 changed files with 191 additions and 41 deletions

View file

@ -101,6 +101,9 @@ int pmic_bus_setbits(u8 reg, u8 bits)
if (ret)
return ret;
if ((val & bits) == bits)
return 0;
val |= bits;
return pmic_bus_write(reg, val);
}
@ -114,6 +117,9 @@ int pmic_bus_clrbits(u8 reg, u8 bits)
if (ret)
return ret;
if (!(val & bits))
return 0;
val &= ~bits;
return pmic_bus_write(reg, val);
}

View file

@ -12,8 +12,13 @@ file describes how to make full use of the 64-bit capabilities.
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 @@ to build it first.
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 pine64_plus_defconfig
$ 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 @@ by using the USB-OTG interface and a host port on another computer.
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 @@ Then write this image to a microSD card, replacing /dev/sdx with the right
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/

View file

@ -637,13 +637,6 @@ void sunxi_board_init(void)
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 @@ void sunxi_board_init(void)
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

View file

@ -26,7 +26,9 @@ CONFIG_ETH_DESIGNWARE=y
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

View file

@ -25,7 +25,9 @@ CONFIG_ETH_DESIGNWARE=y
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

View file

@ -197,6 +197,49 @@ config AXP_ALDO3_VOLT
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

View file

@ -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 @@ int axp_set_aldo2(unsigned int mvolt)
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 @@ int axp_set_aldo3(unsigned int mvolt)
return pmic_bus_clrbits(AXP209_OUTPUT_CTRL,
AXP209_OUTPUT_CTRL_LDO3);
if (mvolt == -1)
cfg = 0x80; /* determined by LDO3IN pin */
else
/*
* 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 (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 @@ int axp_set_aldo4(unsigned int mvolt)
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 @@ int axp_init(void)
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 */

View file

@ -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 @@ enum axp209_reg {
AXP209_SHUTDOWN = 0x32,
};
#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0)
#define AXP209_POWER_STATUS_VBUS_USABLE (1 << 4)
#define AXP209_POWER_STATUS_ON_BY_DC BIT(0)
#define AXP209_POWER_STATUS_VBUS_USABLE BIT(4)
#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)
#define AXP209_CHIP_VERSION_MASK 0x0f
#define AXP209_IRQ5_PEK_UP (1 << 6)
#define AXP209_IRQ5_PEK_DOWN (1 << 5)
#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_POWEROFF (1 << 7)
/*
* 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_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_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