diff options
author | David Lechner <david@lechnology.com> | 2016-02-26 00:46:07 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-03-14 19:18:40 -0400 |
commit | 2ac07f75d1977008e829d00bcce16143e171765d (patch) | |
tree | e0e9dccb8441feb6a11fb53a65b989cdc51d4a5e /board | |
parent | 6f6e9439e4646242bb504e7b5c1ac0dfbf986cfb (diff) |
arm: Add support for LEGO MINDSTORMS EV3
This is based on the davinci da850evm. It can boot from either the
on-board 16MB flash or from a microSD card. It also reads board
information from an I2C EEPROM.
The EV3 itself initally boots from write-protected EEPROM, so no
u-boot SPL is needed.
Signed-off-by: David Lechner <david@lechnology.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'board')
-rw-r--r-- | board/lego/ev3/Kconfig | 12 | ||||
-rw-r--r-- | board/lego/ev3/MAINTAINERS | 6 | ||||
-rw-r--r-- | board/lego/ev3/Makefile | 10 | ||||
-rw-r--r-- | board/lego/ev3/README | 32 | ||||
-rw-r--r-- | board/lego/ev3/legoev3.c | 176 |
5 files changed, 236 insertions, 0 deletions
diff --git a/board/lego/ev3/Kconfig b/board/lego/ev3/Kconfig new file mode 100644 index 00000000000..14b3f0c1cf9 --- /dev/null +++ b/board/lego/ev3/Kconfig @@ -0,0 +1,12 @@ +if TARGET_LEGOEV3 + +config SYS_BOARD + default "ev3" + +config SYS_VENDOR + default "lego" + +config SYS_CONFIG_NAME + default "legoev3" + +endif diff --git a/board/lego/ev3/MAINTAINERS b/board/lego/ev3/MAINTAINERS new file mode 100644 index 00000000000..11b32616090 --- /dev/null +++ b/board/lego/ev3/MAINTAINERS @@ -0,0 +1,6 @@ +LEGOEV3 BOARD +M: David Lechner <david@lechnology.com> +S: Maintained +F: board/lego/ev3/ +F: include/configs/legoev3.h +F: configs/legoev3_defconfig diff --git a/board/lego/ev3/Makefile b/board/lego/ev3/Makefile new file mode 100644 index 00000000000..f3e717ab661 --- /dev/null +++ b/board/lego/ev3/Makefile @@ -0,0 +1,10 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += legoev3.o diff --git a/board/lego/ev3/README b/board/lego/ev3/README new file mode 100644 index 00000000000..1a50ca9d035 --- /dev/null +++ b/board/lego/ev3/README @@ -0,0 +1,32 @@ +Summary +======= + +LEGO MINDSTORMS EV3 is a toy robot produced by the LEGO Group. It is based +on the davinci da850 evm. The EV3 has a 16MB spi flash and a SDHC microSD card +reader. + +Booting +======= + +The EV3 contains a bootloader in EEPROM that loads u-boot.bin from address 0x0 +of the spi flash memory. Using the default configuration, u-boot will check to +see if there is a boot.scr file on the first FAT partition of the mmc. If there +is, it will run the script and boot the kernel from the uImage file also in +the FAT partition. Otherwise, it will load a kernel and rootfs from the flash. +The kernel must be stored at address 0x50000 on the flash and have a maximum +size of 3MiB. The rootfs must be a squasfs image and stored at 0x350000 in the +flash and have a maximum size of 9.3MiB. The flash starting at 0xCB0000 is +reserved for user data. + +Writing image to flash +====================== + +The EEPROM contains a program for uploading an image file to the flash memory. +The program is started by holding down the right button on the EV3 when powering +it on. You can also `run fwupdateboot` in the u-boot shell to reboot into this +mode. The image can then be uploaded using the official LEGO MINDSTORMS EV3 +software or a 3rd party program capable of uploading a firmware file. + +If you are booting from the microSD card, it is enough to just write uboot.bin +to the flash. If you are not using a microSD card, you will need to create an +image file using the layout described above. diff --git a/board/lego/ev3/legoev3.c b/board/lego/ev3/legoev3.c new file mode 100644 index 00000000000..a791b97f8ff --- /dev/null +++ b/board/lego/ev3/legoev3.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2016 David Lechner <david@lechnology.com> + * + * Based on da850evm.c + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * Based on da830evm.c. Original Copyrights follow: + * + * Copyright (C) 2009 Nick Thompson, GE Fanuc, Ltd. <nick.thompson@gefanuc.com> + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <i2c.h> +#include <net.h> +#include <netdev.h> +#include <spi.h> +#include <spi_flash.h> +#include <asm/arch/hardware.h> +#include <asm/arch/pinmux_defs.h> +#include <asm/io.h> +#include <asm/arch/davinci_misc.h> +#include <asm/errno.h> +#include <hwconfig.h> + +#ifdef CONFIG_DAVINCI_MMC +#include <mmc.h> +#include <asm/arch/sdmmc_defs.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +u8 board_rev; + +#define EEPROM_I2C_ADDR 0x50 +#define EEPROM_REV_OFFSET 0x3F00 +#define EEPROM_MAC_OFFSET 0x3F06 + +#ifdef CONFIG_DAVINCI_MMC +static struct davinci_mmc mmc_sd0 = { + .reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE, + .host_caps = MMC_MODE_4BIT, /* DA850 supports only 4-bit SD/MMC */ + .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, + .version = MMC_CTLR_VERSION_2, +}; + +int board_mmc_init(bd_t *bis) +{ + mmc_sd0.input_clk = clk_get(DAVINCI_MMCSD_CLKID); + + /* Add slot-0 to mmc subsystem */ + return davinci_mmc_init(bis, &mmc_sd0); +} +#endif + +const struct pinmux_resource pinmuxes[] = { + PINMUX_ITEM(spi0_pins_base), + PINMUX_ITEM(spi0_pins_scs0), + PINMUX_ITEM(uart1_pins_txrx), + PINMUX_ITEM(i2c0_pins), + PINMUX_ITEM(mmc0_pins), +}; + +const int pinmuxes_size = ARRAY_SIZE(pinmuxes); + +const struct lpsc_resource lpsc[] = { + { DAVINCI_LPSC_SPI0 }, /* Serial Flash */ + { DAVINCI_LPSC_UART1 }, /* console */ + { DAVINCI_LPSC_MMC_SD }, +}; + +const int lpsc_size = ARRAY_SIZE(lpsc); + +u32 get_board_rev(void) +{ + u8 buf[2]; + + if (!board_rev) { + if (i2c_read(EEPROM_I2C_ADDR, EEPROM_REV_OFFSET, 2, buf, 2)) { + printf("\nBoard revision read failed!\n"); + } else { + /* + * Board rev 3 has MAC address at EEPROM_REV_OFFSET. + * Other revisions have checksum at EEPROM_REV_OFFSET+1 + * to detect this. + */ + if ((buf[0] ^ buf[1]) == 0xFF) + board_rev = buf[0]; + else + board_rev = 3; + } + } + + return board_rev; +} + +/* + * The Bluetooth MAC address serves as the board serial number. + */ +void get_board_serial(struct tag_serialnr *serialnr) +{ + u32 offset; + u8 buf[6]; + + if (!board_rev) + board_rev = get_board_rev(); + + /* Board rev 3 has MAC address where rev should be */ + offset = (board_rev == 3) ? EEPROM_REV_OFFSET : EEPROM_MAC_OFFSET; + + if (i2c_read(EEPROM_I2C_ADDR, offset, 2, buf, 6)) { + printf("\nBoard serial read failed!\n"); + } else { + u8 *nr; + + nr = (u8 *)&serialnr->low; + nr[0] = buf[5]; + nr[1] = buf[4]; + nr[2] = buf[3]; + nr[3] = buf[2]; + nr = (u8 *)&serialnr->high; + nr[0] = buf[1]; + nr[1] = buf[0]; + nr[2] = 0; + nr[3] = 0; + } +} + +int board_early_init_f(void) +{ + /* + * Power on required peripherals + * ARM does not have access by default to PSC0 and PSC1 + * assuming here that the DSP bootloader has set the IOPU + * such that PSC access is available to ARM + */ + if (da8xx_configure_lpsc_items(lpsc, ARRAY_SIZE(lpsc))) + return 1; + + return 0; +} + +int board_init(void) +{ +#ifndef CONFIG_USE_IRQ + irq_init(); +#endif + + /* arch number of the board */ + /* LEGO didn't register for a unique number and uses da850evm */ + gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_DA850_EVM; + + /* address of boot parameters */ + gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; + + /* setup the SUSPSRC for ARM to control emulation suspend */ + writel(readl(&davinci_syscfg_regs->suspsrc) & + ~(DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C | + DAVINCI_SYSCFG_SUSPSRC_SPI0 | DAVINCI_SYSCFG_SUSPSRC_TIMER0 | + DAVINCI_SYSCFG_SUSPSRC_UART1), + &davinci_syscfg_regs->suspsrc); + + /* configure pinmux settings */ + if (davinci_configure_pin_mux_items(pinmuxes, ARRAY_SIZE(pinmuxes))) + return 1; + + /* enable the console UART */ + writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST | + DAVINCI_UART_PWREMU_MGMT_UTRST), + &davinci_uart1_ctrl_regs->pwremu_mgmt); + + return 0; +} |