Add latest U-boot support for BPI R2 & BPI R64 (not yet)


#1

Hello,

I’ve already sent the first round patches for MT7623n, and the most of the drivers are based on mainline Linux, like clock, timer, mmc, pinctrl, watchdog, power domain and DTS.

I will also upstream U-boot and ATF for MT7622 (BPI-R64) in the future.

The following are the major differences between Linux and U-boot:

  • Modify the driver interface to adapt the U-boot DM framework.
  • Remove unneeded DT nodes as they don’t have proper drivers in U-boot yet.
  • Just add the basic functions (step-by-step) so that we can monitor the size.
  • Reuse UART driver ns16550.c but add a highspeed register for MediaTek chips.

The current progress for R2:

  • Boot from eMMC or SD card.
  • Boot flow: ROM -> MediaTek preloder -> U-boot -> Linux

Todo list:

  • Ethernet driver.
  • Other peripheral drivers.
  • U-boot for MT7622 (R64)
  • ATF (arm trusted firmware) for MT7622 (R64)

The patch sets:

How to build:

  • make mt7623n_bpir2_defconfig; make

Ryder


(Frank W.) #2

I just want to link thread from armbian-forum here because user chwe had tested this patches and found some small problems (missing options in defconfig): https://forum.armbian.com/topic/7296-bananapi-r2-csc-mt7623-as-new-boardfamily/?page=2

Patches also uploaded here: https://github.com/chwe17/build/tree/mt7623/patch/u-boot/u-boot-mt7623


#3

I think that’s because Armbian has different boot method (zImage) so that he need to modify defconfig.


(Frank W.) #4

i have forked uboot, applied patches and added build-script

also updated uboot-page in my wiki: https://www.fw-web.de/dokuwiki/doku.php?id=en:bpi-r2:uboot#update_uboot

if anybody would test it…currently i need old uboot for netboot-tests and till the new have no ethernet-driver i cannot replace it

btw. @ryder.lee have the uboot support for the emmc-command needed to change the partition-config to run OS from EMMC?


#5

You can read /write/ erase emmc or test it through GPT.


(Frank W.) #6

Have you an example for reading and writing partitionconfig to the needed value 0x48?

U-Boot> mmc list                                                                
mmc@11230000: 0 (eMMC)                                                          
mmc@11240000: 1 (SD)  

U-Boot> gpt read mmc 0
gpt - GUID Partition Table

Usage:
gpt <command> <interface> <dev> <partitions_list> 
 - GUID partition table restoration and validity check
 Restore or verify GPT information on a device connected
 to interface
 Example usage:
 gpt write mmc 0 $partitions
 gpt verify mmc 0 $partitions
 read <interface> <dev>
    - read GPT into a data structure for manipulation
 guid <interface> <dev>
    - print disk GUID
 guid <interface> <dev> <varname> 
    - set environment variable to disk GUID
 Example usage:
 gpt guid mmc 0
 gpt guid mmc 0 varname

as far as i understand does gtp read/write a gpt-partition…the emmc command creates hardware-partitions (separate devices) mmcblkXbootY instead of mmcblkXpY…so i think creaeting this partitions with gpt-command is impossible

Emmc was introduced in 2014 uboot here: https://github.com/BPI-SINOVOIP/BPI-R2-bsp/commit/71d865da906ea1f333b56bf810cb789bad2e8cac

i can read the uenv.txt using definitions from old uboot:

setenv scriptaddr 0x83000000
setenv bpi bananapi
setenv board bpi-r2
setenv service linux 
setenv device mmc
setenv partition 1:1 
setenv bootenv uEnv.txt
setenv loadbootenv fatload ${device} ${partition} ${scriptaddr} ${bpi}/${board}/${service}/${bootenv}
setenv importenv env import -t ${scriptaddr} ${filesize} 

run loadbootenv
run importenv

and got kernel booting with

U-Boot> setenv newboot "fatload mmc ${partition} ${loadaddr} ${bpi}/${board}/${service}/${kernel}; bootm"                                                             
U-Boot> run newboot

it seems that emmc (mmc 0) is always default device, also if i boot from sd-card…how can this be changed?

i booted from SD-Card:

U-Boot> mmc dev                                                                                                                                                       
switch to partitions #0, OK                                                                                                                                           
mmc0(part 0) is current device                                                                                                                                        
U-Boot> mmc list                                                                                                                                                      
mmc@11230000: 0 (eMMC)                                                                                                                                                
mmc@11240000: 1

in old uboot the problem with wrong device is resolved by this 2 definitions:

