BPI-R64 current u-boot support

The 2014 u-boot is 32bits, I think loading an 64 bits u-boot binary to dram, and running in 32 bits CPU mode will cause unexpected results…

I will send our ATF image for upstream u-boot to you in a few days, this ATF image is able to start u-boot in 64 bits CPU mode (default: stating 64 bits u-boot, and can keep holding the WPS button during boot-up to start 32 bits u-boot)

We use CONFIG_OF_EMBED for debug, and forgot to disable it in mt7622 rfb defconfig, But I haven’t tested that it can work with CONFIG_OF_SEPARATE or not

if i understand you right, currently we cannot test uboot due to missing ATF right? can i change arch in uboot before calling go command (after loading the binary)? currently i don’t want to flash it because i need ethernet-support for kernel-testing :slight_smile:

I think it is hard to change 32/64 bits in u-boot from my limited knowledge of Arm Cortex-A53.
If we want to change 32/64 bits cpu instruction set, We should use SPSR_EL3 registers to do that.
This register can only be used under ARM Secured World, In our case here, only ATF and pre-loader
are running in the Secured World.

mhm, seems like our ATF does not support 64bit uboot…

F0: 102B 0000
F5: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 0000 0041 [0000]
G0: 0190 0000
T0: 0000 03BB [000F]
Jump to BL

UNIVPLL_CON0 = 0xFE000000!!!
mt_pll_init: Set pll frequency for 25M crystal
[PMIC_WRAP]wrap_init pass,the return value=0.
[pmic_init] Preloader Start..................
[pmic_init] MT6380 CHIP Code, reg_val = 0, 1:E2  0:E3
[pmic_init] Done...................                                             
Chip part number:7622A                                                          
MT7622 Version: 1.2.7, (iPA)                                                    
SSC OFF                                                                         
mt_pll_post_init: mt_get_cpu_freq = 1350000Khz                                  
mt_pll_post_init: mt_get_mem_freq = 1600000Khz                                  
mt_pll_post_init: mt_get_bus_freq = 1119920Khz                                  
[PLFM] Init I2C: OK(0)                                                          
[BLDR] Build Time: 20181123-214255                                              
==== Dump RGU Reg ========                                                      
RGU MODE:     4D                                                                
RGU LENGTH:   FFE0                                                              
RGU STA:      0                                                                 
RGU INTERVAL: FFF                                                               
RGU SWSYSRST: 8000                                                              
==== Dump RGU Reg End ====                                                      
RGU: g_rgu_satus:0                                                              
 mtk_wdt_mode_config  mode value=10, tmp:22000010                               
