Skip to content

Commit 18261b8

Browse files
committed
- sun8i emac changes (Andre) - SCP firmware (Samuel)
2 parents ae4fdd7 + 1949232 commit 18261b8

File tree

19 files changed

+446
-287
lines changed

19 files changed

+446
-287
lines changed

Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ config SYS_MALLOC_F_LEN
200200
default 0x2000 if (ARCH_IMX8 || ARCH_IMX8M || ARCH_MX7 || \
201201
ARCH_MX7ULP || ARCH_MX6 || ARCH_MX5 || \
202202
ARCH_LS1012A || ARCH_LS1021A || ARCH_LS1043A || \
203-
ARCH_LS1046A || ARCH_QEMU)
203+
ARCH_LS1046A || ARCH_QEMU || ARCH_SUNXI)
204204
default 0x400
205205
help
206206
Before relocation, memory is very limited on many platforms. Still,

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
13321332
-I arch/$(ARCH)/dts -a of-list=$(CONFIG_OF_LIST) \
13331333
-a atf-bl31-path=${BL31} \
13341334
-a default-dt=$(default_dt) \
1335+
-a scp-path=$(SCP) \
13351336
$(BINMAN_$(@F))
13361337

13371338
OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
@@ -1441,11 +1442,13 @@ else
14411442
MKIMAGEFLAGS_u-boot.itb = -E
14421443
endif
14431444

1445+
ifdef U_BOOT_ITS
14441446
u-boot.itb: u-boot-nodtb.bin \
14451447
$(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_OF_HOSTFILE),dts/dt.dtb) \
14461448
$(U_BOOT_ITS) FORCE
14471449
$(call if_changed,mkfitimage)
14481450
$(BOARD_SIZE_CHECK)
1451+
endif
14491452

14501453
u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE
14511454
$(call if_changed,mkimage)

arch/arm/dts/sunxi-u-boot.dtsi

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
#include <config.h>
22