checksd=fatinfo ${device} 1:1
newchecksd=if run checksd; then echo Boot from SD ; setenv partition 1:1; else echo Boot from eMMC ; mmc init 0 ; setenv partition 0:1 ; fi;

“mmc init” seems to be dropped

also “saveenv” seems to be missing, do i have to enable anything for saving the environment?

i tried to activate CONFIG_ENV_IS_IN_MMC to activate saveenv-command (https://patchwork.ozlabs.org/patch/852568/) results in failed build:

env/mmc.c: In function ‘mmc_get_env_dev’:
env/mmc.c:127:9: error: ‘CONFIG_SYS_MMC_ENV_DEV’ undeclared (first use in this function); did you mean ‘CONFIG_SYS_MALLOC_LEN’?
  return CONFIG_SYS_MMC_ENV_DEV;
         ^~~~~~~~~~~~~~~~~~~~~~
         CONFIG_SYS_MALLOC_LEN
env/mmc.c:127:9: note: each undeclared identifier is reported only once for each function it appears in
env/mmc.c:128:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
scripts/Makefile.build:278: recipe for target 'env/mmc.o' failed
make[1]: *** [env/mmc.o] Error 1

this CONST is defined in old uboot here: https://github.com/frank-w/bpi-r2-uboot/blob/master/include/configs/mt7623_evb.h#L263 but surrounded with if/elif

basicly

#elif defined(OFF_BOARD_SD_CARD_COMPONENT)
#define CONFIG_SYS_MMC_ENV_DEV 1
#elif defined(ON_BOARD_EMMC_COMPONENT)
#define CONFIG_SYS_MMC_ENV_DEV 0

are these ON/OFF-Consts available in new uboot? i did not find them in uboot config, in old uboot they are defined in autoconf.h (which is a generated file afaik)

i simly defined

CONFIG_SYS_MMC_ENV_DEV 0

in include/configs/mt7623.h and compile works and i got the saveenv in ubbot…but now target for savenenv is always emmc.

@jackzeng has patched 2014 uboot to use the right mmc. https://github.com/BPI-SINOVOIP/BPI-R2-bsp/commit/0b7eb9e24a66d405970aff1b466bb50b21f925b8

but this modifies global mmc-driver too much in my eyes for a patch…maybe it’s better calling a global function which by default returns CONFIG_SYS_MMC_ENV_DEV and can be overridden by vendor-specific emmc-driver. My c/c++ knowledge is a bit too less to realize this ;(

seems such function exists already for CONFIG_SYS_MMC_ENV_PART but not for CONFIG_SYS_MMC_ENV_DEV:

env/mmc.c:

125 __weak int mmc_get_env_dev(void)
126 {
127     return CONFIG_SYS_MMC_ENV_DEV;
128 }

so we can try to override this function and return the actual boot-device…but how to deal with offset-change (+1MB if SD-Card) from Jacks patch? is this needed?

i tried to override this function in include/configs/mt7623.h, but this leads to some errors…maybe i need to copy this function to a c-file

include/configs/mt7623.h: Assembler messages:
include/configs/mt7623.h:72: Error: bad instruction `int mmc_get_env_dev(void)'
include/configs/mt7623.h:73: Error: junk at end of line, first unrecognized character is `{'
include/configs/mt7623.h:74: Error: bad instruction `return 1'
include/configs/mt7623.h:75: Error: junk at end of line, first unrecognized character is `}'

72 int mmc_get_env_dev(void)
73 {
74     return 1;
75 }

tried also in mtk-sd.c but here i have no access to the defined constant…build without it seems to work…

and can i add the vars somewhere to uboot-code to load it automaticly (and display bootmenu)?

i tried bootcmd, but it is not executed on startup…

bootcmd=run selectmmc; run loadbootenv; run importenv;

added a default environment file to my repo which gets build into uboot (i see the vars with printenv after bootup)


(Frank W.) #7

@ryder.lee Please post ethernet-patch if you have it ready.


(Frank W.) #8

i tried to override the function mmc_get_env_dev in drivers/mmc/mtk-sd.c

1288 int mmc_get_env_dev(void)
1289 {
1290     printf("%s:%d %s",__FILE__,__LINE__,__FUNCTION__);
1291
1292     int   g_mmc_devid = -1;
1293     char *uflag = (char *)0x81DFFFF0;
1294
1295     if((uflag[0] == 'e') && (uflag[1] == 'M') && (uflag[2] == 'M') && (uflag[3] == 'C'))
1296     {
1297         g_mmc_devid = 0;
1298         printf("Boot From Emmc(id:%d)\n\n", g_mmc_devid);
1299     }
1300     else
1301     {
1302         g_mmc_devid = 1;
1303         printf("Boot From SD(id:%d)\n\n", g_mmc_devid);
1304     }
1305
1306     return 1;
1307 }

but it seems it is not called…

Device APC domain init setup:

 bootloader load uboot ,the address of uboot is 81E00000 
[PART]partition name UBOOT 
[PART]partition start block 0x200 
[PART]partition size 0x80000 
[PART]partition blks 0x400 
[PART]partition flags 0x0 
U-Boot> 

(after exit the bootmenu)

any idea why? maybe i need to put this into board-code, but i’ve found only board/mediatek/mt7623/mt7623_rfb.c not bpi-r2 as board-definition…is this used?

ok, due to botmenu the output was not visible…

Loading Environment from MMC... board/mediatek/mt7623/mt7623_rfb.c:20 mmc_get_env_devBoot From SD(id:1)

:grinning: have to test it with emmc now

Loading Environment from MMC... board/mediatek/mt7623/mt7623_rfb.c:20 mmc_get_env_devBoot From Emmc(id:0)

nice :wink:

@jackzeng why do you add a additional offset for SD-Card? can you help me implementing this? currently i don’t understand why you touched the offset because uboot+partitiontable are same for emmc+sd…if you’ve added this for emmc i thought that was for bootx-partitions, but on sd :thinking:

  //If mmc is SD, then set offset 1Mb
if(priv->id == 1)
  *env_addr = offset + mmc->capacity;
else
  *env_addr = offset;
....
//If is SD, set offset 1Mb
if(id == 1)
{
    blk_num+=0x100000;
}
...
mmc->capacity = blk_num;

as far as i see in env/mmc.c there is also a weak mmc_get_env_addr function which seems to implement similar behaviour, but without the device-switch

113 __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
114 {
115     s64 offset = mmc_offset(copy);
116
117     if (offset < 0)
118         offset += mmc->capacity;
119
120     *env_addr = offset;
121
122     return 0;
123 }

which gets called in static int env_mmc_save(void) and int env_mmc_load(void)

@Ryder.Lee is this ethernet-driver compatible: https://patchwork.ozlabs.org/patch/980573/ ? seems it’s not…added it, changed depends (by default only for MT7620/7688 SoCs) so i can select it in menuconfig, but throws different errors

details
  CC      drivers/net/mt76xx-eth.o
drivers/net/mt76xx-eth.c: In function ‘mt76xx_eth_write_hwaddr’:
drivers/net/mt76xx-eth.c:352:56: error: dereferencing pointer to incomplete type ‘struct eth_pdata’
  u8 *addr = ((struct eth_pdata *)dev_get_platdata(dev))->enetaddr;
                                                        ^~
drivers/net/mt76xx-eth.c: In function ‘mt76xx_eth_send’:
drivers/net/mt76xx-eth.c:401:28: warning: implicit declaration of function ‘CPHYSADDR’; did you mean ‘MII_PHYADDR’? [-Wimplicit-function-declaration]
  priv->tx_ring[idx].txd1 = CPHYSADDR(packet);
                            ^~~~~~~~~
                            MII_PHYADDR
drivers/net/mt76xx-eth.c:408:2: warning: implicit declaration of function ‘wmb’; did you mean ‘dmb’? [-Wimplicit-function-declaration]
  wmb();
  ^~~
  dmb
drivers/net/mt76xx-eth.c: In function ‘mt76xx_eth_probe’:
drivers/net/mt76xx-eth.c:587:3: warning: implicit declaration of function ‘KSEG1ADDR’ [-Wimplicit-function-declaration]
   KSEG1ADDR(memalign(ARCH_DMA_MINALIGN,
   ^~~~~~~~~
drivers/net/mt76xx-eth.c: At top level:
drivers/net/mt76xx-eth.c:617:21: error: variable ‘mt76xx_eth_ops’ has initializer but incomplete type
 static const struct eth_ops mt76xx_eth_ops = {
                     ^~~~~~~
drivers/net/mt76xx-eth.c:618:3: error: ‘const struct eth_ops’ has no member named ‘start’
  .start  = mt76xx_eth_start,
   ^~~~~
drivers/net/mt76xx-eth.c:618:12: warning: excess elements in struct initializer
  .start  = mt76xx_eth_start,
            ^~~~~~~~~~~~~~~~
drivers/net/mt76xx-eth.c:618:12: note: (near initialization for ‘mt76xx_eth_ops’)
drivers/net/mt76xx-eth.c:619:3: error: ‘const struct eth_ops’ has no member named ‘send’
  .send  = mt76xx_eth_send,
   ^~~~
drivers/net/mt76xx-eth.c:619:11: warning: excess elements in struct initializer
  .send  = mt76xx_eth_send,
           ^~~~~~~~~~~~~~~
drivers/net/mt76xx-eth.c:619:11: note: (near initialization for ‘mt76xx_eth_ops’)
drivers/net/mt76xx-eth.c:620:3: error: ‘const struct eth_ops’ has no member named ‘recv’
  .recv  = mt76xx_eth_recv,
   ^~~~
drivers/net/mt76xx-eth.c:620:11: warning: excess elements in struct initializer
  .recv  = mt76xx_eth_recv,
           ^~~~~~~~~~~~~~~
drivers/net/mt76xx-eth.c:620:11: note: (near initialization for ‘mt76xx_eth_ops’)
drivers/net/mt76xx-eth.c:621:3: error: ‘const struct eth_ops’ has no member named ‘stop’
  .stop  = mt76xx_eth_stop,
   ^~~~
drivers/net/mt76xx-eth.c:621:11: warning: excess elements in struct initializer
  .stop  = mt76xx_eth_stop,
           ^~~~~~~~~~~~~~~
drivers/net/mt76xx-eth.c:621:11: note: (near initialization for ‘mt76xx_eth_ops’)
drivers/net/mt76xx-eth.c:622:3: error: ‘const struct eth_ops’ has no member named ‘write_hwaddr’
  .write_hwaddr = mt76xx_eth_write_hwaddr,
   ^~~~~~~~~~~~
drivers/net/mt76xx-eth.c:622:18: warning: excess elements in struct initializer
  .write_hwaddr = mt76xx_eth_write_hwaddr,
                  ^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/mt76xx-eth.c:622:18: note: (near initialization for ‘mt76xx_eth_ops’)
drivers/net/mt76xx-eth.c:637:37: error: invalid application of ‘sizeof’ to incomplete type ‘struct eth_pdata’
  .platdata_auto_alloc_size = sizeof(struct eth_pdata),
                                     ^~~~~~
drivers/net/mt76xx-eth.c:617:29: error: storage size of ‘mt76xx_eth_ops’ isn’t known
 static const struct eth_ops mt76xx_eth_ops = {
                             ^~~~~~~~~~~~~~
scripts/Makefile.build:278: recipe for target 'drivers/net/mt76xx-eth.o' failed
make[1]: *** [drivers/net/mt76xx-eth.o] Error 1
Makefile:1423: recipe for target 'drivers/net' failed
make: *** [drivers/net] Error 2

Is anything additional needed (dts-nodes)?


(moore liu) #9

the network HW architecture of mt7623 and mt7620 are different, so you cannot apply this patch directly, thanks.


(Frank W.) #10

I see that new patches are available.

https://patchwork.ozlabs.org/project/uboot/list/?series=69709

Is there anything new or only whitespaces (eol) updated? Ethernet seems not yet included


#11

We’re working on Ethernet driver now.


(Frank W.) #12

:+1:

btw. uboot-patches v2 (https://patchwork.ozlabs.org/patch/982884/) failing on 2018-11-rc1 because of missing MT7621_SPI-symbol in drivers/spi/Kconfig

+config MTK_QSPI
+       bool "Mediatek QSPI driver"
+       help
+         Enable the Mediatek QSPI driver. This driver can be
+         used to access the SPI NOR flash on platforms embedding this
+         Mediatek QSPI IP core.
+

it seems that another patch-series is needed to apply this patch directly, but i didn’t find which one

have it applied here:

problem-patch is here:

i don’t know yet how to answer in patchwork…


(weijie.gao) #13

To use SD card, you should use the following command:

mmc dev 1

the ‘1’ means the second device, which is SD card.

and you will get output like this:

U-Boot> mmc dev 1
switch to partitions #0, OK
mmc1 is current device

U-Boot> mmc list
mmc@11230000: 0
mmc@11240000: 1 (SD)

U-Boot> mmc info
Device: mmc@11240000
Manufacturer ID: 11
OEM: 4499
Name: SD256
Bus Speed: 50000000
Mode : SD High Speed (50MHz)
Rd Block Len: 512
SD version 2.0
High Capacity: No
Capacity: 239 MiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes

To switch HW partitions (boot0/boot1/user), uses the following commands:

mmc dev 0 1

the second number ‘1’ means partition boot0 (according to the eMMC spec)

Read the first block to check it:

U-Boot> mmc dev 0 1
switch to partitions #1, OK
mmc0(part 1) is current device
U-Boot> mmc read 0x80000000 0 2

MMC read: dev # 0, block # 0, count 2 ... 2 blocks read: OK
U-Boot> md 0x80000000
80000000: 434d4d45 4f4f425f 00000054 00000001    EMMC_BOOT.......
80000010: 00000200 ffffffff ffffffff ffffffff    ................
80000020: ffffffff ffffffff ffffffff ffffffff    ................

(Frank W.) #14

right, but i asked because the emmc-command in 2014-uboot which configures emmc to have a boot0 and boot1-device which is needed to flash preloader to it and get image booted from emmc

reference: Can't boot from emmc (see step 4)

btw. is poweroff-command much work? if i enable the command i get: missing »do_poweroff«


#15

btw. uboot-patches v2 (https://patchwork.ozlabs.org/patch/982884/) failing on 2018-11-rc1 because of missing MT7621_SPI-symbol in drivers/spi/Kconfig

You should rebase to the latest branch:

http://git.denx.de/?p=u-boot.git;a=commit;h=5eee9dee419f940ea75977df8b7ed8bb12bc029f


(Frank W.) #16

have v2-patches and my own ready again…waiting for ethernet-driver and the 2018-11 final release :slight_smile:


(Frank W.) #17

How far are you with the ethernet-driver? Btw. In old uboot mac-setting does not work,hoping here it will do.


(Frank W.) #18

@Ryder.Lee can you manage to add ethernet-driver for r2 before 2018-11-release (12th november)?


(Frank W.) #19

emmc-command seems not be needed, i’ve found out how to use uboot-internal commands to read and set the Partitionconfig:

#mmc partconf dev [boot_ack boot_partition partition_access]
# - Show or change the bits of the PARTITION_CONFIG field of the specified device
#example for mode 0x48 (needed for emmc-boot on bpi-r2)
U-Boot> mmc partconf 0
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x1
PARTITION_ACCESS: 0x0

#set via
U-Boot> mmc partconf 0 1 1 0

i resetted the flags and set it with last command to get the same result as read before reset

Currently i don’t know how the 0x48 is calculated…


(Frank W.) #20

@Ryder.Lee i have an issue with v3-patches:

Kernel command line: earlyprintk console=ttyS0,115200 vmalloc=496M debug=7 no_console_suspend

this does not change to the value of bootargs env-variable

Boot from SD
bootargs=board=bpi-r2 console=earlyprintk console=tty1 fbcon=map:0 console=ttyS0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait vmalloc=496M debug=7 initcall_debug=0 video=1920x1080 drm.debug=0x7
6473034 bytes read in 394 ms (15.7 MiB/s)
## Booting kernel from Legacy Image at 80200000 ...
   Image Name:   Linux Kernel 4.19.0-poweroff_new
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    6472970 Bytes = 6.2 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.19.0-bpi-r2-poweroff_new (frank@frank-N56VZ) (gcc version 7.3.0 (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04)) #172 SMP Wed Oct 24 11:38:09 CEST 2018
[    0.000000] CPU: ARMv7 Processor [410fc073] revision 3 (ARMv7), cr=10c5387d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] OF: fdt: Machine model: Bananapi BPI-R2
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] cma: Reserved 64 MiB at 0xfb800000
[    0.000000] On node 0 totalpages: 524287
[    0.000000]   Normal zone: 1170 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 133120 pages, LIFO batch:31
[    0.000000]   HighMem zone: 391167 pages, LIFO batch:63
[    0.000000] random: get_random_bytes called from start_kernel+0xac/0x49c with crng_init=0
[    0.000000] percpu: Embedded 17 pages/cpu @(ptrval) s40268 r8192 d21172 u69632
[    0.000000] pcpu-alloc: s40268 r8192 d21172 u69632 alloc=17*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 523117
[    0.000000] Kernel command line: earlyprintk console=ttyS0,115200 vmalloc=496M debug=7 no_console_suspend
  • v3-patches on rc1 giving same result, so it’s no rc3-issue
  • resetted environment (to default=builtin=uenv.txt in my uboot-repo) before loading kernel
  • builtin-env is same in v2,v3 and v3_old branch
  • uenv.txt on sdcard only contains kernel-var (and root=same as on default env)

works with v2 but not with v3 (rc1/rc3)

any idea?