PL P ON                                                                         
WDT does not trigger reboot                                                     
WDT NONRST=0x20000000                                                           
WDT IRQ_EN=0x340003                                                             
RGU mtk_wdt_init:MTK_WDT_DEBUG_CTL(590200F3)                                    
[EMI] MDL number = 2                                                            
[EMI] DRAMC calibration start                                                   
[EMI] DRAMC calibration end                                                     
[EMI]rank0 size: 0x40000000                                                     
[MEM] complex R/W mem test pass                                                 
RAM_CONSOLE wdt status (0x0)=0x0                                                
[mmc_init]: msdc1 start mmc_init_host() in PL...                                
[msdc_init]: msdc1 Host controller intialization start                          
[SD1] Pins mode(1), none(0), down(1), up(2), keep(3)                            
[SD1] Pins mode(2), none(0), down(1), up(2), keep(3)                            
[info][msdc_config_clksrc] input clock is 200000kHz                             
[SD1] Bus Width: 1                                                              
[info][msdc_config_clksrc] input clock is 200000kHz                             
[SD1] SET_CLK(260kHz): SCLK(259kHz) MODE(0) DDR(0) DIV(193) DS(0) RS(0)         
[msdc_init]: msdc1 Host controller intialization done                           
[mmc_init]: msdc1 start mmc_init_card() in PL...                                
[mmc_init_card]: start                                                          
[SD1] Bus Width: 4                                                              
[SD1] Size: 30436 MB, Max.Speed: 25000 kHz, blklen(512), nblks(62333952), ro(0) 
[mmc_init_mem_card 3140][SD1] Initialized, SD10                                 
before host->cur_bus_clk(259067)                                                
[info][msdc_config_clksrc] input clock is 200000kHz                             
[SD1] SET_CLK(25000kHz): SCLK(25000kHz) MODE(0) DDR(0) DIV(2) DS(0) RS(0)       
[mmc_init_card]: finish successfully                                            
[PLFM] Init Boot Device: OK(0)                                                  
[GPT_PL](BPI)Parsing Primary GPT now...                                         
[GPT_PL]check header, err(signature 0x00000054594C5242!=0x5452415020494645)     
[GPT_PL]Success to find valid GPT.                                              
[PART] blksz: 512B                                                              
[PART] [0x0000000000020000-0x000000000007FFFF] "preloader" (768 blocks)         
[PART] [0x0000000000080000-0x00000000000BFFFF] "tee1" (512 blocks)              
[PART] [0x00000000000C0000-0x000000000013FFFF] "lk" (1024 blocks)               
Device APC domain init setup:                                                   
Domain Setup (0x0)                                                              
Domain Setup (0x0)                                                              
Device APC domain after setup:                                                  
Domain Setup (0x0)                                                              
Domain Setup (0x0)                                                              
[get_part] part->nr_sects=768, part->info->name=preloader                       
[get_part] part->nr_sects=512, part->info->name=tee1                            
[get_part] part->nr_sects=1024, part->info->name=lk                             
[PART] Image with part header                                                   
[PART] name : U-Boot                                                            
[PART] addr : 41E00000h mode : -1                                               
[PART] size : 462976                                                            
[PART] magic: 58881688h                                                         
[PART] load "lk" from 0x00000000000C0200 (dev) to 0x41E00000 (mem) [SUCCESS]    
[PART] load speed: 3532KB/s, 462976 bytes, 128ms                                
load lk (ret=0)                                                                 
[get_part] part->nr_sects=768, part->info->name=preloader                       
[get_part] part->nr_sects=512, part->info->name=tee1                            
[PART] Image with part header                                                   
[PART] name : atf                                                               
[PART] addr : FFFFFFFFh mode : -1                                               
[PART] size : 62032                                                             
[PART] magic: 58881688h                                                         
[PART] load "tee1" from 0x0000000000080200 (dev) to 0x43000DC0 (mem) [SUCCESS]  
[PART] load speed: 2752KB/s, 62032 bytes, 22ms                                  
load tee1 (ret=0)                                                               
[BLDR] bldr load tee part ret=0x0, addr=0x43001000                              
[get_part] part->nr_sects=768, part->info->name=preloader                       
[get_part] part->nr_sects=512, part->info->name=tee1                            
[get_part] part->nr_sects=1024, part->info->name=lk                             
[BLDR] boot part. not found                                                     
[BLDR] part_load_images ret=0x0                                                 
[BLDR] Others, jump to ATF                                                      
[BLDR] jump to 0x41E00000                                                       
[BLDR] <0x41E00000>=0x1400000A                                                  
[BLDR] <0x41E00004>=0xD503201F

Seems that part is for me :slight_smile:

Maybe linux even start with such limited tree, but w/o USB/PCI/Ethernet.

Idea to use FDT is just like PCs use ACPI. You don’t need own copy of ACPI ASL for each PC model. Bootloader (BIOS) pass it to OS. It just works and every modern OS parse it and find where is UART/PCI-RC/watchdog/etc.

i tried using the existing jump64smc function to load 64bit uboot binary from old uboot over tftp

this my quick&dirty way (uboot 2014-04):