3+
#ifdef CONFIG_MACH_SUN50I_H6
4+
#define BL31_ADDR 0x104000
5+
#define SCP_ADDR 0x114000
6+
#else
7+
#define BL31_ADDR 0x44000
8+
#define SCP_ADDR 0x50000
9+
#endif
10+
311
/ {
412
aliases {
513
mmc1 = &mmc2;
@@ -14,9 +22,11 @@
1422
u-boot-sunxi-with-spl {
1523
filename = "u-boot-sunxi-with-spl.bin";
1624
pad-byte = <0xff>;
25+
1726
blob {
1827
filename = "spl/sunxi-spl.bin";
1928
};
29+
2030
#ifdef CONFIG_ARM64
2131
fit {
2232
description = "Configuration to load ATF before U-Boot";
@@ -27,31 +37,43 @@
2737
uboot {
2838
description = "U-Boot (64-bit)";
2939
type = "standalone";
40+
os = "u-boot";
3041
arch = "arm64";
3142
compression = "none";
3243
load = <0x4a000000>;
3344

3445
u-boot-nodtb {
3546
};
3647
};
48+
3749
atf {
3850
description = "ARM Trusted Firmware";
3951
type = "firmware";
52+
os = "arm-trusted-firmware";
4053
arch = "arm64";
4154
compression = "none";
42-
/* TODO: Do this with an overwrite in this board's dtb? */
43-
#ifdef CONFIG_MACH_SUN50I_H6
44-
load = <0x104000>;
45-
entry = <0x104000>;
46-
#else
47-
load = <0x44000>;
48-
entry = <0x44000>;
49-
#endif
55+
load = <BL31_ADDR>;
56+
entry = <BL31_ADDR>;
57+
5058
atf-bl31 {
59+
filename = "bl31.bin";
5160
missing-msg = "atf-bl31-sunxi";
5261
};
5362
};
5463

64+
scp {
65+
description = "SCP firmware";
66+
type = "firmware";
67+
arch = "or1k";
68+
compression = "none";
69+
load = <SCP_ADDR>;
70+
71+
scp {
72+
filename = "scp.bin";
73+
missing-msg = "scp-sunxi";
74+
};
75+
};
76+
5577
@fdt-SEQ {
5678
description = "NAME";
5779
type = "flat_dt";
@@ -61,10 +83,11 @@
6183

6284
configurations {
6385
default = "config-1";
86+
6487
@config-SEQ {
6588
description = "NAME";
66-
firmware = "uboot";
67-
loadables = "atf";
89+
firmware = "atf";
90+
loadables = "scp", "uboot";
6891
fdt = "fdt-SEQ";
6992
};
7093
};

arch/arm/include/asm/arch-sunxi/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#define SOCID_A64 0x1689
1818
#define SOCID_H3 0x1680
19+
#define SOCID_V3S 0x1681
1920
#define SOCID_H5 0x1718
2021
#define SOCID_R40 0x1701
2122

arch/arm/mach-sunxi/dram_sunxi_dw.c

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ enum {
6363
MBUS_PORT_CSI = 5,
6464
MBUS_PORT_NAND = 6,
6565
MBUS_PORT_SS = 7,
66+
MBUS_PORT_DE_V3S = 8,
67+
MBUS_PORT_DE_CFD_V3S = 9,
6668
MBUS_PORT_TS = 8,
6769
MBUS_PORT_DI = 9,
6870
MBUS_PORT_DE = 10,
@@ -134,6 +136,29 @@ static void mctl_set_master_priority_h3(void)
134136
MBUS_CONF(DE_CFD, true, HIGH, 0, 1024, 288, 64);
135137
}
136138

139+
static void mctl_set_master_priority_v3s(void)
140+
{
141+
struct sunxi_mctl_com_reg * const mctl_com =
142+
(struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE;
143+
144+
/* enable bandwidth limit windows and set windows size 1us */
145+
writel((1 << 16) | (400 << 0), &mctl_com->bwcr);
146+
147+
/* set cpu high priority */
148+
writel(0x00000001, &mctl_com->mapr);
149+
150+
MBUS_CONF( CPU, true, HIGHEST, 0, 160, 100, 80);
151+
MBUS_CONF( GPU, true, HIGH, 0, 1792, 1536, 0);
152+
MBUS_CONF( UNUSED, true, HIGHEST, 0, 256, 128, 80);
153+
MBUS_CONF( DMA, true, HIGH, 0, 256, 100, 0);
154+
MBUS_CONF( VE, true, HIGH, 0, 2048, 1600, 0);
155+
MBUS_CONF( CSI, true, HIGHEST, 0, 384, 256, 0);
156+
MBUS_CONF( NAND, true, HIGH, 0, 100, 50, 0);
157+
MBUS_CONF( SS, true, HIGH, 0, 384, 256, 0);
158+
MBUS_CONF( DE_V3S, false, HIGH, 0, 8192, 4096, 0);
159+
MBUS_CONF(DE_CFD_V3S, true, HIGH, 0, 640, 256, 0);
160+
}
161+
137162
static void mctl_set_master_priority_a64(void)
138163
{
139164
struct sunxi_mctl_com_reg * const mctl_com =
@@ -231,6 +256,9 @@ static void mctl_set_master_priority(uint16_t socid)
231256
case SOCID_H3:
232257
mctl_set_master_priority_h3();
233258
return;
259+
case SOCID_V3S:
260+
mctl_set_master_priority_v3s();
261+
return;
234262
case SOCID_A64:
235263
mctl_set_master_priority_a64();
236264
return;
@@ -334,6 +362,28 @@ static void mctl_h3_zq_calibration_quirk(struct dram_para *para)
334362
}
335363
}
336364

365+
static void mctl_v3s_zq_calibration_quirk(struct dram_para *para)
366+
{
367+
struct sunxi_mctl_ctl_reg * const mctl_ctl =
368+
(struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE;
369+
370+
u32 reg_val;
371+
372+
clrsetbits_le32(&mctl_ctl->zqcr, 0xffffff,
373+
CONFIG_DRAM_ZQ & 0xffffff);
374+
mctl_phy_init(PIR_ZCAL);
375+
376+
reg_val = readl(&mctl_ctl->zqdr[0]);
377+
reg_val &= (0x1f << 16) | (0x1f << 0);
378+
reg_val |= reg_val << 8;
379+
writel(reg_val, &mctl_ctl->zqdr[0]);
380+
381+
reg_val = readl(&mctl_ctl->zqdr[1]);
382+
reg_val &= (0x1f << 16) | (0x1f << 0);
383+
reg_val |= reg_val << 8;
384+
writel(reg_val, &mctl_ctl->zqdr[1]);
385+
}
386+
337387
static void mctl_set_cr(uint16_t socid, struct dram_para *para)
338388
{
339389
struct sunxi_mctl_com_reg * const mctl_com =
@@ -391,7 +441,7 @@ static void mctl_sys_init(uint16_t socid, struct dram_para *para)
391441
CCM_DRAMCLK_CFG_DIV(1) |
392442
CCM_DRAMCLK_CFG_SRC_PLL11 |
393443
CCM_DRAMCLK_CFG_UPD);
394-
} else if (socid == SOCID_H3 || socid == SOCID_H5) {
444+
} else if (socid == SOCID_H3 || socid == SOCID_H5 || socid == SOCID_V3S) {
395445
clock_set_pll5(CONFIG_DRAM_CLK * 2 * 1000000, false);
396446
clrsetbits_le32(&ccm->dram_clk_cfg,
397447
CCM_DRAMCLK_CFG_DIV_MASK |
@@ -474,6 +524,13 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
474524
/* dphy & aphy phase select 270 degree */
475525
clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
476526
(0x1 << 10) | (0x2 << 8));
527+
} else if (socid == SOCID_V3S) {
528+
/* dx ddr_clk & hdr_clk dynamic mode */
529+
clrbits_le32(&mctl_ctl->pgcr[0], (0x3 << 14) | (0x3 << 12));
530+
531+
/* dphy & aphy phase select 270 degree */
532+
clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
533+
(0x1 << 10) | (0x1 << 8));
477534
} else if (socid == SOCID_A64 || socid == SOCID_H5) {
478535
/* dphy & aphy phase select ? */
479536
clrsetbits_le32(&mctl_ctl->pgcr[2], (0x3 << 10) | (0x3 << 8),
@@ -506,7 +563,12 @@ static int mctl_channel_init(uint16_t socid, struct dram_para *para)
506563
mctl_set_bit_delays(para);
507564
udelay(50);
508565

509-
if (socid == SOCID_H3) {
566+
if (socid == SOCID_V3S) {
567+
mctl_v3s_zq_calibration_quirk(para);
568+
569+
mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST |
570+
PIR_DRAMRST | PIR_DRAMINIT | PIR_QSGATE);
571+
} else if (socid == SOCID_H3) {
510572
mctl_h3_zq_calibration_quirk(para);
511573

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

572634
/* set PGCR3, CKE polarity */
573-
if (socid == SOCID_H3)
635+
if (socid == SOCID_H3 || socid == SOCID_V3S)
574636
writel(0x00aa0060, &mctl_ctl->pgcr[3]);
575637
else if (socid == SOCID_A64 || socid == SOCID_H5 || socid == SOCID_R40)
576638
writel(0xc0aa0060, &mctl_ctl->pgcr[3]);
@@ -636,6 +698,22 @@ static void mctl_auto_detect_dram_size(uint16_t socid, struct dram_para *para)
636698
0, 0, 0, 0, 0, 0, 0, 0, \
637699
0, 0, 0, 0, 0, 0, 0 }
638700

701+
#define SUN8I_V3S_DX_READ_DELAYS \
702+
{{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0 }, \
703+
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0 }, \
704+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
705+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}
706+
#define SUN8I_V3S_DX_WRITE_DELAYS \
707+
{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4 }, \
708+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 }, \
709+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
710+
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}
711+
#define SUN8I_V3S_AC_DELAYS \
712+
{ 0, 0, 0, 0, 0, 0, 0, 0, \
713+
0, 0, 0, 0, 0, 0, 0, 0, \
714+
0, 0, 0, 0, 0, 0, 0, 0, \
715+
0, 0, 0, 0, 0, 0, 0 }
716+
639717
#define SUN8I_R40_DX_READ_DELAYS \
640718
{{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
641719
{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0 }, \
@@ -702,6 +780,10 @@ unsigned long sunxi_dram_init(void)
702780
.dx_read_delays = SUN8I_H3_DX_READ_DELAYS,
703781
.dx_write_delays = SUN8I_H3_DX_WRITE_DELAYS,
704782
.ac_delays = SUN8I_H3_AC_DELAYS,
783+
#elif defined(CONFIG_MACH_SUN8I_V3S)
784+
.dx_read_delays = SUN8I_V3S_DX_READ_DELAYS,
785+
.dx_write_delays = SUN8I_V3S_DX_WRITE_DELAYS,
786+
.ac_delays = SUN8I_V3S_AC_DELAYS,
705787
#elif defined(CONFIG_MACH_SUN8I_R40)
706788
.dx_read_delays = SUN8I_R40_DX_READ_DELAYS,
707789
.dx_write_delays = SUN8I_R40_DX_WRITE_DELAYS,
@@ -728,8 +810,7 @@ unsigned long sunxi_dram_init(void)
728810
/* Currently we cannot support R40 with dual rank memory */
729811
para.dual_rank = 0;
730812
#elif defined(CONFIG_MACH_SUN8I_V3S)
731-
/* TODO: set delays and mbus priority for V3s */
732-
uint16_t socid = SOCID_H3;
813+
uint16_t socid = SOCID_V3S;
733814
#elif defined(CONFIG_MACH_SUN50I)
734815
uint16_t socid = SOCID_A64;
735816
#elif defined(CONFIG_MACH_SUN50I_H5)

board/sunxi/README.sunxi64

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@ Quick Start / Overview
1414
- Build the ARM Trusted Firmware binary (see "ARM Trusted Firmware (ATF)" below)
1515
$ cd /src/arm-trusted-firmware
1616
$ make PLAT=sun50i_a64 DEBUG=1 bl31
17+
- Build the SCP firmware binary (see "SCP firmware (Crust)" below)
18+
$ cd /src/crust
19+
$ make pine64_plus_defconfig && make -j5 scp
1720
- Build U-Boot (see "SPL/U-Boot" below)
1821
$ export BL31=/path/to/bl31.bin
22+
$ export SCP=/src/crust/build/scp/scp.bin
1923
$ make pine64_plus_defconfig && make -j5
2024
- Transfer to an uSD card (see "microSD card" below)
2125
$ dd if=u-boot-sunxi-with-spl.bin of=/dev/sdx bs=8k seek=1
@@ -24,13 +28,17 @@ Quick Start / Overview
2428
Building the firmware
2529
=====================
2630

27-
The Allwinner A64/H5 firmware consists of three parts: U-Boot's SPL, an
28-
ARM Trusted Firmware (ATF) build and the U-Boot proper.
29-
The SPL will load both ATF and U-Boot proper along with the right device
30-
tree blob (.dtb) and will pass execution to ATF (in EL3), which in turn will
31-
drop into the U-Boot proper (in EL2).
32-
As the ATF binary will become part of the U-Boot image file, you will need
33-
to build it first.
31+
The Allwinner A64/H5/H6 firmware consists of several parts: U-Boot's SPL,
32+
ARM Trusted Firmware (ATF), optional System Control Processor (SCP) firmware
33+
(e.g. Crust), and the U-Boot proper.
34+
35+
The SPL will load all of the other firmware binaries into RAM, along with the
36+
right device tree blob (.dtb), and will pass execution to ATF (in EL3). If SCP
37+
firmware was loaded, ATF will power on the SCP and wait for it to boot.
38+
ATF will then drop into U-Boot proper (in EL2).
39+
40+
As the ATF binary and SCP firmware will become part of the U-Boot image file,
41+
you will need to build them first.
3442

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

64+
SCP firmware (Crust)
65+
----------------------
66+
SCP firmware is responsible for implementing system suspend/resume, and (on
67+
boards without a PMIC) soft poweroff/on. ATF contains fallback code for CPU
68+
power control, so SCP firmware is optional if you don't need either of these
69+
features. It runs on the AR100, with is an or1k CPU, not ARM, so it needs a
70+
different cross toolchain.
71+
72+
There is one SCP firmware implementation currently available, Crust:
73+
$ git clone https://github.com/crust-firmware/crust
74+
$ cd crust
75+
$ export CROSS_COMPILE=or1k-linux-musl-
76+
$ make pine64_plus_defconfig
77+
$ make scp
78+
79+
The same configuration generally works on any board with the same SoC (A64, H5,
80+
or H6), so if there is no config for your board, use one for a similar board.
81+
82+
Like for ATF, U-Boot finds the SCP firmware binary via an environment variable:
83+
$ export SCP=/src/crust/build/scp/scp.bin
84+
85+
If you do not want to use SCP firmware, you can silence the warning from binman
86+
by pointing it to an empty file:
87+
$ export SCP=/dev/null
88+
5689
SPL/U-Boot
5790
------------
5891
Both U-Boot proper and the SPL are using the 64-bit mode. As the boot ROM

common/spl/Kconfig

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,7 @@ config SPL_FIT_IMAGE_TINY
465465
Enable this to reduce the size of the FIT image loading code
466466
in SPL, if space for the SPL binary is very tight.
467467

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

0 commit comments

Comments
 (0)