Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…oot-sunxi

- sun8i emac changes (Andre)
- SCP firmware (Samuel)
  • Loading branch information
trini committed Oct 23, 2020
2 parents ae4fdd7 + 1949232 commit 18261b8
Show file tree
Hide file tree
Showing 19 changed files with 446 additions and 287 deletions.
2 changes: 1 addition & 1 deletion Kconfig
Expand Up @@ -200,7 +200,7 @@ config SYS_MALLOC_F_LEN
default 0x2000 if (ARCH_IMX8 || ARCH_IMX8M || ARCH_MX7 || \
ARCH_MX7ULP || ARCH_MX6 || ARCH_MX5 || \
ARCH_LS1012A || ARCH_LS1021A || ARCH_LS1043A || \
ARCH_LS1046A || ARCH_QEMU)
ARCH_LS1046A || ARCH_QEMU || ARCH_SUNXI)
default 0x400
help
Before relocation, memory is very limited on many platforms. Still,
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Expand Up @@ -1332,6 +1332,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
-I arch/$(ARCH)/dts -a of-list=$(CONFIG_OF_LIST) \
-a atf-bl31-path=${BL31} \
-a default-dt=$(default_dt) \
-a scp-path=$(SCP) \
$(BINMAN_$(@F))

OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
Expand Down Expand Up @@ -1441,11 +1442,13 @@ else
MKIMAGEFLAGS_u-boot.itb = -E
endif

ifdef U_BOOT_ITS
u-boot.itb: u-boot-nodtb.bin \
$(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_OF_HOSTFILE),dts/dt.dtb) \
$(U_BOOT_ITS) FORCE
$(call if_changed,mkfitimage)
$(BOARD_SIZE_CHECK)
endif

u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE
$(call if_changed,mkimage)
Expand Down
43 changes: 33 additions & 10 deletions arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,5 +1,13 @@
#include <config.h>

#ifdef CONFIG_MACH_SUN50I_H6
#define BL31_ADDR 0x104000
#define SCP_ADDR 0x114000
#else
#define BL31_ADDR 0x44000
#define SCP_ADDR 0x50000
#endif