diff --git a/common/cmd_boot.c b/common/cmd_boot.c
index 8f2e0701b5..540f504d34 100644
--- a/common/cmd_boot.c
+++ b/common/cmd_boot.c
@@ -45,6 +45,17 @@ static int do_go(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        return rcode;
+static int do_go64(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+       ulong   addr;
+       addr = simple_strtoul(argv[1], NULL, 16);
+#if defined(CONFIG_MTK_ATF)
+       extern void jumparch64_smc(ulong addr, ulong arg1, ulong arg2);
+       jumparch64_smc(addr, 0, 0);
+       //return do_go(cmdtp, flag, argc,argv);
+       return 0;
 /* -------------------------------------------------------------------- */
@@ -54,6 +65,13 @@ U_BOOT_CMD(
        "      passing 'arg' as arguments"
+       go64, CONFIG_SYS_MAXARGS, 1,    do_go64,
+       "start 64bit application at address 'addr'",
+       "addr [arg ...]\n    - start 64bit application at address 'addr'\n"
+       "      passing 'arg' as arguments"

results in this:

BPI-R64> setenv uboot64net 'tftp ${umtkaddr} ${ufile};go64 $uaddr'
BPI-R64> setenv ufile u-boot_2020.01-rc4-bpi-r64-v1.bin
BPI-R64> run uboot64net
ETH already turn on and power on flow will be skipped...

 Waitting for RX_DMA_BUSY status Start... done

mt7531: mt7531_sw_init
mt7531: mt7531_core_pll_setup, hwstrap = 000000ff
mt7531: mt7531_mac_port_setup, port = 6
mt7531: mt7531_set_port_sgmii_force_mode, port = 6
mt7531: timeout waiting for SGMII_LINK
mt7531: mt7531_mac_port_setup, PMCR6 = f805633b
 0x1b000014 = 0x00110214
Using mtk_eth device
TFTP from server; our IP address is
Filename 'u-boot_2020.01-rc4-bpi-r64-v1.bin'.
Load address: 0x41dffe00
Loading: T ################################
         86.9 KiB/s
Bytes transferred = 463504 (71290 hex)
get filesize 0x71290
[ATF][    55.625586]save kernel info
[ATF][    55.628626]Kernel_EL2
[ATF][    55.631382]Kernel is 64Bit
[ATF][    55.634570]pc=0x41e00000, r0=0x0, r1=0x0
INFO:    BL3-1: Preparing for EL3 exit to normal world, Kernel
INFO:    BL3-1: Next image address = 0x41e00000
INFO:    BL3-1: Next image spsr = 0x3c9
[ATF][    55.652234]el3_exit

U-Boot 2020.01-rc4-bpi-r64-v1-00023-g8cc6bfc180-dirty (Dec 07 2019 - 10:53:57 +)

CPU:   MediaTek MT7622
Model: mt7622-rfb
DRAM:  256 MiB
WDT:   Started with servicing (60s timeout)
MMC:   mmc@11230000: 0, mmc@11240000: 1
In:    serial@11002000
Out:   serial@11002000
Err:   serial@11002000
Net:   No ethernet found.

DRAM seems to be wrong…

i can access both mmc devices (need FS_GENERIC and CMD_FAT)

MT7622> ls mmc 1:1
        0   sd.txt
  8841288   uImage_5.4
    23721   bpi-r64-5.4.dtb

3 file(s), 1 dir(s)

MT7622> ls mmc 0:1
        0   emmc.txt

1 file(s), 1 dir(s)


tried now loading kernel, but it seems not working (maybe because it is wrapped into 32bit container via mkimage)

MT7622> setenv kaddr 0x44000000
MT7622> setenv dtaddr 0x47000000
MT7622> setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait ipp
MT7622> fatload mmc 1:1 ${kaddr} uImage_5.4
8841288 bytes read in 613 ms (13.8 MiB/s)
MT7622> fatload mmc 1:1 ${dtaddr} bpi-r64-5.4.dtb
23721 bytes read in 4 ms (5.7 MiB/s)
MT7622> bootm ${kaddr} - ${dtaddr}
## Booting kernel from Legacy Image at 44000000 ...
   Image Name:   Linux Kernel 5.4.0-rc1-r64
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    8841224 Bytes = 8.4 MiB
   Load Address: 40080000
   Entry Point:  40080000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 47000000
   Booting using the fdt blob at 0x47000000
   Loading Kernel Image
   Loading Device Tree to 000000004f7f3000, end 000000004f7fbca8 ... OK

Starting kernel ...

F0: 102B 0000
F5: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 0000 0041 [0000]
G0: 0190 0000
T0: 0000 0342 [000F]
Jump to BL

it hangs on “starting kernel” till watchdog reset occours

after changing the mkimage-command in my kernels build.sh this way:

mkimage -A arm64 -O linux -T kernel -C none -a 40080000 -e 40080000 -n "Linux Kernel $kernver$gitbranch" -d arch/arm64/boot/Image ./uImage_nodt

i’m able to boot kernel

MT7622> setenv kaddr 0x44000000
MT7622> setenv dtaddr 0x47000000
MT7622> setenv bootargs console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait
MT7622> fatload mmc 1:1 ${kaddr} uImage_5.4_64
8581192 bytes read in 588 ms (13.9 MiB/s)
MT7622> fatload mmc 1:1 ${dtaddr} bpi-r64-5.4_64.dtb
24264 bytes read in 3 ms (7.7 MiB/s)
MT7622> bootm ${kaddr} - ${dtaddr}


for wrong DRAM value i tried modifying the memory-node in arch/arm/dts/mt7622-rfb.dts matching same reg as in linux (except in linux memory-node is 64bit by globally #address-cells = <2>;#size-cells = <2>; in mt7622.dtsi)

        memory@40000000 {
                device_type = "memory";
-               reg = <0x40000000 0x10000000>;
+               reg = <0x40000000 0x40000000>;

now i see

DRAM:  1 GiB

but after this is printed board hangs :frowning: i tried to adjust CONFIG_NR_DRAM_BANKS to 2 and 4 without success

ATF image for 64 bits u-boot (default: stating 64 bits u-boot, and can keep holding the WPS button during boot-up to start 32 bits u-boot)
mt7622_ATF_32_64_release.img (61.1 KB)

thank you

i was able to start new uboot directly with this ATF

[BLDR] part_load_images ret=0x0                                                 
[BLDR] Others, jump to ATF                                                      
[BLDR] jump to 0x41E00000                                                       
[BLDR] <0x41E00000>=0x1400000A                                                  
[BLDR] <0x41E00004>=0xD503201F                                                  
U-Boot 2020.01-rc4-bpi-r64-v1 (Dec 09 2019 - 07:43:54 +0100)                    
CPU:   MediaTek MT7622                                                          
Model: mt7622-rfb                                                               
DRAM:  256 MiB                                                                  
WDT:   Started with servicing (60s timeout)                                     
MMC:   mmc@11230000: 0, mmc@11240000: 1                                         
In:    serial@11002000                                                          
Out:   serial@11002000                                                          
Err:   serial@11002000                                                          
Net:   No ethernet found.                                                       

steps to write ATF if anyone else also want to test it

sudo dd if=$ATF of=$O bs=1k seek=512

made a quick test with WPS-button to start old uboot using this ATF…works…is it possible to invert the button-handling (not press boot 32,press boot 64)?

[BLDR] jump to 0x41E00000                                                       
[BLDR] <0x41E00000>=0xEA00000F                                                  
[BLDR] <0x41E00004>=0xE59FF014                                                  
U-Boot 2014.04-rc1-00045-g955f02c553 (Dec 09 2019 - 07:53:38)                   
DRAM:  1008 MiB                                                                 
relocation Offset is: 3d134000                                                  
WARNING: Caches not enabled                                                     
Now running in RAM - U-Boot at: 7ef34000

any idea about DRAM?

I think it’s mm_region problem.
I forgot to consider bpir64 1Gb dram.
You can modify mt7622_mem_map in. “arch/arm/mach-mediatek/mt7622/init.c”
The size of first mm_region of mt7622_mem_map[] should be 0x40000000UL to support both RFB and BPIR64.
I will send a v2 patch to fix this problem.

Greate idea, it is possible to invert the button-handling for ATF jump to 32/64 bits u-boot.
I will send this to you recently.

1 Like

Ok~ It seems that I should use FDT and CONFIG_OF_SEPARATE to check it works or not.
In the previous development, I was only through the uImage + bootm command to test it.

1 Like

in my tests it worked…see my tree https://github.com/frank-w/u-boot/commits/2020-01-bpi-r64-v1

i have OF_SEPARATE already active :slight_smile: and load kernel like posted above with “bootm $kaddr - $dtaddr”

it is important to use aarch64 uImage not arm uImage like the 32bit uboot (mkimage command)

DRAM is now 1Gib :wink: thank you

till ethernet is working it is better for us press button to go to new uboot…if all is working there we can use the 64bit default atf

it looks like the go64 does not work with the new ATF ;( is something different to the bpi version in 32bit way? i cannot even start kernel there…seems that the jump64_smc target is missing to go back to 64bit-mode…is there the sourcecode of ATF (yours/bpi)?

Is go64 work in 2014 u-boot with new ATF ?
Or it only not work in upstream u-boot with new ATF ?

go64 is my own function in old 32bit uboot (my repo) to switch to 64bit mode (to load new 64bit uboot binary). See here. This uses existing jumparch64_smc which was used to start 64bit kernel. Both is not working with new ATF in 32bit-mode (wps button).

Upstream uboot is 64bit and does not not need this switch. The switch is needed only in 32bit (2014) uboot and does only work in bpi’s ATF not in 32bit mode of yours :frowning:

If ethernet will be ready soon i can switch completely,but i guess it’s much work so my main uboot needs to be the old and i want to be able to load new one for testing without permanently flashing it :slight_smile:

waiting for v2 show up in patchwork…seems it hangs, got mails but cannot export to mbox

@sam can you tell me adress for exception (smc) handler in your atf which is used for switch to 64bit mode?

i don’t know why there is a fixed address and not the smc-command above which seems to be commented out

OK, I know the root cause of this …
The SMC handler of jumparch64_smc was gone …
I will update a new version, and also provide WPS button 32 bits & WPS button 64 bits (In previous discussion) images to you.

1 Like


“… and this lets us keep the files otherwise unchanged from the Linux kernel we import them from.”

But that can be committed later.


@sam33, here is support to build 32bits version. based on your patches.

1 Like

with your Patch and the 2014-source i added the jumparch64 to preserve compatibility (64bit kernel in 32bit uImage) with upstream uboot-code

made a quick test…works so far (except ethernet of course)…it boots with bpi’s ATF and i can load 32bit uImage containing 64bit kernel

1 Like

Update. Here is version based on @sam33’s patches:

It support SD/MMC/NAND.

It also has an USB support, but it won’t works. Sees only root hub emulation.

Here is two issues:

  1. SPI NAND works much slower if you initialize SD before it. Seems wrong clock sharing or misuse.
  2. No real USB devices visible.

@sam33 can you please do quick look on it and point me what to do? In case of XHCI we have clock named CLK_SSUSB_MCU_EN. I saw similar MCU clock source somewhere else. Maybe we have to power up that MCU first?


1 Like

PCI Express finally works. But dunno yet, why is SATA SSD behind PCI AHCI card does not detect. Controller see link, but can’t read. Maybe power related.

good news: first Patchset is merged: https://patchwork.ozlabs.org/patch/1220976/

do we want to add separate dts for r64 (at least for memory-node 256M vs. 1G) and 32-bit config (to stay compatible with current kernels/images)?