summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
Diffstat (limited to 'board')
-rw-r--r--board/amarula/vyasa-rk3288/vyasa-rk3288.c8
-rw-r--r--board/chipspark/popmetal_rk3288/popmetal-rk3288.c8
-rw-r--r--board/emulation/qemu-riscv/Kconfig1
-rw-r--r--board/mqmaker/miqi_rk3288/miqi-rk3288.c9
-rw-r--r--board/rockchip/evb_rk3288/evb-rk3288.c9
-rw-r--r--board/rockchip/evb_rk3399/README6
-rw-r--r--board/rockchip/fennec_rk3288/fennec-rk3288.c9
-rw-r--r--board/sifive/fu540/Kconfig7
-rw-r--r--board/sifive/fu540/fu540.c122
-rw-r--r--board/sunxi/MAINTAINERS6
-rw-r--r--board/ti/am65x/Kconfig8
-rw-r--r--board/ti/am65x/README52
-rw-r--r--board/ti/am65x/evm.c241
-rw-r--r--board/ti/common/board_detect.c246
-rw-r--r--board/ti/common/board_detect.h206
-rw-r--r--board/vamrs/rock960_rk3399/MAINTAINERS4
16 files changed, 890 insertions, 52 deletions
diff --git a/board/amarula/vyasa-rk3288/vyasa-rk3288.c b/board/amarula/vyasa-rk3288/vyasa-rk3288.c
index 2b509f529f..baf197c485 100644
--- a/board/amarula/vyasa-rk3288/vyasa-rk3288.c
+++ b/board/amarula/vyasa-rk3288/vyasa-rk3288.c
@@ -6,14 +6,6 @@
#include <common.h>
#ifndef CONFIG_TPL_BUILD
-#include <spl.h>
-
-void board_boot_order(u32 *spl_boot_list)
-{
- /* eMMC prior to sdcard. */
- spl_boot_list[0] = BOOT_DEVICE_MMC2;
- spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
int spl_start_uboot(void)
{
diff --git a/board/chipspark/popmetal_rk3288/popmetal-rk3288.c b/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
index 355c78b7b7..9ba1fbd0e2 100644
--- a/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
+++ b/board/chipspark/popmetal_rk3288/popmetal-rk3288.c
@@ -4,16 +4,8 @@
*/
#include <common.h>
-#include <spl.h>
#include <asm/gpio.h>
-void board_boot_order(u32 *spl_boot_list)
-{
- /* eMMC prior to sdcard */
- spl_boot_list[0] = BOOT_DEVICE_MMC2;
- spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
-
#define GPIO7A3_HUB_RST 227
int rk_board_late_init(void)
diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
index 7f9a74dd48..6cc7c31dc6 100644
--- a/board/emulation/qemu-riscv/Kconfig
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -24,6 +24,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
imply VIRTIO_MMIO
imply VIRTIO_NET
imply VIRTIO_BLK
+ imply VIRTIO_PCI
imply CMD_PING
imply CMD_FS_GENERIC
imply DOS_PARTITION
diff --git a/board/mqmaker/miqi_rk3288/miqi-rk3288.c b/board/mqmaker/miqi_rk3288/miqi-rk3288.c
index d6992a26ca..779bc646b2 100644
--- a/board/mqmaker/miqi_rk3288/miqi-rk3288.c
+++ b/board/mqmaker/miqi_rk3288/miqi-rk3288.c
@@ -3,12 +3,3 @@
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*/
-#include <common.h>
-#include <spl.h>
-
-void board_boot_order(u32 *spl_boot_list)
-{
- /* eMMC prior to sdcard. */
- spl_boot_list[0] = BOOT_DEVICE_MMC2;
- spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
diff --git a/board/rockchip/evb_rk3288/evb-rk3288.c b/board/rockchip/evb_rk3288/evb-rk3288.c
index d6992a26ca..779bc646b2 100644
--- a/board/rockchip/evb_rk3288/evb-rk3288.c
+++ b/board/rockchip/evb_rk3288/evb-rk3288.c
@@ -3,12 +3,3 @@
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*/
-#include <common.h>
-#include <spl.h>
-
-void board_boot_order(u32 *spl_boot_list)
-{
- /* eMMC prior to sdcard. */
- spl_boot_list[0] = BOOT_DEVICE_MMC2;
- spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
diff --git a/board/rockchip/evb_rk3399/README b/board/rockchip/evb_rk3399/README
index 6469821987..ea3258cf37 100644
--- a/board/rockchip/evb_rk3399/README
+++ b/board/rockchip/evb_rk3399/README
@@ -35,12 +35,6 @@ Get the Source and prebuild binary
> git clone https://github.com/rockchip-linux/rkbin.git
> git clone https://github.com/rockchip-linux/rkdeveloptool.git
-Get some prerequisites
-======================
-
-You need the Python elftools.elf.elffile library for make_fit_atf.py to work:
-
- > sudo apt-get install python-pyelftools
Compile ATF
===========
diff --git a/board/rockchip/fennec_rk3288/fennec-rk3288.c b/board/rockchip/fennec_rk3288/fennec-rk3288.c
index ce455449dd..779bc646b2 100644
--- a/board/rockchip/fennec_rk3288/fennec-rk3288.c
+++ b/board/rockchip/fennec_rk3288/fennec-rk3288.c
@@ -3,12 +3,3 @@
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*/
-#include <common.h>
-#include <spl.h>
-
-void board_boot_order(u32 *spl_boot_list)
-{
- /* eMMC prior to sdcard */
- spl_boot_list[0] = BOOT_DEVICE_MMC2;
- spl_boot_list[1] = BOOT_DEVICE_MMC1;
-}
diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig
index 8eb5e304ab..5d65080429 100644
--- a/board/sifive/fu540/Kconfig
+++ b/board/sifive/fu540/Kconfig
@@ -28,7 +28,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
imply CMD_PING
imply CLK_SIFIVE
imply CLK_SIFIVE_FU540_PRCI
- imply CLK_SIFIVE_GEMGXL_MGMT
imply DOS_PARTITION
imply EFI_PARTITION
imply IP_DYN
@@ -39,6 +38,12 @@ config BOARD_SPECIFIC_OPTIONS # dummy
imply PHY_LIB
imply PHY_MSCC
imply SIFIVE_SERIAL
+ imply SPI
+ imply SPI_SIFIVE
+ imply MMC
+ imply MMC_SPI
+ imply MMC_BROKEN_CD
+ imply CMD_MMC
imply SMP
endif
diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
index 5adc4a3d4a..11daf1a75a 100644
--- a/board/sifive/fu540/fu540.c
+++ b/board/sifive/fu540/fu540.c
@@ -8,6 +8,128 @@
#include <common.h>
#include <dm.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#ifdef CONFIG_MISC_INIT_R
+
+#define FU540_OTP_BASE_ADDR 0x10070000
+
+struct fu540_otp_regs {
+ u32 pa; /* Address input */
+ u32 paio; /* Program address input */
+ u32 pas; /* Program redundancy cell selection input */
+ u32 pce; /* OTP Macro enable input */
+ u32 pclk; /* Clock input */
+ u32 pdin; /* Write data input */
+ u32 pdout; /* Read data output */
+ u32 pdstb; /* Deep standby mode enable input (active low) */
+ u32 pprog; /* Program mode enable input */
+ u32 ptc; /* Test column enable input */
+ u32 ptm; /* Test mode enable input */
+ u32 ptm_rep;/* Repair function test mode enable input */
+ u32 ptr; /* Test row enable input */
+ u32 ptrim; /* Repair function enable input */
+ u32 pwe; /* Write enable input (defines program cycle) */
+} __packed;
+
+#define BYTES_PER_FUSE 4
+#define NUM_FUSES 0x1000
+
+static int fu540_otp_read(int offset, void *buf, int size)
+{
+ struct fu540_otp_regs *regs = (void __iomem *)FU540_OTP_BASE_ADDR;
+ unsigned int i;
+ int fuseidx = offset / BYTES_PER_FUSE;
+ int fusecount = size / BYTES_PER_FUSE;
+ u32 fusebuf[fusecount];
+
+ /* check bounds */
+ if (offset < 0 || size < 0)
+ return -EINVAL;
+ if (fuseidx >= NUM_FUSES)
+ return -EINVAL;
+ if ((fuseidx + fusecount) > NUM_FUSES)
+ return -EINVAL;
+
+ /* init OTP */
+ writel(0x01, &regs->pdstb); /* wake up from stand-by */
+ writel(0x01, &regs->ptrim); /* enable repair function */
+ writel(0x01, &regs->pce); /* enable input */
+
+ /* read all requested fuses */
+ for (i = 0; i < fusecount; i++, fuseidx++) {
+ writel(fuseidx, &regs->pa);
+
+ /* cycle clock to read */
+ writel(0x01, &regs->pclk);
+ mdelay(1);
+ writel(0x00, &regs->pclk);
+ mdelay(1);
+
+ /* read the value */
+ fusebuf[i] = readl(&regs->pdout);
+ }
+
+ /* shut down */
+ writel(0, &regs->pce);
+ writel(0, &regs->ptrim);
+ writel(0, &regs->pdstb);
+
+ /* copy out */
+ memcpy(buf, fusebuf, size);
+
+ return 0;
+}
+
+static u32 fu540_read_serialnum(void)
+{
+ int ret;
+ u32 serial[2] = {0};
+
+ for (int i = 0xfe * 4; i > 0; i -= 8) {
+ ret = fu540_otp_read(i, serial, sizeof(serial));
+ if (ret) {
+ printf("%s: error reading from OTP\n", __func__);
+ break;
+ }
+ if (serial[0] == ~serial[1])
+ return serial[0];
+ }
+
+ return 0;
+}
+
+static void fu540_setup_macaddr(u32 serialnum)
+{
+ /* Default MAC address */
+ unsigned char mac[6] = { 0x70, 0xb3, 0xd5, 0x92, 0xf0, 0x00 };
+
+ /*
+ * We derive our board MAC address by ORing last three bytes
+ * of board serial number to above default MAC address.
+ *
+ * This logic of deriving board MAC address is taken from
+ * SiFive FSBL and is kept unchanged.
+ */
+ mac[5] |= (serialnum >> 0) & 0xff;
+ mac[4] |= (serialnum >> 8) & 0xff;
+ mac[3] |= (serialnum >> 16) & 0xff;
+
+ /* Update environment variable */
+ eth_env_set_enetaddr("ethaddr", mac);
+}
+
+int misc_init_r(void)
+{
+ /* Set ethaddr environment variable if not set */
+ if (!env_get("ethaddr"))
+ fu540_setup_macaddr(fu540_read_serialnum());
+
+ return 0;
+}
+
+#endif
int board_init(void)
{
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index bdd1854197..c7e9d3eda0 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -172,6 +172,12 @@ S: Maintained
F: configs/beelink_gs1_defconfig
F: arch/arm/dts/sun50i-h6-beelink-gs1.dts
+BEELINK X2 BOARD
+M: Marcus Cooper <codekipper@gmail.com>
+S: Maintained
+F: configs/beelink_x2_defconfig
+F: arch/arm/dts/sun8i-h3-beelink-x2.dts
+
COLOMBUS BOARD
M: Maxime Ripard <maxime.ripard@bootlin.com>
S: Maintained
diff --git a/board/ti/am65x/Kconfig b/board/ti/am65x/Kconfig
index 98172c28f5..47b41cd6af 100644
--- a/board/ti/am65x/Kconfig
+++ b/board/ti/am65x/Kconfig
@@ -12,14 +12,18 @@ config TARGET_AM654_A53_EVM
select ARM64
select SOC_K3_AM6
select SYS_DISABLE_DCACHE_OPS
+ select BOARD_LATE_INIT
+ imply TI_I2C_BOARD_DETECT
config TARGET_AM654_R5_EVM
bool "TI K3 based AM654 EVM running on R5"
select CPU_V7R
select SYS_THUMB_BUILD
select SOC_K3_AM6
+ select K3_LOAD_SYSFW
select K3_AM654_DDRSS
imply SYS_K3_SPL_ATF
+ imply TI_I2C_BOARD_DETECT
endchoice
@@ -34,6 +38,8 @@ config SYS_VENDOR
config SYS_CONFIG_NAME
default "am65x_evm"
+source "board/ti/common/Kconfig"
+
endif
if TARGET_AM654_R5_EVM
@@ -50,4 +56,6 @@ config SYS_CONFIG_NAME
config SPL_LDSCRIPT
default "arch/arm/mach-omap2/u-boot-spl.lds"
+source "board/ti/common/Kconfig"
+
endif
diff --git a/board/ti/am65x/README b/board/ti/am65x/README
index 0b82bd557b..16384e05ea 100644
--- a/board/ti/am65x/README
+++ b/board/ti/am65x/README
@@ -209,3 +209,55 @@ Image formats:
| | Secure config | |
| +-------------------+ |
+-----------------------+
+
+eMMC:
+-----
+ROM supports booting from eMMC from boot0 partition offset 0x0
+
+Flashing images to eMMC:
+
+The following commands can be used to download tiboot3.bin, tispl.bin,
+u-boot.img, and sysfw.itb from an SD card and write them to the eMMC boot0
+partition at respective addresses.
+
+=> mmc dev 0 1
+=> fatload mmc 1 ${loadaddr} tiboot3.bin
+=> mmc write ${loadaddr} 0x0 0x400
+=> fatload mmc 1 ${loadaddr} tispl.bin
+=> mmc write ${loadaddr} 0x400 0x1000
+=> fatload mmc 1 ${loadaddr} u-boot.img
+=> mmc write ${loadaddr} 0x1400 0x2000
+=> fatload mmc 1 ${loadaddr} sysfw.itb
+=> mmc write ${loadaddr} 0x3600 0x800
+
+To give the ROM access to the boot partition, the following commands must be
+used for the first time:
+=> mmc partconf 0 1 1 1
+=> mmc bootbus 0 1 0 0
+
+To create a software partition for the rootfs, the following command can be
+used:
+=> gpt write mmc 0 ${partitions}
+
+eMMC layout:
+
+ boot0 partition (8 MB) user partition
+ 0x0+----------------------------------+ 0x0+-------------------------+
+ | tiboot3.bin (512 KB) | | |
+ 0x400+----------------------------------+ | |
+ | tispl.bin (2 MB) | | |
+0x1400+----------------------------------+ | rootfs |
+ | u-boot.img (4 MB) | | |
+0x3400+----------------------------------+ | |
+ | environment (128 KB) | | |
+0x3500+----------------------------------+ | |
+ | backup environment (128 KB) | | |
+0x3600+----------------------------------+ | |
+ | sysfw (1 MB) | | |
+0x3E00+----------------------------------+ +-------------------------+
+
+Kernel image and DT are expected to be present in the /boot folder of rootfs.
+To boot kernel from eMMC, use the following commands:
+=> setenv mmcdev 0
+=> setenv bootpart 0
+=> boot
diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index 52f5d6b11e..7bd8c4fa66 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -8,10 +8,31 @@
*/
#include <common.h>
+#include <dm.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/gpio.h>
#include <asm/io.h>
+#include <asm/omap_common.h>
#include <spl.h>
#include <asm/arch/sys_proto.h>
+#include "../common/board_detect.h"
+
+#define board_is_am65x_base_board() board_ti_is("AM6-COMPROCEVM")
+
+/* Daughter card presence detection signals */
+enum {
+ AM65X_EVM_APP_BRD_DET,
+ AM65X_EVM_LCD_BRD_DET,
+ AM65X_EVM_SERDES_BRD_DET,
+ AM65X_EVM_HDMI_GPMC_BRD_DET,
+ AM65X_EVM_BRD_DET_COUNT,
+};
+
+/* Max number of MAC addresses that are parsed/processed per daughter card */
+#define DAUGHTER_CARD_NO_OF_MAC_ADDR 8
+
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
@@ -80,3 +101,223 @@ int ft_board_setup(void *blob, bd_t *bd)
return ret;
}
#endif
+
+int do_board_detect(void)
+{
+ int ret;
+
+ ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS,
+ CONFIG_EEPROM_CHIP_ADDRESS);
+ if (ret)
+ pr_err("Reading on-board EEPROM at 0x%02x failed %d\n",
+ CONFIG_EEPROM_CHIP_ADDRESS, ret);
+
+ return ret;
+}
+
+static void setup_board_eeprom_env(void)
+{
+ char *name = "am65x";
+
+ if (do_board_detect())
+ goto invalid_eeprom;
+
+ if (board_is_am65x_base_board())
+ name = "am65x";
+ else
+ printf("Unidentified board claims %s in eeprom header\n",
+ board_ti_get_name());
+
+invalid_eeprom:
+ set_board_info_env_am6(name);
+}
+
+static int init_daughtercard_det_gpio(char *gpio_name, struct gpio_desc *desc)
+{
+ int ret;
+
+ memset(desc, 0, sizeof(*desc));
+
+ ret = dm_gpio_lookup_name(gpio_name, desc);
+ if (ret < 0)
+ return ret;
+
+ /* Request GPIO, simply re-using the name as label */
+ ret = dm_gpio_request(desc, gpio_name);
+ if (ret < 0)
+ return ret;
+
+ return dm_gpio_set_dir_flags(desc, GPIOD_IS_IN);
+}
+
+static int probe_daughtercards(void)
+{
+ struct ti_am6_eeprom ep;
+ struct gpio_desc board_det_gpios[AM65X_EVM_BRD_DET_COUNT];
+ char mac_addr[DAUGHTER_CARD_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
+ u8 mac_addr_cnt;
+ char name_overlays[1024] = { 0 };
+ int i, j;
+ int ret;
+
+ /*
+ * Daughter card presence detection signal name to GPIO (via I2C I/O
+ * expander @ address 0x38) name and EEPROM I2C address mapping.
+ */
+ const struct {
+ char *gpio_name;
+ u8 i2c_addr;
+ } slot_map[AM65X_EVM_BRD_DET_COUNT] = {
+ { "gpio@38_0", 0x52, }, /* AM65X_EVM_APP_BRD_DET */
+ { "gpio@38_1", 0x55, }, /* AM65X_EVM_LCD_BRD_DET */
+ { "gpio@38_2", 0x54, }, /* AM65X_EVM_SERDES_BRD_DET */
+ { "gpio@38_3", 0x53, }, /* AM65X_EVM_HDMI_GPMC_BRD_DET */
+ };
+
+ /* Declaration of daughtercards to probe */
+ const struct {
+ u8 slot_index; /* Slot the card is installed */
+ char *card_name; /* EEPROM-programmed card name */
+ char *dtbo_name; /* Device tree overlay to apply */
+ u8 eth_offset; /* ethXaddr MAC address index offset */
+ } cards[] = {
+ {
+ AM65X_EVM_APP_BRD_DET,
+ "AM6-GPAPPEVM",
+ "k3-am654-gp.dtbo",
+ 0,
+ },
+ {
+ AM65X_EVM_APP_BRD_DET,
+ "AM6-IDKAPPEVM",
+ "k3-am654-idk.dtbo",
+ 3,
+ },
+ {
+ AM65X_EVM_SERDES_BRD_DET,
+ "SER-PCIE2LEVM",
+ "k3-am654-pcie-usb2.dtbo",
+ 0,
+ },
+ {
+ AM65X_EVM_SERDES_BRD_DET,
+ "SER-PCIEUSBEVM",
+ "k3-am654-pcie-usb3.dtbo",
+ 0,
+ },
+ {
+ AM65X_EVM_LCD_BRD_DET,
+ "OLDI-LCD1EVM",
+ "k3-am654-evm-oldi-lcd1evm.dtbo",
+ 0,
+ },
+ };
+
+ /*
+ * Initialize GPIO used for daughtercard slot presence detection and
+ * keep the resulting handles in local array for easier access.
+ */
+ for (i = 0; i < AM65X_EVM_BRD_DET_COUNT; i++) {
+ ret = init_daughtercard_det_gpio(slot_map[i].gpio_name,
+ &board_det_gpios[i]);
+ if (ret < 0)
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(cards); i++) {
+ /* Obtain card-specific slot index and associated I2C address */
+ u8 slot_index = cards[i].slot_index;
+ u8 i2c_addr = slot_map[slot_index].i2c_addr;
+
+ /*
+ * The presence detection signal is active-low, hence skip
+ * over this card slot if anything other than 0 is returned.
+ */
+ ret = dm_gpio_get_value(&board_det_gpios[slot_index]);
+ if (ret < 0)
+ return ret;
+ else if (ret)
+ continue;
+
+ /* Get and parse the daughter card EEPROM record */
+ ret = ti_i2c_eeprom_am6_get(CONFIG_EEPROM_BUS_ADDRESS, i2c_addr,
+ &ep,
+ (char **)mac_addr,
+ DAUGHTER_CARD_NO_OF_MAC_ADDR,
+ &mac_addr_cnt);
+ if (ret) {
+ pr_err("Reading daughtercard EEPROM at 0x%02x failed %d\n",
+ i2c_addr, ret);
+ /*
+ * Even this is pretty serious let's just skip over
+ * this particular daughtercard, rather than ending
+ * the probing process altogether.
+ */
+ continue;
+ }
+
+ /* Only process the parsed data if we found a match */
+ if (strncmp(ep.name, cards[i].card_name, sizeof(ep.name)))
+ continue;
+
+ printf("detected %s\n", cards[i].card_name);
+
+ /*
+ * Populate any MAC addresses from daughtercard into the U-Boot
+ * environment, starting with a card-specific offset so we can
+ * have multiple cards contribute to the MAC pool in a well-
+ * defined manner.
+ */
+ for (j = 0; j < mac_addr_cnt; j++) {
+ if (!is_valid_ethaddr((u8 *)mac_addr[j]))
+ continue;
+
+ eth_env_set_enetaddr_by_index("eth",
+ cards[i].eth_offset + j,
+ (uchar *)mac_addr[j]);
+ }
+
+ /* Skip if no overlays are to be added */
+ if (!strlen(cards[i].dtbo_name))
+ continue;
+
+ /*
+ * Make sure we are not running out of buffer space by checking
+ * if we can fit the new overlay, a trailing space to be used
+ * as a separator, plus the terminating zero.
+ */
+ if (strlen(name_overlays) + strlen(cards[i].dtbo_name) + 2 >
+ sizeof(name_overlays))
+ return -ENOMEM;
+
+ /* Append to our list of overlays */
+ strcat(name_overlays, cards[i].dtbo_name);
+ strcat(name_overlays, " ");
+ }
+
+ /* Apply device tree overlay(s) to the U-Boot environment, if any */
+ if (strlen(name_overlays))
+ return env_set("name_overlays", name_overlays);
+
+ return 0;
+}
+
+int board_late_init(void)
+{
+ struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+
+ setup_board_eeprom_env();
+
+ /*
+ * The first MAC address for ethernet a.k.a. ethernet0 comes from
+ * efuse populated via the am654 gigabit eth switch subsystem driver.
+ * All the other ones are populated via EEPROM, hence continue with
+ * an index of 1.
+ */
+ board_ti_am6_set_ethaddr(1, ep->mac_addr_cnt);
+
+ /* Check for and probe any plugged-in daughtercards */
+ probe_daughtercards();
+
+ return 0;
+}
diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c
index e258e22f37..32fa10599e 100644
--- a/board/ti/common/board_detect.c
+++ b/board/ti/common/board_detect.c
@@ -8,6 +8,7 @@
*/
#include <common.h>
+#include <asm/arch/hardware.h>
#include <asm/omap_common.h>
#include <dm/uclass.h>
#include <i2c.h>
@@ -284,6 +285,191 @@ int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
return 0;
}
+static int ti_i2c_eeprom_am6_parse_record(struct ti_am6_eeprom_record *record,
+ struct ti_am6_eeprom *ep,
+ char **mac_addr,
+ u8 mac_addr_max_cnt,
+ u8 *mac_addr_cnt)
+{
+ switch (record->header.id) {
+ case TI_AM6_EEPROM_RECORD_BOARD_INFO:
+ if (record->header.len != sizeof(record->data.board_info))
+ return -EINVAL;
+
+ if (!ep)
+ break;
+
+ /* Populate (and clean, if needed) the board name */
+ strlcpy(ep->name, record->data.board_info.name,
+ sizeof(ep->name));
+ ti_eeprom_string_cleanup(ep->name);
+
+ /* Populate selected other fields from the board info record */
+ strlcpy(ep->version, record->data.board_info.version,
+ sizeof(ep->version));
+ strlcpy(ep->software_revision,
+ record->data.board_info.software_revision,
+ sizeof(ep->software_revision));
+ strlcpy(ep->serial, record->data.board_info.serial,
+ sizeof(ep->serial));
+ break;
+ case TI_AM6_EEPROM_RECORD_MAC_INFO:
+ if (record->header.len != sizeof(record->data.mac_info))
+ return -EINVAL;
+
+ if (!mac_addr || !mac_addr_max_cnt)
+ break;
+
+ *mac_addr_cnt = ((record->data.mac_info.mac_control &
+ TI_AM6_EEPROM_MAC_ADDR_COUNT_MASK) >>
+ TI_AM6_EEPROM_MAC_ADDR_COUNT_SHIFT) + 1;
+
+ /*
+ * The EEPROM can (but may not) hold a very large amount
+ * of MAC addresses, by far exceeding what we want/can store
+ * in the common memory array, so only grab what we can fit.
+ * Note that a value of 0 means 1 MAC address, and so on.
+ */
+ *mac_addr_cnt = min(*mac_addr_cnt, mac_addr_max_cnt);
+
+ memcpy(mac_addr, record->data.mac_info.mac_addr,
+ *mac_addr_cnt * TI_EEPROM_HDR_ETH_ALEN);
+ break;
+ case 0x00:
+ /* Illegal value... Fall through... */
+ case 0xFF:
+ /* Illegal value... Something went horribly wrong... */
+ return -EINVAL;
+ default:
+ pr_warn("%s: Ignoring record id %u\n", __func__,
+ record->header.id);
+ }
+
+ return 0;
+}
+
+int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
+ struct ti_am6_eeprom *ep,
+ char **mac_addr,
+ u8 mac_addr_max_cnt,
+ u8 *mac_addr_cnt)
+{
+ struct udevice *dev;
+ struct udevice *bus;
+ unsigned int eeprom_addr;
+ struct ti_am6_eeprom_record_board_id board_id;
+ struct ti_am6_eeprom_record record;
+ int rc;
+
+ /* Initialize with a known bad marker for i2c fails.. */
+ memset(ep, 0, sizeof(*ep));
+ ep->header = TI_DEAD_EEPROM_MAGIC;
+
+ /* Read the board ID record which is always the first EEPROM record */
+ rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
+ sizeof(board_id), (uint8_t *)&board_id);
+ if (rc)
+ return rc;
+
+ if (board_id.header.id != TI_AM6_EEPROM_RECORD_BOARD_ID) {
+ pr_err("%s: Invalid board ID record!\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Establish DM handle to board config EEPROM */
+ rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
+ if (rc)
+ return rc;
+ rc = i2c_get_chip(bus, dev_addr, 1, &dev);
+ if (rc)
+ return rc;
+
+ ep->header = TI_EEPROM_HEADER_MAGIC;
+
+ /* Ready to parse TLV structure. Initialize variables... */
+ *mac_addr_cnt = 0;
+
+ /*
+ * After the all-encompassing board ID record all other records follow
+ * a TLV-type scheme. Point to the first such record and then start
+ * parsing those one by one.
+ */
+ eeprom_addr = sizeof(board_id);
+
+ while (true) {
+ rc = dm_i2c_read(dev, eeprom_addr, (uint8_t *)&record.header,
+ sizeof(record.header));
+ if (rc)
+ return rc;
+
+ /*
+ * Check for end of list marker. If we reached it don't go
+ * any further and stop parsing right here.
+ */
+ if (record.header.id == TI_AM6_EEPROM_RECORD_END_LIST)
+ break;
+
+ eeprom_addr += sizeof(record.header);
+
+ debug("%s: dev_addr=0x%02x header.id=%u header.len=%u\n",
+ __func__, dev_addr, record.header.id,
+ record.header.len);
+
+ /* Read record into memory if it fits */
+ if (record.header.len <= sizeof(record.data)) {
+ rc = dm_i2c_read(dev, eeprom_addr,
+ (uint8_t *)&record.data,
+ record.header.len);
+ if (rc)
+ return rc;
+
+ /* Process record */
+ rc = ti_i2c_eeprom_am6_parse_record(&record, ep,
+ mac_addr,
+ mac_addr_max_cnt,
+ mac_addr_cnt);
+ if (rc) {
+ pr_err("%s: EEPROM parsing error!\n", __func__);
+ return rc;
+ }
+ } else {
+ /*
+ * We may get here in case of larger records which
+ * are not yet understood.
+ */
+ pr_err("%s: Ignoring record id %u\n", __func__,
+ record.header.id);
+ }
+
+ eeprom_addr += record.header.len;
+ }
+
+ return 0;
+}
+
+int __maybe_unused ti_i2c_eeprom_am6_get_base(int bus_addr, int dev_addr)
+{
+ struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+ int ret;
+
+ /*
+ * Always execute EEPROM read by not allowing to bypass it during the
+ * first invocation of SPL which happens on the R5 core.
+ */
+#if !(defined(CONFIG_SPL_BUILD) && defined(CONFIG_CPU_V7R))
+ if (ep->header == TI_EEPROM_HEADER_MAGIC) {
+ debug("%s: EEPROM has already been read\n", __func__);
+ return 0;
+ }
+#endif
+
+ ret = ti_i2c_eeprom_am6_get(bus_addr, dev_addr, ep,
+ (char **)ep->mac_addr,
+ AM6_EEPROM_HDR_NO_OF_MAC_ADDR,
+ &ep->mac_addr_cnt);
+ return ret;
+}
+
bool __maybe_unused board_ti_is(char *name_tag)
{
struct ti_common_eeprom *ep = TI_EEPROM_DATA;
@@ -348,6 +534,25 @@ fail:
memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
}
+void __maybe_unused
+board_ti_am6_get_eth_mac_addr(int index,
+ u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
+{
+ struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+
+ if (ep->header == TI_DEAD_EEPROM_MAGIC)
+ goto fail;
+
+ if (index < 0 || index >= ep->mac_addr_cnt)
+ goto fail;
+
+ memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
+ return;
+
+fail:
+ memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
+}
+
u64 __maybe_unused board_ti_get_emif1_size(void)
{
struct ti_common_eeprom *ep = TI_EEPROM_DATA;
@@ -391,6 +596,34 @@ void __maybe_unused set_board_info_env(char *name)
env_set("board_serial", unknown);
}
+void __maybe_unused set_board_info_env_am6(char *name)
+{
+ char *unknown = "unknown";
+ struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+
+ if (name)
+ env_set("board_name", name);
+ else if (ep->name)
+ env_set("board_name", ep->name);
+ else
+ env_set("board_name", unknown);
+
+ if (ep->version)
+ env_set("board_rev", ep->version);
+ else
+ env_set("board_rev", unknown);
+
+ if (ep->software_revision)
+ env_set("board_software_revision", ep->software_revision);
+ else
+ env_set("board_software_revision", unknown);
+
+ if (ep->serial)
+ env_set("board_serial", ep->serial);
+ else
+ env_set("board_serial", unknown);
+}
+
static u64 mac_to_u64(u8 mac[6])
{
int i;
@@ -453,6 +686,19 @@ void board_ti_set_ethaddr(int index)
}
}
+void board_ti_am6_set_ethaddr(int index, int count)
+{
+ u8 mac_addr[6];
+ int i;
+
+ for (i = 0; i < count; i++) {
+ board_ti_am6_get_eth_mac_addr(i, mac_addr);
+ if (is_valid_ethaddr(mac_addr))
+ eth_env_set_enetaddr_by_index("eth", i + index,
+ mac_addr);
+ }
+}
+
bool __maybe_unused board_ti_was_eeprom_read(void)
{
struct ti_common_eeprom *ep = TI_EEPROM_DATA;
diff --git a/board/ti/common/board_detect.h b/board/ti/common/board_detect.h
index f8495a7a7c..a45d8961b9 100644
--- a/board/ti/common/board_detect.h
+++ b/board/ti/common/board_detect.h
@@ -43,6 +43,133 @@ struct ti_am_eeprom {
char mac_addr[TI_EEPROM_HDR_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
} __attribute__ ((__packed__));
+/* AM6x TI EVM EEPROM Definitions */
+#define TI_AM6_EEPROM_RECORD_BOARD_ID 0x01
+#define TI_AM6_EEPROM_RECORD_BOARD_INFO 0x10
+#define TI_AM6_EEPROM_RECORD_DDR_INFO 0x11
+#define TI_AM6_EEPROM_RECORD_DDR_SPD 0x12
+#define TI_AM6_EEPROM_RECORD_MAC_INFO 0x13
+#define TI_AM6_EEPROM_RECORD_END_LIST 0xFE
+
+/*
+ * Common header for AM6x TI EVM EEPROM records. Used to encapsulate the config
+ * EEPROM in its entirety as well as for individual records contained within.
+ */
+struct ti_am6_eeprom_record_header {
+ u8 id;
+ u16 len;
+} __attribute__ ((__packed__));
+
+/* AM6x TI EVM EEPROM board ID structure */
+struct ti_am6_eeprom_record_board_id {
+ u32 magic_number;
+ struct ti_am6_eeprom_record_header header;
+} __attribute__ ((__packed__));
+
+/* AM6x TI EVM EEPROM board info structure */
+#define AM6_EEPROM_HDR_NAME_LEN 16
+#define AM6_EEPROM_HDR_VERSION_LEN 2
+#define AM6_EEPROM_HDR_PROC_NR_LEN 4
+#define AM6_EEPROM_HDR_VARIANT_LEN 2
+#define AM6_EEPROM_HDR_PCB_REV_LEN 2
+#define AM6_EEPROM_HDR_SCH_BOM_REV_LEN 2
+#define AM6_EEPROM_HDR_SW_REV_LEN 2
+#define AM6_EEPROM_HDR_VID_LEN 2
+#define AM6_EEPROM_HDR_BLD_WK_LEN 2
+#define AM6_EEPROM_HDR_BLD_YR_LEN 2
+#define AM6_EEPROM_HDR_4P_NR_LEN 6
+#define AM6_EEPROM_HDR_SERIAL_LEN 4
+
+struct ti_am6_eeprom_record_board_info {
+ char name[AM6_EEPROM_HDR_NAME_LEN];
+ char version[AM6_EEPROM_HDR_VERSION_LEN];
+ char proc_number[AM6_EEPROM_HDR_PROC_NR_LEN];
+ char variant[AM6_EEPROM_HDR_VARIANT_LEN];
+ char pcb_revision[AM6_EEPROM_HDR_PCB_REV_LEN];
+ char schematic_bom_revision[AM6_EEPROM_HDR_SCH_BOM_REV_LEN];
+ char software_revision[AM6_EEPROM_HDR_SW_REV_LEN];
+ char vendor_id[AM6_EEPROM_HDR_VID_LEN];
+ char build_week[AM6_EEPROM_HDR_BLD_WK_LEN];
+ char build_year[AM6_EEPROM_HDR_BLD_YR_LEN];
+ char board_4p_number[AM6_EEPROM_HDR_4P_NR_LEN];
+ char serial[AM6_EEPROM_HDR_SERIAL_LEN];
+} __attribute__ ((__packed__));
+
+/* Memory location to keep a copy of the AM6 board info record */
+#define TI_AM6_EEPROM_BD_INFO_DATA ((struct ti_am6_eeprom_record_board_info *) \
+ TI_SRAM_SCRATCH_BOARD_EEPROM_START)
+
+/* AM6x TI EVM EEPROM DDR info structure */
+#define TI_AM6_EEPROM_DDR_CTRL_INSTANCE_MASK GENMASK(1, 0)
+#define TI_AM6_EEPROM_DDR_CTRL_INSTANCE_SHIFT 0
+#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_MASK GENMASK(3, 2)
+#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_NA (0 << 2)
+#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_BOARDID (2 << 2)
+#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_I2C51 (3 << 2)
+#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_MASK GENMASK(5, 4)
+#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_DDR3 (0 << 4)
+#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_DDR4 (1 << 4)
+#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_LPDDR4 (2 << 4)
+#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_MASK GENMASK(7, 6)
+#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_16 (0 << 6)
+#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_32 (1 << 6)
+#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_64 (2 << 6)
+#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_MASK GENMASK(9, 8)
+#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_8 (0 << 8)
+#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_16 (1 << 8)
+#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_32 (2 << 8)
+#define TI_AM6_EEPROM_DDR_CTRL_RANKS_2 BIT(10)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_MASK GENMASK(13, 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_1GB (0 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_2GB (1 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_4GB (2 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_8GB (3 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_12GB (4 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_16GB (5 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_24GB (6 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_32GB (7 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_ECC BIT(14)
+
+struct ti_am6_eeprom_record_ddr_info {
+ u16 ddr_control;
+} __attribute__ ((__packed__));
+
+/* AM6x TI EVM EEPROM DDR SPD structure */
+#define TI_AM6_EEPROM_DDR_SPD_INSTANCE_MASK GENMASK(1, 0)
+#define TI_AM6_EEPROM_DDR_SPD_INSTANCE_SHIFT 0
+#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_MASK GENMASK(4, 3)
+#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_DDR3 (0 << 3)
+#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_DDR4 (1 << 3)
+#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_LPDDR4 (2 << 3)
+#define TI_AM6_EEPROM_DDR_SPD_DATA_LEN 512
+
+struct ti_am6_eeprom_record_ddr_spd {
+ u16 spd_control;
+ u8 data[TI_AM6_EEPROM_DDR_SPD_DATA_LEN];
+} __attribute__ ((__packed__));
+
+/* AM6x TI EVM EEPROM MAC info structure */
+#define TI_AM6_EEPROM_MAC_INFO_INSTANCE_MASK GENMASK(2, 0)
+#define TI_AM6_EEPROM_MAC_INFO_INSTANCE_SHIFT 0
+#define TI_AM6_EEPROM_MAC_ADDR_COUNT_MASK GENMASK(7, 3)
+#define TI_AM6_EEPROM_MAC_ADDR_COUNT_SHIFT 3
+#define TI_AM6_EEPROM_MAC_ADDR_MAX_COUNT 32
+
+struct ti_am6_eeprom_record_mac_info {
+ u16 mac_control;
+ u8 mac_addr[TI_AM6_EEPROM_MAC_ADDR_MAX_COUNT][TI_EEPROM_HDR_ETH_ALEN];
+} __attribute__ ((__packed__));
+
+struct ti_am6_eeprom_record {
+ struct ti_am6_eeprom_record_header header;
+ union {
+ struct ti_am6_eeprom_record_board_info board_info;
+ struct ti_am6_eeprom_record_ddr_info ddr_info;
+ struct ti_am6_eeprom_record_ddr_spd ddr_spd;
+ struct ti_am6_eeprom_record_mac_info mac_info;
+ } data;
+} __attribute__ ((__packed__));
+
/* DRA7 EEPROM MAGIC Header identifier */
#define DRA7_EEPROM_HEADER_MAGIC 0xAA5533EE
#define DRA7_EEPROM_HDR_NAME_LEN 16
@@ -99,6 +226,37 @@ struct ti_common_eeprom {
#define TI_EEPROM_DATA ((struct ti_common_eeprom *)\
TI_SRAM_SCRATCH_BOARD_EEPROM_START)
+/*
+ * Maximum number of Ethernet MAC addresses extracted from the AM6x on-board
+ * EEPROM during the initial probe and carried forward in SRAM.
+ */
+#define AM6_EEPROM_HDR_NO_OF_MAC_ADDR 8
+
+/**
+ * struct ti_am6_eeprom - Null terminated, usable EEPROM contents, as extracted
+ * from the AM6 on-board EEPROM. Note that we only carry a subset of data
+ * at this time to be considerate about memory consumption.
+ * @header: Magic number for data validity indication
+ * @name: NULL terminated name
+ * @version: NULL terminated version
+ * @software_revision: NULL terminated software revision
+ * @serial: Board serial number
+ * @mac_addr_cnt: Number of MAC addresses stored in this object
+ * @mac_addr: MAC addresses
+ */
+struct ti_am6_eeprom {
+ u32 header;
+ char name[AM6_EEPROM_HDR_NAME_LEN + 1];
+ char version[AM6_EEPROM_HDR_VERSION_LEN + 1];
+ char software_revision[AM6_EEPROM_HDR_SW_REV_LEN + 1];
+ char serial[AM6_EEPROM_HDR_SERIAL_LEN + 1];
+ u8 mac_addr_cnt;
+ char mac_addr[AM6_EEPROM_HDR_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
+};
+
+#define TI_AM6_EEPROM_DATA ((struct ti_am6_eeprom *) \
+ TI_SRAM_SCRATCH_BOARD_EEPROM_START)
+
/**
* ti_i2c_eeprom_am_get() - Consolidated eeprom data collection for AM* TI EVMs
* @bus_addr: I2C bus address
@@ -117,6 +275,33 @@ int ti_i2c_eeprom_am_get(int bus_addr, int dev_addr);
int ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr);
/**
+ * ti_i2c_eeprom_am6_get() - Consolidated eeprom data for AM6x TI EVMs and
+ * associated daughter cards, parsed into user-
+ * provided data structures
+ * @bus_addr: I2C bus address
+ * @dev_addr: I2C slave address
+ * @ep: Pointer to structure receiving AM6-specific header data
+ * @mac_addr: Pointer to memory receiving parsed MAC addresses. May be
+ * NULL to skip MAC parsing.
+ * @mac_addr_max_cnt: Maximum number of MAC addresses that can be stored into
+ * mac_addr. May be NULL to skip MAC parsing.
+ * @mac_addr_cnt: Pointer to a location returning how many MAC addressed got
+ * actually parsed.
+ */
+int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
+ struct ti_am6_eeprom *ep,
+ char **mac_addr,
+ u8 mac_addr_max_cnt,
+ u8 *mac_addr_cnt);
+
+/**
+ * ti_i2c_eeprom_am6_get_base() - Consolidated eeprom data for AM6x TI EVMs
+ * @bus_addr: I2C bus address
+ * @dev_addr: I2C slave address
+ */
+int __maybe_unused ti_i2c_eeprom_am6_get_base(int bus_addr, int dev_addr);
+
+/**
* board_ti_is() - Board detection logic for TI EVMs
* @name_tag: Tag used in eeprom for the board
*
@@ -193,6 +378,15 @@ u64 board_ti_get_emif2_size(void);
void set_board_info_env(char *name);
/**
+ * set_board_info_env_am6() - Setup commonly used board information environment
+ * vars for AM6-type boards
+ * @name: Name of the board
+ *
+ * If name is NULL, default_name is used.
+ */
+void set_board_info_env_am6(char *name);
+
+/**
* board_ti_set_ethaddr- Sets the ethaddr environment from EEPROM
* @index: The first eth<index>addr environment variable to set
*
@@ -205,6 +399,18 @@ void set_board_info_env(char *name);
void board_ti_set_ethaddr(int index);
/**
+ * board_ti_am6_set_ethaddr- Sets the ethaddr environment from EEPROM
+ * @index: The first eth<index>addr environment variable to set
+ * @count: The number of MAC addresses to process
+ *
+ * EEPROM should be already read before calling this function. The EEPROM
+ * contains n dedicated MAC addresses. This function sets the ethaddr
+ * environment variable for all the available MAC addresses starting
+ * from eth<index>addr.
+ */
+void board_ti_am6_set_ethaddr(int index, int count);
+
+/**
* board_ti_was_eeprom_read() - Check to see if the eeprom contents have been read
*
* This function is useful to determine if the eeprom has already been read and
diff --git a/board/vamrs/rock960_rk3399/MAINTAINERS b/board/vamrs/rock960_rk3399/MAINTAINERS
index 22b2db925a..5ee5256495 100644
--- a/board/vamrs/rock960_rk3399/MAINTAINERS
+++ b/board/vamrs/rock960_rk3399/MAINTAINERS
@@ -1,11 +1,11 @@
ROCK960-RK3399
-M: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
+M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
S: Maintained
F: board/rockchip/rock960_rk3399
F: include/configs/rock960_rk3399.h
F: configs/rock960-rk3399_defconfig
FICUS EE
-M: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
+M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
S: Maintained
F: configs/ficus-rk3399_defconfig