/ {
aliases {
mmc1 = &mmc2;
Expand All @@ -14,9 +22,11 @@
u-boot-sunxi-with-spl {
filename = "u-boot-sunxi-with-spl.bin";
pad-byte = <0xff>;

blob {
filename = "spl/sunxi-spl.bin";
};

#ifdef CONFIG_ARM64
fit {
description = "Configuration to load ATF before U-Boot";
Expand All @@ -27,31 +37,43 @@
uboot {
description = "U-Boot (64-bit)";
type = "standalone";
os = "u-boot";
arch = "arm64";
compression = "none";
load = <0x4a000000>;

u-boot-nodtb {
};
};

atf {
description = "ARM Trusted Firmware";
type = "firmware";
os = "arm-trusted-firmware";
arch = "arm64";
compression = "none";
/* TODO: Do this with an overwrite in this board's dtb? */
#ifdef CONFIG_MACH_SUN50I_H6
load = <0x104000>;
entry = <0x104000>;
#else
load = <0x44000>;
entry = <0x44000>;
#endif
load = <BL31_ADDR>;
entry = <BL31_ADDR>;

atf-bl31 {
filename = "bl31.bin";
missing-msg = "atf-bl31-sunxi";
};
};

scp {
description = "SCP firmware";
type = "firmware";
arch = "or1k";
compression = "none";
load = <SCP_ADDR>;

scp {
filename = "scp.bin";
missing-msg = "scp-sunxi";
};
};

@fdt-SEQ {
description = "NAME";
type = "flat_dt";
Expand All @@ -61,10 +83,11 @@

configurations {
default = "config-1";

@config-SEQ {
description = "NAME";
firmware = "uboot";
loadables = "atf";
firmware = "atf";
loadables = "scp", "uboot";
fdt = "fdt-SEQ";
};
};
Expand Down
1 change: 1 addition & 0 deletions arch/arm/include/asm/arch-sunxi/cpu.h
Expand Up @@ -16,6 +16,7 @@

#define SOCID_A64 0x1689
#define SOCID_H3 0x1680
#define SOCID_V3S 0x1681
#define SOCID_H5 0x1718
#define SOCID_R40 0x1701

Expand Down
91 changes: 86 additions & 5 deletions arch/arm/mach-sunxi/dram_sunxi_dw.c
Expand Up @@ -63,6 +63,8 @@ enum {
MBUS_PORT_CSI = 5,
MBUS_PORT_NAND = 6,
MBUS_PORT_SS = 7,
MBUS_PORT_DE_V3S = 8,
MBUS_PORT_DE_CFD_V3S = 9,
MBUS_PORT_TS = 8,
MBUS_PORT_DI = 9,
MBUS_PORT_DE = 10,
Expand Down Expand Up @@ -134,6 +136,29 @@ static void mctl_set_master_priority_h3(void)
MBUS_CONF(DE_CFD, true, HIGH, 0, 1024, 288, 64);
}

static void mctl_set_master_priority_v3s(void)
{
struct sunxi_mctl_com_reg * const mctl_com =
(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;

/* enable bandwidth limit windows and set windows size 1us */
writel((1 << 16) | (400 << 0), &mctl_com->bwcr);

/* set cpu high priority */
writel(0x00000001, &mctl_com->mapr);

MBUS_CONF( CPU, true, HIGHEST, 0, 160, 100, 80);
MBUS_CONF( GPU, true, HIGH, 0, 1792, 1536, 0);
MBUS_CONF( UNUSED, true, HIGHEST, 0, 256, 128, 80);
MBUS_CONF( DMA, true, HIGH, 0, 256, 100, 0);
MBUS_CONF( VE, true, HIGH, 0, 2048, 1600, 0);
MBUS_CONF( CSI, true, HIGHEST, 0, 384, 256, 0);
MBUS_CONF( NAND, true, HIGH, 0, 100, 50, 0);
MBUS_CONF( SS, true, HIGH, 0, 384, 256, 0);
MBUS_CONF( DE_V3S, false, HIGH, 0, 8192, 4096, 0);
MBUS_CONF(DE_CFD_V3S, true, HIGH, 0, 640, 256, 0);
}

static void mctl_set_master_priority_a64(void)
{
struct sunxi_mctl_com_reg * const mctl_com =
Expand Down Expand Up @@ -231,6 +256,9 @@ static void mctl_set_master_priority(uint16_t socid)
case SOCID_H3:
mctl_set_master_priority_h3();
return;
case SOCID_V3S:
mctl_set_master_priority_v3s();
return;
case SOCID_A64:
mctl_set_master_priority_a64();
return;
Expand Down Expand Up @@ -334,6 +362,28 @@ static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
}
}

static void mctl_v3s_zq_calibration_quirk(struct dram_para *para)
{
struct sunxi_mctl_ctl_reg * const mctl_ctl =
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;

u32 reg_val;

clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff,
CONFIG_DRAM_ZQ & 0xffffff);
mctl_phy_init(PIR_ZCAL);

reg_val = readl(&mctl_ctl->zqdr[0]);
reg_val &= (0x1f << 16) | (0x1f << 0);
reg_val |= reg_val << 8;
writel(reg_val, &mctl_ctl->zqdr[0]);

reg_val = readl(&mctl_ctl->zqdr[1]);
reg_val &= (0x1f << 16) | (0x1f << 0);
reg_val |= reg_val << 8;
writel(reg_val, &mctl_ctl->zqdr[1]);
}

static void mctl_set_cr(uint16_t socid, struct dram_para *para)
{
struct sunxi_mctl_com_reg * const mctl_com =
Expand Down Expand Up @@ -391,7 +441,7 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para)
CCM_DRAMCLK_CFG_DIV(1) |
CCM_DRAMCLK_CFG_SRC_PLL11 |
CCM_DRAMCLK_CFG_UPD);
} else if (socid == SOCID_H3 || socid == SOCID_H5) {
} else if (socid == SOCID_H3 || socid == SOCID_H5 || socid == SOCID_V3S) {
clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
clrsetbits_le32(&ccm->dram_clk_cfg,
CCM_DRAMCLK_CFG_DIV_MASK |
Expand Down Expand Up @@ -474,6 +524,13 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
/* dphy & aphy phase select 270 degree */
clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
(0x1 << 10) | (0x2 << 8));
} else if (socid == SOCID_V3S) {
/* dx ddr_clk & hdr_clk dynamic mode */
clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));

/* dphy & aphy phase select 270 degree */
clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
(0x1 << 10) | (0x1 << 8));
} else if (socid == SOCID_A64 || socid == SOCID_H5) {
/* dphy & aphy phase select ? */
clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
Expand Down Expand Up @@ -506,7 +563,12 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
mctl_set_bit_delays(para);
udelay(50);

if (socid == SOCID_H3) {
if (socid == SOCID_V3S) {
mctl_v3s_zq_calibration_quirk(para);

mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
} else if (socid == SOCID_H3) {
mctl_h3_zq_calibration_quirk(para);

mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
Expand Down Expand Up @@ -570,7 +632,7 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
udelay(10);

/* set PGCR3, CKE polarity */
if (socid == SOCID_H3)
if (socid == SOCID_H3 || socid == SOCID_V3S)
writel(0x00aa0060, &mctl_ctl->pgcr[3]);
else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
Expand Down Expand Up @@ -636,6 +698,22 @@ static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0 }

#define SUN8I_V3S_DX_READ_DELAYS \
{{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0 }, \
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0 }, \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}
#define SUN8I_V3S_DX_WRITE_DELAYS \
{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4 }, \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 }, \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}
#define SUN8I_V3S_AC_DELAYS \
{ 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0 }

