[U-Boot] [PATCH 0/1] board: imx7d tqma7d support

This work is based on the vendor BSP and an attempt to mainline tqma7 board support. The module is used by many long life products, so it would be nice with upstream supported bootloader. So it's easier to update when secure boot and TPM 2.0 support improves. This patch focus on core bootloader features and not whistles & bells. I have successfully booted a 4.19 mainline kernel with this patch and a device tree patch series currently under review [1]. It compiles without warnings against 2019.01, there are a few checkpatch warnings left that I have not found a valid solution for.
Checkpatch does not like GPL-2.0+ and it results in a few:
WARNING: Missing or malformed SPDX-License-Identifier tag in line 1
Using grep I have found many lines in the current tree with the same SPDX line.
There are about 30 lines that I can refacture between the following two checkpatch warnings:
WARNING: Avoid unnecessary line continuations
WARNING: line over 80 characters
Not sure which warning should be preferred.
Any testing and/or review would be welcome.
[1] https://www.spinics.net/lists/devicetree/msg277129.html
Bruno Thomsen (1): board: tq mba7 tqma7d 1gb emmc support.
arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/cpu.c | 2 +- arch/arm/mach-imx/mx7/Kconfig | 9 + arch/arm/mach-imx/mx7/soc.c | 7 + board/tqc/common/Kconfig | 4 + board/tqc/common/Makefile | 10 + board/tqc/common/tqc_bb.h | 30 ++ board/tqc/common/tqc_emmc.c | 78 ++++ board/tqc/common/tqc_emmc.h | 12 + board/tqc/tqma7/Kconfig | 79 ++++ board/tqc/tqma7/MAINTAINERS | 8 + board/tqc/tqma7/Makefile | 9 + board/tqc/tqma7/README | 38 ++ board/tqc/tqma7/tqma7.c | 328 ++++++++++++++ board/tqc/tqma7/tqma7_mba7.c | 596 ++++++++++++++++++++++++++ board/tqc/tqma7/tqma7d.cfg | 68 +++ board/tqc/tqma7/tqma7d_ddr_1gb.cfg | 58 +++ board/tqc/tqma7/tqma7d_ddr_512mb.cfg | 58 +++ configs/tqma7d_1gb_mba7_mmc_defconfig | 50 +++ include/configs/tqma7.h | 426 ++++++++++++++++++ include/configs/tqma7_mba7.h | 35 ++ 21 files changed, 1905 insertions(+), 2 deletions(-) create mode 100644 board/tqc/common/Kconfig create mode 100644 board/tqc/common/Makefile create mode 100644 board/tqc/common/tqc_bb.h create mode 100644 board/tqc/common/tqc_emmc.c create mode 100644 board/tqc/common/tqc_emmc.h create mode 100644 board/tqc/tqma7/Kconfig create mode 100644 board/tqc/tqma7/MAINTAINERS create mode 100644 board/tqc/tqma7/Makefile create mode 100644 board/tqc/tqma7/README create mode 100644 board/tqc/tqma7/tqma7.c create mode 100644 board/tqc/tqma7/tqma7_mba7.c create mode 100644 board/tqc/tqma7/tqma7d.cfg create mode 100644 board/tqc/tqma7/tqma7d_ddr_1gb.cfg create mode 100644 board/tqc/tqma7/tqma7d_ddr_512mb.cfg create mode 100644 configs/tqma7d_1gb_mba7_mmc_defconfig create mode 100644 include/configs/tqma7.h create mode 100644 include/configs/tqma7_mba7.h