#define SUN8I_R40_DX_READ_DELAYS \
{{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
Expand Down Expand Up @@ -702,6 +780,10 @@ unsigned long sunxi_dram_init(void)
.dx_read_delays = SUN8I_H3_DX_READ_DELAYS,
.dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
.ac_delays = SUN8I_H3_AC_DELAYS,
#elif defined(CONFIG_MACH_SUN8I_V3S)
.dx_read_delays = SUN8I_V3S_DX_READ_DELAYS,
.dx_write_delays = SUN8I_V3S_DX_WRITE_DELAYS,
.ac_delays = SUN8I_V3S_AC_DELAYS,
#elif defined(CONFIG_MACH_SUN8I_R40)
.dx_read_delays = SUN8I_R40_DX_READ_DELAYS,
.dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
Expand All @@ -728,8 +810,7 @@ unsigned long sunxi_dram_init(void)
/* Currently we cannot support R40 with dual rank memory */
para.dual_rank = 0;
#elif defined(CONFIG_MACH_SUN8I_V3S)
/* TODO: set delays and mbus priority for V3s */
uint16_t socid = SOCID_H3;
uint16_t socid = SOCID_V3S;
#elif defined(CONFIG_MACH_SUN50I)
uint16_t socid = SOCID_A64;
#elif defined(CONFIG_MACH_SUN50I_H5)
Expand Down
47 changes: 40 additions & 7 deletions board/sunxi/README.sunxi64
Expand Up @@ -14,8 +14,12 @@ 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 the SCP firmware binary (see "SCP firmware (Crust)" below)
$ cd /src/crust
$ make pine64_plus_defconfig && make -j5 scp
- Build U-Boot (see "SPL/U-Boot" below)
$ export BL31=/path/to/bl31.bin
$ export SCP=/src/crust/build/scp/scp.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
Expand All @@ -24,13 +28,17 @@ Quick Start / Overview
Building the firmware
=====================

The Allwinner A64/H5 firmware consists of three parts: U-Boot's SPL, an
ARM Trusted Firmware (ATF) build and the U-Boot proper.
The SPL will load both ATF and U-Boot proper along with the right device
tree blob (.dtb) and will pass execution to ATF (in EL3), which in turn will
drop into the U-Boot proper (in EL2).
As the ATF binary will become part of the U-Boot image file, you will need
to build it first.
The Allwinner A64/H5/H6 firmware consists of several parts: U-Boot's SPL,
ARM Trusted Firmware (ATF), optional System Control Processor (SCP) firmware
(e.g. Crust), and the U-Boot proper.

The SPL will load all of the other firmware binaries into RAM, along with the
right device tree blob (.dtb), and will pass execution to ATF (in EL3). If SCP
firmware was loaded, ATF will power on the SCP and wait for it to boot.
ATF will then drop into U-Boot proper (in EL2).

As the ATF binary and SCP firmware will become part of the U-Boot image file,
you will need to build them first.

ARM Trusted Firmware (ATF)
----------------------------
Expand All @@ -53,6 +61,31 @@ As sometimes the ATF build process is a bit picky about the toolchain used,
or if you can't be bothered with building ATF, there are known working
binaries in the firmware repository[3], purely for convenience reasons.

SCP firmware (Crust)
----------------------
SCP firmware is responsible for implementing system suspend/resume, and (on
boards without a PMIC) soft poweroff/on. ATF contains fallback code for CPU
power control, so SCP firmware is optional if you don't need either of these
features. It runs on the AR100, with is an or1k CPU, not ARM, so it needs a
different cross toolchain.

There is one SCP firmware implementation currently available, Crust:
$ git clone https://github.com/crust-firmware/crust
$ cd crust
$ export CROSS_COMPILE=or1k-linux-musl-
$ make pine64_plus_defconfig
$ make scp

The same configuration generally works on any board with the same SoC (A64, H5,
or H6), so if there is no config for your board, use one for a similar board.

Like for ATF, U-Boot finds the SCP firmware binary via an environment variable:
$ export SCP=/src/crust/build/scp/scp.bin

If you do not want to use SCP firmware, you can silence the warning from binman
by pointing it to an empty file:
$ export SCP=/dev/null

SPL/U-Boot
------------
Both U-Boot proper and the SPL are using the 64-bit mode. As the boot ROM
Expand Down
4 changes: 1 addition & 3 deletions common/spl/Kconfig
Expand Up @@ -465,9 +465,7 @@ config SPL_FIT_IMAGE_TINY
Enable this to reduce the size of the FIT image loading code
in SPL, if space for the SPL binary is very tight.

This removes the detection of image types (which forces the
first image to be treated as having a U-Boot style calling
convention) and skips the recording of each loaded payload
This skips the recording of each loaded payload
(i.e. loadable) into the FDT (modifying the loaded FDT to
ensure this information is available to the next image
invoked).
Expand Down

0 comments on commit 18261b8

Please sign in to comment.