Add TQMa7D SoM support when mounted on MBa7 evaluation board.
Signed-off-by: Bruno Thomsen bruno.thomsen@gmail.com --- arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/cpu.c | 2 +- arch/arm/mach-imx/mx7/Kconfig | 9 + arch/arm/mach-imx/mx7/soc.c | 7 + board/tqc/common/Kconfig | 4 + board/tqc/common/Makefile | 10 + board/tqc/common/tqc_bb.h | 30 ++ board/tqc/common/tqc_emmc.c | 78 ++++ board/tqc/common/tqc_emmc.h | 12 + board/tqc/tqma7/Kconfig | 79 ++++ board/tqc/tqma7/MAINTAINERS | 8 + board/tqc/tqma7/Makefile | 9 + board/tqc/tqma7/README | 38 ++ board/tqc/tqma7/tqma7.c | 328 ++++++++++++++ board/tqc/tqma7/tqma7_mba7.c | 596 ++++++++++++++++++++++++++ board/tqc/tqma7/tqma7d.cfg | 68 +++ board/tqc/tqma7/tqma7d_ddr_1gb.cfg | 58 +++ board/tqc/tqma7/tqma7d_ddr_512mb.cfg | 58 +++ configs/tqma7d_1gb_mba7_mmc_defconfig | 50 +++ include/configs/tqma7.h | 426 ++++++++++++++++++ include/configs/tqma7_mba7.h | 35 ++ 21 files changed, 1905 insertions(+), 2 deletions(-) create mode 100644 board/tqc/common/Kconfig create mode 100644 board/tqc/common/Makefile create mode 100644 board/tqc/common/tqc_bb.h create mode 100644 board/tqc/common/tqc_emmc.c create mode 100644 board/tqc/common/tqc_emmc.h create mode 100644 board/tqc/tqma7/Kconfig create mode 100644 board/tqc/tqma7/MAINTAINERS create mode 100644 board/tqc/tqma7/Makefile create mode 100644 board/tqc/tqma7/README create mode 100644 board/tqc/tqma7/tqma7.c create mode 100644 board/tqc/tqma7/tqma7_mba7.c create mode 100644 board/tqc/tqma7/tqma7d.cfg create mode 100644 board/tqc/tqma7/tqma7d_ddr_1gb.cfg create mode 100644 board/tqc/tqma7/tqma7d_ddr_512mb.cfg create mode 100644 configs/tqma7d_1gb_mba7_mmc_defconfig create mode 100644 include/configs/tqma7.h create mode 100644 include/configs/tqma7_mba7.h
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 8631fbd481..0335c0e8db 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -46,7 +46,7 @@ config SECURE_BOOT config CMD_BMODE bool "Support the 'bmode' command" default y - depends on ARCH_MX6 || ARCH_MX5 + depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5 help This enables the 'bmode' (bootmode) command for forcing a boot from specific media. diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 6b83f92662..113f228c86 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -251,7 +251,7 @@ int cpu_eth_init(bd_t *bis) { int rc = -ENODEV;
-#if defined(CONFIG_FEC_MXC) +#if defined(CONFIG_FEC_MXC) && defined(CONFIG_FEC_MXC_PHYADDR) rc = fecmxc_initialize(bis); #endif
diff --git a/arch/arm/mach-imx/mx7/Kconfig b/arch/arm/mach-imx/mx7/Kconfig index 232f33285d..dfe1bedd3f 100644 --- a/arch/arm/mach-imx/mx7/Kconfig +++ b/arch/arm/mach-imx/mx7/Kconfig @@ -60,6 +60,14 @@ config TARGET_COLIBRI_IMX7 select DM_THERMAL imply CMD_DM
+config TARGET_TQMA7 + bool "tqma7" + select MX7D + select TQMA7 + select DM + select DM_THERMAL + select TQC_EMMC + endchoice
config SYS_SOC @@ -70,5 +78,6 @@ source "board/freescale/mx7dsabresd/Kconfig" source "board/technexion/pico-imx7d/Kconfig" source "board/toradex/colibri_imx7/Kconfig" source "board/warp7/Kconfig" +source "board/tqc/tqma7/Kconfig"
endif diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c index 7cfdff0981..f4d697daea 100644 --- a/arch/arm/mach-imx/mx7/soc.c +++ b/arch/arm/mach-imx/mx7/soc.c @@ -8,6 +8,7 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> +#include <asm/mach-imx/boot_mode.h> #include <asm/mach-imx/dma.h> #include <asm/mach-imx/hab.h> #include <asm/mach-imx/rdc-sema.h> @@ -128,6 +129,12 @@ struct imx_sec_config_fuse_t const imx_sec_config_fuse = { }; #endif
+#if defined(CONFIG_CMD_BMODE) +const struct boot_mode soc_boot_modes[] = { + {NULL, 0}, +}; +#endif + static bool is_mx7d(void) { struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; diff --git a/board/tqc/common/Kconfig b/board/tqc/common/Kconfig new file mode 100644 index 0000000000..6d77ad6052 --- /dev/null +++ b/board/tqc/common/Kconfig @@ -0,0 +1,4 @@ + +config TQC_EMMC + bool + default n diff --git a/board/tqc/common/Makefile b/board/tqc/common/Makefile new file mode 100644 index 0000000000..d2f34f88db --- /dev/null +++ b/board/tqc/common/Makefile @@ -0,0 +1,10 @@ +# +# Copyright (C) 2016, Markus Niebel Markus.Niebel@tq-group.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +# necessary to create built-in.o +obj- := __dummy__.o + +obj-$(CONFIG_TQC_EMMC) += tqc_emmc.o diff --git a/board/tqc/common/tqc_bb.h b/board/tqc/common/tqc_bb.h new file mode 100644 index 0000000000..d84d799c3b --- /dev/null +++ b/board/tqc/common/tqc_bb.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2013, 2014, 2016 TQ Systems + * Author: Markus Niebel markus.niebel@tq-group.com + */ + +#ifndef __TQC_BB__ +#define __TQC_BB__ + +#include <common.h> + +int tqc_bb_board_mmc_getwp(struct mmc *mmc); +int tqc_bb_board_mmc_getcd(struct mmc *mmc); +int tqc_bb_board_mmc_init(bd_t *bis); + +int tqc_bb_board_early_init_f(void); +int tqc_bb_board_init(void); +int tqc_bb_board_late_init(void); +int tqc_bb_checkboard(void); + +const char *tqc_bb_get_boardname(void); + +/* + * Device Tree Support + */ +#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) +void tqc_bb_ft_board_setup(void *blob, bd_t *bd); +#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */ + +#endif diff --git a/board/tqc/common/tqc_emmc.c b/board/tqc/common/tqc_emmc.c new file mode 100644 index 0000000000..a75e0c7d23 --- /dev/null +++ b/board/tqc/common/tqc_emmc.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 TQ Systems GmbH + * Markus Niebel Markus.Niebel@tq-group.com + */ + +#include <common.h> +#include <fdt_support.h> +#include <mmc.h> + +#include "tqc_emmc.h" + +struct emmc_dsr_lookup { + uint mfgid; + char *pnm; + int dsr_needed; +}; + +static const struct emmc_dsr_lookup dsr_tbl[] = { + /* Micron, e-MMC 4.41 */ + { 0xfe, "MMC02G", 1 }, + { 0xfe, "MMC04G", 1 }, + { 0xfe, "MMC08G", 1 }, + /* Micron, e-MMC 5.0 4 GB*/ + { 0x13, "Q1J54A", 1 }, + { 0x13, "Q2J54A", 1 }, + /* Micron, e-MMC 5.0 8 GB*/ + { 0x13, "Q2J55L", 0 }, + /* Samsung, e-MMC 5.0 */ + { 0x15, "8GSD3R", 0 }, + { 0x15, "AGSD3R", 0 }, + { 0x15, "BGSD3R", 0 }, + { 0x15, "CGSD3R", 0 }, + /* SanDisk, iNAND 7250 5.1 */ + { 0x45, "DG4008", 0 }, + { 0x45, "DG4016", 0 }, + { 0x45, "DG4032", 0 }, + { 0x45, "DG4064", 0 }, + /* Kingston TBD. */ + { 0x100, "?????", 0 }, +}; + +int tqc_emmc_need_dsr(struct mmc *mmc) +{ + uint mfgid = mmc->cid[0] >> 24; + char name[7]; + unsigned int i; + int ret = -1; + + if (IS_SD(mmc)) + return 0; + + sprintf(name, "%c%c%c%c%c%c", mmc->cid[0] & 0xff, (mmc->cid[1] >> 24), + (mmc->cid[1] >> 16) & 0xff, (mmc->cid[1] >> 8) & 0xff, + mmc->cid[1] & 0xff, (mmc->cid[2] >> 24)); + + for (i = 0; i < ARRAY_SIZE(dsr_tbl) && (ret < 0); ++i) { + if (dsr_tbl[i].mfgid == mfgid && + !strncmp(name, dsr_tbl[i].pnm, 6)) { + ret = dsr_tbl[i].dsr_needed; + debug("MFG: %x PNM: %s\n", mfgid, name); + } + } + + if (ret < 0) { + printf("e-MMC unknown: MFG: %x PNM: %s\n", mfgid, name); + /* request DSR, even if not known if supported to be safe */ + ret = 1; + } + + return ret; +} + +int tqc_ft_fixup_emmc_dsr(void *blob, const char *path, u32 value) +{ + do_fixup_by_path_u32(blob, path, "dsr", value, 1); + return 0; +} diff --git a/board/tqc/common/tqc_emmc.h b/board/tqc/common/tqc_emmc.h new file mode 100644 index 0000000000..8b40d2887d --- /dev/null +++ b/board/tqc/common/tqc_emmc.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2017 TQ Systems GmbH + * Markus Niebel Markus.Niebel@tq-group.com + */ +#ifndef __TQC_EMMC_H__ +#define __TQC_EMMC_H__ + +int tqc_emmc_need_dsr(struct mmc *mmc); +int tqc_ft_fixup_emmc_dsr(void *blob, const char *path, u32 value); + +#endif /* __TQC_EMMC_H__ */ diff --git a/board/tqc/tqma7/Kconfig b/board/tqc/tqma7/Kconfig new file mode 100644 index 0000000000..76338c8d3e --- /dev/null +++ b/board/tqc/tqma7/Kconfig @@ -0,0 +1,79 @@ +if TARGET_TQMA7 + +config SYS_BOARD + default "tqma7" + +config SYS_VENDOR + default "tqc" + +config SYS_SOC + default "mx7" + +config SYS_CONFIG_NAME + default "tqma7" + +config TQMA7 + bool + select MX7D + select SPI_FLASH_STMICRO if SPI_FLASH + select SPI_FLASH_WINBOND if SPI_FLASH + select SPI_FLASH_SPANSION if SPI_FLASH + select SPI_FLASH_MTD if SPI_FLASH + select SPI_FLASH_BAR if SPI_FLASH + +choice + prompt "TQMa7 boot configuration" + default TQMA7_MMC_BOOT + help + Configure boot device. This is also used to implement environment + location. + +config TQMA7_MMC_BOOT + bool "MMC / SD Boot" + help + Boot from eMMC / SD Card. + +config TQMA7_QSPI_BOOT + bool "QSPI NOR Boot" + help + Boot from on board QSPI NOR flash. + +endchoice + + +choice + prompt "TQMa7 DRAM configuration" + default TQMA7_512MB + help + Configure DRAM size. + +config TQMA7_512MB + bool "512 MB DRAM" + help + configure for variant with 512 MB DRAM. + +config TQMA7_1GB + bool "1 GB DRAM" + help + configure for variant with 1 GB DRAM. + +endchoice + + +choice + prompt "TQMa7 base board variant" + default MBA7 + +config MBA7 + bool "TQMa7 on MBa7 Starterkit" + help + Select the MBa7 starterkit. + +endchoice + +config IMX_CONFIG + default "board/tqc/tqma7/tqma7d.cfg" + +source "board/tqc/common/Kconfig" + +endif diff --git a/board/tqc/tqma7/MAINTAINERS b/board/tqc/tqma7/MAINTAINERS new file mode 100644 index 0000000000..dcf0b88817 --- /dev/null +++ b/board/tqc/tqma7/MAINTAINERS @@ -0,0 +1,8 @@ +TQ SYSTEMS TQMA7 BOARD +M: Markus Niebel Markus.Niebel@tq-group.com +R: Bruno Thomsen bruno.thomsen@gmail.com +S: Maintained +F: board/tqc/tqma7/* +F: include/configs/tqma7.h +F: include/configs/tqma7_*.h +F: configs/tqma7*_defconfig diff --git a/board/tqc/tqma7/Makefile b/board/tqc/tqma7/Makefile new file mode 100644 index 0000000000..048205f121 --- /dev/null +++ b/board/tqc/tqma7/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2016, Markus Niebel Markus.Niebel@tq-group.com +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := tqma7.o + +obj-$(CONFIG_MBA7) += tqma7_mba7.o diff --git a/board/tqc/tqma7/README b/board/tqc/tqma7/README new file mode 100644 index 0000000000..be5313aa8b --- /dev/null +++ b/board/tqc/tqma7/README @@ -0,0 +1,38 @@ +U-Boot for the TQ Systems TQMa7x modules + +This file contains information for the port of +U-Boot to the TQ Systems TQMa7x modules. + +1. Boot source +-------------- + +The following boot source is supported: + +- SD/eMMC +- QSPI NOR (work in progress) + +2. Building +------------ + +To build U-Boot for the TQ Systems TQMa6 modules: + + make tqma7d_<dram>_<baseboard>_<boot>_defconfig + make + +dram is a placeholder for the DRAM size +512mb +1gb + +baseboard is a placeholder for the mainboard to compile for +mba7 + +boot is a placeholder for the boot device +mmc - means eMMC +qspi - mean QSPI NOR + +This gives the following configurations: + +tqma7d_512mb_mba7_mmc_defconfig (work in progress) +tqma7d_1gb_mba7_mmc_defconfig +tqma7d_512mb_mba7_qspi_defconfig (work in progress) +tqma7d_1gb_mba7_qspi_defconfig (work in progress) diff --git a/board/tqc/tqma7/tqma7.c b/board/tqc/tqma7/tqma7.c new file mode 100644 index 0000000000..7adef79f9a --- /dev/null +++ b/board/tqc/tqma7/tqma7.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016-2018 TQ Systems GmbH + * Author: Markus Niebel Markus.Niebel@tq-group.com + * Copyright (C) 2019 Bruno Thomsen bruno.thomsen@gmail.com + */ + +#include <asm/arch/clock.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/mx7-pins.h> +#include <asm/arch/sys_proto.h> +#include <linux/errno.h> +#include <asm/gpio.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/mxc_i2c.h> +#include <asm/mach-imx/spi.h> +#include <asm/io.h> +#include <common.h> +#include <fdt_support.h> +#include <fsl_esdhc.h> +#include <linux/libfdt.h> +#include <linux/sizes.h> +#include <i2c.h> +#include <mmc.h> +#include <miiphy.h> +#include <netdev.h> +#include <power/pfuze3000_pmic.h> +#include <power/pmic.h> +#if defined(CONFIG_FSL_QSPI) +#include <spi.h> +#include <spi_flash.h> +#endif + +#include "../common/tqc_bb.h" +#include "../common/tqc_emmc.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define USDHC_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \ + PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + +#define USDHC_CMD_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \ + PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + +#define USDHC_CLK_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_FAST | \ + PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + +/* HW Rev.0200, DDR50 */ +#define USDHC_CLK_PAD_CTRL_R0200 (PAD_CTL_DSE_3P3V_49OHM | \ + PAD_CTL_SRE_SLOW | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + +#define GPIO_IN_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | \ + PAD_CTL_DSE_3P3V_196OHM | PAD_CTL_HYS | PAD_CTL_SRE_SLOW) +#define GPIO_OUT_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | \ + PAD_CTL_DSE_3P3V_98OHM | PAD_CTL_HYS | PAD_CTL_SRE_SLOW) + +#define I2C_PAD_CTRL (PAD_CTL_DSE_3P3V_196OHM | PAD_CTL_SRE_FAST | \ + PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU100KOHM) + +#define QSPI_DATA_PAD_CTRL (PAD_CTL_PUS_PU47KOHM | PAD_CTL_PUE | \ + PAD_CTL_HYS | PAD_CTL_SRE_FAST | PAD_CTL_DSE_3P3V_98OHM) +#define QSPI_CLK_PAD_CTRL (PAD_CTL_PUS_PD100KOHM | PAD_CTL_PUE | \ + PAD_CTL_SRE_FAST | PAD_CTL_DSE_3P3V_49OHM) +#define QSPI_SS_PAD_CTRL (PAD_CTL_PUS_PU47KOHM | PAD_CTL_PUE | \ + PAD_CTL_SRE_SLOW | PAD_CTL_DSE_3P3V_196OHM) +#define QSPI_RST_PAD_CTRL (PAD_CTL_PUS_PU47KOHM | PAD_CTL_PUE | \ + PAD_CTL_SRE_FAST | PAD_CTL_DSE_3P3V_98OHM) + +static const u16 tqma7_emmc_dsr = 0x0100; + +int dram_init(void) +{ + gd->ram_size = PHYS_SDRAM_SIZE; + + return 0; +} + +/* eMMC on USDHCI3 always present */ +static iomux_v3_cfg_t const tqma7_usdhc3_pads[] = { + NEW_PAD_CTRL(MX7D_PAD_SD3_CLK__SD3_CLK, USDHC_CLK_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_CMD__SD3_CMD, USDHC_CMD_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_DATA0__SD3_DATA0, USDHC_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_DATA1__SD3_DATA1, USDHC_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_DATA2__SD3_DATA2, USDHC_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_DATA3__SD3_DATA3, USDHC_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_DATA4__SD3_DATA4, USDHC_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_DATA5__SD3_DATA5, USDHC_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_DATA6__SD3_DATA6, USDHC_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_DATA7__SD3_DATA7, USDHC_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD3_STROBE__SD3_STROBE, USDHC_PAD_CTRL), + /* eMMC reset */ + NEW_PAD_CTRL(MX7D_PAD_SD3_RESET_B__SD3_RESET_B, USDHC_PAD_CTRL), +}; + +static iomux_v3_cfg_t const tqma7_usdhc3_r0200_pads[] = { + NEW_PAD_CTRL(MX7D_PAD_SD3_CLK__SD3_CLK, USDHC_CLK_PAD_CTRL_R0200), +}; + +/* + * According to board_mmc_init() the following map is done: + * (U-boot device node) (Physical Port) + * mmc0 eMMC (SD3) on TQMa7 + * mmc1 .. n optional slots used on baseboard + */ +struct fsl_esdhc_cfg tqma7_usdhc_cfg = { + .esdhc_base = USDHC3_BASE_ADDR, + .max_bus_width = 8, +}; + +bool tqma7_emmc_needs_dsr(struct mmc *mmc) +{ + struct mmc *emmc = find_mmc_device(0); + + if (!emmc) { + puts("e-MMC: not present?\n"); + return false; + } + + if (mmc && emmc != mmc) + return false; + + if (!mmc && mmc_init(emmc)) { + puts("e-MMC: not present?\n"); + return false; + } + + return (tqc_emmc_need_dsr(emmc) > 0) ? true : false; +} + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC3_BASE_ADDR) + /* eMMC/uSDHC3 is always present */ + ret = 1; + else + ret = tqc_bb_board_mmc_getcd(mmc); + + return ret; +} + +int board_mmc_getwp(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC3_BASE_ADDR) + /* eMMC/uSDHC3 is always present */ + ret = 0; + else + ret = tqc_bb_board_mmc_getwp(mmc); + + return ret; +} + +int board_mmc_init(bd_t *bis) +{ + imx_iomux_v3_setup_multiple_pads(tqma7_usdhc3_pads, + ARRAY_SIZE(tqma7_usdhc3_pads)); + tqma7_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + if (fsl_esdhc_initialize(bis, &tqma7_usdhc_cfg)) + puts("Warning: failed to initialize eMMC dev\n"); + + tqc_bb_board_mmc_init(bis); + + return 0; +} + +/* board-specific MMC card detection / modification */ +void board_mmc_detect_card_type(struct mmc *mmc) +{ + if (tqma7_emmc_needs_dsr(mmc) > 0) + mmc_set_dsr(mmc, tqma7_emmc_dsr); + else + imx_iomux_v3_setup_multiple_pads(tqma7_usdhc3_r0200_pads, + ARRAY_SIZE(tqma7_usdhc3_r0200_pads)); +} + +static iomux_v3_cfg_t const tqma7_quadspi_pads[] = { + MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0 | MUX_PAD_CTRL(QSPI_DATA_PAD_CTRL), + MX7D_PAD_EPDC_DATA01__QSPI_A_DATA1 | MUX_PAD_CTRL(QSPI_DATA_PAD_CTRL), + MX7D_PAD_EPDC_DATA02__QSPI_A_DATA2 | MUX_PAD_CTRL(QSPI_DATA_PAD_CTRL), + MX7D_PAD_EPDC_DATA03__QSPI_A_DATA3 | MUX_PAD_CTRL(QSPI_DATA_PAD_CTRL), + MX7D_PAD_EPDC_DATA05__QSPI_A_SCLK | MUX_PAD_CTRL(QSPI_CLK_PAD_CTRL), + MX7D_PAD_EPDC_DATA06__QSPI_A_SS0_B | MUX_PAD_CTRL(QSPI_SS_PAD_CTRL), + MX7D_PAD_EPDC_DATA07__QSPI_A_SS1_B | MUX_PAD_CTRL(QSPI_SS_PAD_CTRL), + MX7D_PAD_EPDC_DATA04__GPIO2_IO4 | MUX_PAD_CTRL(QSPI_RST_PAD_CTRL) | + MUX_MODE_SION, +}; + +#define QSPI_RESET_GPIO IMX_GPIO_NR(2, 4) + +static void tqma7_setup_qspi(void) +{ + gpio_request(QSPI_RESET_GPIO, "qspi-rst#"); + gpio_direction_output(QSPI_RESET_GPIO, 1); + + /* Set the iomux */ + imx_iomux_v3_setup_multiple_pads(tqma7_quadspi_pads, + ARRAY_SIZE(tqma7_quadspi_pads)); + /* Set the clock */ + set_clk_qspi(); +} + +static struct i2c_pads_info tqma7_i2c1_pads = { + /* I2C1: on board LM75, M24C64, */ + .scl = { + .i2c_mode = NEW_PAD_CTRL(MX7D_PAD_I2C1_SCL__I2C1_SCL, + I2C_PAD_CTRL), + .gpio_mode = NEW_PAD_CTRL(MX7D_PAD_I2C1_SCL__GPIO4_IO8, + I2C_PAD_CTRL), + .gp = IMX_GPIO_NR(4, 8) + }, + .sda = { + .i2c_mode = NEW_PAD_CTRL(MX7D_PAD_I2C1_SDA__I2C1_SDA, + I2C_PAD_CTRL), + .gpio_mode = NEW_PAD_CTRL(MX7D_PAD_I2C1_SDA__GPIO4_IO9, + I2C_PAD_CTRL), + .gp = IMX_GPIO_NR(4, 9) + } +}; + +static void tqma7_setup_i2c(void) +{ + int ret; + + /* + * use logical index for bus, e.g. I2C1 -> 0 + * warn on error + */ + ret = setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, + &tqma7_i2c1_pads); + if (ret) + printf("setup I2C1 failed: %d\n", ret); +} + +int board_early_init_f(void) +{ + return tqc_bb_board_early_init_f(); +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + tqma7_setup_i2c(); + + tqma7_setup_qspi(); + + tqc_bb_board_init(); + + return 0; +} + +static const char *tqma7_get_boardname(void) +{ + u32 cpurev = get_cpu_rev(); + + switch ((cpurev & 0xFF000) >> 12) { + case MXC_CPU_MX7S: + return "TQMa7S"; + case MXC_CPU_MX7D: + return "TQMa7D"; + default: + return "??"; + }; +} + +/* setup board specific PMIC */ +int power_init_board(void) +{ + struct pmic *p; + u32 reg, rev; + + power_pfuze3000_init(0); + p = pmic_get("PFUZE3000"); + if (p && !pmic_probe(p)) { + pmic_reg_read(p, PFUZE3000_DEVICEID, ®); + pmic_reg_read(p, PFUZE3000_REVID, &rev); + printf("PMIC: PFUZE3000 ID=0x%02x REV=0x%02x\n", reg, rev); + } + + return 0; +} + +static const struct boot_mode tqma7_board_boot_modes[] = { + /* 4 bit bus width */ + {"sd1", MAKE_CFGVAL(0x10, 0x12, 0x00, 0x00)}, + {"emmc", MAKE_CFGVAL(0x10, 0x2a, 0x00, 0x00)}, + {"qspi", MAKE_CFGVAL(0x00, 0x40, 0x00, 0x00)}, + {NULL, 0}, +}; + +int board_late_init(void) +{ + add_board_boot_modes(tqma7_board_boot_modes); + + tqc_bb_board_late_init(); + + return 0; +} + +u32 get_board_rev(void) +{ + return tqma7_emmc_needs_dsr(0) ? 100 : 200; +} + +int checkboard(void) +{ + printf("Board: %s rev 0%u on %s\n", tqma7_get_boardname(), + get_board_rev(), tqc_bb_get_boardname()); + return 0; +} + +int board_get_rtc_bus(void) +{ + return 0; +} + +int board_get_dtt_bus(void) +{ + return 0; +} diff --git a/board/tqc/tqma7/tqma7_mba7.c b/board/tqc/tqma7/tqma7_mba7.c new file mode 100644 index 0000000000..59902a14a1 --- /dev/null +++ b/board/tqc/tqma7/tqma7_mba7.c @@ -0,0 +1,596 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016-2018 TQ Systems GmbH + * Author: Markus Niebel Markus.Niebel@tq-group.com + * Copyright (C) 2019 Bruno Thomsen bruno.thomsen@gmail.com + */ + +#include <asm/arch/clock.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/mx7-pins.h> +#include <asm/arch/sys_proto.h> +#include <linux/errno.h> +#include <asm/gpio.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/mach-imx/spi.h> +#include <asm/io.h> +#include <common.h> +#include <fsl_esdhc.h> +#include <linux/libfdt.h> +#include <linux/sizes.h> +#include <malloc.h> +#include <miiphy.h> +#include <mmc.h> +#include <netdev.h> +#include <pca953x.h> +#include <usb.h> + +#include "../common/tqc_bb.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_RX_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | \ + PAD_CTL_PUS_PU100KOHM | PAD_CTL_PUE | PAD_CTL_HYS | PAD_CTL_SRE_SLOW) + +#define UART_TX_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | \ + PAD_CTL_PUS_PU100KOHM | PAD_CTL_PUE | PAD_CTL_SRE_SLOW) + +#define USDHC_DATA_PAD_CTRL (PAD_CTL_DSE_3P3V_98OHM | \ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + +#define USDHC_CMD_PAD_CTRL (USDHC_DATA_PAD_CTRL) + +#define USDHC_CLK_PAD_CTRL (PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_SRE_SLOW | \ + PAD_CTL_PUE | PAD_CTL_PUS_PU47KOHM) + +/* output of MIC2016 is open drain */ +#define USB_OC_PAD_CTRL (PAD_CTL_PUS_PU47KOHM | \ + PAD_CTL_DSE_3P3V_32OHM | PAD_CTL_HYS | PAD_CTL_SRE_SLOW) + +#define GPIO_IN_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | \ + PAD_CTL_DSE_3P3V_196OHM | PAD_CTL_HYS | PAD_CTL_SRE_SLOW) + +#define GPIO_OUT_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | \ + PAD_CTL_DSE_3P3V_196OHM | PAD_CTL_HYS | PAD_CTL_SRE_FAST) + +#define I2C_PAD_CTRL (PAD_CTL_DSE_3P3V_196OHM | PAD_CTL_SRE_FAST | \ + PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PUS_PU100KOHM) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | PAD_CTL_PUE | \ + PAD_CTL_SRE_FAST | PAD_CTL_DSE_3P3V_49OHM) +#define ENET_TX_PAD_CTRL (ENET_PAD_CTRL) +#define ENET_RX_PAD_CTRL (ENET_PAD_CTRL | PAD_CTL_HYS) +#define ENET_PAD_CTRL_MDC (PAD_CTL_DSE_3P3V_196OHM) +#define ENET_PAD_CTRL_MDIO (PAD_CTL_DSE_3P3V_98OHM) +#define ENET_RST_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | PAD_CTL_PUE | \ + PAD_CTL_DSE_3P3V_196OHM | PAD_CTL_SRE_FAST) + +#define WDOG_PAD_CTRL (PAD_CTL_PUS_PU5KOHM | PAD_CTL_PUE | \ + PAD_CTL_SRE_FAST | PAD_CTL_DSE_3P3V_196OHM) + +static iomux_v3_cfg_t const mba7_fec1_pads[] = { + MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + + MX7D_PAD_GPIO1_IO10__ENET1_MDIO | \ + MUX_PAD_CTRL(ENET_PAD_CTRL_MDIO), + MX7D_PAD_GPIO1_IO11__ENET1_MDC | \ + MUX_PAD_CTRL(ENET_PAD_CTRL_MDC), + /* PHY reset */ + MX7D_PAD_ENET1_COL__GPIO7_IO15 | \ + MUX_PAD_CTRL(ENET_RST_PAD_CTRL) | MUX_MODE_SION, + /* INT/PWDN */ + MX7D_PAD_GPIO1_IO09__GPIO1_IO9 | \ + MUX_PAD_CTRL(GPIO_OUT_PAD_CTRL) | MUX_MODE_SION, +}; + +#define ENET1_PHY_RESET_GPIO IMX_GPIO_NR(7, 15) +#define ENET1_PHY_INT_GPIO IMX_GPIO_NR(1, 9) + +static iomux_v3_cfg_t const mba7_fec2_pads[] = { + MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC | \ + MUX_PAD_CTRL(ENET_RX_PAD_CTRL), + MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC | \ + MUX_PAD_CTRL(ENET_TX_PAD_CTRL), + + MX7D_PAD_SD2_CD_B__ENET2_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL_MDIO), + MX7D_PAD_SD2_WP__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL_MDC), + + /* PHY reset */ + MX7D_PAD_EPDC_BDR0__GPIO2_IO28 | MUX_PAD_CTRL(ENET_RST_PAD_CTRL) | + MUX_MODE_SION, + /* INT/PWDN */ + MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 | MUX_PAD_CTRL(GPIO_OUT_PAD_CTRL) | + MUX_MODE_SION, +}; + +#define ENET2_PHY_RESET_GPIO IMX_GPIO_NR(2, 28) +#define ENET2_PHY_INT_GPIO IMX_GPIO_NR(2, 31) + +static void mba7_setup_iomuxc_enet(void) +{ + imx_iomux_v3_setup_multiple_pads(mba7_fec1_pads, + ARRAY_SIZE(mba7_fec1_pads)); + + gpio_request(ENET1_PHY_RESET_GPIO, "enet1-phy-rst#"); + gpio_request(ENET1_PHY_INT_GPIO, "enet1-phy-intpwdn"); + gpio_direction_output(ENET1_PHY_INT_GPIO, 1); + /* Reset PHY */ + gpio_direction_output(ENET1_PHY_RESET_GPIO, 0); + udelay(100); + gpio_set_value(ENET1_PHY_RESET_GPIO, 1); + udelay(500); + + if (is_cpu_type(MXC_CPU_MX7D)) { + imx_iomux_v3_setup_multiple_pads(mba7_fec2_pads, + ARRAY_SIZE(mba7_fec2_pads)); + gpio_request(ENET2_PHY_RESET_GPIO, "enet2-phy-rst#"); + gpio_request(ENET2_PHY_INT_GPIO, "enet2-phy-intpwdn"); + gpio_direction_output(ENET2_PHY_INT_GPIO, 1); + /* Reset PHY */ + gpio_direction_output(ENET2_PHY_RESET_GPIO, 0); + udelay(100); + gpio_set_value(ENET2_PHY_RESET_GPIO, 1); + udelay(500); + } else { + gpio_request(ENET2_PHY_RESET_GPIO, "enet2-reserved0"); + gpio_request(ENET2_PHY_INT_GPIO, "enet2-reserved1"); + gpio_direction_output(ENET2_PHY_INT_GPIO, 0); + gpio_direction_output(ENET2_PHY_RESET_GPIO, 0); + } +} + +static const u32 fec_base[] = { + ENET_IPS_BASE_ADDR, + ENET2_IPS_BASE_ADDR +}; + +static const u32 phy_addr[] = { + TQMA7_ENET1_PHYADDR, + TQMA7_ENET2_PHYADDR +}; + +int board_eth_init(bd_t *bis) +{ + int ret; + int i; + int count = (is_cpu_type(MXC_CPU_MX7D)) ? ARRAY_SIZE(fec_base) : 1; + + struct mii_dev *bus = NULL; + struct phy_device *phydev = NULL; + + for (i = 0; i < count; ++i) { + bus = fec_get_miibus(fec_base[i], i); + if (!bus) + goto err_bus; + /* scan phy */ + phydev = phy_find_by_mask(bus, (0x1 << phy_addr[i]), + PHY_INTERFACE_MODE_RGMII_ID); + if (!phydev) + goto err_phydev; + ret = fec_probe(bis, i, fec_base[i], bus, phydev); + if (ret) + goto err_fec; + continue; + +err_fec: + free(phydev); +err_phydev: + free(bus); +err_bus: + printf("Error init FEC%d\n", i); + } + + return 0; +} + +static int mba7_setup_fec(int fec_id) +{ + struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs + = (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + int ret; + + switch (fec_id) { + case 0: + /* Use 125M anatop REF_CLK1 for ENET1, + * clear gpr1[13], gpr1[17] + */ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + (IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK | + IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK), 0); + break; + case 1: + /* Use 125M anatop REF_CLK2 for ENET2, + * clear gpr1[14], gpr1[18] + */ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + (IOMUXC_GPR_GPR1_GPR_ENET2_TX_CLK_SEL_MASK | + IOMUXC_GPR_GPR1_GPR_ENET2_CLK_DIR_MASK), 0); + break; + default: + printf("FEC%d: unsupported\n", fec_id); + return -1; + } + + ret = set_clk_enet(ENET_125MHZ); + if (ret) + return ret; + + return 0; +} + +#define DP83867_DEVADDR 0x1f + +/* TODO: needed here until we have DT init */ + +#define MBA7_DP83867_RGMII_TX_DELAY_CTRL 0x09 /* 0b1001 = 2,5 ns */ +#define MBA7_DP83867_RGMII_RX_DELAY_CTRL 0x09 /* 0b1001 = 2,5 ns */ + +/* Extended Registers */ +#define DP83867_RGMIICTL 0x0032 +#define DP83867_RGMIIDCTL 0x0086 + +/* RGMIIDCTL bits */ +#define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4 + +/* RGMIICTL bits */ +#define DP83867_RGMII_TX_CLK_DELAY_EN BIT(1) +#define DP83867_RGMII_RX_CLK_DELAY_EN BIT(0) + +int board_phy_config(struct phy_device *phydev) +{ + u32 val; + + if (phydev->drv->config) + phydev->drv->config(phydev); + + /* + * LED configuration: + * LED1: Link / Activity + * LED2: error + */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x18, 0x0db0); + /* active low, LED1/2 driven by phy */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x19, 0x1001); + + if (!phydev->drv || + !phydev->drv->writeext || !phydev->drv->readext) { + puts("PHY does not have extended functions\n"); + return 0; + } + + /* set GPIO to out low */ + phydev->drv->writeext(phydev, phydev->addr, DP83867_DEVADDR, + 0x0171, 0x8888); + phydev->drv->writeext(phydev, phydev->addr, DP83867_DEVADDR, + 0x0172, 0x8888); + + val = phydev->drv->readext(phydev, phydev->addr, DP83867_DEVADDR, + DP83867_RGMIICTL); + val |= (DP83867_RGMII_TX_CLK_DELAY_EN | + DP83867_RGMII_RX_CLK_DELAY_EN); + + phydev->drv->writeext(phydev, phydev->addr, DP83867_DEVADDR, + DP83867_RGMIICTL, val); + + val = ((MBA7_DP83867_RGMII_RX_DELAY_CTRL) | + (MBA7_DP83867_RGMII_TX_DELAY_CTRL << + DP83867_RGMII_TX_CLK_DELAY_SHIFT)); + + phydev->drv->writeext(phydev, phydev->addr, DP83867_DEVADDR, + DP83867_RGMIIDCTL, val); + + return 0; +} + +/*! + * @brief HW_PMU_REG_HSIC_1P2 - Anadig 1.2V HSIC Regulator Control Register RW + * + * Reset value: 0x00001878U + * + * This register defines the control and status bits for the 1.1V regulator. + * This regulator is designed to power the digital portions of the + * analog cells. + */ +static inline void hsic_1p2_regulator_out(void) +{ + struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) + ANATOP_BASE_ADDR; + /* + * allow the GPC to override register settings. + * use ANATOP_BASE_ADDR which is 0x30360000 instead of + * PMU_BASE (0x30360200) + */ + writel(PMU_REG_HSIC_1P2_SET_OVERRIDE_MASK, \ + &ccm_anatop->reg_hsic_1p2_set); +} + +#define GPC_PGC_HSIC 0xd00 +#define GPC_PGC_CPU_MAPPING 0xec +#define GPC_PU_PGC_SW_PUP_REQ 0xf8 +#define BM_CPU_PGC_SW_PDN_PUP_REQ_USB_HSIC_PHY 0x10 +#define USB_HSIC_PHY_A7_DOMAIN 0x40 + +static int imx_set_usb_hsic_power(void) +{ + u32 reg; + u32 val; + + writel(1, GPC_IPS_BASE_ADDR + GPC_PGC_HSIC); + + reg = GPC_IPS_BASE_ADDR + GPC_PGC_CPU_MAPPING; + val = readl(reg); + val |= USB_HSIC_PHY_A7_DOMAIN; + writel(val, reg); + + hsic_1p2_regulator_out(); + + reg = GPC_IPS_BASE_ADDR + GPC_PU_PGC_SW_PUP_REQ; + val = readl(reg); + val |= BM_CPU_PGC_SW_PDN_PUP_REQ_USB_HSIC_PHY; + writel(val, reg); + + while ((readl(reg) & + BM_CPU_PGC_SW_PDN_PUP_REQ_USB_HSIC_PHY) != 0) + ; + + writel(0, GPC_IPS_BASE_ADDR + GPC_PGC_HSIC); + + return 0; +} + +iomux_v3_cfg_t const mba7_usb_otg1_pads[] = { + MX7D_PAD_GPIO1_IO04__USB_OTG1_OC | + MUX_PAD_CTRL(USB_OC_PAD_CTRL), + MX7D_PAD_GPIO1_IO05__GPIO1_IO5 | + MUX_PAD_CTRL(GPIO_OUT_PAD_CTRL), +}; + +iomux_v3_cfg_t const mba7_usb_otg2_pads[] = { + MX7D_PAD_GPIO1_IO06__USB_OTG2_OC | + MUX_PAD_CTRL(USB_OC_PAD_CTRL), + MX7D_PAD_GPIO1_IO07__GPIO1_IO7 | + MUX_PAD_CTRL(GPIO_OUT_PAD_CTRL), +}; + +/* + * Use gpio instead of PWR as log as he ehci driver does not support + * board specific polarity + */ +#define MBA7_OTG1_PWR_GPIO IMX_GPIO_NR(1, 5) +#define MBA7_OTG2_PWR_GPIO IMX_GPIO_NR(1, 7) + +static void mba7_setup_iomux_usb(void) +{ + int ret; + + imx_iomux_v3_setup_multiple_pads(mba7_usb_otg1_pads, + ARRAY_SIZE(mba7_usb_otg1_pads)); + ret = gpio_request(MBA7_OTG1_PWR_GPIO, "usb-otg1-pwr"); + if (!ret) + gpio_direction_output(MBA7_OTG1_PWR_GPIO, 0); + + imx_set_usb_hsic_power(); + + if (is_cpu_type(MXC_CPU_MX7S)) + return; + + imx_iomux_v3_setup_multiple_pads(mba7_usb_otg2_pads, + ARRAY_SIZE(mba7_usb_otg2_pads)); + ret = gpio_request(MBA7_OTG2_PWR_GPIO, "usb-otg2-pwr"); + if (!ret) + gpio_direction_output(MBA7_OTG2_PWR_GPIO, 0); +} + +/* + * Force phy mode to host for all supported boards + * supporting gadget mode needs an USB VID + */ +int board_usb_phy_mode(int port) +{ + return USB_INIT_HOST; +} + +int board_ehci_power(int port, int on) +{ + switch (port) { + case 0: + gpio_set_value(MBA7_OTG1_PWR_GPIO, on); + break; + case 1: + if (is_cpu_type(MXC_CPU_MX7S)) + return -ENODEV; + gpio_set_value(MBA7_OTG2_PWR_GPIO, on); + break; + case 2: + break; + default: + return -ENODEV; + } + return 0; +} + +static iomux_v3_cfg_t const mba7_uart6_pads[] = { + NEW_PAD_CTRL(MX7D_PAD_EPDC_DATA08__UART6_DCE_RX, UART_RX_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_EPDC_DATA09__UART6_DCE_TX, UART_TX_PAD_CTRL), +}; + +static void mba7_setup_iomuxc_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(mba7_uart6_pads, + ARRAY_SIZE(mba7_uart6_pads)); +} + +static iomux_v3_cfg_t const mba7_usdhc1_pads[] = { + NEW_PAD_CTRL(MX7D_PAD_SD1_CLK__SD1_CLK, USDHC_CLK_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD1_CMD__SD1_CMD, USDHC_CMD_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD1_DATA0__SD1_DATA0, USDHC_DATA_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD1_DATA1__SD1_DATA1, USDHC_DATA_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD1_DATA2__SD1_DATA2, USDHC_DATA_PAD_CTRL), + NEW_PAD_CTRL(MX7D_PAD_SD1_DATA3__SD1_DATA3, USDHC_DATA_PAD_CTRL), + /* CD */ + NEW_PAD_CTRL(MX7D_PAD_SD1_CD_B__GPIO5_IO0, GPIO_IN_PAD_CTRL), + /* WP */ + NEW_PAD_CTRL(MX7D_PAD_SD1_WP__GPIO5_IO1, GPIO_IN_PAD_CTRL), +}; + +#define USDHC1_CD_GPIO IMX_GPIO_NR(5, 0) +#define USDHC1_WP_GPIO IMX_GPIO_NR(5, 1) + +int tqc_bb_board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC1_BASE_ADDR) + ret = !gpio_get_value(USDHC1_CD_GPIO); + + return ret; +} + +int tqc_bb_board_mmc_getwp(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + if (cfg->esdhc_base == USDHC1_BASE_ADDR) + ret = gpio_get_value(USDHC1_WP_GPIO); + + return ret; +} + +static struct fsl_esdhc_cfg mba7_usdhc_cfg = { + .esdhc_base = USDHC1_BASE_ADDR, + .max_bus_width = 4, +}; + +int tqc_bb_board_mmc_init(bd_t *bis) +{ + imx_iomux_v3_setup_multiple_pads(mba7_usdhc1_pads, + ARRAY_SIZE(mba7_usdhc1_pads)); + gpio_request(USDHC1_CD_GPIO, "usdhc1-cd"); + gpio_request(USDHC1_WP_GPIO, "usdhc1-wp"); + gpio_direction_input(USDHC1_CD_GPIO); + gpio_direction_input(USDHC1_WP_GPIO); + + mba7_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + if (fsl_esdhc_initialize(bis, &mba7_usdhc_cfg)) + puts("Warning: failed to initialize SD\n"); + + return 0; +} + +int tqc_bb_board_early_init_f(void) +{ + mba7_setup_iomuxc_uart(); + + return 0; +} + +int tqc_bb_board_init(void) +{ + /* do it here - to have reset completed */ + mba7_setup_iomuxc_enet(); + mba7_setup_fec(0); + + if (!is_cpu_type(MXC_CPU_MX7S)) + mba7_setup_fec(1); + + mba7_setup_iomux_usb(); + + return 0; +} + +static iomux_v3_cfg_t const mba7_wdog_pads[] = { + NEW_PAD_CTRL(MX7D_PAD_GPIO1_IO00__WDOG1_WDOG_B, WDOG_PAD_CTRL), +}; + +int tqc_bb_board_late_init(void) +{ + imx_iomux_v3_setup_multiple_pads(mba7_wdog_pads, + ARRAY_SIZE(mba7_wdog_pads)); + set_wdog_reset((struct wdog_regs *)WDOG1_BASE_ADDR); + + return 0; +} + +const char *tqc_bb_get_boardname(void) +{ + return "MBa7"; +} + +int board_mmc_get_env_dev(int devno) +{ + int env_dev; + /* + * eMMC: USDHC3 -> 0 + * SD: USDHC1 -> 1 + */ + switch (devno) { + case 2: + env_dev = 0; + break; + case 0: + env_dev = 1; + break; + default: + printf("mmc boot dev %d not supported, use default", + devno); + env_dev = 0; + }; + + return env_dev; +} + +/* + * Device Tree Support + */ +#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) +void tqc_bb_ft_board_setup(void *blob, bd_t *bd) +{ +} +#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */ diff --git a/board/tqc/tqma7/tqma7d.cfg b/board/tqc/tqma7/tqma7d.cfg new file mode 100644 index 0000000000..8c578c3f68 --- /dev/null +++ b/board/tqc/tqma7/tqma7d.cfg @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Markus Niebel Markus.Niebel@tq-group.com + * + * Refer doc/README.imximage for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +/* image version */ +IMAGE_VERSION 2 + +#define __ASSEMBLY__ +#include <config.h> + +/* + * Boot Device : one of + * qspi, sd (the board has no nand neither onenand) + */ +#if defined(CONFIG_TQMA7_MMC_BOOT) +BOOT_FROM sd +#elif defined(CONFIG_TQMA7_QSPI_BOOT) +BOOT_FROM qspi +#endif + +#ifdef CONFIG_SECURE_BOOT +CSF CONFIG_CSF_SIZE +#endif + +/* TQMa7D DDR config */ + +/* + * Device Configuration Data (DCD) + * + * Each entry must have the format: + * Addr-type Address Value + * + * where: + * Addr-type register length (1,2 or 4 bytes) + * Address absolute address of the register + * value value to be stored in the register + */ + +/* IOMUXC_GPR_GPR1 */ +DATA 4 0x30340004 0x4F400005 + +/* Clear then set bit30 to ensure exit from DDR retention */ +DATA 4 0x30360388 0x40000000 +DATA 4 0x30360384 0x40000000 + +#if defined(CONFIG_TQMA7_512MB) +#include "tqma7d_ddr_512mb.cfg" +#elif defined(CONFIG_TQMA7_1GB) +#include "tqma7d_ddr_1gb.cfg" +#endif + +/* CCM_CCGRn */ +DATA 4 0x30384130 0x00000000 +/* IOMUXC_GPR_GPR8 */ +DATA 4 0x30340020 0x00000178 +/* CCM_CCGRn */ +DATA 4 0x30384130 0x00000002 +/* DDR_PHY_LP_CON0 */ +DATA 4 0x30790018 0x0000000f + +/* DDRC_STAT */ +CHECK_BITS_SET 4 0x307a0004 0x1 diff --git a/board/tqc/tqma7/tqma7d_ddr_1gb.cfg b/board/tqc/tqma7/tqma7d_ddr_1gb.cfg new file mode 100644 index 0000000000..b1f4736714 --- /dev/null +++ b/board/tqc/tqma7/tqma7d_ddr_1gb.cfg @@ -0,0 +1,58 @@ +/* TQMa7x DRAM Timing REV0100 */ +/* DCD Code i.MX7D/S 528 MHz 1 GByte Samsung K4B4G1646D */ +DATA 4 0x30360070 0x0070302C /* CCM_ANALOG_PLL_DDRx */ +DATA 4 0x30360090 0x00000000 /* CCM_ANALOG_PLL_NUM */ +DATA 4 0x30360070 0x0060302C /* CCM_ANALOG_PLL_DDRx */ +CHECK_BITS_SET 4 0x30360070 0x80000000 +DATA 4 0x30391000 0x00000002 /* SRC_DDRC_RCR */ +DATA 4 0x307a0000 0x01040001 /* DDRC_MSTR */ +DATA 4 0x307a01a0 0x80400003 /* DDRC_DFIUPD0 */ +DATA 4 0x307a01a4 0x00100020 /* DDRC_DFIUPD1 */ +DATA 4 0x307a01a8 0x80100004 /* DDRC_DFIUPD2 */ +DATA 4 0x307a0064 0x00200045 /* DDRC_RFSHTMG */ +DATA 4 0x307a0490 0x00000001 /* DDRC_MP_PCTRL_0 */ +DATA 4 0x307a00d0 0x00020081 /* DDRC_INIT0 */ +DATA 4 0x307a00d4 0x00680000 /* DDRC_INIT1 */ +DATA 4 0x307a00dc 0x09300004 /* DDRC_INIT3 */ +DATA 4 0x307a00e0 0x00480000 /* DDRC_INIT4 */ +DATA 4 0x307a00e4 0x00100004 /* DDRC_INIT5 */ +DATA 4 0x307a00f4 0x0000033F /* DDRC_RANKCTL */ +DATA 4 0x307a0100 0x090E0809 /* DDRC_DRAMTMG0 */ +DATA 4 0x307a0104 0x0007020E /* DDRC_DRAMTMG1 */ +DATA 4 0x307a0108 0x03040407 /* DDRC_DRAMTMG2 */ +DATA 4 0x307a010c 0x00002006 /* DDRC_DRAMTMG3 */ +DATA 4 0x307a0110 0x04020304 /* DDRC_DRAMTMG4 */ +DATA 4 0x307a0114 0x03030202 /* DDRC_DRAMTMG5 */ +DATA 4 0x307a0120 0x00000803 /* DDRC_DRAMTMG8 */ +DATA 4 0x307a0180 0x00800020 /* DDRC_ZQCTL0 */ +DATA 4 0x307a0190 0x02098204 /* DDRC_DFITMG0 */ +DATA 4 0x307a0194 0x00030303 /* DDRC_DFITMG1 */ +DATA 4 0x307a0200 0x00000016 /* DDRC_ADDRMAP0 */ +DATA 4 0x307a0204 0x00171717 /* DDRC_ADDRMAP1 */ +DATA 5 0x307a0210 0x00000F0F /* DDRC_ADDRMAP4 */ +DATA 4 0x307a0214 0x04040404 /* DDRC_ADDRMAP5 */ +DATA 4 0x307a0218 0x0F040404 /* DDRC_ADDRMAP6 */ +DATA 4 0x307a0240 0x06000604 /* DDRC_ODTCFG */ +DATA 4 0x307a0244 0x00000001 /* DDRC_ODTMAP */ +DATA 4 0x30391000 0x00000000 /* SRC_DDRC_RCR */ +DATA 4 0x30790000 0x17420F40 /* DDR_PHY_PHY_CON0 */ +DATA 4 0x30790004 0x10210100 /* DDR_PHY_PHY_CON1 */ +DATA 4 0x30790010 0x00060807 /* DDR_PHY_PHY_CON4 */ +DATA 4 0x307900b0 0x1010007E /* DDR_PHY_MDLL_CON0 */ +DATA 4 0x3079009c 0x00000924 /* DDR_PHY_DRVDS_CON0 */ +/* DDR_PHY_CMD_DESKEW_CON0 */ +/* DDR_PHY_CMD_DESKEW_CON1 */ +/* DDR_PHY_CMD_DESKEW_CON2 */ +/* DDR_PHY_CMD_DESKEW_CON3 */ +/* DDR_PHY_LVL_CON0 */ +DATA 4 0x30790020 0x0B0B0B0B /* DDR_PHY_OFFSET_RD_CON0 */ +DATA 4 0x30790030 0x06060606 /* DDR_PHY_OFFSET_WR_CON0 */ +DATA 4 0x30790050 0x01000010 /* DDR_PHY_CMD_SDLL_CON0 */ +DATA 4 0x30790050 0x00000010 /* DDR_PHY_CMD_SDLL_CON0 */ + +DATA 4 0x307900c0 0x0C407304 /* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0C447304 /* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0C447306 /* DDR_PHY_ZQ_CON0 */ +CHECK_BITS_SET 4 0x307900c4 0x1 /* ZQ Calibration is finished */ +DATA 4 0x307900c0 0x0C447304 /* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0C407304 /* DDR_PHY_ZQ_CON0 */ diff --git a/board/tqc/tqma7/tqma7d_ddr_512mb.cfg b/board/tqc/tqma7/tqma7d_ddr_512mb.cfg new file mode 100644 index 0000000000..79a5b18712 --- /dev/null +++ b/board/tqc/tqma7/tqma7d_ddr_512mb.cfg @@ -0,0 +1,58 @@ +/* TQMa7x DRAM Timing REV0100 */ +/* DCD Code i.MX7D/S 528 MHz 512 MByte Samsung K4B2G1646F */ +DATA 4 0x30360070 0x0070302C /* CCM_ANALOG_PLL_DDRx */ +DATA 4 0x30360090 0x00000000 /* CCM_ANALOG_PLL_NUM */ +DATA 4 0x30360070 0x0060302C /* CCM_ANALOG_PLL_DDRx */ +CHECK_BITS_SET 4 0x30360070 0x80000000 +DATA 4 0x30391000 0x00000002 /* SRC_DDRC_RCR */ +DATA 4 0x307a0000 0x01040001 /* DDRC_MSTR */ +DATA 4 0x307a01a0 0x80400003 /* DDRC_DFIUPD0 */ +DATA 4 0x307a01a4 0x00100020 /* DDRC_DFIUPD1 */ +DATA 4 0x307a01a8 0x80100004 /* DDRC_DFIUPD2 */ +DATA 4 0x307a0064 0x0020005B /* DDRC_RFSHTMG */ +DATA 4 0x307a0490 0x00000001 /* DDRC_MP_PCTRL_0 */ +DATA 4 0x307a00d0 0x00020081 /* DDRC_INIT0 */ +DATA 4 0x307a00d4 0x00680000 /* DDRC_INIT1 */ +DATA 4 0x307a00dc 0x09300004 /* DDRC_INIT3 */ +DATA 4 0x307a00e0 0x00480000 /* DDRC_INIT4 */ +DATA 4 0x307a00e4 0x00100004 /* DDRC_INIT5 */ +DATA 4 0x307a00f4 0x0000033F /* DDRC_RANKCTL */ +DATA 4 0x307a0100 0x090E0809 /* DDRC_DRAMTMG0 */ +DATA 4 0x307a0104 0x0007020E /* DDRC_DRAMTMG1 */ +DATA 4 0x307a0108 0x03040407 /* DDRC_DRAMTMG2 */ +DATA 4 0x307a010c 0x00002006 /* DDRC_DRAMTMG3 */ +DATA 4 0x307a0110 0x04020304 /* DDRC_DRAMTMG4 */ +DATA 4 0x307a0114 0x03030202 /* DDRC_DRAMTMG5 */ +DATA 4 0x307a0120 0x00000803 /* DDRC_DRAMTMG8 */ +DATA 4 0x307a0180 0x00800020 /* DDRC_ZQCTL0 */ +DATA 4 0x307a0190 0x02098204 /* DDRC_DFITMG0 */ +DATA 4 0x307a0194 0x00030303 /* DDRC_DFITMG1 */ +DATA 4 0x307a0200 0x00000015 /* DDRC_ADDRMAP0 */ +DATA 4 0x307a0204 0x00161616 /* DDRC_ADDRMAP1 */ +DATA 5 0x307a0210 0x00000F0F /* DDRC_ADDRMAP4 */ +DATA 4 0x307a0214 0x04040404 /* DDRC_ADDRMAP5 */ +DATA 4 0x307a0218 0x0F0F0404 /* DDRC_ADDRMAP6 */ +DATA 4 0x307a0240 0x06000604 /* DDRC_ODTCFG */ +DATA 4 0x307a0244 0x00000001 /* DDRC_ODTMAP */ +DATA 4 0x30391000 0x00000000 /* SRC_DDRC_RCR */ +DATA 4 0x30790000 0x17420F40 /* DDR_PHY_PHY_CON0 */ +DATA 4 0x30790004 0x10210100 /* DDR_PHY_PHY_CON1 */ +DATA 4 0x30790010 0x00060807 /* DDR_PHY_PHY_CON4 */ +DATA 4 0x307900b0 0x1010007E /* DDR_PHY_MDLL_CON0 */ +DATA 4 0x3079009c 0x00000924 /* DDR_PHY_DRVDS_CON0 */ +/* DDR_PHY_CMD_DESKEW_CON0 */ +/* DDR_PHY_CMD_DESKEW_CON1 */ +/* DDR_PHY_CMD_DESKEW_CON2 */ +/* DDR_PHY_CMD_DESKEW_CON3 */ +/* DDR_PHY_LVL_CON0 */ +DATA 4 0x30790020 0x0B0B0B0B /* DDR_PHY_OFFSET_RD_CON0 */ +DATA 4 0x30790030 0x06060606 /* DDR_PHY_OFFSET_WR_CON0 */ +DATA 4 0x30790050 0x01000010 /* DDR_PHY_CMD_SDLL_CON0 */ +DATA 4 0x30790050 0x00000010 /* DDR_PHY_CMD_SDLL_CON0 */ + +DATA 4 0x307900c0 0x0C407304 /* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0C447304 /* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0C447306 /* DDR_PHY_ZQ_CON0 */ +CHECK_BITS_SET 4 0x307900c4 0x1 /* ZQ Calibration is finished */ +DATA 4 0x307900c0 0x0C447304 /* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0C407304 /* DDR_PHY_ZQ_CON0 */ diff --git a/configs/tqma7d_1gb_mba7_mmc_defconfig b/configs/tqma7d_1gb_mba7_mmc_defconfig new file mode 100644 index 0000000000..97bbcbadb6 --- /dev/null +++ b/configs/tqma7d_1gb_mba7_mmc_defconfig @@ -0,0 +1,50 @@ +CONFIG_ARM=y +CONFIG_ARCH_MX7=y +CONFIG_SYS_TEXT_BASE=0xbfc00000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_TARGET_TQMA7=y +CONFIG_TQMA7_1GB=y +CONFIG_DEFAULT_FDT_FILE="imx7d-mba7.dtb" +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_DISPLAY_CPUINFO=y +# CONFIG_DM_GPIO is not set +# CONFIG_DM_MMC is not set +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_MEMINFO=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_I2C=y +# CONFIG_CMD_USB is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_CMD_GPIO is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_PING=y +CONFIG_CMD_TIME=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_MMC=y +CONFIG_CMD_TPM=y +CONFIG_CMD_TPM_V2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_FAT=y +CONFIG_CMD_MII=y +CONFIG_CMD_BMODE=y +CONFIG_CMD_BOOTZ=y +CONFIG_SYS_I2C_MXC=y +CONFIG_SYS_I2C_MXC_I2C1=y +CONFIG_SYS_I2C_MXC_I2C2=y +CONFIG_HUSH_PARSER=y +# CONFIG_DM_WARN is not set +# CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_DM_STDIO is not set +# CONFIG_DISK is not set +# CONFIG_SPI_FLASH is not set +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_FS_EXT4=y +CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FSL_ESDHC=y +CONFIG_OF_LIBFDT=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SUPPORT_EMMC_RPMB=y diff --git a/include/configs/tqma7.h b/include/configs/tqma7.h new file mode 100644 index 0000000000..3771914d4d --- /dev/null +++ b/include/configs/tqma7.h @@ -0,0 +1,426 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016-2018 TQ Systems GmbH + * Copyright (C) 2019 Bruno Thomsen bruno.thomsen@gmail.com + * Configuration settings for the TQ Systems TQMa7x SoM + */ + +#ifndef __TQMA7_CONFIG_H +#define __TQMA7_CONFIG_H + +#include <linux/kconfig.h> + +#include <asm/arch/imx-regs.h> +#include <asm/mach-imx/gpio.h> +#include <linux/sizes.h> +#include "mx7_common.h" + +#if defined(CONFIG_DISPLAY_BOARDINFO) +#undef CONFIG_DISPLAY_BOARDINFO +#endif +#define CONFIG_DISPLAY_BOARDINFO_LATE + +/* uncomment for SECURE mode support */ +/* #define CONFIG_SECURE_BOOT */ + +#ifdef CONFIG_SECURE_BOOT +#ifndef CONFIG_CSF_SIZE +#define CONFIG_CSF_SIZE 0x4000 +#endif +#endif + +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG +#define CONFIG_REVISION_TAG + +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_MXC_UART + +/* Allow overwrite of serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 + +/* I2C */ +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_SPEED 100000 + +/* PMIC */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_PFUZE3000 +#define CONFIG_POWER_PFUZE3000_I2C_ADDR 0x08 + +/* MMC Configs, other options from mx7_common */ +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 + +#if defined(CONFIG_TQMA7_512MB) +#define PHYS_SDRAM_SIZE SZ_512M +#elif defined(CONFIG_TQMA7_1GB) +#define PHYS_SDRAM_SIZE SZ_1G +#endif + +#define CONFIG_FEC_MXC +#define CONFIG_PHYLIB +#define CONFIG_MII + +#if !defined(CONFIG_SYS_BOOTM_LEN) || (CONFIG_SYS_BOOTM_LEN < SZ_16M) +#undef CONFIG_SYS_BOOTM_LEN +#define CONFIG_SYS_BOOTM_LEN SZ_16M +#endif + +#undef CONFIG_BOOTM_NETBSD +#undef CONFIG_BOOTM_PLAN9 +#undef CONFIG_BOOTM_RTEMS + +#if defined(CONFIG_LOADADDR) && (CONFIG_LOADADDR < 0x82000000) +#undef CONFIG_LOADADDR +#endif +#define CONFIG_LOADADDR 0x82000000 + +#define CONFIG_ENV_SIZE (SZ_8K) +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (32 * SZ_1M) + +/* + * above 128 MiB offset as in ARM related docu for linux suggested + * DTB is loaded at 128 MiB, so use just 16 MiB more + */ +#define TQMA7_INITRD_ADDRESS 0x89000000 + +#define TQMA7_MFG_ENV_SETTINGS \ + "mfgtool_args=setenv bootargs console=" CONSOLE_DEV ",115200 " \ + "rdinit=/linuxrc " \ + "g_mass_storage.stall=0 g_mass_storage.removable=1 " \ + "g_mass_storage.file=/fat g_mass_storage.ro=1 " \ + "g_mass_storage.idVendor=0x066F " \ + "g_mass_storage.idProduct=0x37FF " \ + "g_mass_storage.iSerialNumber="" " \ + "enable_wait_mode=off " \ + "\0" \ + "initrd_addr=" __stringify(TQMA7_INITRD_ADDRESS) "\0" \ + "initrd_high=0xffffffff\0" \ + "bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} " \ + "${initrd_addr} ${fdt_addr};\0" + +#if defined(CONFIG_TQMA7_MMC_BOOT) + +#define CONFIG_SYS_MMC_ENV_DEV -1 +#define TQMA7_UBOOT_OFFSET SZ_1K +#define TQMA7_UBOOT_SECTOR_START 0x2 +#define TQMA7_UBOOT_SECTOR_COUNT 0x7fe + +#define CONFIG_ENV_OFFSET SZ_1M + +#define TQMA7_EXTRA_BOOTDEV_ENV_SETTINGS \ + "uboot_start=" __stringify(TQMA7_UBOOT_SECTOR_START) "\0" \ + "uboot_size=" __stringify(TQMA7_UBOOT_SECTOR_COUNT) "\0" \ + "mmcdev=1\0" \ + "firmwarepart=1\0" \ + "loadimage=run kernel_name; " \ + "fatload mmc ${mmcdev}:${firmwarepart} " \ + "${loadaddr} ${kernel}\0" \ + "loadfdt=fatload mmc ${mmcdev}:${firmwarepart} " \ + "${fdt_addr} ${fdt_file}\0" \ + "update_uboot=run set_getcmd; " \ + "if ${getcmd} ${uboot}; then " \ + "if itest ${filesize} > 0; then " \ + "mmc dev ${mmcdev}; mmc rescan; " \ + "setexpr blkc ${filesize} + 0x1ff; " \ + "setexpr blkc ${blkc} / 0x200; " \ + "if itest ${blkc} <= ${uboot_size}; then " \ + "mmc write ${loadaddr} ${uboot_start} "\ + "${blkc}; " \ + "fi; " \ + "fi; " \ + "fi; " \ + "setenv filesize; setenv blkc; setenv getcmd \0" \ + "update_kernel=run kernel_name; run set_getcmd; " \ + "if ${getcmd} ${kernel}; then " \ + "if itest ${filesize} > 0; then " \ + "mmc dev ${mmcdev}; mmc rescan; " \ + "echo Write kernel image to mmc " \ + "${mmcdev}:${firmwarepart}...; " \ + "save mmc ${mmcdev}:${firmwarepart} " \ + "${loadaddr} ${kernel} ${filesize}; " \ + "fi; " \ + "fi; " \ + "setenv filesize; setenv getcmd \0" \ + "update_fdt=run set_getcmd; " \ + "if ${getcmd} ${fdt_file}; then " \ + "if itest ${filesize} > 0; then " \ + "mmc dev ${mmcdev}; mmc rescan; " \ + "echo Write fdt image to mmc "\ + "${mmcdev}:${firmwarepart}...; " \ + "save mmc ${mmcdev}:${firmwarepart} "\ + "${loadaddr} ${fdt_file} ${filesize}; "\ + "fi; " \ + "fi; " \ + "setenv filesize; setenv getcmd \0" + +#define CONFIG_BOOTCOMMAND \ + "run mmcboot; run netboot; run panicboot" + +#elif defined(CONFIG_TQMA7_QSPI_BOOT) + +#define TQMA7_SPI_FLASH_SECTOR_SIZE SZ_64K + +#define TQMA7_UBOOT_OFFSET SZ_4K +#define TQMA7_UBOOT_SECTOR_START 0x0 +/* max u-boot size: 832kiB */ +#define TQMA7_UBOOT_SECTOR_SIZE TQMA7_SPI_FLASH_SECTOR_SIZE +#define TQMA7_UBOOT_SECTOR_COUNT 13 +#define TQMA7_UBOOT_SIZE (TQMA7_UBOOT_SECTOR_SIZE * \ + TQMA7_UBOOT_SECTOR_COUNT) + +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_SYS_REDUNDAND_ENVIRONMENT +#define CONFIG_ENV_OFFSET (TQMA7_UBOOT_SIZE) +#define CONFIG_ENV_SECT_SIZE TQMA7_SPI_FLASH_SECTOR_SIZE +#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + \ + CONFIG_ENV_SECT_SIZE) + +#define CONFIG_ENV_SPI_BUS (CONFIG_SF_DEFAULT_BUS) +#define CONFIG_ENV_SPI_CS (CONFIG_SF_DEFAULT_CS) +#define CONFIG_ENV_SPI_MAX_HZ (CONFIG_SF_DEFAULT_SPEED) +#define CONFIG_ENV_SPI_MODE (CONFIG_SF_DEFAULT_MODE) + +#define TQMA7_EXTRA_BOOTDEV_ENV_SETTINGS \ + "mmcblkdev=1\0" \ + "update_uboot=run set_getcmd; if ${getcmd} ${uboot}; then " \ + "if itest ${filesize} > 0; then " \ + "sf probe 0; " \ + "sf update ${loadaddr} ${uboot_mtdpart} ${filesize}; " \ + "fi; fi; " \ + "setenv filesize; setenv getcmd \0" \ + "update_kernel=run kernel_name; run set_getcmd; " \ + "if ${getcmd} ${kernel}; then " \ + "if itest ${filesize} > 0; then " \ + "sf probe 0; " \ + "sf update ${loadaddr} ${kernel_mtdpart} " \ + "${filesize};" \ + "fi; fi; " \ + "setenv filesize; setenv getcmd; setenv kernel \0" \ + "update_fdt=run set_getcmd; if ${getcmd} ${fdt_file}; then " \ + "if itest ${filesize} > 0; then " \ + "sf probe 0; " \ + "sf update ${loadaddr} ${fdt_mtdpart} ${filesize}; " \ + "fi; fi; " \ + "setenv filesize; setenv getcmd \0" \ + "loadimage=sf probe 0; sf read ${loadaddr} ${kernel_mtdpart}\0" \ + "loadfdt=sf probe 0; sf read ${fdt_addr} ${fdt_mtdpart}\0" + +#define CONFIG_BOOTCOMMAND "sf probe; run qspiboot; run netboot; run panicboot" + +#else + +#error "need to define boot source" + +#endif + +#ifdef CONFIG_SYS_USE_QSPI +/* Set to QSPI1 A flash, offset 1M */ +#define CONFIG_SYS_AUXCORE_BOOTDATA 0x60100000 +#else +/* Set to TCML address */ +#define CONFIG_SYS_AUXCORE_BOOTDATA 0x7F8000 +#endif + +/* 128 MiB offset as in ARM related docu for linux suggested */ +#define TQMA7_FDT_ADDRESS 0x88000000 + +/* set to a resonable value, changeable by user */ +#define TQMA7_CMA_SIZE 32M + +#if defined(CONFIG_DEFAULT_FDT_FILE) +#define TQMA7_FDT_FILE_ENV "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" +#else +#define TQMA7_FDT_FILE_ENV +#endif + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "board=TQMa7D\0" \ + "boardtype=TQMa7D-AB.0201\0" \ + "boot_dev=mmc\0" \ + "ethact="FEC0"\0" \ + "fdt_file="imx7d-mba7.dtb"\0" \ + "uimage=uImage\0" \ + "zimage=linuximage\0" \ + "boot_type=bootz\0" \ + "kernel_name=if test "${boot_type}" != bootz; then " \ + "setenv kernel ${uimage}; " \ + "else setenv kernel ${zimage}; fi\0" \ + "uboot=u-boot.imx\0" \ + TQMA7_FDT_FILE_ENV \ + "fdt_addr=" __stringify(TQMA7_FDT_ADDRESS) "\0" \ + "console=" CONSOLE_DEV "\0" \ + "cma_size=" __stringify(TQMA7_CMA_SIZE) "\0" \ + "fdt_high=0xffffffff\0" \ + "initrd_high=0xffffffff\0" \ + "rootfsmode=ro\0" \ + "addcma=setenv bootargs ${bootargs} cma=${cma_size}\0" \ + "addtty=setenv bootargs ${bootargs} console=${console},${baudrate} " \ + "consoleblank=0\0" \ + "mmcpart=5\0" \ + "mmcblkdev=1\0" \ + "mmcargs=run addmmc addtty addcma\0" \ + "addmmc=setenv bootargs ${bootargs} " \ + "root=/dev/mmcblk${mmcblkdev}p${mmcpart} ${rootfsmode} " \ + "rootwait\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "setenv bootargs; " \ + "run boot_setup_var;" \ + "run boot_find_firmware;" \ + "run boot_save_env;" \ + "run mmcargs; " \ + "if run loadimage; then " \ + "if run loadfdt; then " \ + "echo boot device tree kernel ...; " \ + "${boot_type} ${loadaddr} - ${fdt_addr}; " \ + "fi; " \ + "else " \ + "${boot_type}; " \ + "fi;\0" \ + "setenv bootargs \0" \ + "qspiboot=echo Booting from qspi ...; " \ + "setenv bootargs; " \ + "run qspiargs; " \ + "if run loadimage; then " \ + "if run loadfdt; then " \ + "echo boot device tree kernel ...; " \ + "${boot_type} ${loadaddr} - ${fdt_addr}; " \ + "fi; " \ + "else " \ + "${boot_type}; " \ + "fi;\0" \ + "setenv bootargs \0" \ + "netdev=eth0\0" \ + "rootpath=/srv/nfs/tqma6\0" \ + "ipmode=static\0" \ + "netargs=run addnfs addip addtty addcma\0" \ + "addnfs=setenv bootargs ${bootargs} " \ + "root=/dev/nfs rw " \ + "nfsroot=${serverip}:${rootpath},v3,tcp;\0" \ + "addip_static=setenv bootargs ${bootargs} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:" \ + "${hostname}:${netdev}:off\0" \ + "addip_dynamic=setenv bootargs ${bootargs} ip=dhcp\0" \ + "addip=if test "${ipmode}" != static; then " \ + "run addip_dynamic; else run addip_static; fi\0" \ + "set_getcmd=if test "${ipmode}" != static; then " \ + "setenv getcmd dhcp; setenv autoload yes; " \ + "else setenv getcmd tftp; setenv autoload no; fi\0" \ + "netboot=echo Booting from net ...; " \ + "run kernel_name; " \ + "run set_getcmd; " \ + "setenv bootargs; " \ + "run netargs; " \ + "if ${getcmd} ${fdt_addr} ${fdt_file}; then " \ + "if ${getcmd} ${loadaddr} ${kernel}; then " \ + "${boot_type} ${loadaddr} - ${fdt_addr}; " \ + "fi; " \ + "fi; " \ + "echo ... failed\0" \ + "panicboot=echo No boot device !!! reset\0" \ + "rootfs_mtddev=5\0" \ + "addqspi=setenv bootargs ${bootargs} root=ubi0:root ${rootfsmode} " \ + "rootfstype=ubifs ubi.mtd=${rootfs_mtddev}\0" \ + "qspiargs=run addqspi addtty addcma\0" \ + "uboot_mtdpart=U-Boot\0" \ + "fdt_mtdpart=DTB\0" \ + "kernel_mtdpart=Linux\0" \ + "rootfs_mtdpart=RootFS\0" \ + "boot_setup_var=test -n ${BOOT_ORDER} || setenv BOOT_ORDER "A B";" \ + "test -n "${BOOT_A_LEFT}" || setenv BOOT_A_LEFT 3; " \ + "test -n "${BOOT_B_LEFT}" || setenv BOOT_B_LEFT 3; " \ + "test -n "${BOOT_B_LEFT}" || setenv BOOT_B_LEFT 3;" \ + "setenv bootargs;\0" \ + "boot_find_firmware=for BOOT_SLOT in "${BOOT_ORDER}"; do" \ + "if test "x${bootargs}" = "x"; then" \ + "if test "x${BOOT_SLOT}" = "xA"; then" \ + "if test ${BOOT_A_LEFT} -gt 0; then" \ + "echo "Found valid slot A, ${BOOT_A_LEFT} attempts remaining"; " \ + "setenv firmwarepart "1";" \ + "setenv mmcpart "5";" \ + "setenv bootargs "rauc.slot=A";" \ + "setexpr BOOT_A_LEFT ${BOOT_A_LEFT} - 1;" \ + "fi;" \ + "elif test "x${BOOT_SLOT}" = "xB"; then" \ + "if test ${BOOT_B_LEFT} -gt 0; then" \ + "echo "Found valid slot B, ${BOOT_B_LEFT} attempts remaining";" \ + "setenv firmwarepart "2";" \ + "setenv mmcpart "6";" \ + "setenv bootargs "rauc.slot=B";" \ + "setexpr BOOT_B_LEFT ${BOOT_B_LEFT} - 1;" \ + "fi;" \ + "fi;" \ + "fi;" \ + "done;\0 " \ + "boot_save_env=if test -n "${bootargs}"; then" \ + "saveenv;" \ + "else" \ + "echo "No valid slot found, resetting tries to 3";" \ + "setenv BOOT_A_LEFT 3;" \ + "setenv BOOT_B_LEFT 3;" \ + "saveenv; " \ + "reset; " \ + "fi;\0 " \ + "mtdparts=" MTDPARTS_DEFAULT "\0" \ + TQMA7_EXTRA_BOOTDEV_ENV_SETTINGS \ + TQMA7_MFG_ENV_SETTINGS \ + +/* Miscellaneous configurable options */ + +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +#if defined(CONFIG_CMD_MEMTEST) +/* + * config alternate mtest: + * enable 3/4 of RAM to test + * U-Boot is relocated to the end of RAM + */ +#define CONFIG_SYS_ALT_MEMTEST +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + \ + (PHYS_SDRAM_SIZE) / 4 * 3) +#define CONFIG_SYS_MEMTEST_SCRATCH CONFIG_SYS_MEMTEST_END +#endif + +/* Physical Memory Map */ +#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE + +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +#ifndef CONFIG_SYS_DCACHE_OFF +#define CONFIG_CMD_CACHE +#endif + +#define CONFIG_SYS_CONSOLE_IS_IN_ENV + +#define CONFIG_IMX_THERMAL + +/* + * All the defines above are for the TQMa7 SoM + * + * Now include the baseboard specific configuration + */ +#undef CONFIG_MXC_UART_BASE + +#ifdef CONFIG_MBA7 +#include "tqma7_mba7.h" +#else +#error "No baseboard for the TQMa7 SoM defined!" +#endif + +#endif /* __TQMA7_CONFIG_H */ diff --git a/include/configs/tqma7_mba7.h b/include/configs/tqma7_mba7.h new file mode 100644 index 0000000000..0e562bff08 --- /dev/null +++ b/include/configs/tqma7_mba7.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016-2018 Markus Niebel Markus.Niebel@tq-group.com + * Copyright (C) 2019 Bruno Thomsen bruno.thomsen@gmail.com + * + * Configuration settings for the TQ Systems MBa7x carrier board + * for TQMa7x module. + */ + +#ifndef __CONFIG_TQMA7_MBA7_H +#define __CONFIG_TQMA7_MBA7_H + +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_ETHPRIME "FEC" +#define CONFIG_PHY_TI + +#define TQMA7_ENET1_PHYADDR 0x00 +#define TQMA7_ENET2_PHYADDR 0x00 + +#define CONFIG_MXC_UART_BASE UART6_IPS_BASE_ADDR +#define CONSOLE_DEV "ttymxc5" + +#define MTDIDS_DEFAULT \ + "nor0=nor0\0" + +#define MTDPARTS_DEFAULT \ + "mtdparts=nor0:" \ + "832k@0k(U-Boot)," \ + "64k@832k(ENV1)," \ + "64k@896k(ENV2)," \ + "64k@960k(DTB)," \ + "7M@1M(Linux)," \ + "56M@8M(RootFS)" \ + +#endif /* __CONFIG_TQMA7_MBA7_H */

Hi Bruno,
On Tue, Mar 12, 2019 at 1:58 PM Bruno Thomsen bruno.thomsen@gmail.com wrote:
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 8631fbd481..0335c0e8db 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -46,7 +46,7 @@ config SECURE_BOOT config CMD_BMODE bool "Support the 'bmode' command" default y
depends on ARCH_MX6 || ARCH_MX5
depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5
This should be a separate patch.
help This enables the 'bmode' (bootmode) command for forcing a boot from specific media.
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 6b83f92662..113f228c86 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -251,7 +251,7 @@ int cpu_eth_init(bd_t *bis) { int rc = -ENODEV;
-#if defined(CONFIG_FEC_MXC) +#if defined(CONFIG_FEC_MXC) && defined(CONFIG_FEC_MXC_PHYADDR)
This one too.
Also, please consider converting this board to DM.
participants (2)
-
Bruno Thomsen
-
Fabio Estevam