diff options
Diffstat (limited to 'roms/u-boot/board/toradex')
87 files changed, 12041 insertions, 0 deletions
diff --git a/roms/u-boot/board/toradex/apalis-imx8/Kconfig b/roms/u-boot/board/toradex/apalis-imx8/Kconfig new file mode 100644 index 000000000..c680d63fa --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8/Kconfig @@ -0,0 +1,30 @@ +if TARGET_APALIS_IMX8 + +config SYS_BOARD + default "apalis-imx8" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "apalis-imx8" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/apalis-imx8/MAINTAINERS b/roms/u-boot/board/toradex/apalis-imx8/MAINTAINERS new file mode 100644 index 000000000..7fbd1be10 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8/MAINTAINERS @@ -0,0 +1,10 @@ +Apalis iMX8 +M: Marcel Ziswiler <marcel.ziswiler@toradex.com> +W: http://developer.toradex.com/software/linux/linux-software +S: Maintained +F: arch/arm/dts/fsl-imx8-apalis.dts +F: arch/arm/dts/fsl-imx8-apalis-u-boot.dtsi +F: board/toradex/apalis-imx8/ +F: configs/apalis-imx8_defconfig +F: doc/board/toradex/apalix-imx8.rst +F: include/configs/apalis-imx8.h diff --git a/roms/u-boot/board/toradex/apalis-imx8/Makefile b/roms/u-boot/board/toradex/apalis-imx8/Makefile new file mode 100644 index 000000000..a8c3eb724 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2019 Toradex +# + +obj-y += apalis-imx8.o diff --git a/roms/u-boot/board/toradex/apalis-imx8/apalis-imx8-imximage.cfg b/roms/u-boot/board/toradex/apalis-imx8/apalis-imx8-imximage.cfg new file mode 100644 index 000000000..b8f0f3dc1 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8/apalis-imx8-imximage.cfg @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Toradex + * + * Refer doc/imx/mkimage/imx8image.txt for more details about how-to configure + * and create imx8image boot image + */ + +#define __ASSEMBLY__ + +/* Boot from SD, sector size 0x400 */ +BOOT_FROM EMMC_FASTBOOT 0x400 +/* SoC type IMX8QM */ +SOC_TYPE IMX8QM +/* Append seco container image */ +APPEND mx8qm-ahab-container.img +/* Create the 2nd container */ +CONTAINER +/* Add scfw image with exec attribute */ +IMAGE SCU mx8qm-apalis-scfw-tcm.bin +/* Add ATF image with exec attribute */ +IMAGE A35 bl31.bin 0x80000000 +/* Add U-Boot image with load attribute */ +DATA A35 u-boot-dtb.bin 0x80020000 diff --git a/roms/u-boot/board/toradex/apalis-imx8/apalis-imx8.c b/roms/u-boot/board/toradex/apalis-imx8/apalis-imx8.c new file mode 100644 index 000000000..04877fcd9 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8/apalis-imx8.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Toradex + */ + +#include <common.h> +#include <cpu_func.h> +#include <init.h> +#include <asm/global_data.h> + +#include <asm/arch/clock.h> +#include <asm/arch/imx8-pins.h> +#include <asm/arch/iomux.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/sys_proto.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <env.h> +#include <errno.h> +#include <linux/libfdt.h> + +#include "../common/tdx-cfg-block.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +static iomux_cfg_t uart1_pads[] = { + SC_P_UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + SC_P_UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static void setup_iomux_uart(void) +{ + imx8_iomux_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); +} + +void board_mem_get_layout(u64 *phys_sdram_1_start, + u64 *phys_sdram_1_size, + u64 *phys_sdram_2_start, + u64 *phys_sdram_2_size) +{ + u32 is_quadplus = 0, val = 0; + sc_err_t scierr = sc_misc_otp_fuse_read(-1, 6, &val); + + if (scierr == SC_ERR_NONE) { + /* QP has one A72 core disabled */ + is_quadplus = ((val >> 4) & 0x3) != 0x0; + } + + *phys_sdram_1_start = PHYS_SDRAM_1; + *phys_sdram_1_size = PHYS_SDRAM_1_SIZE; + *phys_sdram_2_start = PHYS_SDRAM_2; + if (is_quadplus) + /* Our QP based SKUs only have 2 GB RAM (PHYS_SDRAM_1_SIZE) */ + *phys_sdram_2_size = 0x0UL; + else + *phys_sdram_2_size = PHYS_SDRAM_2_SIZE; +} + +int board_early_init_f(void) +{ + sc_pm_clock_rate_t rate = SC_80MHZ; + sc_err_t err = 0; + + /* Set UART1 clock root to 80 MHz and enable it */ + err = sc_pm_setup_uart(SC_R_UART_1, rate); + if (err != SC_ERR_NONE) + return 0; + + setup_iomux_uart(); + + return 0; +} + +#if CONFIG_IS_ENABLED(DM_GPIO) +static void board_gpio_init(void) +{ + /* TODO */ +} +#else +static inline void board_gpio_init(void) {} +#endif + +#if IS_ENABLED(CONFIG_FEC_MXC) +#include <miiphy.h> + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} +#endif + +int checkboard(void) +{ + puts("Model: Toradex Apalis iMX8\n"); + + build_info(); + print_bootinfo(); + + return 0; +} + +int board_init(void) +{ + board_gpio_init(); + + return 0; +} + +/* + * Board specific reset that is system reset. + */ +void reset_cpu(void) +{ + /* TODO */ +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +/* TODO move to common */ + env_set("board_name", "Apalis iMX8QM"); + env_set("board_rev", "v1.0"); +#endif + + return 0; +} diff --git a/roms/u-boot/board/toradex/apalis-imx8x/Kconfig b/roms/u-boot/board/toradex/apalis-imx8x/Kconfig new file mode 100644 index 000000000..ee61e0973 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8x/Kconfig @@ -0,0 +1,30 @@ +if TARGET_APALIS_IMX8X + +config SYS_BOARD + default "apalis-imx8x" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "apalis-imx8x" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/apalis-imx8x/MAINTAINERS b/roms/u-boot/board/toradex/apalis-imx8x/MAINTAINERS new file mode 100644 index 000000000..527215444 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8x/MAINTAINERS @@ -0,0 +1,10 @@ +Apalis iMX8X +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +W: http://developer.toradex.com/software/linux/linux-software +S: Maintained +F: arch/arm/dts/fsl-imx8x-apalis.dts +F: arch/arm/dts/fsl-imx8x-apalis-u-boot.dtsi +F: board/toradex/apalis-imx8x/ +F: configs/apalis-imx8x_defconfig +F: doc/board/toradex/apalis-imx8x.rst +F: include/configs/apalis-imx8x.h diff --git a/roms/u-boot/board/toradex/apalis-imx8x/Makefile b/roms/u-boot/board/toradex/apalis-imx8x/Makefile new file mode 100644 index 000000000..9d6e85b74 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8x/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2020 Toradex +# + +obj-y += apalis-imx8x.o diff --git a/roms/u-boot/board/toradex/apalis-imx8x/apalis-imx8x-imximage.cfg b/roms/u-boot/board/toradex/apalis-imx8x/apalis-imx8x-imximage.cfg new file mode 100644 index 000000000..58c62d0a6 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8x/apalis-imx8x-imximage.cfg @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Toradex + * + * Refer doc/imx/mkimage/imx8image.txt for more details about how-to configure + * and create imx8image boot image + */ + +#define __ASSEMBLY__ + +/* Boot from SD, sector size 0x400 */ +BOOT_FROM EMMC_FASTBOOT 0x400 +/* SoC type IMX8QX */ +SOC_TYPE IMX8QX +/* Append seco container image */ +APPEND mx8qx-ahab-container.img +/* Create the 2nd container */ +CONTAINER +/* Add scfw image with exec attribute */ +IMAGE SCU mx8qx-apalis-scfw-tcm.bin +/* Add ATF image with exec attribute */ +IMAGE A35 bl31.bin 0x80000000 +/* Add U-Boot image with load attribute */ +DATA A35 u-boot-dtb.bin 0x80020000 diff --git a/roms/u-boot/board/toradex/apalis-imx8x/apalis-imx8x.c b/roms/u-boot/board/toradex/apalis-imx8x/apalis-imx8x.c new file mode 100644 index 000000000..ac3bac66a --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-imx8x/apalis-imx8x.c @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Toradex + */ + +#include <common.h> +#include <cpu_func.h> +#include <init.h> + +#include <asm/arch/clock.h> +#include <asm/arch/imx8-pins.h> +#include <asm/arch/iomux.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/sys_proto.h> +#include <asm/global_data.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <env.h> +#include <errno.h> +#include <linux/libfdt.h> + +#include "../common/tdx-cfg-block.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +static iomux_cfg_t uart1_pads[] = { + SC_P_UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + SC_P_UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static void setup_iomux_uart(void) +{ + imx8_iomux_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); +} + +void board_mem_get_layout(u64 *phys_sdram_1_start, + u64 *phys_sdram_1_size, + u64 *phys_sdram_2_start, + u64 *phys_sdram_2_size) +{ + u32 is_dualx = 0, val = 0; + sc_err_t scierr = sc_misc_otp_fuse_read(-1, 6, &val); + + if (scierr == SC_ERR_NONE) { + /* DX has two A35 cores disabled */ + is_dualx = (val & 0xf) != 0x0; + } + + *phys_sdram_1_start = PHYS_SDRAM_1; + if (is_dualx) + /* Our DX based SKUs only have 1 GB RAM */ + *phys_sdram_1_size = SZ_1G; + else + *phys_sdram_1_size = PHYS_SDRAM_1_SIZE; + *phys_sdram_2_start = PHYS_SDRAM_2; + *phys_sdram_2_size = PHYS_SDRAM_2_SIZE; +} + +int board_early_init_f(void) +{ + sc_pm_clock_rate_t rate; + sc_err_t err = 0; + + /* + * This works around that having only UART3 up the baudrate is 1.2M + * instead of 115.2k. Set UART0 clock root to 80 MHz + */ + rate = 80000000; + err = sc_pm_set_clock_rate(-1, SC_R_UART_0, SC_PM_CLK_PER, &rate); + if (err != SC_ERR_NONE) + return 0; + + /* Set UART3 clock root to 80 MHz and enable it */ + rate = SC_80MHZ; + err = sc_pm_setup_uart(SC_R_UART_1, rate); + if (err != SC_ERR_NONE) + return 0; + + setup_iomux_uart(); + + return 0; +} + +#if IS_ENABLED(CONFIG_DM_GPIO) +static void board_gpio_init(void) +{ + /* TODO */ +} +#else +static inline void board_gpio_init(void) {} +#endif + +#if IS_ENABLED(CONFIG_FEC_MXC) +#include <miiphy.h> + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} +#endif + +int checkboard(void) +{ + puts("Model: Toradex Apalis iMX8X\n"); + + build_info(); + print_bootinfo(); + + return 0; +} + +int board_init(void) +{ + board_gpio_init(); + + return 0; +} + +/* + * Board specific reset that is system reset. + */ +void reset_cpu(void) +{ + /* TODO */ +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +/* TODO move to common */ + env_set("board_name", "Apalis iMX8X"); +#endif + + return 0; +} diff --git a/roms/u-boot/board/toradex/apalis-tk1/Kconfig b/roms/u-boot/board/toradex/apalis-tk1/Kconfig new file mode 100644 index 000000000..159b8fb19 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-tk1/Kconfig @@ -0,0 +1,38 @@ +if TARGET_APALIS_TK1 + +config SYS_BOARD + default "apalis-tk1" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "apalis-tk1" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +config APALIS_TK1_PCIE_EVALBOARD_INIT + bool "Apalis Evaluation Board PCIe Initialisation" + help + Bring up the Apalis PCIe port with the PCIe switch as found on the + Apalis Evaluation board. Note that by default the PCIe port is also + left disabled in the device tree which needs changing as well for this + to actually work. + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/apalis-tk1/MAINTAINERS b/roms/u-boot/board/toradex/apalis-tk1/MAINTAINERS new file mode 100644 index 000000000..3c908e119 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-tk1/MAINTAINERS @@ -0,0 +1,7 @@ +Apalis TK1 +M: Marcel Ziswiler <marcel.ziswiler@toradex.com> +S: Maintained +F: board/toradex/apalis-tk1/ +F: include/configs/apalis-tk1.h +F: configs/apalis-tk1_defconfig +F: arch/arm/dts/tegra124-apalis.dtb diff --git a/roms/u-boot/board/toradex/apalis-tk1/Makefile b/roms/u-boot/board/toradex/apalis-tk1/Makefile new file mode 100644 index 000000000..9ef06dd61 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-tk1/Makefile @@ -0,0 +1,5 @@ +# Copyright (c) 2016 Toradex, Inc. +# SPDX-License-Identifier: GPL-2.0+ + +obj-y += as3722_init.o +obj-y += apalis-tk1.o diff --git a/roms/u-boot/board/toradex/apalis-tk1/apalis-tk1.c b/roms/u-boot/board/toradex/apalis-tk1/apalis-tk1.c new file mode 100644 index 000000000..b97617cfc --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-tk1/apalis-tk1.c @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2016-2018 Toradex, Inc. + */ + +#include <common.h> +#include <dm.h> +#include <env.h> +#include <init.h> +#include <log.h> +#include <asm/arch-tegra/ap.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/arch/gpio.h> +#include <asm/arch/pinmux.h> +#include <env_internal.h> +#include <pci_tegra.h> +#include <linux/delay.h> +#include <power/as3722.h> +#include <power/pmic.h> + +#include "../common/tdx-common.h" +#include "pinmux-config-apalis-tk1.h" + +#define LAN_DEV_OFF_N TEGRA_GPIO(O, 6) +#define LAN_RESET_N TEGRA_GPIO(S, 2) +#define FAN_EN TEGRA_GPIO(DD, 2) +#define LAN_WAKE_N TEGRA_GPIO(O, 5) +#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT +#define PEX_PERST_N TEGRA_GPIO(DD, 1) /* Apalis GPIO7 */ +#define RESET_MOCI_CTRL TEGRA_GPIO(U, 4) +#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */ +#define VCC_USBH TEGRA_GPIO(T, 6) +#define VCC_USBH_V1_0 TEGRA_GPIO(N, 5) +#define VCC_USBO1 TEGRA_GPIO(T, 5) +#define VCC_USBO1_V1_0 TEGRA_GPIO(N, 4) + +int arch_misc_init(void) +{ + if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) == + NVBOOTTYPE_RECOVERY) + printf("USB recovery mode\n"); + + /* PCB Version Indication: V1.2 and later have GPIO_PV0 wired to GND */ + gpio_request(TEGRA_GPIO(V, 0), "PCB Version Indication"); + gpio_direction_input(TEGRA_GPIO(V, 0)); + if (gpio_get_value(TEGRA_GPIO(V, 0))) { + /* + * if using the default device tree for new V1.2 and later HW, + * use version for older V1.0 and V1.1 HW + */ + char *fdt_env = env_get("fdt_module"); + + if (fdt_env && !strcmp(FDT_MODULE, fdt_env)) { + env_set("fdt_module", FDT_MODULE_V1_0); + printf("patching fdt_module to " FDT_MODULE_V1_0 + " for older V1.0 and V1.1 HW\n"); +#ifndef CONFIG_ENV_IS_NOWHERE + env_save(); +#endif + } + + /* activate USB power enable GPIOs */ + gpio_request(VCC_USBH_V1_0, "VCC_USBH"); + gpio_direction_output(VCC_USBH_V1_0, 1); + gpio_request(VCC_USBO1_V1_0, "VCC_USBO1"); + gpio_direction_output(VCC_USBO1_V1_0, 1); + } else { + /* activate USB power enable GPIOs */ + gpio_request(VCC_USBH, "VCC_USBH"); + gpio_direction_output(VCC_USBH, 1); + gpio_request(VCC_USBO1, "VCC_USBO1"); + gpio_direction_output(VCC_USBO1, 1); + } + + return 0; +} + +int checkboard(void) +{ + puts("Model: Toradex Apalis TK1 2GB\n"); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +/* + * Routine: pinmux_init + * Description: Do individual peripheral pinmux configs + */ +void pinmux_init(void) +{ + pinmux_clear_tristate_input_clamping(); + + gpio_config_table(apalis_tk1_gpio_inits, + ARRAY_SIZE(apalis_tk1_gpio_inits)); + + pinmux_config_pingrp_table(apalis_tk1_pingrps, + ARRAY_SIZE(apalis_tk1_pingrps)); + + pinmux_config_drvgrp_table(apalis_tk1_drvgrps, + ARRAY_SIZE(apalis_tk1_drvgrps)); +} + +#ifdef CONFIG_PCI_TEGRA +/* TODO: Convert to driver model */ +static int as3722_sd_enable(struct udevice *pmic, unsigned int sd) +{ + int err; + + if (sd > 6) + return -EINVAL; + + err = pmic_clrsetbits(pmic, AS3722_SD_CONTROL, 0, 1 << sd); + if (err) { + pr_err("failed to update SD control register: %d", err); + return err; + } + + return 0; +} + +/* TODO: Convert to driver model */ +static int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo) +{ + int err; + u8 ctrl_reg = AS3722_LDO_CONTROL0; + + if (ldo > 11) + return -EINVAL; + + if (ldo > 7) { + ctrl_reg = AS3722_LDO_CONTROL1; + ldo -= 8; + } + + err = pmic_clrsetbits(pmic, ctrl_reg, 0, 1 << ldo); + if (err) { + pr_err("failed to update LDO control register: %d", err); + return err; + } + + return 0; +} + +int tegra_pcie_board_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_DRIVER_GET(pmic_as3722), &dev); + if (ret) { + pr_err("failed to find AS3722 PMIC: %d\n", ret); + return ret; + } + + ret = as3722_sd_enable(dev, 4); + if (ret < 0) { + pr_err("failed to enable SD4: %d\n", ret); + return ret; + } + + ret = as3722_sd_set_voltage(dev, 4, 0x24); + if (ret < 0) { + pr_err("failed to set SD4 voltage: %d\n", ret); + return ret; + } + + gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N"); + gpio_request(LAN_RESET_N, "LAN_RESET_N"); + gpio_request(LAN_WAKE_N, "LAN_WAKE_N"); + +#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT + gpio_request(PEX_PERST_N, "PEX_PERST_N"); + gpio_request(RESET_MOCI_CTRL, "RESET_MOCI_CTRL"); +#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */ + + return 0; +} + +void tegra_pcie_board_port_reset(struct tegra_pcie_port *port) +{ + int index = tegra_pcie_port_index_of_port(port); + + if (index == 1) { /* I210 Gigabit Ethernet Controller (On-module) */ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_PMIC, + DM_DRIVER_GET(pmic_as3722), + &dev); + if (ret) { + debug("%s: Failed to find PMIC\n", __func__); + return; + } + + /* Reset I210 Gigabit Ethernet Controller */ + gpio_direction_output(LAN_RESET_N, 0); + + /* + * Make sure we don't get any back feeding from DEV_OFF_N resp. + * LAN_WAKE_N + */ + gpio_direction_output(LAN_DEV_OFF_N, 0); + gpio_direction_output(LAN_WAKE_N, 0); + + /* Make sure LDO9 and LDO10 are initially enabled @ 0V */ + ret = as3722_ldo_enable(dev, 9); + if (ret < 0) { + pr_err("failed to enable LDO9: %d\n", ret); + return; + } + ret = as3722_ldo_enable(dev, 10); + if (ret < 0) { + pr_err("failed to enable LDO10: %d\n", ret); + return; + } + ret = as3722_ldo_set_voltage(dev, 9, 0x80); + if (ret < 0) { + pr_err("failed to set LDO9 voltage: %d\n", ret); + return; + } + ret = as3722_ldo_set_voltage(dev, 10, 0x80); + if (ret < 0) { + pr_err("failed to set LDO10 voltage: %d\n", ret); + return; + } + + /* Make sure controller gets enabled by disabling DEV_OFF_N */ + gpio_set_value(LAN_DEV_OFF_N, 1); + + /* + * Enable LDO9 and LDO10 for +V3.3_ETH on patched prototype + * V1.0A and sample V1.0B and newer modules + */ + ret = as3722_ldo_set_voltage(dev, 9, 0xff); + if (ret < 0) { + pr_err("failed to set LDO9 voltage: %d\n", ret); + return; + } + ret = as3722_ldo_set_voltage(dev, 10, 0xff); + if (ret < 0) { + pr_err("failed to set LDO10 voltage: %d\n", ret); + return; + } + + /* + * Must be asserted for 100 ms after power and clocks are stable + */ + mdelay(100); + + gpio_set_value(LAN_RESET_N, 1); + } else if (index == 0) { /* Apalis PCIe */ +#ifdef CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT + /* + * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis + * Evaluation Board + */ + gpio_direction_output(PEX_PERST_N, 0); + gpio_direction_output(RESET_MOCI_CTRL, 0); + + /* + * Must be asserted for 100 ms after power and clocks are stable + */ + mdelay(100); + + gpio_set_value(PEX_PERST_N, 1); + /* + * Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed + * Until 900 us After PEX_PERST# De-assertion + */ + mdelay(1); + gpio_set_value(RESET_MOCI_CTRL, 1); +#endif /* CONFIG_APALIS_TK1_PCIE_EVALBOARD_INIT */ + } +} +#endif /* CONFIG_PCI_TEGRA */ + +/* + * Enable/start PWM CPU fan + */ +void start_cpu_fan(void) +{ + gpio_request(FAN_EN, "FAN_EN"); + gpio_direction_output(FAN_EN, 1); +} + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(TEGRA_GPIO(BB, 5), "BL_ON"); + gpio_direction_output(TEGRA_GPIO(BB, 5), 0); +} diff --git a/roms/u-boot/board/toradex/apalis-tk1/as3722_init.c b/roms/u-boot/board/toradex/apalis-tk1/as3722_init.c new file mode 100644 index 000000000..68169f554 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-tk1/as3722_init.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2012-2016 Toradex, Inc. + */ + +#include <common.h> +#include <log.h> +#include <asm/io.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include <linux/delay.h> +#include "as3722_init.h" + +/* AS3722-PMIC-specific early init code - get CPU rails up, etc */ + +void tegra_i2c_ll_write_addr(uint addr, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(addr, ®->cmd_addr0); + writel(config, ®->cnfg); +} + +void tegra_i2c_ll_write_data(uint data, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(data, ®->cmd_data1); + writel(config, ®->cnfg); +} + +void pmic_enable_cpu_vdd(void) +{ + debug("%s entry\n", __func__); + +#ifdef AS3722_SD1VOLTAGE_DATA + /* Set up VDD_CORE, for boards where OTP is incorrect*/ + debug("%s: Setting VDD_CORE via AS3722 reg 1\n", __func__); + /* Configure VDD_CORE via the AS3722 PMIC on the PWR I2C bus */ + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(AS3722_SD1VOLTAGE_DATA, I2C_SEND_2_BYTES); + /* + * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. + * tegra_i2c_ll_write_data(AS3722_SD1CONTROL_DATA, I2C_SEND_2_BYTES); + */ + udelay(10 * 1000); +#endif + + /* + * Make sure all non-fused regulators are down. + * That way we're in known state after software reboot from linux + */ + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x0003, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x0004, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x001b, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x0014, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x001a, I2C_SEND_2_BYTES); + udelay(10 * 1000); + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(0x0019, I2C_SEND_2_BYTES); + udelay(10 * 1000); + + debug("%s: Setting VDD_CPU to 1.0V via AS3722 reg 0/4D\n", __func__); + /* + * Bring up VDD_CPU via the AS3722 PMIC on the PWR I2C bus. + * First set VDD to 1.0V, then enable the VDD regulator. + */ + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(AS3722_SD0VOLTAGE_DATA, I2C_SEND_2_BYTES); + /* + * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. + * tegra_i2c_ll_write_data(AS3722_SD0CONTROL_DATA, I2C_SEND_2_BYTES); + */ + udelay(10 * 1000); + + debug("%s: Setting VDD_GPU to 1.0V via AS3722 reg 6/4D\n", __func__); + /* + * Bring up VDD_GPU via the AS3722 PMIC on the PWR I2C bus. + * First set VDD to 1.0V, then enable the VDD regulator. + */ + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(AS3722_SD6VOLTAGE_DATA, I2C_SEND_2_BYTES); + /* + * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. + * tegra_i2c_ll_write_data(AS3722_SD6CONTROL_DATA, I2C_SEND_2_BYTES); + */ + udelay(10 * 1000); + + debug("%s: Set VPP_FUSE to 1.2V via AS3722 reg 0x12/4E\n", __func__); + /* + * Bring up VPP_FUSE via the AS3722 PMIC on the PWR I2C bus. + * First set VDD to 1.2V, then enable the VDD regulator. + */ + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(AS3722_LDO2VOLTAGE_DATA, I2C_SEND_2_BYTES); + /* + * Don't write LDCONTROL - it's already 0xFF, i.e. all LDOs enabled. + * tegra_i2c_ll_write_data(AS3722_LDO2CONTROL_DATA, I2C_SEND_2_BYTES); + */ + udelay(10 * 1000); + + debug("%s: Set VDD_SDMMC1 to 3.3V via AS3722 reg 0x11/4E\n", __func__); + /* + * Bring up VDD_SDMMC1 via the AS3722 PMIC on the PWR I2C bus. + * First set it to value closest to 3.3V, then enable the regulator + * + * NOTE: We do this early because doing it later seems to hose the CPU + * power rail/partition startup. Need to debug. + */ + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(AS3722_LDO1VOLTAGE_DATA, I2C_SEND_2_BYTES); + /* + * Don't write LDCONTROL - it's already 0xFF, i.e. all LDOs enabled. + * tegra_i2c_ll_write_data(AS3722_LDO1CONTROL_DATA, I2C_SEND_2_BYTES); + */ + udelay(10 * 1000); + + debug("%s: Set VDD_SDMMC3 to 3.3V via AS3722 reg 0x16/4E\n", __func__); + /* + * Bring up VDD_SDMMC3 via the AS3722 PMIC on the PWR I2C bus. + * First set it to bypass 3.3V straight thru, then enable the regulator + * + * NOTE: We do this early because doing it later seems to hose the CPU + * power rail/partition startup. Need to debug. + */ + tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); + tegra_i2c_ll_write_data(AS3722_LDO6VOLTAGE_DATA, I2C_SEND_2_BYTES); + /* + * Don't write LDCONTROL - it's already 0xFF, i.e. all LDOs enabled. + * tegra_i2c_ll_write_data(AS3722_LDO6CONTROL_DATA, I2C_SEND_2_BYTES); + */ + udelay(10 * 1000); +} diff --git a/roms/u-boot/board/toradex/apalis-tk1/as3722_init.h b/roms/u-boot/board/toradex/apalis-tk1/as3722_init.h new file mode 100644 index 000000000..99836de96 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-tk1/as3722_init.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2012-2016 Toradex, Inc. + */ + +/* AS3722-PMIC-specific early init regs */ + +#define AS3722_I2C_ADDR 0x80 + +#define AS3722_SD0VOLTAGE_REG 0x00 /* CPU */ +#define AS3722_SD1VOLTAGE_REG 0x01 /* CORE, already set by OTP */ +#define AS3722_SD6VOLTAGE_REG 0x06 /* GPU */ +#define AS3722_SDCONTROL_REG 0x4D + +#define AS3722_LDO1VOLTAGE_REG 0x11 /* VDD_SDMMC1 */ +#define AS3722_LDO2VOLTAGE_REG 0x12 /* VPP_FUSE */ +#define AS3722_LDO6VOLTAGE_REG 0x16 /* VDD_SDMMC3 */ +#define AS3722_LDCONTROL_REG 0x4E + +#define AS3722_SD0VOLTAGE_DATA (0x3C00 | AS3722_SD0VOLTAGE_REG) +#define AS3722_SD0CONTROL_DATA (0x0100 | AS3722_SDCONTROL_REG) + +#define AS3722_SD1VOLTAGE_DATA (0x3200 | AS3722_SD1VOLTAGE_REG) +#define AS3722_SD1CONTROL_DATA (0x0200 | AS3722_SDCONTROL_REG) + +#define AS3722_SD6CONTROL_DATA (0x4000 | AS3722_SDCONTROL_REG) +#define AS3722_SD6VOLTAGE_DATA (0x2800 | AS3722_SD6VOLTAGE_REG) + +#define AS3722_LDO1CONTROL_DATA (0x0200 | AS3722_LDCONTROL_REG) +#define AS3722_LDO1VOLTAGE_DATA (0x7F00 | AS3722_LDO1VOLTAGE_REG) + +#define AS3722_LDO2CONTROL_DATA (0x0400 | AS3722_LDCONTROL_REG) +#define AS3722_LDO2VOLTAGE_DATA (0x1000 | AS3722_LDO2VOLTAGE_REG) + +#define AS3722_LDO6CONTROL_DATA (0x4000 | AS3722_LDCONTROL_REG) +#define AS3722_LDO6VOLTAGE_DATA (0x3F00 | AS3722_LDO6VOLTAGE_REG) + +#define I2C_SEND_2_BYTES 0x0A02 + +void pmic_enable_cpu_vdd(void); diff --git a/roms/u-boot/board/toradex/apalis-tk1/pinmux-config-apalis-tk1.h b/roms/u-boot/board/toradex/apalis-tk1/pinmux-config-apalis-tk1.h new file mode 100644 index 000000000..6778a41e0 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis-tk1/pinmux-config-apalis-tk1.h @@ -0,0 +1,285 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2016-2019, Toradex, Inc. + */ + +#ifndef _PINMUX_CONFIG_APALIS_TK1_H_ +#define _PINMUX_CONFIG_APALIS_TK1_H_ + +#define GPIO_INIT(_port, _gpio, _init) \ + { \ + .gpio = TEGRA_GPIO(_port, _gpio), \ + .init = TEGRA_GPIO_INIT_##_init, \ + } + +static const struct tegra_gpio_config apalis_tk1_gpio_inits[] = { + /* port, pin, init_val */ + GPIO_INIT(A, 1, IN), + GPIO_INIT(B, 1, IN), + GPIO_INIT(C, 0, OUT0), + GPIO_INIT(I, 5, IN), + GPIO_INIT(I, 6, IN), + GPIO_INIT(J, 0, IN), + GPIO_INIT(J, 2, IN), + GPIO_INIT(K, 2, IN), + GPIO_INIT(K, 7, IN), + GPIO_INIT(N, 2, OUT1), + GPIO_INIT(N, 7, IN), + GPIO_INIT(O, 5, IN), + GPIO_INIT(Q, 0, OUT0), /* Shift_CTRL_OE[0] */ + GPIO_INIT(Q, 1, OUT0), /* Shift_CTRL_OE[1] */ + GPIO_INIT(Q, 2, OUT0), /* Shift_CTRL_OE[2] */ + GPIO_INIT(Q, 4, OUT0), /* Shift_CTRL_OE[4] */ + GPIO_INIT(Q, 5, OUT1), /* Shift_CTRL_Dir_Out[0] */ + GPIO_INIT(Q, 6, OUT1), /* Shift_CTRL_Dir_Out[1] */ + GPIO_INIT(Q, 7, OUT1), /* Shift_CTRL_Dir_Out[2] */ + GPIO_INIT(R, 0, OUT0), /* Shift_CTRL_Dir_In[0] */ + GPIO_INIT(R, 1, OUT0), /* Shift_CTRL_Dir_In[1] */ + GPIO_INIT(R, 2, OUT0), /* Shift_CTRL_OE[3] */ + GPIO_INIT(S, 3, OUT0), /* Shift_CTRL_Dir_In[2] */ + GPIO_INIT(U, 4, OUT0), /* RESET_MOCI_CTRL */ + GPIO_INIT(V, 0, IN), + GPIO_INIT(W, 3, IN), + GPIO_INIT(W, 5, IN), + GPIO_INIT(BB, 0, IN), + GPIO_INIT(BB, 3, OUT0), + GPIO_INIT(BB, 4, IN), + GPIO_INIT(BB, 5, OUT1), + GPIO_INIT(BB, 6, OUT0), + GPIO_INIT(CC, 5, IN), + GPIO_INIT(DD, 3, IN), + GPIO_INIT(EE, 3, IN), + GPIO_INIT(EE, 5, IN), + GPIO_INIT(FF, 1, IN), +}; + +#define PINCFG(_pingrp, _mux, _pull, _tri, _io, _od, _rcv_sel) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .od = PMUX_PIN_OD_##_od, \ + .rcv_sel = PMUX_PIN_RCV_SEL_##_rcv_sel, \ + .lock = PMUX_PIN_LOCK_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +static const struct pmux_pingrp_config apalis_tk1_pingrps[] = { + /* pingrp, mux, pull, tri, e_input, od, rcv_sel */ + PINCFG(CLK_32K_OUT_PA0, SOC, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(UART3_CTS_N_PA1, GMI, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(DAP2_FS_PA2, HDA, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(DAP2_SCLK_PA3, HDA, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(DAP2_DIN_PA4, HDA, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(DAP2_DOUT_PA5, HDA, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC3_CLK_PA6, SDMMC3, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC3_CMD_PA7, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PB0, UARTD, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(PB1, RSVD2, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC3_DAT3_PB4, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC3_DAT2_PB5, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC3_DAT1_PB6, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC3_DAT0_PB7, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(UART3_RTS_N_PC0, GMI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(UART2_TXD_PC2, IRDA, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(UART2_RXD_PC3, IRDA, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(GEN1_I2C_SCL_PC4, I2C1, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT), + PINCFG(GEN1_I2C_SDA_PC5, I2C1, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT), + PINCFG(PC7, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PG0, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PG1, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PG2, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PG3, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PG4, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PG5, SPI4, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PG6, SPI4, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PG7, SPI4, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(PH0, PWM0, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PH1, PWM1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PH2, PWM2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PH3, PWM3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PH4, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PH5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PH6, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PH7, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PI0, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PI1, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PI2, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PI3, SPI4, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PI4, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PI5, RSVD2, UP, TRISTATE, INPUT, ENABLE, DEFAULT), + PINCFG(PI6, RSVD1, UP, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(PI7, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PJ0, RSVD1, UP, TRISTATE, INPUT, ENABLE, DEFAULT), + PINCFG(PJ2, RSVD1, UP, TRISTATE, INPUT, ENABLE, DEFAULT), + PINCFG(UART2_CTS_N_PJ5, UARTB, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(UART2_RTS_N_PJ6, UARTB, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PJ7, UARTD, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PK0, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PK1, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PK2, RSVD1, UP, TRISTATE, INPUT, ENABLE, DEFAULT), + PINCFG(PK3, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PK4, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(SPDIF_OUT_PK5, SPDIF, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(SPDIF_IN_PK6, SPDIF, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(PK7, RSVD2, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(DAP1_FS_PN0, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP1_DIN_PN1, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP1_DOUT_PN2, SATA, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP1_SCLK_PN3, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(USB_VBUS_EN0_PN4, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT), + PINCFG(USB_VBUS_EN1_PN5, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT), + PINCFG(HDMI_INT_PN7, RSVD1, DOWN, TRISTATE, INPUT, DEFAULT, NORMAL), + PINCFG(ULPI_DATA7_PO0, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_DATA0_PO1, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_DATA1_PO2, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_DATA2_PO3, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_DATA3_PO4, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_DATA4_PO5, ULPI, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_DATA5_PO6, ULPI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_DATA6_PO7, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP3_FS_PP0, I2S2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP3_DIN_PP1, I2S2, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(DAP3_DOUT_PP2, I2S2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP3_SCLK_PP3, I2S2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP4_FS_PP4, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP4_DIN_PP5, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP4_DOUT_PP6, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP4_SCLK_PP7, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_COL0_PQ0, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_COL1_PQ1, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_COL2_PQ2, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_COL3_PQ3, KBC, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_COL4_PQ4, KBC, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_COL5_PQ5, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_COL6_PQ6, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_COL7_PQ7, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW0_PR0, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW1_PR1, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW2_PR2, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW3_PR3, KBC, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW4_PR4, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW5_PR5, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW6_PR6, KBC, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW7_PR7, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW8_PS0, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW9_PS1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW10_PS2, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW11_PS3, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW12_PS4, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW13_PS5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW14_PS6, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW15_PS7, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW16_PT0, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(KB_ROW17_PT1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(GEN2_I2C_SCL_PT5, RSVD2, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT), + PINCFG(GEN2_I2C_SDA_PT6, RSVD2, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT), + PINCFG(SDMMC4_CMD_PT7, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PU0, UARTA, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PU1, UARTA, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(PU2, UARTA, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(PU3, UARTA, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PU4, GMI, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PU5, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PU6, PWM3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PV0, RSVD1, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PV1, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC3_CD_N_PV2, RSVD3, UP, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC1_WP_N_PV3, SDMMC1, UP, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(DDC_SCL_PV4, I2C4, NORMAL, NORMAL, INPUT, DEFAULT, NORMAL), + PINCFG(DDC_SDA_PV5, I2C4, NORMAL, NORMAL, INPUT, DEFAULT, NORMAL), + PINCFG(GPIO_W2_AUD_PW2, SPI2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(GPIO_W3_AUD_PW3, SPI6, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(DAP_MCLK1_PW4, EXTPERIPH1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(CLK2_OUT_PW5, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(UART3_TXD_PW6, UARTC, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(UART3_RXD_PW7, UARTC, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(DVFS_PWM_PX0, CLDVFS, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(GPIO_X1_AUD_PX1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DVFS_CLK_PX2, CLDVFS, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(GPIO_X3_AUD_PX3, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(GPIO_X4_AUD_PX4, SPI2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(GPIO_X5_AUD_PX5, SPI2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(GPIO_X6_AUD_PX6, SPI2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(GPIO_X7_AUD_PX7, SPI2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_CLK_PY0, SPI1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_DIR_PY1, SPI1, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_NXT_PY2, SPI1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(ULPI_STP_PY3, SPI1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC1_DAT3_PY4, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC1_DAT2_PY5, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC1_DAT1_PY6, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC1_DAT0_PY7, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC1_CLK_PZ0, SDMMC1, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC1_CMD_PZ1, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PWR_I2C_SCL_PZ6, I2CPWR, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT), + PINCFG(PWR_I2C_SDA_PZ7, I2CPWR, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT), + PINCFG(SDMMC4_DAT0_PAA0, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC4_DAT1_PAA1, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC4_DAT2_PAA2, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC4_DAT3_PAA3, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC4_DAT4_PAA4, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC4_DAT5_PAA5, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC4_DAT6_PAA6, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC4_DAT7_PAA7, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PBB0, VGP6, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(CAM_I2C_SCL_PBB1, I2C3, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT), + PINCFG(CAM_I2C_SDA_PBB2, I2C3, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT), + PINCFG(PBB3, VGP3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PBB4, VGP4, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(PBB5, VGP5, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PBB6, RSVD2, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PBB7, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(CAM_MCLK_PCC0, VI_ALT3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PCC1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PCC2, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC4_CLK_PCC4, SDMMC4, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(CLK2_REQ_PCC5, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PEX_L0_RST_N_PDD1, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PEX_L0_CLKREQ_N_PDD2, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PEX_WAKE_N_PDD3, RSVD2, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(PEX_L1_RST_N_PDD5, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(PEX_L1_CLKREQ_N_PDD6, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(CLK3_OUT_PEE0, EXTPERIPH3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(CLK3_REQ_PEE1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(DAP_MCLK1_REQ_PEE2, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT), + PINCFG(HDMI_CEC_PEE3, CEC, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT), + /* + * Leave SDMMC3_CLK_LB_OUT muxed as SDMMC3 with output driver enabled aka not + * tristated and input driver enabled as well as it features some magic + * properties even though the external loopback is disabled and the internal + * loopback used as per SDMMC_VENDOR_MISC_CNTRL_0 register's SDMMC_SPARE1 bits + * being set to 0xfffd according to the TRM! + */ + PINCFG(SDMMC3_CLK_LB_OUT_PEE4, SDMMC3, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(SDMMC3_CLK_LB_IN_PEE5, RSVD2, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(DP_HPD_PFF0, DP, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(USB_VBUS_EN2_PFF1, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT), + PINCFG(PFF2, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT), + PINCFG(CORE_PWR_REQ, PWRON, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(CPU_PWR_REQ, CPU, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT), + PINCFG(PWR_INT_N, PMI, UP, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(RESET_OUT_N, RESET_OUT_N, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT), + PINCFG(OWR, RSVD2, NORMAL, TRISTATE, OUTPUT, DEFAULT, NORMAL), + PINCFG(CLK_32K_IN, CLK, NORMAL, TRISTATE, INPUT, DEFAULT, DEFAULT), + PINCFG(JTAG_RTCK, RTCK, UP, NORMAL, OUTPUT, DEFAULT, DEFAULT), +}; + +#define DRVCFG(_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) \ + { \ + .drvgrp = PMUX_DRVGRP_##_drvgrp, \ + .slwf = _slwf, \ + .slwr = _slwr, \ + .drvup = _drvup, \ + .drvdn = _drvdn, \ + .lpmd = PMUX_LPMD_##_lpmd, \ + .schmt = PMUX_SCHMT_##_schmt, \ + .hsm = PMUX_HSM_##_hsm, \ + } + +static const struct pmux_drvgrp_config apalis_tk1_drvgrps[] = { +}; + +#endif /* PINMUX_CONFIG_APALIS_TK1_H */ diff --git a/roms/u-boot/board/toradex/apalis_imx6/Kconfig b/roms/u-boot/board/toradex/apalis_imx6/Kconfig new file mode 100644 index 000000000..14f8c10c6 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_imx6/Kconfig @@ -0,0 +1,55 @@ +if TARGET_APALIS_IMX6 + +config SYS_BOARD + default "apalis_imx6" + +config SYS_CONFIG_NAME + default "apalis_imx6" + +config SYS_CPU + default "armv7" + +config SYS_SOC + default "mx6" + +config SYS_VENDOR + default "toradex" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +config TDX_CMD_IMX_MFGR + bool "Enable factory testing commands for Toradex iMX 6 modules" + help + This adds the commands + pf0100_otp_prog - Program the OTP fuses on the PMIC PF0100 + If executed on already fused modules it doesn't change any fuse setting. + default y + +config TDX_APALIS_IMX6_V1_0 + bool "Apalis iMX6 V1.0 HW" + help + Apalis iMX6 V1.0 HW has a different pinout for the UART. + The UARTs must be used in DCE mode, RTS/CTS are swapped and + thus unusable on standard carrier boards. + This option configures DCE mode unconditionally. Whithout this + option the config block stating V1.0 HW selects DCE mode, + otherwise the UARTs are configuered in DTE mode. + default n + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/apalis_imx6/MAINTAINERS b/roms/u-boot/board/toradex/apalis_imx6/MAINTAINERS new file mode 100644 index 000000000..fde4d92dc --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_imx6/MAINTAINERS @@ -0,0 +1,9 @@ +Apalis iMX6 +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +W: http://developer.toradex.com/software/linux/linux-software +W: https://www.toradex.com/community +S: Maintained +F: board/toradex/apalis_imx6/ +F: include/configs/apalis_imx6.h +F: configs/apalis_imx6_defconfig +F: arch/arm/dts/imx6-apalis.dts diff --git a/roms/u-boot/board/toradex/apalis_imx6/Makefile b/roms/u-boot/board/toradex/apalis_imx6/Makefile new file mode 100644 index 000000000..128f1794d --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_imx6/Makefile @@ -0,0 +1,5 @@ +# Copyright (c) 2012-2014 Toradex, Inc. +# SPDX-License-Identifier: GPL-2.0+ + +obj-y := apalis_imx6.o do_fuse.o +obj-$(CONFIG_TDX_CMD_IMX_MFGR) += pf0100.o diff --git a/roms/u-boot/board/toradex/apalis_imx6/apalis_imx6.c b/roms/u-boot/board/toradex/apalis_imx6/apalis_imx6.c new file mode 100644 index 000000000..74060daad --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_imx6/apalis_imx6.c @@ -0,0 +1,1156 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. + * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com> + * Copyright (C) 2014-2019, Toradex AG + * copied from nitrogen6x + */ + +#include <common.h> +#include <cpu_func.h> +#include <dm.h> +#include <image.h> +#include <init.h> +#include <net.h> +#include <asm/global_data.h> +#include <linux/bitops.h> +#include <linux/delay.h> + +#include <ahci.h> +#include <asm/arch/clock.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/mx6-ddr.h> +#include <asm/arch/mx6-pins.h> +#include <asm/arch/mxc_hdmi.h> +#include <asm/arch/sys_proto.h> +#include <asm/bootm.h> +#include <asm/gpio.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/mach-imx/sata.h> +#include <asm/mach-imx/video.h> +#include <dm/device-internal.h> +#include <dm/platform_data/serial_mxc.h> +#include <dwc_ahsata.h> +#include <env.h> +#include <fsl_esdhc_imx.h> +#include <imx_thermal.h> +#include <micrel.h> +#include <miiphy.h> +#include <netdev.h> + +#include "../common/tdx-cfg-block.h" +#ifdef CONFIG_TDX_CMD_IMX_MFGR +#include "pf0100.h" +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_EMMC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) + +#define WEAK_PULLUP (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_SRE_SLOW) + +#define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_HYS | PAD_CTL_SRE_SLOW) + +#define TRISTATE (PAD_CTL_HYS | PAD_CTL_SPEED_MED) + +#define OUTPUT_RGB (PAD_CTL_SPEED_MED|PAD_CTL_DSE_60ohm|PAD_CTL_SRE_FAST) + +#define APALIS_IMX6_SATA_INIT_RETRIES 10 + +int dram_init(void) +{ + /* use the DDR controllers configured size */ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, + (ulong)imx_ddr_size()); + + return 0; +} + +/* Apalis UART1 */ +iomux_v3_cfg_t const uart1_pads_dce[] = { + MX6_PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; +iomux_v3_cfg_t const uart1_pads_dte[] = { + MX6_PAD_CSI0_DAT10__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT11__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +#if defined(CONFIG_FSL_ESDHC_IMX) && defined(CONFIG_SPL_BUILD) +/* Apalis MMC1 */ +iomux_v3_cfg_t const usdhc1_pads[] = { + MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D0__SD1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D1__SD1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D2__SD1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D3__SD1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_DI0_PIN4__GPIO4_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +# define GPIO_MMC_CD IMX_GPIO_NR(4, 20) +}; + +/* Apalis SD1 */ +iomux_v3_cfg_t const usdhc2_pads[] = { + MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_CS1__GPIO6_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +# define GPIO_SD_CD IMX_GPIO_NR(6, 14) +}; + +/* eMMC */ +iomux_v3_cfg_t const usdhc3_pads[] = { + MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(WEAK_PULLUP) | MUX_MODE_SION, +}; +#endif /* CONFIG_FSL_ESDHC_IMX & CONFIG_SPL_BUILD */ + +int mx6_rgmii_rework(struct phy_device *phydev) +{ + int tmp; + + switch (ksz9xx1_phy_get_id(phydev) & MII_KSZ9x31_SILICON_REV_MASK) { + case PHY_ID_KSZ9131: + /* read rxc dll control - devaddr = 0x02, register = 0x4c */ + tmp = ksz9031_phy_extended_read(phydev, 0x02, + MII_KSZ9131_EXT_RGMII_2NS_SKEW_RXDLL, + MII_KSZ9031_MOD_DATA_NO_POST_INC); + /* disable rxdll bypass (enable 2ns skew delay on RXC) */ + tmp &= ~MII_KSZ9131_RXTXDLL_BYPASS; + /* rxc data pad skew 2ns - devaddr = 0x02, register = 0x4c */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9131_EXT_RGMII_2NS_SKEW_RXDLL, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + tmp); + /* read txc dll control - devaddr = 0x02, register = 0x4d */ + tmp = ksz9031_phy_extended_read(phydev, 0x02, + MII_KSZ9131_EXT_RGMII_2NS_SKEW_TXDLL, + MII_KSZ9031_MOD_DATA_NO_POST_INC); + /* disable rxdll bypass (enable 2ns skew delay on TXC) */ + tmp &= ~MII_KSZ9131_RXTXDLL_BYPASS; + /* txc data pad skew 2ns - devaddr = 0x02, register = 0x4d */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9131_EXT_RGMII_2NS_SKEW_TXDLL, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + tmp); + + /* control data pad skew - devaddr = 0x02, register = 0x04 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x007d); + /* rx data pad skew - devaddr = 0x02, register = 0x05 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x7777); + /* tx data pad skew - devaddr = 0x02, register = 0x05 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0xdddd); + /* gtx and rx clock pad skew - devaddr = 0x02,register = 0x08 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x0007); + break; + case PHY_ID_KSZ9031: + default: + /* control data pad skew - devaddr = 0x02, register = 0x04 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x0000); + /* rx data pad skew - devaddr = 0x02, register = 0x05 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x0000); + /* tx data pad skew - devaddr = 0x02, register = 0x05 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x0000); + /* gtx and rx clock pad skew - devaddr = 0x02,register = 0x08 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x03FF); + break; + } + + return 0; +} + +iomux_v3_cfg_t const enet_pads[] = { + MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), + MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), + /* KSZ9031 PHY Reset */ + MX6_PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL) | + MUX_MODE_SION, +# define GPIO_ENET_PHY_RESET IMX_GPIO_NR(1, 25) +}; + +/* mux the Apalis GPIO pins, so they can be used from the U-Boot cmdline */ +iomux_v3_cfg_t const gpio_pads[] = { + /* Apalis GPIO1 - GPIO8 */ + MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_D7__GPIO2_IO07 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_RB0__GPIO6_IO10 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_WP_B__GPIO6_IO09 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(WEAK_PULLDOWN) | + MUX_MODE_SION, + MX6_PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, +}; + +static void setup_iomux_gpio(void) +{ + imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads)); +} + +iomux_v3_cfg_t const usb_pads[] = { + /* USBH_EN */ + MX6_PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL) | MUX_MODE_SION, +# define GPIO_USBH_EN IMX_GPIO_NR(1, 0) + /* USB_VBUS_DET */ + MX6_PAD_EIM_D28__GPIO3_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL), +# define GPIO_USB_VBUS_DET IMX_GPIO_NR(3, 28) + /* USBO1_ID */ + MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(WEAK_PULLUP), + /* USBO1_EN */ + MX6_PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL) | MUX_MODE_SION, +# define GPIO_USBO_EN IMX_GPIO_NR(3, 22) +}; + +/* + * UARTs are used in DTE mode, switch the mode on all UARTs before + * any pinmuxing connects a (DCE) output to a transceiver output. + */ +#define UCR3 0x88 /* FIFO Control Register */ +#define UCR3_RI BIT(8) /* RIDELT DTE mode */ +#define UCR3_DCD BIT(9) /* DCDDELT DTE mode */ +#define UFCR 0x90 /* FIFO Control Register */ +#define UFCR_DCEDTE BIT(6) /* DCE=0 */ + +static void setup_dtemode_uart(void) +{ + setbits_le32((u32 *)(UART1_BASE + UFCR), UFCR_DCEDTE); + setbits_le32((u32 *)(UART2_BASE + UFCR), UFCR_DCEDTE); + setbits_le32((u32 *)(UART4_BASE + UFCR), UFCR_DCEDTE); + setbits_le32((u32 *)(UART5_BASE + UFCR), UFCR_DCEDTE); + + clrbits_le32((u32 *)(UART1_BASE + UCR3), UCR3_DCD | UCR3_RI); + clrbits_le32((u32 *)(UART2_BASE + UCR3), UCR3_DCD | UCR3_RI); + clrbits_le32((u32 *)(UART4_BASE + UCR3), UCR3_DCD | UCR3_RI); + clrbits_le32((u32 *)(UART5_BASE + UCR3), UCR3_DCD | UCR3_RI); +} +static void setup_dcemode_uart(void) +{ + clrbits_le32((u32 *)(UART1_BASE + UFCR), UFCR_DCEDTE); + clrbits_le32((u32 *)(UART2_BASE + UFCR), UFCR_DCEDTE); + clrbits_le32((u32 *)(UART4_BASE + UFCR), UFCR_DCEDTE); + clrbits_le32((u32 *)(UART5_BASE + UFCR), UFCR_DCEDTE); +} + +static void setup_iomux_dte_uart(void) +{ + setup_dtemode_uart(); + imx_iomux_v3_setup_multiple_pads(uart1_pads_dte, + ARRAY_SIZE(uart1_pads_dte)); +} +static void setup_iomux_dce_uart(void) +{ + setup_dcemode_uart(); + imx_iomux_v3_setup_multiple_pads(uart1_pads_dce, + ARRAY_SIZE(uart1_pads_dce)); +} + +#ifdef CONFIG_USB_EHCI_MX6 +int board_ehci_hcd_init(int port) +{ + imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads)); + return 0; +} +#endif + +#if defined(CONFIG_FSL_ESDHC_IMX) && defined(CONFIG_SPL_BUILD) +/* use the following sequence: eMMC, MMC1, SD1 */ +struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { + {USDHC3_BASE_ADDR}, + {USDHC1_BASE_ADDR}, + {USDHC2_BASE_ADDR}, +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = true; /* default: assume inserted */ + + switch (cfg->esdhc_base) { + case USDHC1_BASE_ADDR: + gpio_request(GPIO_MMC_CD, "MMC_CD"); + gpio_direction_input(GPIO_MMC_CD); + ret = !gpio_get_value(GPIO_MMC_CD); + break; + case USDHC2_BASE_ADDR: + gpio_request(GPIO_MMC_CD, "SD_CD"); + gpio_direction_input(GPIO_SD_CD); + ret = !gpio_get_value(GPIO_SD_CD); + break; + } + + return ret; +} + +int board_mmc_init(struct bd_info *bis) +{ + struct src *psrc = (struct src *)SRC_BASE_ADDR; + unsigned reg = readl(&psrc->sbmr1) >> 11; + /* + * Upon reading BOOT_CFG register the following map is done: + * Bit 11 and 12 of BOOT_CFG register can determine the current + * mmc port + * 0x1 SD1 + * 0x2 SD2 + * 0x3 SD4 + */ + + switch (reg & 0x3) { + case 0x0: + imx_iomux_v3_setup_multiple_pads( + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + break; + case 0x1: + imx_iomux_v3_setup_multiple_pads( + usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + break; + case 0x2: + imx_iomux_v3_setup_multiple_pads( + usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + break; + default: + puts("MMC boot device not available"); + } + + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +} +#endif /* CONFIG_FSL_ESDHC_IMX & CONFIG_SPL_BUILD */ + +int board_phy_config(struct phy_device *phydev) +{ + mx6_rgmii_rework(phydev); + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + +static iomux_v3_cfg_t const pwr_intb_pads[] = { + /* + * the bootrom sets the iomux to vselect, potentially connecting + * two outputs. Set this back to GPIO + */ + MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL) +}; + +#if defined(CONFIG_VIDEO_IPUV3) + +static iomux_v3_cfg_t const backlight_pads[] = { + /* Backlight on RGB connector: J15 */ + MX6_PAD_EIM_DA13__GPIO3_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL) | + MUX_MODE_SION, +#define RGB_BACKLIGHT_GP IMX_GPIO_NR(3, 13) + /* additional CPU pin on BKL_PWM, keep in tristate */ + MX6_PAD_EIM_DA14__GPIO3_IO14 | MUX_PAD_CTRL(TRISTATE), + /* Backlight PWM, used as GPIO in U-Boot */ + MX6_PAD_SD4_DAT2__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL) | + MUX_MODE_SION, +#define RGB_BACKLIGHTPWM_GP IMX_GPIO_NR(2, 10) + /* buffer output enable 0: buffer enabled */ + MX6_PAD_EIM_A25__GPIO5_IO02 | MUX_PAD_CTRL(WEAK_PULLUP) | MUX_MODE_SION, +#define RGB_BACKLIGHTPWM_OE IMX_GPIO_NR(5, 2) + /* PSAVE# integrated VDAC */ + MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL) | + MUX_MODE_SION, +#define VGA_PSAVE_NOT_GP IMX_GPIO_NR(6, 31) +}; + +static iomux_v3_cfg_t const rgb_pads[] = { + MX6_PAD_EIM_A16__IPU1_DI1_DISP_CLK | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA10__IPU1_DI1_PIN15 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA11__IPU1_DI1_PIN02 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA12__IPU1_DI1_PIN03 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA9__IPU1_DISP1_DATA00 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA8__IPU1_DISP1_DATA01 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA7__IPU1_DISP1_DATA02 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA6__IPU1_DISP1_DATA03 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA5__IPU1_DISP1_DATA04 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA4__IPU1_DISP1_DATA05 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA3__IPU1_DISP1_DATA06 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA2__IPU1_DISP1_DATA07 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA1__IPU1_DISP1_DATA08 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_DA0__IPU1_DISP1_DATA09 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_EB1__IPU1_DISP1_DATA10 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_EB0__IPU1_DISP1_DATA11 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_A17__IPU1_DISP1_DATA12 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_A18__IPU1_DISP1_DATA13 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_A19__IPU1_DISP1_DATA14 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_A20__IPU1_DISP1_DATA15 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_A21__IPU1_DISP1_DATA16 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_A22__IPU1_DISP1_DATA17 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_A23__IPU1_DISP1_DATA18 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_A24__IPU1_DISP1_DATA19 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_D26__IPU1_DISP1_DATA22 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_D27__IPU1_DISP1_DATA23 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_D30__IPU1_DISP1_DATA21 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_EIM_D31__IPU1_DISP1_DATA20 | MUX_PAD_CTRL(OUTPUT_RGB), +}; + +static void do_enable_hdmi(struct display_info_t const *dev) +{ + imx_enable_hdmi_phy(); +} + +static void enable_lvds(struct display_info_t const *dev) +{ + struct iomuxc *iomux = (struct iomuxc *) + IOMUXC_BASE_ADDR; + u32 reg = readl(&iomux->gpr[2]); + reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT; + writel(reg, &iomux->gpr[2]); + gpio_direction_output(RGB_BACKLIGHT_GP, 1); + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0); + gpio_direction_output(RGB_BACKLIGHTPWM_OE, 0); +} + +static void enable_rgb(struct display_info_t const *dev) +{ + imx_iomux_v3_setup_multiple_pads( + rgb_pads, + ARRAY_SIZE(rgb_pads)); + gpio_direction_output(RGB_BACKLIGHT_GP, 1); + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0); + gpio_direction_output(RGB_BACKLIGHTPWM_OE, 0); +} + +static int detect_default(struct display_info_t const *dev) +{ + (void) dev; + return 1; +} + +struct display_info_t const displays[] = {{ + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB24, + .detect = detect_hdmi, + .enable = do_enable_hdmi, + .mode = { + .name = "HDMI", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15385, + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED +} }, { + .bus = -1, + .addr = 0, + .di = 1, + .pixfmt = IPU_PIX_FMT_RGB24, + .detect = detect_default, + .enable = enable_rgb, + .mode = { + .name = "vga-rgb", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 33000, + .left_margin = 48, + .right_margin = 16, + .upper_margin = 31, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED +} }, { + .bus = -1, + .addr = 0, + .di = 1, + .pixfmt = IPU_PIX_FMT_RGB24, + .enable = enable_rgb, + .mode = { + .name = "wvga-rgb", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = 25000, + .left_margin = 40, + .right_margin = 88, + .upper_margin = 33, + .lower_margin = 10, + .hsync_len = 128, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED +} }, { + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_LVDS666, + .enable = enable_lvds, + .mode = { + .name = "wsvga-lvds", + .refresh = 60, + .xres = 1024, + .yres = 600, + .pixclock = 15385, + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED +} } }; +size_t display_count = ARRAY_SIZE(displays); + +static void setup_display(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + int reg; + + enable_ipu_clock(); + imx_setup_hdmi(); + /* Turn on LDB0,IPU,IPU DI0 clocks */ + reg = __raw_readl(&mxc_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_LDB_DI0_MASK; + writel(reg, &mxc_ccm->CCGR3); + + /* set LDB0, LDB1 clk select to 011/011 */ + reg = readl(&mxc_ccm->cs2cdr); + reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK + |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK); + reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) + |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET); + writel(reg, &mxc_ccm->cs2cdr); + + reg = readl(&mxc_ccm->cscmr2); + reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV; + writel(reg, &mxc_ccm->cscmr2); + + reg = readl(&mxc_ccm->chsccdr); + reg |= (CHSCCDR_CLK_SEL_LDB_DI0 + <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); + writel(reg, &mxc_ccm->chsccdr); + + reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES + |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH + |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW + |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG + |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT + |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG + |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT + |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED + |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0; + writel(reg, &iomux->gpr[2]); + + reg = readl(&iomux->gpr[3]); + reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK + |IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) + | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 + <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET); + writel(reg, &iomux->gpr[3]); + + /* backlight unconditionally on for now */ + imx_iomux_v3_setup_multiple_pads(backlight_pads, + ARRAY_SIZE(backlight_pads)); + /* use 0 for EDT 7", use 1 for LG fullHD panel */ + gpio_request(RGB_BACKLIGHTPWM_GP, "BKL1_PWM"); + gpio_request(RGB_BACKLIGHTPWM_OE, "BKL1_PWM_EN"); + gpio_request(RGB_BACKLIGHT_GP, "BKL1_ON"); + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0); + gpio_direction_output(RGB_BACKLIGHTPWM_OE, 0); + gpio_direction_output(RGB_BACKLIGHT_GP, 1); +} + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 1); + gpio_direction_output(RGB_BACKLIGHT_GP, 0); +} +#endif /* defined(CONFIG_VIDEO_IPUV3) */ + +int board_early_init_f(void) +{ + imx_iomux_v3_setup_multiple_pads(pwr_intb_pads, + ARRAY_SIZE(pwr_intb_pads)); +#ifndef CONFIG_TDX_APALIS_IMX6_V1_0 + setup_iomux_dte_uart(); +#else + setup_iomux_dce_uart(); +#endif + return 0; +} + +/* + * Do not overwrite the console + * Use always serial for U-Boot console + */ +int overwrite_console(void) +{ + return 1; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#if defined(CONFIG_VIDEO_IPUV3) + setup_display(); +#endif + +#ifdef CONFIG_TDX_CMD_IMX_MFGR + (void) pmic_init(); +#endif + +#ifdef CONFIG_SATA + setup_sata(); +#endif + + setup_iomux_gpio(); + + return 0; +} + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ +#if defined(CONFIG_REVISION_TAG) && \ + defined(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG) + char env_str[256]; + u32 rev; + + rev = get_board_rev(); + snprintf(env_str, ARRAY_SIZE(env_str), "%.4x", rev); + env_set("board_rev", env_str); + +#ifndef CONFIG_TDX_APALIS_IMX6_V1_0 + if ((rev & 0xfff0) == 0x0100) { + char *fdt_env; + + /* reconfigure the UART to DCE mode dynamically if on V1.0 HW */ + setup_iomux_dce_uart(); + + /* if using the default device tree, use version for V1.0 HW */ + fdt_env = env_get("fdt_file"); + if ((fdt_env != NULL) && (strcmp(FDT_FILE, fdt_env) == 0)) { + env_set("fdt_file", FDT_FILE_V1_0); + printf("patching fdt_file to " FDT_FILE_V1_0 "\n"); +#ifndef CONFIG_ENV_IS_NOWHERE + env_save(); +#endif + } + } +#endif /* CONFIG_TDX_APALIS_IMX6_V1_0 */ +#endif /* CONFIG_REVISION_TAG */ + +#ifdef CONFIG_CMD_USB_SDP + if (is_boot_from_usb()) { + printf("Serial Downloader recovery mode, using sdp command\n"); + env_set("bootdelay", "0"); + env_set("bootcmd", "sdp 0"); + } +#endif /* CONFIG_CMD_USB_SDP */ + + return 0; +} +#endif /* CONFIG_BOARD_LATE_INIT */ + +int checkboard(void) +{ + char it[] = " IT"; + int minc, maxc; + + switch (get_cpu_temp_grade(&minc, &maxc)) { + case TEMP_AUTOMOTIVE: + case TEMP_INDUSTRIAL: + break; + case TEMP_EXTCOMMERCIAL: + default: + it[0] = 0; + }; + printf("Model: Toradex Apalis iMX6 %s %s%s\n", + is_cpu_type(MXC_CPU_MX6D) ? "Dual" : "Quad", + (gd->ram_size == 0x80000000) ? "2GB" : + (gd->ram_size == 0x40000000) ? "1GB" : "512MB", it); + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +#ifdef CONFIG_CMD_BMODE +static const struct boot_mode board_boot_modes[] = { + /* 4-bit bus width */ + {"mmc", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, + {"sd", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, + {NULL, 0}, +}; +#endif + +int misc_init_r(void) +{ +#ifdef CONFIG_CMD_BMODE + add_board_boot_modes(board_boot_modes); +#endif + return 0; +} + +#ifdef CONFIG_LDO_BYPASS_CHECK +/* TODO, use external pmic, for now always ldo_enable */ +void ldo_mode_set(int ldo_bypass) +{ + return; +} +#endif + +#ifdef CONFIG_SPL_BUILD +#include <spl.h> +#include <linux/libfdt.h> +#include "asm/arch/mx6q-ddr.h" +#include "asm/arch/iomux.h" +#include "asm/arch/crm_regs.h" + +static int mx6_com_dcd_table[] = { +/* ddr-setup.cfg */ +MX6_IOM_DRAM_SDQS0, 0x00000030, +MX6_IOM_DRAM_SDQS1, 0x00000030, +MX6_IOM_DRAM_SDQS2, 0x00000030, +MX6_IOM_DRAM_SDQS3, 0x00000030, +MX6_IOM_DRAM_SDQS4, 0x00000030, +MX6_IOM_DRAM_SDQS5, 0x00000030, +MX6_IOM_DRAM_SDQS6, 0x00000030, +MX6_IOM_DRAM_SDQS7, 0x00000030, + +MX6_IOM_GRP_B0DS, 0x00000030, +MX6_IOM_GRP_B1DS, 0x00000030, +MX6_IOM_GRP_B2DS, 0x00000030, +MX6_IOM_GRP_B3DS, 0x00000030, +MX6_IOM_GRP_B4DS, 0x00000030, +MX6_IOM_GRP_B5DS, 0x00000030, +MX6_IOM_GRP_B6DS, 0x00000030, +MX6_IOM_GRP_B7DS, 0x00000030, +MX6_IOM_GRP_ADDDS, 0x00000030, +/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ +MX6_IOM_GRP_CTLDS, 0x00000030, + +MX6_IOM_DRAM_DQM0, 0x00020030, +MX6_IOM_DRAM_DQM1, 0x00020030, +MX6_IOM_DRAM_DQM2, 0x00020030, +MX6_IOM_DRAM_DQM3, 0x00020030, +MX6_IOM_DRAM_DQM4, 0x00020030, +MX6_IOM_DRAM_DQM5, 0x00020030, +MX6_IOM_DRAM_DQM6, 0x00020030, +MX6_IOM_DRAM_DQM7, 0x00020030, + +MX6_IOM_DRAM_CAS, 0x00020030, +MX6_IOM_DRAM_RAS, 0x00020030, +MX6_IOM_DRAM_SDCLK_0, 0x00020030, +MX6_IOM_DRAM_SDCLK_1, 0x00020030, + +MX6_IOM_DRAM_RESET, 0x00020030, +MX6_IOM_DRAM_SDCKE0, 0x00003000, +MX6_IOM_DRAM_SDCKE1, 0x00003000, + +MX6_IOM_DRAM_SDODT0, 0x00003030, +MX6_IOM_DRAM_SDODT1, 0x00003030, + +/* (differential input) */ +MX6_IOM_DDRMODE_CTL, 0x00020000, +/* (differential input) */ +MX6_IOM_GRP_DDRMODE, 0x00020000, +/* disable ddr pullups */ +MX6_IOM_GRP_DDRPKE, 0x00000000, +MX6_IOM_DRAM_SDBA2, 0x00000000, +/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ +MX6_IOM_GRP_DDR_TYPE, 0x000C0000, + +/* Read data DQ Byte0-3 delay */ +MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333, + +/* + * MDMISC mirroring interleaved (row/bank/col) + */ +MX6_MMDC_P0_MDMISC, 0x00081740, + +/* + * MDSCR con_req + */ +MX6_MMDC_P0_MDSCR, 0x00008000, + +/* 1066mhz_4x128mx16.cfg */ + +MX6_MMDC_P0_MDPDC, 0x00020036, +MX6_MMDC_P0_MDCFG0, 0x555A7954, +MX6_MMDC_P0_MDCFG1, 0xDB328F64, +MX6_MMDC_P0_MDCFG2, 0x01FF00DB, +MX6_MMDC_P0_MDRWD, 0x000026D2, +MX6_MMDC_P0_MDOR, 0x005A1023, +MX6_MMDC_P0_MDOTC, 0x09555050, +MX6_MMDC_P0_MDPDC, 0x00025576, +MX6_MMDC_P0_MDASP, 0x00000027, +MX6_MMDC_P0_MDCTL, 0x831A0000, +MX6_MMDC_P0_MDSCR, 0x04088032, +MX6_MMDC_P0_MDSCR, 0x00008033, +MX6_MMDC_P0_MDSCR, 0x00428031, +MX6_MMDC_P0_MDSCR, 0x19308030, +MX6_MMDC_P0_MDSCR, 0x04008040, +MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003, +MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003, +MX6_MMDC_P0_MDREF, 0x00005800, +MX6_MMDC_P0_MPODTCTRL, 0x00000000, +MX6_MMDC_P1_MPODTCTRL, 0x00000000, + +MX6_MMDC_P0_MPDGCTRL0, 0x432A0338, +MX6_MMDC_P0_MPDGCTRL1, 0x03260324, +MX6_MMDC_P1_MPDGCTRL0, 0x43340344, +MX6_MMDC_P1_MPDGCTRL1, 0x031E027C, + +MX6_MMDC_P0_MPRDDLCTL, 0x33272D2E, +MX6_MMDC_P1_MPRDDLCTL, 0x2F312B37, + +MX6_MMDC_P0_MPWRDLCTL, 0x3A35433C, +MX6_MMDC_P1_MPWRDLCTL, 0x4336453F, + +MX6_MMDC_P0_MPWLDECTRL0, 0x0009000E, +MX6_MMDC_P0_MPWLDECTRL1, 0x0018000B, +MX6_MMDC_P1_MPWLDECTRL0, 0x00060015, +MX6_MMDC_P1_MPWLDECTRL1, 0x0006000E, + +MX6_MMDC_P0_MPMUR0, 0x00000800, +MX6_MMDC_P1_MPMUR0, 0x00000800, +MX6_MMDC_P0_MDSCR, 0x00000000, +MX6_MMDC_P0_MAPSR, 0x00011006, +}; + +static int mx6_it_dcd_table[] = { +/* ddr-setup.cfg */ +MX6_IOM_DRAM_SDQS0, 0x00000030, +MX6_IOM_DRAM_SDQS1, 0x00000030, +MX6_IOM_DRAM_SDQS2, 0x00000030, +MX6_IOM_DRAM_SDQS3, 0x00000030, +MX6_IOM_DRAM_SDQS4, 0x00000030, +MX6_IOM_DRAM_SDQS5, 0x00000030, +MX6_IOM_DRAM_SDQS6, 0x00000030, +MX6_IOM_DRAM_SDQS7, 0x00000030, + +MX6_IOM_GRP_B0DS, 0x00000030, +MX6_IOM_GRP_B1DS, 0x00000030, +MX6_IOM_GRP_B2DS, 0x00000030, +MX6_IOM_GRP_B3DS, 0x00000030, +MX6_IOM_GRP_B4DS, 0x00000030, +MX6_IOM_GRP_B5DS, 0x00000030, +MX6_IOM_GRP_B6DS, 0x00000030, +MX6_IOM_GRP_B7DS, 0x00000030, +MX6_IOM_GRP_ADDDS, 0x00000030, +/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ +MX6_IOM_GRP_CTLDS, 0x00000030, + +MX6_IOM_DRAM_DQM0, 0x00020030, +MX6_IOM_DRAM_DQM1, 0x00020030, +MX6_IOM_DRAM_DQM2, 0x00020030, +MX6_IOM_DRAM_DQM3, 0x00020030, +MX6_IOM_DRAM_DQM4, 0x00020030, +MX6_IOM_DRAM_DQM5, 0x00020030, +MX6_IOM_DRAM_DQM6, 0x00020030, +MX6_IOM_DRAM_DQM7, 0x00020030, + +MX6_IOM_DRAM_CAS, 0x00020030, +MX6_IOM_DRAM_RAS, 0x00020030, +MX6_IOM_DRAM_SDCLK_0, 0x00020030, +MX6_IOM_DRAM_SDCLK_1, 0x00020030, + +MX6_IOM_DRAM_RESET, 0x00020030, +MX6_IOM_DRAM_SDCKE0, 0x00003000, +MX6_IOM_DRAM_SDCKE1, 0x00003000, + +MX6_IOM_DRAM_SDODT0, 0x00003030, +MX6_IOM_DRAM_SDODT1, 0x00003030, + +/* (differential input) */ +MX6_IOM_DDRMODE_CTL, 0x00020000, +/* (differential input) */ +MX6_IOM_GRP_DDRMODE, 0x00020000, +/* disable ddr pullups */ +MX6_IOM_GRP_DDRPKE, 0x00000000, +MX6_IOM_DRAM_SDBA2, 0x00000000, +/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ +MX6_IOM_GRP_DDR_TYPE, 0x000C0000, + +/* Read data DQ Byte0-3 delay */ +MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333, + +/* + * MDMISC mirroring interleaved (row/bank/col) + */ +MX6_MMDC_P0_MDMISC, 0x00081740, + +/* + * MDSCR con_req + */ +MX6_MMDC_P0_MDSCR, 0x00008000, + +/* 1066mhz_4x256mx16.cfg */ + +MX6_MMDC_P0_MDPDC, 0x00020036, +MX6_MMDC_P0_MDCFG0, 0x898E78f5, +MX6_MMDC_P0_MDCFG1, 0xff328f64, +MX6_MMDC_P0_MDCFG2, 0x01FF00DB, +MX6_MMDC_P0_MDRWD, 0x000026D2, +MX6_MMDC_P0_MDOR, 0x008E1023, +MX6_MMDC_P0_MDOTC, 0x09444040, +MX6_MMDC_P0_MDPDC, 0x00025576, +MX6_MMDC_P0_MDASP, 0x00000047, +MX6_MMDC_P0_MDCTL, 0x841A0000, +MX6_MMDC_P0_MDSCR, 0x02888032, +MX6_MMDC_P0_MDSCR, 0x00008033, +MX6_MMDC_P0_MDSCR, 0x00048031, +MX6_MMDC_P0_MDSCR, 0x19408030, +MX6_MMDC_P0_MDSCR, 0x04008040, +MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003, +MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003, +MX6_MMDC_P0_MDREF, 0x00007800, +MX6_MMDC_P0_MPODTCTRL, 0x00022227, +MX6_MMDC_P1_MPODTCTRL, 0x00022227, + +MX6_MMDC_P0_MPDGCTRL0, 0x03300338, +MX6_MMDC_P0_MPDGCTRL1, 0x03240324, +MX6_MMDC_P1_MPDGCTRL0, 0x03440350, +MX6_MMDC_P1_MPDGCTRL1, 0x032C0308, + +MX6_MMDC_P0_MPRDDLCTL, 0x40363C3E, +MX6_MMDC_P1_MPRDDLCTL, 0x3C3E3C46, + +MX6_MMDC_P0_MPWRDLCTL, 0x403E463E, +MX6_MMDC_P1_MPWRDLCTL, 0x4A384C46, + +MX6_MMDC_P0_MPWLDECTRL0, 0x0009000E, +MX6_MMDC_P0_MPWLDECTRL1, 0x0018000B, +MX6_MMDC_P1_MPWLDECTRL0, 0x00060015, +MX6_MMDC_P1_MPWLDECTRL1, 0x0006000E, + +MX6_MMDC_P0_MPMUR0, 0x00000800, +MX6_MMDC_P1_MPMUR0, 0x00000800, +MX6_MMDC_P0_MDSCR, 0x00000000, +MX6_MMDC_P0_MAPSR, 0x00011006, +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFFFF3, &ccm->CCGR2); + writel(0x3FF0300F, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0000F3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); + +/* + * Setup CCM_CCOSR register as follows: + * + * cko1_en = 1 --> CKO1 enabled + * cko1_div = 111 --> divide by 8 + * cko1_sel = 1011 --> ahb_clk_root + * + * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz + */ + writel(0x000000FB, &ccm->ccosr); +} + +static void ddr_init(int *table, int size) +{ + int i; + + for (i = 0; i < size / 2 ; i++) + writel(table[2 * i + 1], table[2 * i]); +} + +static void spl_dram_init(void) +{ + int minc, maxc; + + switch (get_cpu_temp_grade(&minc, &maxc)) { + case TEMP_COMMERCIAL: + case TEMP_EXTCOMMERCIAL: + puts("Commercial temperature grade DDR3 timings.\n"); + ddr_init(mx6_com_dcd_table, ARRAY_SIZE(mx6_com_dcd_table)); + break; + case TEMP_INDUSTRIAL: + case TEMP_AUTOMOTIVE: + default: + puts("Industrial temperature grade DDR3 timings.\n"); + ddr_init(mx6_it_dcd_table, ARRAY_SIZE(mx6_it_dcd_table)); + break; + }; + udelay(100); +} + +void board_init_f(ulong dummy) +{ + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + ccgr_init(); + gpr_init(); + + /* iomux */ + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + +#ifndef CONFIG_TDX_APALIS_IMX6_V1_0 + /* Make sure we use dte mode */ + setup_dtemode_uart(); +#endif + + /* DDR initialization */ + spl_dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + if (!strcmp(name, "imx6-apalis")) + return 0; + + return -1; +} +#endif + +void reset_cpu(void) +{ +} + +#endif /* CONFIG_SPL_BUILD */ + +static struct mxc_serial_plat mxc_serial_plat = { + .reg = (struct mxc_uart *)UART1_BASE, + .use_dte = true, +}; + +U_BOOT_DRVINFO(mxc_serial) = { + .name = "serial_mxc", + .plat = &mxc_serial_plat, +}; diff --git a/roms/u-boot/board/toradex/apalis_imx6/do_fuse.c b/roms/u-boot/board/toradex/apalis_imx6/do_fuse.c new file mode 100644 index 000000000..6991b1bc1 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_imx6/do_fuse.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014-2016, Toradex AG + */ + +/* + * Helpers for i.MX OTP fusing during module production +*/ + +#include <common.h> +#ifndef CONFIG_SPL_BUILD +#include <command.h> +#include <console.h> +#include <fuse.h> + +static int mfgr_fuse(void) +{ + unsigned val, val6; + + fuse_sense(0, 5, &val); + printf("Fuse 0, 5: %8x\n", val); + fuse_sense(0, 6, &val6); + printf("Fuse 0, 6: %8x\n", val6); + fuse_sense(4, 3, &val); + printf("Fuse 4, 3: %8x\n", val); + fuse_sense(4, 2, &val); + printf("Fuse 4, 2: %8x\n", val); + if (val6 & 0x10) { + puts("BT_FUSE_SEL already fused, will do nothing\n"); + return CMD_RET_FAILURE; + } + /* boot cfg */ + fuse_prog(0, 5, 0x00005062); + /* BT_FUSE_SEL */ + fuse_prog(0, 6, 0x00000010); + return CMD_RET_SUCCESS; +} + +int do_mfgr_fuse(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + puts("Fusing...\n"); + ret = mfgr_fuse(); + if (ret == CMD_RET_SUCCESS) + puts("done.\n"); + else + puts("failed.\n"); + return ret; +} + +int do_updt_fuse(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + unsigned val; + int ret; + int confirmed = argc >= 1 && !strcmp(argv[1], "-y"); + + /* can be used in scripts for command availability check */ + if (argc >= 1 && !strcmp(argv[1], "-n")) + return CMD_RET_SUCCESS; + + /* boot cfg */ + fuse_sense(0, 5, &val); + printf("Fuse 0, 5: %8x\n", val); + if (val & 0x10) { + puts("Fast boot mode already fused, no need to fuse\n"); + return CMD_RET_SUCCESS; + } + if (!confirmed) { + puts("Warning: Programming fuses is an irreversible operation!\n" + " Updating to fast boot mode prevents easy\n" + " downgrading to previous BSP versions.\n" + "\nReally perform this fuse programming? <y/N>\n"); + if (!confirm_yesno()) + return CMD_RET_FAILURE; + } + puts("Fusing fast boot mode...\n"); + ret = fuse_prog(0, 5, 0x00005072); + if (ret == CMD_RET_SUCCESS) + puts("done.\n"); + else + puts("failed.\n"); + return ret; +} + +U_BOOT_CMD( + mfgr_fuse, 1, 0, do_mfgr_fuse, + "OTP fusing during module production", + "" +); + +U_BOOT_CMD( + updt_fuse, 2, 0, do_updt_fuse, + "OTP fusing during module update", + "updt_fuse [-n] [-y] - boot cfg fast boot mode fusing" +); +#endif /* CONFIG_SPL_BUILD */ diff --git a/roms/u-boot/board/toradex/apalis_imx6/pf0100.c b/roms/u-boot/board/toradex/apalis_imx6/pf0100.c new file mode 100644 index 000000000..c89052ff5 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_imx6/pf0100.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014-2019, Toradex AG + */ + +/* + * Helpers for Freescale PMIC PF0100 +*/ + +#include <common.h> +#include <command.h> +#include <i2c.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux.h> +#include <asm/arch/mx6-pins.h> +#include <asm/gpio.h> +#include <asm/mach-imx/iomux-v3.h> +#include <linux/delay.h> + +#include "pf0100_otp.inc" +#include "pf0100.h" + +/* define for PMIC register dump */ +/*#define DEBUG */ + +#define WARNBAR "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" + +/* use Apalis GPIO1 to switch on VPGM, ON: 1 */ +static __maybe_unused iomux_v3_cfg_t const pmic_prog_pads[] = { + MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL), +# define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 4) +}; + +unsigned pmic_init(void) +{ + int rc; + struct udevice *dev = NULL; + unsigned programmed = 0; + uchar bus = 1; + uchar devid, revid, val; + + puts("PMIC: "); + rc = i2c_get_chip_for_busnum(bus, PFUZE100_I2C_ADDR, 1, &dev); + if (rc) { + printf("failed to get device for PMIC at address 0x%x\n", + PFUZE100_I2C_ADDR); + return 0; + } + + /* check for errors in PMIC fuses */ + if (dm_i2c_read(dev, PFUZE100_INTSTAT3, &val, 1) < 0) { + puts("i2c pmic INTSTAT3 register read failed\n"); + return 0; + } + if (val & PFUZE100_BIT_OTP_ECCI) { + puts("\n" WARNBAR); + puts("WARNING: ecc errors found in pmic fuse banks\n"); + puts(WARNBAR); + } + if (dm_i2c_read(dev, PFUZE100_OTP_ECC_SE1, &val, 1) < 0) { + puts("i2c pmic ECC_SE1 register read failed\n"); + return 0; + } + if (val & PFUZE100_BITS_ECC_SE1) { + puts(WARNBAR); + puts("WARNING: ecc has made bit corrections in banks 1 to 5\n"); + puts(WARNBAR); + } + if (dm_i2c_read(dev, PFUZE100_OTP_ECC_SE2, &val, 1) < 0) { + puts("i2c pmic ECC_SE2 register read failed\n"); + return 0; + } + if (val & PFUZE100_BITS_ECC_SE2) { + puts(WARNBAR); + puts("WARNING: ecc has made bit corrections in banks 6 to 10\n" + ); + puts(WARNBAR); + } + if (dm_i2c_read(dev, PFUZE100_OTP_ECC_DE1, &val, 1) < 0) { + puts("i2c pmic ECC_DE register read failed\n"); + return 0; + } + if (val & PFUZE100_BITS_ECC_DE1) { + puts(WARNBAR); + puts("ERROR: banks 1 to 5 have uncorrectable bits\n"); + puts(WARNBAR); + } + if (dm_i2c_read(dev, PFUZE100_OTP_ECC_DE2, &val, 1) < 0) { + puts("i2c pmic ECC_DE register read failed\n"); + return 0; + } + if (val & PFUZE100_BITS_ECC_DE2) { + puts(WARNBAR); + puts("ERROR: banks 6 to 10 have uncorrectable bits\n"); + puts(WARNBAR); + } + + /* get device ident */ + if (dm_i2c_read(dev, PFUZE100_DEVICEID, &devid, 1) < 0) { + puts("i2c pmic devid read failed\n"); + return 0; + } + if (dm_i2c_read(dev, PFUZE100_REVID, &revid, 1) < 0) { + puts("i2c pmic revid read failed\n"); + return 0; + } + printf("device id: 0x%.2x, revision id: 0x%.2x, ", devid, revid); + + /* get device programmed state */ + val = PFUZE100_PAGE_REGISTER_PAGE1; + if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) { + puts("i2c write failed\n"); + return 0; + } + if (dm_i2c_read(dev, PFUZE100_FUSE_POR1, &val, 1) < 0) { + puts("i2c fuse_por read failed\n"); + return 0; + } + if (val & PFUZE100_FUSE_POR_M) + programmed++; + + if (dm_i2c_read(dev, PFUZE100_FUSE_POR2, &val, 1) < 0) { + puts("i2c fuse_por read failed\n"); + return programmed; + } + if (val & PFUZE100_FUSE_POR_M) + programmed++; + + if (dm_i2c_read(dev, PFUZE100_FUSE_POR3, &val, 1) < 0) { + puts("i2c fuse_por read failed\n"); + return programmed; + } + if (val & PFUZE100_FUSE_POR_M) + programmed++; + + switch (programmed) { + case 0: + puts("not programmed\n"); + break; + case 3: + puts("programmed\n"); + break; + default: + puts("undefined programming state\n"); + break; + } + + /* The following is needed during production */ + if (programmed != 3) { + /* set VGEN1 to 1.2V */ + val = PFUZE100_VGEN1_VAL; + if (dm_i2c_write(dev, PFUZE100_VGEN1CTL, &val, 1)) { + puts("i2c write failed\n"); + return programmed; + } + + /* set SWBST to 5.0V */ + val = PFUZE100_SWBST_VAL; + if (dm_i2c_write(dev, PFUZE100_SWBSTCTL, &val, 1)) + puts("i2c write failed\n"); + } + +#ifdef DEBUG + { + unsigned int i, j; + + for (i = 0; i < 16; i++) + printf("\t%x", i); + for (j = 0; j < 0x80; ) { + printf("\n%2x", j); + for (i = 0; i < 16; i++) { + dm_i2c_read(dev, j + i, &val, 1); + printf("\t%2x", val); + } + j += 0x10; + } + printf("\nEXT Page 1"); + + val = PFUZE100_PAGE_REGISTER_PAGE1; + if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) { + puts("i2c write failed\n"); + return 0; + } + + for (j = 0x80; j < 0x100; ) { + printf("\n%2x", j); + for (i = 0; i < 16; i++) { + dm_i2c_read(dev, j + i, &val, 1); + printf("\t%2x", val); + } + j += 0x10; + } + printf("\nEXT Page 2"); + + val = PFUZE100_PAGE_REGISTER_PAGE2; + if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) { + puts("i2c write failed\n"); + return 0; + } + + for (j = 0x80; j < 0x100; ) { + printf("\n%2x", j); + for (i = 0; i < 16; i++) { + dm_i2c_read(dev, j + i, &val, 1); + printf("\t%2x", val); + } + j += 0x10; + } + printf("\n"); + } +#endif /* DEBUG */ + + return programmed; +} + +#ifndef CONFIG_SPL_BUILD +static int pf0100_prog(void) +{ + int rc; + struct udevice *dev = NULL; + unsigned char bus = 1; + unsigned char val; + unsigned int i; + + if (pmic_init() == 3) { + puts("PMIC already programmed, exiting\n"); + return CMD_RET_FAILURE; + } + /* set up gpio to manipulate vprog, initially off */ + imx_iomux_v3_setup_multiple_pads(pmic_prog_pads, + ARRAY_SIZE(pmic_prog_pads)); + gpio_direction_output(PMIC_PROG_VOLTAGE, 0); + + rc = i2c_get_chip_for_busnum(bus, PFUZE100_I2C_ADDR, 1, &dev); + if (rc) { + printf("failed to get device for PMIC at address 0x%x\n", + PFUZE100_I2C_ADDR); + return CMD_RET_FAILURE; + } + + for (i = 0; i < ARRAY_SIZE(pmic_otp_prog); i++) { + switch (pmic_otp_prog[i].cmd) { + case pmic_i2c: + val = (unsigned char) (pmic_otp_prog[i].value & 0xff); + if (dm_i2c_write(dev, pmic_otp_prog[i].reg, &val, 1)) { + printf("i2c write failed, reg 0x%2x, value 0x%2x\n", + pmic_otp_prog[i].reg, val); + return CMD_RET_FAILURE; + } + break; + case pmic_delay: + udelay(pmic_otp_prog[i].value * 1000); + break; + case pmic_vpgm: + gpio_direction_output(PMIC_PROG_VOLTAGE, + pmic_otp_prog[i].value); + break; + case pmic_pwr: + /* TODO */ + break; + } + } + return CMD_RET_SUCCESS; +} + +static int do_pf0100_prog(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + puts("Programming PMIC OTP..."); + ret = pf0100_prog(); + if (ret == CMD_RET_SUCCESS) + puts("done.\n"); + else + puts("failed.\n"); + return ret; +} + +U_BOOT_CMD( + pf0100_otp_prog, 1, 0, do_pf0100_prog, + "Program the OTP fuses on the PMIC PF0100", + "" +); +#endif /* CONFIG_SPL_BUILD */ diff --git a/roms/u-boot/board/toradex/apalis_imx6/pf0100.h b/roms/u-boot/board/toradex/apalis_imx6/pf0100.h new file mode 100644 index 000000000..925762051 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_imx6/pf0100.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2014-2019, Toradex AG + */ + +/* + * Helpers for Freescale PMIC PF0100 +*/ + +#ifndef PF0100_H_ +#define PF0100_H_ + +/* bit definitions */ +#define PFUZE100_BIT_0 (0x01 << 0) +#define PFUZE100_BIT_1 (0x01 << 1) +#define PFUZE100_BIT_2 (0x01 << 2) +#define PFUZE100_BIT_3 (0x01 << 3) +#define PFUZE100_BIT_4 (0x01 << 4) +#define PFUZE100_BIT_5 (0x01 << 5) +#define PFUZE100_BIT_6 (0x01 << 6) +#define PFUZE100_BIT_7 (0x01 << 7) + +/* 7-bit I2C bus slave address */ +#define PFUZE100_I2C_ADDR (0x08) +/* Register Addresses */ +#define PFUZE100_DEVICEID (0x0) +#define PFUZE100_REVID (0x3) +#define PFUZE100_INTSTAT3 (0xe) +#define PFUZE100_BIT_OTP_ECCI PFUZE100_BIT_7 +#define PFUZE100_SW1AMODE (0x23) +#define PFUZE100_SW1ACON 36 +#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */ +#define PFUZE100_SW1ACON_SPEED_M (0x3<<6) +#define PFUZE100_SW1CCON 49 +#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */ +#define PFUZE100_SW1CCON_SPEED_M (0x3<<6) +#define PFUZE100_SW1AVOL 32 +#define PFUZE100_SW1AVOL_VSEL_M (0x3f<<0) +#define PFUZE100_SW1CVOL 46 +#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0) +#define PFUZE100_VGEN1CTL (0x6c) +#define PFUZE100_VGEN1_VAL (0x30 + 0x08) /* Always ON, 1.2V */ +#define PFUZE100_SWBSTCTL (0x66) +/* Always ON, Auto Switching Mode, 5.0V */ +#define PFUZE100_SWBST_VAL (0x40 + 0x08 + 0x00) + +/* chooses the extended page (registers 0x80..0xff) */ +#define PFUZE100_PAGE_REGISTER 0x7f +#define PFUZE100_PAGE_REGISTER_PAGE_M (0x1f << 0) +#define PFUZE100_PAGE_REGISTER_PAGE1 (0x01 & PFUZE100_PAGE_REGISTER_PAGE_M) +#define PFUZE100_PAGE_REGISTER_PAGE2 (0x02 & PFUZE100_PAGE_REGISTER_PAGE_M) + +/* extended page 1 */ +#define PFUZE100_OTP_ECC_SE1 0x8a +#define PFUZE100_BIT_ECC1_SE PFUZE100_BIT_0 +#define PFUZE100_BIT_ECC2_SE PFUZE100_BIT_1 +#define PFUZE100_BIT_ECC3_SE PFUZE100_BIT_2 +#define PFUZE100_BIT_ECC4_SE PFUZE100_BIT_3 +#define PFUZE100_BIT_ECC5_SE PFUZE100_BIT_4 +#define PFUZE100_BITS_ECC_SE1 ((PFUZE100_BIT_ECC1_SE) | \ + (PFUZE100_BIT_ECC2_SE) | \ + (PFUZE100_BIT_ECC3_SE) | \ + (PFUZE100_BIT_ECC4_SE) | \ + (PFUZE100_BIT_ECC5_SE)) +#define PFUZE100_OTP_ECC_SE2 0x8b +#define PFUZE100_BIT_ECC6_SE PFUZE100_BIT_0 +#define PFUZE100_BIT_ECC7_SE PFUZE100_BIT_1 +#define PFUZE100_BIT_ECC8_SE PFUZE100_BIT_2 +#define PFUZE100_BIT_ECC9_SE PFUZE100_BIT_3 +#define PFUZE100_BIT_ECC10_SE PFUZE100_BIT_4 +#define PFUZE100_BITS_ECC_SE2 ((PFUZE100_BIT_ECC6_SE) | \ + (PFUZE100_BIT_ECC7_SE) | \ + (PFUZE100_BIT_ECC8_SE) | \ + (PFUZE100_BIT_ECC9_SE) | \ + (PFUZE100_BIT_ECC10_SE)) +#define PFUZE100_OTP_ECC_DE1 0x8c +#define PFUZE100_BIT_ECC1_DE PFUZE100_BIT_0 +#define PFUZE100_BIT_ECC2_DE PFUZE100_BIT_1 +#define PFUZE100_BIT_ECC3_DE PFUZE100_BIT_2 +#define PFUZE100_BIT_ECC4_DE PFUZE100_BIT_3 +#define PFUZE100_BIT_ECC5_DE PFUZE100_BIT_4 +#define PFUZE100_BITS_ECC_DE1 ((PFUZE100_BIT_ECC1_DE) | \ + (PFUZE100_BIT_ECC2_DE) | \ + (PFUZE100_BIT_ECC3_DE) | \ + (PFUZE100_BIT_ECC4_DE) | \ + (PFUZE100_BIT_ECC5_DE)) +#define PFUZE100_OTP_ECC_DE2 0x8d +#define PFUZE100_BIT_ECC6_DE PFUZE100_BIT_0 +#define PFUZE100_BIT_ECC7_DE PFUZE100_BIT_1 +#define PFUZE100_BIT_ECC8_DE PFUZE100_BIT_2 +#define PFUZE100_BIT_ECC9_DE PFUZE100_BIT_3 +#define PFUZE100_BIT_ECC10_DE PFUZE100_BIT_4 +#define PFUZE100_BITS_ECC_DE2 ((PFUZE100_BIT_ECC6_DE) | \ + (PFUZE100_BIT_ECC7_DE) | \ + (PFUZE100_BIT_ECC8_DE) | \ + (PFUZE100_BIT_ECC9_DE) | \ + (PFUZE100_BIT_ECC10_DE)) +#define PFUZE100_FUSE_POR1 0xe4 +#define PFUZE100_FUSE_POR2 0xe5 +#define PFUZE100_FUSE_POR3 0xe6 +#define PFUZE100_FUSE_POR_M (0x1 << 1) + +/* output some informational messages, return the number FUSE_POR=1 */ +/* i.e. 0: unprogrammed, 3: programmed, other: undefined prog. state */ +unsigned pmic_init(void); + +#endif /* PF0100_H_ */ diff --git a/roms/u-boot/board/toradex/apalis_imx6/pf0100_otp.inc b/roms/u-boot/board/toradex/apalis_imx6/pf0100_otp.inc new file mode 100644 index 000000000..a7790fd6c --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_imx6/pf0100_otp.inc @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014-2016, Toradex AG + */ + +// Register Output for PF0100 programmer +// Customer: Toradex AG +// Program: Apalis iMX6 +// Sample marking: +// Date: 12.02.2014 +// Time: 17:16:41 +// Generated from Spreadsheet Revision: P1.8 + +/* sed commands to get from programmer script to struct */ +/* sed -e 's/^WRITE_I2C:\(..\):\(..\)/\{pmic_i2c, 0x\1, 0x\2\},/g' -e 's/^DELAY:\([0-9]*\)/\{pmic_delay, 0, \1\},/g' pf0100_otp.txt > pf0100_otp.inc + sed -i -e 's/^VPGM:ON/\{pmic_vpgm, 0, 1},/g' -e 's/^VPGM:OFF/\{pmic_vpgm, 0, 0},/g' pf0100_otp.inc + sed -i -e 's/^PWRON: HIGH/\{pmic_pwr, 0, 1},/g' -e 's/^PWRON:LOW/\{pmic_pwr, 0, 0},/g' pf0100_otp.inc */ + +enum { pmic_i2c, pmic_delay, pmic_vpgm, pmic_pwr }; +struct pmic_otp_prog_t{ + unsigned char cmd; + unsigned char reg; + unsigned short value; +}; + +struct pmic_otp_prog_t pmic_otp_prog[] = { +{pmic_i2c, 0x7F, 0x01}, // Access FSL EXT Page 1 +{pmic_i2c, 0xA0, 0x2B}, // Auto gen from Row94 +{pmic_i2c, 0xA1, 0x01}, // Auto gen from Row95 +{pmic_i2c, 0xA2, 0x05}, // Auto gen from Row96 +{pmic_i2c, 0xA8, 0x2B}, // Auto gen from Row102 +{pmic_i2c, 0xA9, 0x02}, // Auto gen from Row103 +{pmic_i2c, 0xAA, 0x01}, // Auto gen from Row104 +{pmic_i2c, 0xAC, 0x18}, // Auto gen from Row106 +{pmic_i2c, 0xAE, 0x01}, // Auto gen from Row108 +{pmic_i2c, 0xB0, 0x2C}, // Auto gen from Row110 +{pmic_i2c, 0xB1, 0x04}, // Auto gen from Row111 +{pmic_i2c, 0xB2, 0x01}, // Auto gen from Row112 +{pmic_i2c, 0xB4, 0x2C}, // Auto gen from Row114 +{pmic_i2c, 0xB5, 0x04}, // Auto gen from Row115 +{pmic_i2c, 0xB6, 0x01}, // Auto gen from Row116 +{pmic_i2c, 0xB8, 0x18}, // Auto gen from Row118 +{pmic_i2c, 0xBA, 0x01}, // Auto gen from Row120 +{pmic_i2c, 0xBD, 0x1F}, // Auto gen from Row123 +{pmic_i2c, 0xC0, 0x06}, // Auto gen from Row126 +{pmic_i2c, 0xC4, 0x04}, // Auto gen from Row130 +{pmic_i2c, 0xC8, 0x0E}, // Auto gen from Row134 +{pmic_i2c, 0xC9, 0x08}, // Auto gen from Row135 +{pmic_i2c, 0xCC, 0x0E}, // Auto gen from Row138 +{pmic_i2c, 0xCD, 0x05}, // Auto gen from Row139 +{pmic_i2c, 0xD0, 0x0C}, // Auto gen from Row142 +{pmic_i2c, 0xD1, 0x05}, // Auto gen from Row143 +{pmic_i2c, 0xD5, 0x07}, // Auto gen from Row147 +{pmic_i2c, 0xD8, 0x07}, // Auto gen from Row150 +{pmic_i2c, 0xD9, 0x06}, // Auto gen from Row151 +{pmic_i2c, 0xDC, 0x0A}, // Auto gen from Row154 +{pmic_i2c, 0xDD, 0x03}, // Auto gen from Row155 +{pmic_i2c, 0xE0, 0x07}, // Auto gen from Row158 + +#if 0 /* TBB mode */ +{pmic_i2c, 0xE4, 0x80}, // TBB_POR = 1 +{pmic_delay, 0, 10}, +#else +// Write OTP +{pmic_i2c, 0xE4, 0x02}, // FUSE POR1=1 +{pmic_i2c, 0xE5, 0x02}, // FUSE POR2=1 +{pmic_i2c, 0xE6, 0x02}, // FUSE POR3=1 +{pmic_i2c, 0xF0, 0x1F}, // Enable ECC for fuse banks 1 to 5 by writing to OTP EN ECC0 register +{pmic_i2c, 0xF1, 0x1F}, // Enable ECC for fuse banks 6 to 10 by writing to OTP EN ECC1 register +{pmic_i2c, 0x7F, 0x02}, // Access PF0100 EXT Page2 +{pmic_i2c, 0xD0, 0x1F}, // Set Auto ECC for fuse banks 1 to 5 by writing to OTP AUTO ECC0 register +{pmic_i2c, 0xD1, 0x1F}, // Set Auto ECC for fuse banks 6 to 10 by writing to OTP AUTO ECC1 register +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +{pmic_vpgm, 0, 1}, // Turn ON 8V SWBST +//VPGM:DOWN:n +//VPGM:UP:n +{pmic_delay, 0, 500}, // Adds 500msec delay to allow VPGM time to ramp up +//----------------------------------------------------------------------------------- +// PF0100 OTP MANUAL-PROGRAMMING (BANK 1 thru 10) +//----------------------------------------------------------------------------------- +// BANK 1 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF1, 0x03}, // Set Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF1, 0x0B}, // Set Bank 1 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF1, 0x03}, // Reset Bank 1 ANTIFUSE_EN +{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 2 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF2, 0x03}, // Set Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF2, 0x0B}, // Set Bank 2 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF2, 0x03}, // Reset Bank 2 ANTIFUSE_EN +{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 3 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF3, 0x03}, // Set Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF3, 0x0B}, // Set Bank 3 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF3, 0x03}, // Reset Bank 3 ANTIFUSE_EN +{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 4 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF4, 0x03}, // Set Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF4, 0x0B}, // Set Bank 4 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF4, 0x03}, // Reset Bank 4 ANTIFUSE_EN +{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 5 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF5, 0x03}, // Set Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF5, 0x0B}, // Set Bank 5 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF5, 0x03}, // Reset Bank 5 ANTIFUSE_EN +{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 6 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF6, 0x03}, // Set Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF6, 0x0B}, // Set Bank 6 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF6, 0x03}, // Reset Bank 6 ANTIFUSE_EN +{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 7 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF7, 0x03}, // Set Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF7, 0x0B}, // Set Bank 7 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF7, 0x03}, // Reset Bank 7 ANTIFUSE_EN +{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 8 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF8, 0x03}, // Set Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF8, 0x0B}, // Set Bank 8 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF8, 0x03}, // Reset Bank 8 ANTIFUSE_EN +{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 9 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF9, 0x03}, // Set Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF9, 0x0B}, // Set Bank 9 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF9, 0x03}, // Reset Bank 9 ANTIFUSE_EN +{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 10 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xFA, 0x03}, // Set Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xFA, 0x0B}, // Set Bank 10 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xFA, 0x03}, // Reset Bank 10 ANTIFUSE_EN +{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +{pmic_vpgm, 0, 0}, // Turn off 8V SWBST +{pmic_delay, 0, 500}, // Adds delay to allow VPGM to bleed off +{pmic_i2c, 0xD0, 0x00}, // Clear +{pmic_i2c, 0xD1, 0x00}, // Clear +{pmic_pwr, 0, 0}, // PWRON LOW to reload new OTP data +{pmic_delay, 0, 500}, +{pmic_pwr, 0, 1}, +#endif +};
\ No newline at end of file diff --git a/roms/u-boot/board/toradex/apalis_t30/Kconfig b/roms/u-boot/board/toradex/apalis_t30/Kconfig new file mode 100644 index 000000000..9cd497091 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_t30/Kconfig @@ -0,0 +1,39 @@ +if TARGET_APALIS_T30 + +config SYS_BOARD + default "apalis_t30" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "apalis_t30" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +config APALIS_T30_PCIE_EVALBOARD_INIT + bool "Apalis Evaluation Board PCIe Initialisation" + help + Bring up the Apalis type specific 4 lane PCIe port as well as the + Apalis PCIe port with the PCIe switch as found on the Apalis + Evaluation board. Note that by default both those ports are also left + disabled in the device tree which needs changing as well for this to + actually work. + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/apalis_t30/MAINTAINERS b/roms/u-boot/board/toradex/apalis_t30/MAINTAINERS new file mode 100644 index 000000000..01bc73e46 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_t30/MAINTAINERS @@ -0,0 +1,7 @@ +Apalis T30 +M: Marcel Ziswiler <marcel.ziswiler@toradex.com> +S: Maintained +F: board/toradex/apalis_t30/ +F: include/configs/apalis_t30.h +F: configs/apalis_t30_defconfig +F: arch/arm/dts/tegra30-apalis.dtb diff --git a/roms/u-boot/board/toradex/apalis_t30/Makefile b/roms/u-boot/board/toradex/apalis_t30/Makefile new file mode 100644 index 000000000..0ea3d8f21 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_t30/Makefile @@ -0,0 +1,4 @@ +# Copyright (c) 2014 Marcel Ziswiler +# SPDX-License-Identifier: GPL-2.0+ + +obj-y += apalis_t30.o diff --git a/roms/u-boot/board/toradex/apalis_t30/apalis_t30.c b/roms/u-boot/board/toradex/apalis_t30/apalis_t30.c new file mode 100644 index 000000000..0396eea56 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_t30/apalis_t30.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2014-2018 + * Marcel Ziswiler <marcel@ziswiler.com> + */ + +#include <common.h> +#include <init.h> +#include <log.h> +#include <asm/arch/gp_padctrl.h> +#include <asm/arch/pinmux.h> +#include <asm/arch-tegra/ap.h> +#include <asm/arch-tegra/tegra.h> +#include <asm/global_data.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <dm.h> +#include <i2c.h> +#include <pci_tegra.h> +#include <linux/delay.h> +#include "../common/tdx-common.h" + +#include "pinmux-config-apalis_t30.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define PMU_I2C_ADDRESS 0x2D +#define MAX_I2C_RETRY 3 + +#ifdef CONFIG_APALIS_T30_PCIE_EVALBOARD_INIT +#define PEX_PERST_N TEGRA_GPIO(S, 7) /* Apalis GPIO7 */ +#define RESET_MOCI_CTRL TEGRA_GPIO(I, 4) + +static int pci_reset_status; +#endif /* CONFIG_APALIS_T30_PCIE_EVALBOARD_INIT */ + +int arch_misc_init(void) +{ + if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) == + NVBOOTTYPE_RECOVERY) + printf("USB recovery mode\n"); + + return 0; +} + +int checkboard(void) +{ + printf("Model: Toradex Apalis T30 %dGB\n", + (gd->ram_size == 0x40000000) ? 1 : 2); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +/* + * Routine: pinmux_init + * Description: Do individual peripheral pinmux configs + */ +void pinmux_init(void) +{ + pinmux_config_pingrp_table(tegra3_pinmux_common, + ARRAY_SIZE(tegra3_pinmux_common)); + + pinmux_config_pingrp_table(unused_pins_lowpower, + ARRAY_SIZE(unused_pins_lowpower)); + + /* Initialize any non-default pad configs (APB_MISC_GP regs) */ + pinmux_config_drvgrp_table(apalis_t30_padctrl, + ARRAY_SIZE(apalis_t30_padctrl)); +} + +#ifdef CONFIG_PCI_TEGRA +int tegra_pcie_board_init(void) +{ + struct udevice *dev; + u8 addr, data[1]; + int err; + + err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); + if (err) { + debug("%s: Cannot find PMIC I2C chip\n", __func__); + return err; + } + + /* TPS659110: VDD2_OP_REG = 1.05V */ + data[0] = 0x27; + addr = 0x25; + + err = dm_i2c_write(dev, addr, data, 1); + if (err) { + debug("failed to set VDD supply\n"); + return err; + } + + /* TPS659110: VDD2_REG 7.5 mV/us, ACTIVE */ + data[0] = 0x0D; + addr = 0x24; + + err = dm_i2c_write(dev, addr, data, 1); + if (err) { + debug("failed to enable VDD supply\n"); + return err; + } + + /* TPS659110: LDO6_REG = 1.1V, ACTIVE */ + data[0] = 0x0D; + addr = 0x35; + + err = dm_i2c_write(dev, addr, data, 1); + if (err) { + debug("failed to set AVDD supply\n"); + return err; + } + +#ifdef CONFIG_APALIS_T30_PCIE_EVALBOARD_INIT + gpio_request(PEX_PERST_N, "PEX_PERST_N"); + gpio_request(RESET_MOCI_CTRL, "RESET_MOCI_CTRL"); +#endif /* CONFIG_APALIS_T30_PCIE_EVALBOARD_INIT */ + + return 0; +} + +void tegra_pcie_board_port_reset(struct tegra_pcie_port *port) +{ + int index = tegra_pcie_port_index_of_port(port); + + if (index == 2) { /* I210 Gigabit Ethernet Controller (On-module) */ + tegra_pcie_port_reset(port); + } +#ifdef CONFIG_APALIS_T30_PCIE_EVALBOARD_INIT + /* + * Apalis PCIe aka port 1 and Apalis Type Specific 4 Lane PCIe aka port + * 0 share the same RESET_MOCI therefore only assert it once for both + * ports to avoid losing the previously brought up port again. + */ + else if ((index == 1) || (index == 0)) { + /* only do it once per init cycle */ + if (pci_reset_status % 2 == 0) { + /* + * Reset PLX PEX 8605 PCIe Switch plus PCIe devices on + * Apalis Evaluation Board + */ + gpio_direction_output(PEX_PERST_N, 0); + gpio_direction_output(RESET_MOCI_CTRL, 0); + + /* + * Must be asserted for 100 ms after power and clocks + * are stable + */ + mdelay(100); + + gpio_set_value(PEX_PERST_N, 1); + /* + * Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not + * Guaranteed Until 900 us After PEX_PERST# De-assertion + */ + mdelay(1); + gpio_set_value(RESET_MOCI_CTRL, 1); + } + pci_reset_status++; + } +#endif /* CONFIG_APALIS_T30_PCIE_EVALBOARD_INIT */ +} +#endif /* CONFIG_PCI_TEGRA */ + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(TEGRA_GPIO(V, 2), "BKL1_ON"); + gpio_direction_output(TEGRA_GPIO(V, 2), 0); +} diff --git a/roms/u-boot/board/toradex/apalis_t30/pinmux-config-apalis_t30.h b/roms/u-boot/board/toradex/apalis_t30/pinmux-config-apalis_t30.h new file mode 100644 index 000000000..3a2cf4606 --- /dev/null +++ b/roms/u-boot/board/toradex/apalis_t30/pinmux-config-apalis_t30.h @@ -0,0 +1,343 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2014, Marcel Ziswiler + */ + +#ifndef _PINMUX_CONFIG_APALIS_T30_H_ +#define _PINMUX_CONFIG_APALIS_T30_H_ + +#define DEFAULT_PINMUX(_pingrp, _mux, _pull, _tri, _io) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ +/* TRISTATE here means output driver is tri-stated */ \ + .tristate = PMUX_TRI_##_tri, \ +/* INPUT here means input driver is enabled vs. OUTPUT where it is disabled */ \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_DEFAULT, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define I2C_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _od) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_##_od, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define LV_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _ioreset) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_##_ioreset \ + } + +#define DEFAULT_PADCFG(_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) \ + { \ + .drvgrp = PMUX_DRVGRP_##_drvgrp, \ + .slwf = _slwf, \ + .slwr = _slwr, \ + .drvup = _drvup, \ + .drvdn = _drvdn, \ + .lpmd = PMUX_LPMD_##_lpmd, \ + .schmt = PMUX_SCHMT_##_schmt, \ + .hsm = PMUX_HSM_##_hsm, \ + } + +static struct pmux_pingrp_config tegra3_pinmux_common[] = { + /* SDMMC1 pinmux */ + DEFAULT_PINMUX(SDMMC1_CLK_PZ0, SDMMC1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_CMD_PZ1, SDMMC1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT3_PY4, SDMMC1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT2_PY5, SDMMC1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT1_PY6, SDMMC1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT0_PY7, SDMMC1, NORMAL, NORMAL, INPUT), + + /* SDMMC3 pinmux */ + DEFAULT_PINMUX(SDMMC3_CLK_PA6, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_CMD_PA7, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT0_PB7, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT1_PB6, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT2_PB5, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT3_PB4, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT4_PD1, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT5_PD0, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT6_PD3, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT7_PD4, SDMMC3, NORMAL, NORMAL, INPUT), + + /* SDMMC4 pinmux (eMMC) */ + LV_PINMUX(SDMMC4_CLK_PCC4, SDMMC4, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_CMD_PT7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT0_PAA0, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT1_PAA1, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT2_PAA2, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT3_PAA3, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT4_PAA4, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT5_PAA5, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT6_PAA6, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT7_PAA7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_RST_N_PCC3, RSVD1, DOWN, NORMAL, INPUT, DISABLE, DISABLE), + + /* I2C1 pinmux */ + I2C_PINMUX(GEN1_I2C_SCL_PC4, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(GEN1_I2C_SDA_PC5, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C2 pinmux */ + I2C_PINMUX(GEN2_I2C_SCL_PT5, RSVD3, NORMAL, NORMAL, INPUT, DEFAULT, DISABLE), + I2C_PINMUX(GEN2_I2C_SDA_PT6, RSVD3, NORMAL, NORMAL, INPUT, DEFAULT, DISABLE), + + /* I2C3 pinmux */ + I2C_PINMUX(CAM_I2C_SCL_PBB1, I2C3, NORMAL, TRISTATE, INPUT, DISABLE, ENABLE), + I2C_PINMUX(CAM_I2C_SDA_PBB2, I2C3, NORMAL, TRISTATE, INPUT, DISABLE, ENABLE), + + /* I2C4 pinmux */ + I2C_PINMUX(DDC_SCL_PV4, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(DDC_SDA_PV5, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* Power I2C pinmux */ + I2C_PINMUX(PWR_I2C_SCL_PZ6, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(PWR_I2C_SDA_PZ7, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + DEFAULT_PINMUX(ULPI_DATA0_PO1, UARTA, NORMAL, NORMAL, OUTPUT), + /* UARTA RX, make sure we don't get input form a floating Pin */ + DEFAULT_PINMUX(ULPI_DATA1_PO2, UARTA, UP, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA2_PO3, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA3_PO4, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA4_PO5, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA5_PO6, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA6_PO7, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA7_PO0, UARTA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(ULPI_CLK_PY0, UARTD, NORMAL, NORMAL, OUTPUT), + /* UARTD RX, make sure we don't get input form a floating Pin */ + DEFAULT_PINMUX(ULPI_DIR_PY1, UARTD, UP, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_NXT_PY2, UARTD, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_STP_PY3, UARTD, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(DAP3_FS_PP0, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_DIN_PP1, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_DOUT_PP2, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_SCLK_PP3, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PV2, OWR, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PV3, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK2_OUT_PW5, EXTPERIPH2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK2_REQ_PCC5, DAP, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR1_PC1, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(LCD_PWR2_PC6, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(LCD_SDIN_PZ2, SPI5, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SDOUT_PN5, SPI5, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_WR_N_PZ3, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(LCD_CS0_N_PN4, SPI5, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DC0_PN6, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(LCD_SCK_PZ4, SPI5, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR0_PB2, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(LCD_PCLK_PB3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DE_PJ1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_HSYNC_PJ3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_VSYNC_PJ4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D0_PE0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D1_PE1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D2_PE2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D3_PE3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D4_PE4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D5_PE5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D6_PE6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D7_PE7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D8_PF0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D9_PF1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D10_PF2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D11_PF3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D12_PF4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D13_PF5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D14_PF6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D15_PF7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D16_PM0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D17_PM1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D18_PM2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D19_PM3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D20_PM4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D21_PM5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D22_PM6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D23_PM7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_CS1_N_PW0, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(LCD_M1_PW1, DISPLAYA, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(LCD_DC1_PD2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CRT_HSYNC_PV6, CRT, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CRT_VSYNC_PV7, CRT, NORMAL, NORMAL, OUTPUT), + LV_PINMUX(VI_D0_PT4, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D1_PD5, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D2_PL0, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D3_PL1, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D4_PL2, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D5_PL3, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D6_PL4, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D7_PL5, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D8_PL6, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D9_PL7, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D10_PT2, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D11_PT3, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_HSYNC_PD7, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_MCLK_PT1, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_PCLK_PT0, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_VSYNC_PD6, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + /* UARTB RX, make sure we don't get input form a floating Pin */ + DEFAULT_PINMUX(UART2_RXD_PC3, UARTB, UP, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_TXD_PC2, UARTB, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(UART2_RTS_N_PJ6, UARTB, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(UART2_CTS_N_PJ5, UARTB, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(UART3_TXD_PW6, UARTC, NORMAL, NORMAL, OUTPUT), + /* UARTC RX, make sure we don't get input form a floating Pin */ + DEFAULT_PINMUX(UART3_RXD_PW7, UARTC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_CTS_N_PA1, UARTC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_RTS_N_PC0, PWM0, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU0, RSVD1, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(PU1, RSVD1, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(PU2, RSVD1, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(PU3, PWM0, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU4, PWM1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU5, PWM2, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU6, PWM3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(DAP4_FS_PP4, I2S3, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(DAP4_DIN_PP5, I2S3, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(DAP4_DOUT_PP6, I2S3, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(DAP4_SCLK_PP7, I2S3, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(CLK3_OUT_PEE0, EXTPERIPH3, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(CLK3_REQ_PEE1, DEV3, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_WP_N_PC7, GMI, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_CS2_N_PK3, RSVD1, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_AD8_PH0, PWM0, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_AD10_PH2, NAND, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_A16_PJ7, UARTD, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_A17_PB0, UARTD, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_A18_PB1, UARTD, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_A19_PK7, UARTD, DOWN, TRISTATE, OUTPUT), /* NC */ + + DEFAULT_PINMUX(CAM_MCLK_PCC0, VI_ALT2, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB0, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB3, VGP3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB4, VGP4, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB5, VGP5, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB6, VGP6, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB7, I2S4, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PCC1, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PCC2, I2S4, NORMAL, NORMAL, OUTPUT), + + DEFAULT_PINMUX(JTAG_RTCK_PU7, RTCK, NORMAL, NORMAL, OUTPUT), + + /* multiplexed VI_D2, VI_D3, VI_D4, VI_D5, VI_D6, VI_D7, VI_D8 and VI_D9 + */ + DEFAULT_PINMUX(KB_ROW0_PR0, RSVD2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW1_PR1, RSVD2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW2_PR2, RSVD2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW3_PR3, RSVD2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW4_PR4, RSVD3, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW5_PR5, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW6_PR6, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW7_PR7, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW8_PS0, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW9_PS1, KBC, NORMAL, TRISTATE, INPUT), + + /* GPIOs */ + DEFAULT_PINMUX(KB_ROW10_PS2, SDMMC2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW11_PS3, SDMMC2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW12_PS4, SDMMC2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW13_PS5, SDMMC2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW14_PS6, SDMMC2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW15_PS7, SDMMC2, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(KB_COL0_PQ0, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL1_PQ1, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL2_PQ2, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL3_PQ3, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL4_PQ4, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL5_PQ5, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL6_PQ6, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL7_PQ7, KBC, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(PV0, RSVD1, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(CLK_32K_OUT_PA0, BLINK, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(SYS_CLK_REQ_PZ5, SYSCLK, NORMAL, NORMAL, INPUT), + /* multiplexed KB_COL0 */ + DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_FS_PN0, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_DIN_PN1, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_DOUT_PN2, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_SCLK_PN3, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK1_REQ_PEE2, DAP, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CLK1_OUT_PW4, EXTPERIPH1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(SPDIF_IN_PK6, SPDIF, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPDIF_OUT_PK5, SPDIF, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(DAP2_FS_PA2, I2S1, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(DAP2_DIN_PA4, I2S1, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(DAP2_DOUT_PA5, I2S1, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(DAP2_SCLK_PA3, I2S1, NORMAL, TRISTATE, OUTPUT), + + DEFAULT_PINMUX(SPI2_CS1_N_PW2, SPI2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_MOSI_PX4, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_SCK_PX5, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_CS0_N_PX6, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_MISO_PX7, SPI1, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(PEX_L0_PRSNT_N_PDD0, RSVD2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L0_RST_N_PDD1, RSVD2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L0_CLKREQ_N_PDD2, RSVD2, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(PEX_L1_PRSNT_N_PDD4, RSVD2, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(PEX_L1_RST_N_PDD5, RSVD2, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(PEX_L1_CLKREQ_N_PDD6, RSVD2, DOWN, TRISTATE, OUTPUT), /* NC */ + + DEFAULT_PINMUX(PEX_L2_PRSNT_N_PDD7, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L2_RST_N_PCC6, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L2_CLKREQ_N_PCC7, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_WAKE_N_PDD3, PCIE, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(HDMI_CEC_PEE3, CEC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(HDMI_INT_PN7, RSVD1, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(GMI_IORDY_PI5, RSVD1, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_AD12_PH4, NAND, DOWN, TRISTATE, OUTPUT), /* NC */ + DEFAULT_PINMUX(GMI_AD14_PH6, NAND, DOWN, TRISTATE, OUTPUT), /* NC */ + + DEFAULT_PINMUX(SPI2_SCK_PX2, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW8_PS0, KBC, NORMAL, NORMAL, INPUT), +}; + +static struct pmux_pingrp_config unused_pins_lowpower[] = { + DEFAULT_PINMUX(GMI_WAIT_PI7, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_ADV_N_PK0, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CLK_PK1, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CS3_N_PK4, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CS7_N_PI6, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD0_PG0, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD1_PG1, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD2_PG2, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD3_PG3, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD4_PG4, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD5_PG5, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD6_PG6, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD7_PG7, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD9_PH1, PWM1, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD11_PH3, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD13_PH5, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_WR_N_PI0, NAND, DOWN, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_OE_N_PI1, NAND, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_DQS_PI2, NAND, DOWN, TRISTATE, OUTPUT), +}; + +static struct pmux_drvgrp_config apalis_t30_padctrl[] = { + /* (_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */ + DEFAULT_PADCFG(SDIO1, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \ + SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, DISABLE, DISABLE), +}; +#endif /* _PINMUX_CONFIG_APALIS_T30_H_ */ diff --git a/roms/u-boot/board/toradex/colibri-imx6ull/Kconfig b/roms/u-boot/board/toradex/colibri-imx6ull/Kconfig new file mode 100644 index 000000000..3ce9885c1 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx6ull/Kconfig @@ -0,0 +1,29 @@ +if TARGET_COLIBRI_IMX6ULL + +config SYS_BOARD + default "colibri-imx6ull" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "colibri-imx6ull" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_NAND + default y + +config TDX_CFG_BLOCK_OFFSET + default "2048" + +config TDX_CFG_BLOCK_OFFSET2 + default "133120" + +config TDX_CFG_BLOCK_2ND_ETHADDR + default y + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/colibri-imx6ull/MAINTAINERS b/roms/u-boot/board/toradex/colibri-imx6ull/MAINTAINERS new file mode 100644 index 000000000..899b1ff55 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx6ull/MAINTAINERS @@ -0,0 +1,11 @@ +Colibri iMX6ULL +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +W: http://developer.toradex.com/software/linux/linux-software +W: https://www.toradex.com/community +S: Maintained +F: arch/arm/dts/imx6ull-colibri.dts +F: arch/arm/dts/imx6ull-colibri-u-boot.dtsi +F: arch/arm/dts/imx6ull-colibri.dtsi +F: board/toradex/colibri-imx6ull/ +F: configs/colibri-imx6ull_defconfig +F: include/configs/colibri-imx6ull.h diff --git a/roms/u-boot/board/toradex/colibri-imx6ull/Makefile b/roms/u-boot/board/toradex/colibri-imx6ull/Makefile new file mode 100644 index 000000000..f478e6804 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx6ull/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2018 Toradex AG + +obj-y := colibri-imx6ull.o diff --git a/roms/u-boot/board/toradex/colibri-imx6ull/colibri-imx6ull.c b/roms/u-boot/board/toradex/colibri-imx6ull/colibri-imx6ull.c new file mode 100644 index 000000000..01f556159 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx6ull/colibri-imx6ull.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018-2019 Toradex AG + */ +#include <common.h> +#include <init.h> +#include <asm/global_data.h> +#include <linux/delay.h> + +#include <asm/arch/clock.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch-mx6/clock.h> +#include <asm/arch-mx6/imx-regs.h> +#include <asm/arch-mx6/mx6ull_pins.h> +#include <asm/arch/sys_proto.h> +#include <asm/gpio.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/io.h> +#include <dm.h> +#include <dm/platform_data/serial_mxc.h> +#include <env.h> +#include <fdt_support.h> +#include <imx_thermal.h> +#include <jffs2/load_kernel.h> +#include <linux/sizes.h> +#include <miiphy.h> +#include <mtd_node.h> +#include <netdev.h> + +#include "../common/tdx-common.h" +#include "../common/tdx-cfg-block.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ + PAD_CTL_DSE_48ohm) + +#define MX6_PAD_SNVS_PMIC_STBY_REQ_ADDR 0x2290040 + +#define NAND_PAD_CTRL (PAD_CTL_DSE_48ohm | PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define NAND_PAD_READY0_CTRL (PAD_CTL_DSE_48ohm | PAD_CTL_PUS_22K_UP) + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + + return 0; +} + +#ifdef CONFIG_NAND_MXS +static void setup_gpmi_nand(void) +{ + setup_gpmi_io_clk((3 << MXC_CCM_CSCDR1_BCH_PODF_OFFSET) | + (3 << MXC_CCM_CSCDR1_GPMI_PODF_OFFSET)); +} +#endif /* CONFIG_NAND_MXS */ + +#ifdef CONFIG_DM_VIDEO +static iomux_v3_cfg_t const backlight_pads[] = { + /* Backlight On */ + MX6_PAD_JTAG_TMS__GPIO1_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* Backlight PWM<A> (multiplexed pin) */ + MX6_PAD_NAND_WP_B__GPIO4_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +#define GPIO_BL_ON IMX_GPIO_NR(1, 11) +#define GPIO_PWM_A IMX_GPIO_NR(4, 11) + +static int setup_lcd(void) +{ + imx_iomux_v3_setup_multiple_pads(backlight_pads, ARRAY_SIZE(backlight_pads)); + + /* Set BL_ON */ + gpio_request(GPIO_BL_ON, "BL_ON"); + gpio_direction_output(GPIO_BL_ON, 1); + + /* Set PWM<A> to full brightness (assuming inversed polarity) */ + gpio_request(GPIO_PWM_A, "PWM<A>"); + gpio_direction_output(GPIO_PWM_A, 0); + + return 0; +} +#endif + +#ifdef CONFIG_FEC_MXC +static int setup_fec(void) +{ + struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; + int ret; + + /* provide the PHY clock from the i.MX 6 */ + ret = enable_fec_anatop_clock(1, ENET_50MHZ); + if (ret) + return ret; + + /* Use 50M anatop REF_CLK and output it on ENET2_TX_CLK */ + clrsetbits_le32(&iomuxc_regs->gpr[1], + IOMUX_GPR1_FEC2_CLOCK_MUX2_SEL_MASK, + IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK); + + /* give new Ethernet PHY power save mode circuitry time to settle */ + mdelay(300); + + return 0; +} + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif /* CONFIG_FEC_MXC */ + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + +#ifdef CONFIG_NAND_MXS + setup_gpmi_nand(); +#endif + return 0; +} + +#ifdef CONFIG_CMD_BMODE +/* TODO */ +static const struct boot_mode board_boot_modes[] = { + /* 4 bit bus width */ + {"nand", MAKE_CFGVAL(0x40, 0x34, 0x00, 0x00)}, + {"sd1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)}, + {NULL, 0}, +}; +#endif + +int board_late_init(void) +{ +#ifdef CONFIG_TDX_CFG_BLOCK + /* + * If we have a valid config block and it says we are a module with + * Wi-Fi/Bluetooth make sure we use the -wifi device tree. + */ + if (tdx_hw_tag.prodid == COLIBRI_IMX6ULL_WIFI_BT_IT || + tdx_hw_tag.prodid == COLIBRI_IMX6ULL_WIFI_BT) + env_set("variant", "-wifi"); +#endif + + /* + * Disable output driver of PAD CCM_PMIC_STBY_REQ. This prevents the + * SOC to request for a lower voltage during sleep. This is necessary + * because the voltage is changing too slow for the SOC to wake up + * properly. + */ + __raw_writel(0x8080, MX6_PAD_SNVS_PMIC_STBY_REQ_ADDR); + +#ifdef CONFIG_CMD_BMODE + add_board_boot_modes(board_boot_modes); +#endif + +#ifdef CONFIG_CMD_USB_SDP + if (is_boot_from_usb()) { + printf("Serial Downloader recovery mode, using sdp command\n"); + env_set("bootdelay", "0"); + env_set("bootcmd", "sdp 0"); + } +#endif /* CONFIG_CMD_USB_SDP */ + +#if defined(CONFIG_DM_VIDEO) + setup_lcd(); +#endif + + return 0; +} + +int checkboard(void) +{ + printf("Model: Toradex Colibri iMX6ULL\n"); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ +#if defined(CONFIG_FDT_FIXUP_PARTITIONS) + static struct node_info nodes[] = { + { "fsl,imx6ull-gpmi-nand", MTD_DEV_TYPE_NAND, }, + { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, }, + }; + + /* Update partition nodes using info from mtdparts env var */ + puts(" Updating MTD partitions...\n"); + fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); +#endif + + return ft_common_board_setup(blob, bd); +} +#endif + +static struct mxc_serial_plat mxc_serial_plat = { + .reg = (struct mxc_uart *)UART1_BASE, + .use_dte = 1, +}; + +U_BOOT_DRVINFO(mxc_serial) = { + .name = "serial_mxc", + .plat = &mxc_serial_plat, +}; diff --git a/roms/u-boot/board/toradex/colibri-imx6ull/imximage.cfg b/roms/u-boot/board/toradex/colibri-imx6ull/imximage.cfg new file mode 100644 index 000000000..8d869d9f7 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx6ull/imximage.cfg @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright (C) 2018 Toradex AG + * + * Refer doc/imx/mkimage/imximage.txt for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +#define __ASSEMBLY__ +#include <config.h> + +/* image version */ + +IMAGE_VERSION 2 + +/* + * Boot Device : nand + */ + +BOOT_FROM nand + +/* + * Secure boot support + */ +#ifdef CONFIG_IMX_HAB +CSF CONFIG_CSF_SIZE +#endif + +/* + * 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 + */ + +/* Enable all clocks */ +DATA 4 0x020c4068 0xffffffff +DATA 4 0x020c406c 0xffffffff +DATA 4 0x020c4070 0xffffffff +DATA 4 0x020c4074 0xffffffff +DATA 4 0x020c4078 0xffffffff +DATA 4 0x020c407c 0xffffffff +DATA 4 0x020c4080 0xffffffff + +DATA 4 0x020E04B4 0x000C0000 +DATA 4 0x020E04AC 0x00000000 +DATA 4 0x020E027C 0x00000030 +DATA 4 0x020E0250 0x00000030 +DATA 4 0x020E024C 0x00000030 +DATA 4 0x020E0490 0x00000030 +DATA 4 0x020E0288 0x000C0030 +DATA 4 0x020E0270 0x00000000 +DATA 4 0x020E0260 0x00000030 +DATA 4 0x020E0264 0x00000030 +DATA 4 0x020E04A0 0x00000030 +DATA 4 0x020E0494 0x00020000 +DATA 4 0x020E0280 0x00000030 +DATA 4 0x020E0284 0x00000030 +DATA 4 0x020E04B0 0x00020000 +DATA 4 0x020E0498 0x00000030 +DATA 4 0x020E04A4 0x00000030 +DATA 4 0x020E0244 0x00000030 +DATA 4 0x020E0248 0x00000030 +DATA 4 0x021B001C 0x00008000 +DATA 4 0x021B0800 0xA1390003 +DATA 4 0x021B080C 0x00000004 +DATA 4 0x021B083C 0x41640158 +DATA 4 0x021B0848 0x40403237 +DATA 4 0x021B0850 0x40403C33 +DATA 4 0x021B081C 0x33333333 +DATA 4 0x021B0820 0x33333333 +DATA 4 0x021B082C 0xf3333333 +DATA 4 0x021B0830 0xf3333333 +DATA 4 0x021B08C0 0x00944009 +DATA 4 0x021B08b8 0x00000800 +DATA 4 0x021B0004 0x0002002D +DATA 4 0x021B0008 0x1B333030 +DATA 4 0x021B000C 0x676B52F3 +DATA 4 0x021B0010 0xB66D0B63 +DATA 4 0x021B0014 0x01FF00DB +DATA 4 0x021B0018 0x00201740 +DATA 4 0x021B001C 0x00008000 +DATA 4 0x021B002C 0x000026D2 +DATA 4 0x021B0030 0x006B1023 +DATA 4 0x021B0040 0x0000004F +DATA 4 0x021B0000 0x84180000 +DATA 4 0x021B0890 0x00400000 +DATA 4 0x021B001C 0x02008032 +DATA 4 0x021B001C 0x00008033 +DATA 4 0x021B001C 0x00048031 +DATA 4 0x021B001C 0x15208030 +DATA 4 0x021B001C 0x04008040 +DATA 4 0x021B0020 0x00000800 +DATA 4 0x021B0818 0x00000227 +DATA 4 0x021B0004 0x0002552D +DATA 4 0x021B0404 0x00011006 +DATA 4 0x021B001C 0x00000000 + diff --git a/roms/u-boot/board/toradex/colibri-imx8x/Kconfig b/roms/u-boot/board/toradex/colibri-imx8x/Kconfig new file mode 100644 index 000000000..d97fed020 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx8x/Kconfig @@ -0,0 +1,30 @@ +if TARGET_COLIBRI_IMX8X + +config SYS_BOARD + default "colibri-imx8x" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "colibri-imx8x" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/colibri-imx8x/MAINTAINERS b/roms/u-boot/board/toradex/colibri-imx8x/MAINTAINERS new file mode 100644 index 000000000..de62f87a5 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx8x/MAINTAINERS @@ -0,0 +1,10 @@ +Colibri iMX8X +M: Marcel Ziswiler <marcel.ziswiler@toradex.com> +W: http://developer.toradex.com/software/linux/linux-software +S: Maintained +F: arch/arm/dts/fsl-imx8x-colibri.dts +F: arch/arm/dts/fsl-imx8x-colibri-u-boot.dtsi +F: board/toradex/colibri-imx8x/ +F: configs/colibri-imx8x_defconfig +F: doc/board/toradex/colibri-imx8x.rst +F: include/configs/colibri-imx8x.h diff --git a/roms/u-boot/board/toradex/colibri-imx8x/Makefile b/roms/u-boot/board/toradex/colibri-imx8x/Makefile new file mode 100644 index 000000000..e3945c8f1 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx8x/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2019 Toradex +# + +obj-y += colibri-imx8x.o diff --git a/roms/u-boot/board/toradex/colibri-imx8x/colibri-imx8x-imximage.cfg b/roms/u-boot/board/toradex/colibri-imx8x/colibri-imx8x-imximage.cfg new file mode 100644 index 000000000..44f6c0c45 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx8x/colibri-imx8x-imximage.cfg @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Toradex + * + * Refer doc/imx/mkimage/imx8image.txt for more details about how-to configure + * and create imx8image boot image + */ + +#define __ASSEMBLY__ + +/* Boot from SD, sector size 0x400 */ +BOOT_FROM EMMC_FASTBOOT 0x400 +/* SoC type IMX8QX */ +SOC_TYPE IMX8QX +/* Append seco container image */ +APPEND mx8qx-ahab-container.img +/* Create the 2nd container */ +CONTAINER +/* Add scfw image with exec attribute */ +IMAGE SCU mx8qx-colibri-scfw-tcm.bin +/* Add ATF image with exec attribute */ +IMAGE A35 bl31.bin 0x80000000 +/* Add U-Boot image with load attribute */ +DATA A35 u-boot-dtb.bin 0x80020000 diff --git a/roms/u-boot/board/toradex/colibri-imx8x/colibri-imx8x.c b/roms/u-boot/board/toradex/colibri-imx8x/colibri-imx8x.c new file mode 100644 index 000000000..169d4d04b --- /dev/null +++ b/roms/u-boot/board/toradex/colibri-imx8x/colibri-imx8x.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Toradex + */ + +#include <common.h> +#include <cpu_func.h> +#include <init.h> +#include <asm/global_data.h> + +#include <asm/arch/clock.h> +#include <asm/arch/imx8-pins.h> +#include <asm/arch/iomux.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/sys_proto.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <env.h> +#include <errno.h> +#include <linux/libfdt.h> + +#include "../common/tdx-cfg-block.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +static iomux_cfg_t uart3_pads[] = { + SC_P_FLEXCAN2_RX | MUX_MODE_ALT(2) | MUX_PAD_CTRL(UART_PAD_CTRL), + SC_P_FLEXCAN2_TX | MUX_MODE_ALT(2) | MUX_PAD_CTRL(UART_PAD_CTRL), + /* Transceiver FORCEOFF# signal, mux to use pull-up */ + SC_P_QSPI0B_DQS | MUX_MODE_ALT(4) | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static void setup_iomux_uart(void) +{ + imx8_iomux_setup_multiple_pads(uart3_pads, ARRAY_SIZE(uart3_pads)); +} + +void board_mem_get_layout(u64 *phys_sdram_1_start, + u64 *phys_sdram_1_size, + u64 *phys_sdram_2_start, + u64 *phys_sdram_2_size) +{ + u32 is_dualx = 0, val = 0; + sc_err_t scierr = sc_misc_otp_fuse_read(-1, 6, &val); + + if (scierr == SC_ERR_NONE) { + /* DX has two A35 cores disabled */ + is_dualx = (val & 0xf) != 0x0; + } + + *phys_sdram_1_start = PHYS_SDRAM_1; + if (is_dualx) + /* Our DX based SKUs only have 1 GB RAM */ + *phys_sdram_1_size = SZ_1G; + else + *phys_sdram_1_size = PHYS_SDRAM_1_SIZE; + *phys_sdram_2_start = PHYS_SDRAM_2; + *phys_sdram_2_size = PHYS_SDRAM_2_SIZE; +} + +int board_early_init_f(void) +{ + sc_pm_clock_rate_t rate; + sc_err_t err = 0; + + /* + * This works around that having only UART3 up the baudrate is 1.2M + * instead of 115.2k. Set UART0 clock root to 80 MHz + */ + rate = 80000000; + err = sc_pm_set_clock_rate(-1, SC_R_UART_0, SC_PM_CLK_PER, &rate); + if (err != SC_ERR_NONE) + return 0; + + /* Set UART3 clock root to 80 MHz and enable it */ + rate = SC_80MHZ; + err = sc_pm_setup_uart(SC_R_UART_3, rate); + if (err != SC_ERR_NONE) + return 0; + + setup_iomux_uart(); + + return 0; +} + +#if IS_ENABLED(CONFIG_DM_GPIO) +static void board_gpio_init(void) +{ + /* TODO */ +} +#else +static inline void board_gpio_init(void) {} +#endif + +#if IS_ENABLED(CONFIG_FEC_MXC) +#include <miiphy.h> + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} +#endif + +int checkboard(void) +{ + puts("Model: Toradex Colibri iMX8X\n"); + + build_info(); + print_bootinfo(); + + return 0; +} + +int board_init(void) +{ + board_gpio_init(); + + return 0; +} + +/* + * Board specific reset that is system reset. + */ +void reset_cpu(void) +{ + /* TODO */ +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +/* TODO move to common */ + env_set("board_name", "Colibri iMX8QXP"); + env_set("board_rev", "v1.0"); +#endif + + return 0; +} diff --git a/roms/u-boot/board/toradex/colibri_imx6/Kconfig b/roms/u-boot/board/toradex/colibri_imx6/Kconfig new file mode 100644 index 000000000..d2ad1ce2a --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx6/Kconfig @@ -0,0 +1,44 @@ +if TARGET_COLIBRI_IMX6 + +config SYS_BOARD + default "colibri_imx6" + +config SYS_CONFIG_NAME + default "colibri_imx6" + +config SYS_CPU + default "armv7" + +config SYS_SOC + default "mx6" + +config SYS_VENDOR + default "toradex" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +config TDX_CMD_IMX_MFGR + bool "Enable factory testing commands for Toradex iMX 6 modules" + help + This adds the commands + pf0100_otp_prog - Program the OTP fuses on the PMIC PF0100 + If executed on already fused modules it doesn't change any fuse setting. + default y + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/colibri_imx6/MAINTAINERS b/roms/u-boot/board/toradex/colibri_imx6/MAINTAINERS new file mode 100644 index 000000000..2cbf65433 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx6/MAINTAINERS @@ -0,0 +1,9 @@ +Colibri iMX6 +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +W: http://developer.toradex.com/software/linux/linux-software +W: https://www.toradex.com/community +S: Maintained +F: board/toradex/colibri_imx6/ +F: include/configs/colibri_imx6.h +F: configs/colibri_imx6_defconfig +F: arch/arm/dts/imx6-colibri.dts diff --git a/roms/u-boot/board/toradex/colibri_imx6/Makefile b/roms/u-boot/board/toradex/colibri_imx6/Makefile new file mode 100644 index 000000000..c81bc2d74 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx6/Makefile @@ -0,0 +1,5 @@ +# Copyright (c) 2012-2014 Toradex, Inc. +# SPDX-License-Identifier: GPL-2.0+ + +obj-y := colibri_imx6.o do_fuse.o +obj-$(CONFIG_TDX_CMD_IMX_MFGR) += pf0100.o diff --git a/roms/u-boot/board/toradex/colibri_imx6/colibri_imx6.c b/roms/u-boot/board/toradex/colibri_imx6/colibri_imx6.c new file mode 100644 index 000000000..c0e775446 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx6/colibri_imx6.c @@ -0,0 +1,1098 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. + * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com> + * Copyright (C) 2014-2019, Toradex AG + * copied from nitrogen6x + */ + +#include <common.h> +#include <cpu_func.h> +#include <dm.h> +#include <env.h> +#include <init.h> +#include <net.h> +#include <asm/global_data.h> +#include <linux/bitops.h> +#include <linux/delay.h> + +#include <asm/arch/clock.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/mx6-ddr.h> +#include <asm/arch/mx6-pins.h> +#include <asm/arch/mxc_hdmi.h> +#include <asm/arch/sys_proto.h> +#include <asm/bootm.h> +#include <asm/gpio.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/mach-imx/sata.h> +#include <asm/mach-imx/video.h> +#include <cpu.h> +#include <dm/platform_data/serial_mxc.h> +#include <fsl_esdhc_imx.h> +#include <imx_thermal.h> +#include <miiphy.h> +#include <netdev.h> +#include <cpu.h> + +#include "../common/tdx-cfg-block.h" +#ifdef CONFIG_TDX_CMD_IMX_MFGR +#include "pf0100.h" +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC_EMMC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define WEAK_PULLUP (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_SRE_SLOW) + +#define NO_PULLUP ( \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_SRE_SLOW) + +#define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_HYS | PAD_CTL_SRE_SLOW) + +#define OUTPUT_RGB (PAD_CTL_SPEED_MED|PAD_CTL_DSE_60ohm|PAD_CTL_SRE_FAST) + +int dram_init(void) +{ + /* use the DDR controllers configured size */ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, + (ulong)imx_ddr_size()); + + return 0; +} + +/* Colibri UARTA */ +iomux_v3_cfg_t const uart1_pads[] = { + MX6_PAD_CSI0_DAT10__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), + MX6_PAD_CSI0_DAT11__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +#if defined(CONFIG_FSL_ESDHC_IMX) && defined(CONFIG_SPL_BUILD) +/* Colibri MMC */ +iomux_v3_cfg_t const usdhc1_pads[] = { + MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + MX6_PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ +# define GPIO_MMC_CD IMX_GPIO_NR(2, 5) +}; + +/* eMMC */ +iomux_v3_cfg_t const usdhc3_pads[] = { + MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_EMMC_PAD_CTRL), + MX6_PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL), +}; +#endif /* CONFIG_FSL_ESDHC_IMX & CONFIG_SPL_BUILD */ + +/* mux auxiliary pins to GPIO, so they can be used from the U-Boot cmdline */ +iomux_v3_cfg_t const gpio_pads[] = { + /* ADDRESS[17:18] [25] used as GPIO */ + MX6_PAD_KEY_ROW2__GPIO4_IO11 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_D1__GPIO2_IO01 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + /* ADDRESS[19:24] used as GPIO */ + MX6_PAD_DISP0_DAT23__GPIO5_IO17 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_DISP0_DAT22__GPIO5_IO16 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_DISP0_DAT21__GPIO5_IO15 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_DISP0_DAT20__GPIO5_IO14 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_DISP0_DAT19__GPIO5_IO13 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_DISP0_DAT18__GPIO5_IO12 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + /* DATA[16:29] [31] used as GPIO */ + MX6_PAD_EIM_LBA__GPIO2_IO27 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_CS3__GPIO6_IO16 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_CS1__GPIO6_IO14 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_RB0__GPIO6_IO10 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_ALE__GPIO6_IO08 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_WP_B__GPIO6_IO09 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_CS0__GPIO6_IO11 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_CLE__GPIO6_IO07 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_CSI0_MCLK__GPIO5_IO19 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_CSI0_PIXCLK__GPIO5_IO18 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_GPIO_5__GPIO1_IO05 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + /* DQM[0:3] used as GPIO */ + MX6_PAD_EIM_EB0__GPIO2_IO28 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_EB1__GPIO2_IO29 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_SD2_DAT2__GPIO1_IO13 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_D0__GPIO2_IO00 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + /* RDY used as GPIO */ + MX6_PAD_EIM_WAIT__GPIO5_IO00 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + /* ADDRESS[16] DATA[30] used as GPIO */ + MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(WEAK_PULLDOWN) | + MUX_MODE_SION, + MX6_PAD_KEY_COL4__GPIO4_IO14 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + /* CSI pins used as GPIO */ + MX6_PAD_EIM_A24__GPIO5_IO04 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_SD2_CMD__GPIO1_IO11 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_CS2__GPIO6_IO15 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_D18__GPIO3_IO18 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(WEAK_PULLDOWN) | + MUX_MODE_SION, + MX6_PAD_EIM_A23__GPIO6_IO06 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_A17__GPIO2_IO21 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_A18__GPIO2_IO20 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_EB3__GPIO2_IO31 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_D17__GPIO3_IO17 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_SD2_DAT0__GPIO1_IO15 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + /* GPIO */ + MX6_PAD_EIM_D26__GPIO3_IO26 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_EIM_D27__GPIO3_IO27 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_D6__GPIO2_IO06 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_D3__GPIO2_IO03 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_ENET_REF_CLK__GPIO1_IO23 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_DI0_PIN4__GPIO4_IO20 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_NANDF_D4__GPIO2_IO04 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_GPIO_7__GPIO1_IO07 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + MX6_PAD_GPIO_8__GPIO1_IO08 | MUX_PAD_CTRL(WEAK_PULLUP) | + MUX_MODE_SION, + /* USBH_OC */ + MX6_PAD_EIM_D30__GPIO3_IO30 | MUX_PAD_CTRL(WEAK_PULLUP), + /* USBC_ID */ + MX6_PAD_NANDF_D2__GPIO2_IO02 | MUX_PAD_CTRL(WEAK_PULLUP), + /* USBC_DET */ + MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(WEAK_PULLUP), +}; + +static void setup_iomux_gpio(void) +{ + imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads)); +} + +iomux_v3_cfg_t const usb_pads[] = { + /* USBH_PEN */ + MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL) | MUX_MODE_SION, +# define GPIO_USBH_EN IMX_GPIO_NR(3, 31) +}; + +/* + * UARTs are used in DTE mode, switch the mode on all UARTs before + * any pinmuxing connects a (DCE) output to a transceiver output. + */ +#define UCR3 0x88 /* FIFO Control Register */ +#define UCR3_RI BIT(8) /* RIDELT DTE mode */ +#define UCR3_DCD BIT(9) /* DCDDELT DTE mode */ +#define UFCR 0x90 /* FIFO Control Register */ +#define UFCR_DCEDTE BIT(6) /* DCE=0 */ + +static void setup_dtemode_uart(void) +{ + setbits_le32((u32 *)(UART1_BASE + UFCR), UFCR_DCEDTE); + setbits_le32((u32 *)(UART2_BASE + UFCR), UFCR_DCEDTE); + setbits_le32((u32 *)(UART3_BASE + UFCR), UFCR_DCEDTE); + + clrbits_le32((u32 *)(UART1_BASE + UCR3), UCR3_DCD | UCR3_RI); + clrbits_le32((u32 *)(UART2_BASE + UCR3), UCR3_DCD | UCR3_RI); + clrbits_le32((u32 *)(UART3_BASE + UCR3), UCR3_DCD | UCR3_RI); +} + +static void setup_iomux_uart(void) +{ + setup_dtemode_uart(); + imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); +} + +#ifdef CONFIG_USB_EHCI_MX6 +int board_ehci_hcd_init(int port) +{ + imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads)); + return 0; +} +#endif + +#if defined(CONFIG_FSL_ESDHC_IMX) && defined(CONFIG_SPL_BUILD) +/* use the following sequence: eMMC, MMC */ +struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { + {USDHC3_BASE_ADDR}, + {USDHC1_BASE_ADDR}, +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = true; /* default: assume inserted */ + + switch (cfg->esdhc_base) { + case USDHC1_BASE_ADDR: + gpio_request(GPIO_MMC_CD, "MMC_CD"); + gpio_direction_input(GPIO_MMC_CD); + ret = !gpio_get_value(GPIO_MMC_CD); + break; + } + + return ret; +} + +int board_mmc_init(struct bd_info *bis) +{ + struct src *psrc = (struct src *)SRC_BASE_ADDR; + unsigned reg = readl(&psrc->sbmr1) >> 11; + /* + * Upon reading BOOT_CFG register the following map is done: + * Bit 11 and 12 of BOOT_CFG register can determine the current + * mmc port + * 0x1 SD1 + * 0x2 SD2 + * 0x3 SD4 + */ + + switch (reg & 0x3) { + case 0x0: + imx_iomux_v3_setup_multiple_pads( + usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + break; + case 0x2: + imx_iomux_v3_setup_multiple_pads( + usdhc3_pads, ARRAY_SIZE(usdhc3_pads)); + usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; + break; + default: + puts("MMC boot device not available"); + } + + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +} +#endif /* CONFIG_FSL_ESDHC_IMX & CONFIG_SPL_BUILD */ + +int board_phy_config(struct phy_device *phydev) +{ + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} + +int setup_fec(void) +{ + int ret; + struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; + + /* provide the PHY clock from the i.MX 6 */ + ret = enable_fec_anatop_clock(0, ENET_50MHZ); + if (ret) + return ret; + + setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); + + return 0; +} + +static iomux_v3_cfg_t const pwr_intb_pads[] = { + /* + * the bootrom sets the iomux to vselect, potentially connecting + * two outputs. Set this back to GPIO + */ + MX6_PAD_GPIO_18__GPIO7_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL) +}; + +#if defined(CONFIG_VIDEO_IPUV3) + +static iomux_v3_cfg_t const backlight_pads[] = { + /* Backlight On */ + MX6_PAD_EIM_D26__GPIO3_IO26 | MUX_PAD_CTRL(NO_PAD_CTRL) | MUX_MODE_SION, +#define RGB_BACKLIGHT_GP IMX_GPIO_NR(3, 26) + /* Backlight PWM, used as GPIO in U-Boot */ + MX6_PAD_EIM_A22__GPIO2_IO16 | MUX_PAD_CTRL(NO_PULLUP), + MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL) | + MUX_MODE_SION, +#define RGB_BACKLIGHTPWM_GP IMX_GPIO_NR(2, 9) +}; + +static iomux_v3_cfg_t const rgb_pads[] = { + MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(OUTPUT_RGB), + MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(OUTPUT_RGB), +}; + +static void do_enable_hdmi(struct display_info_t const *dev) +{ + imx_enable_hdmi_phy(); +} + +static void enable_rgb(struct display_info_t const *dev) +{ + imx_iomux_v3_setup_multiple_pads( + rgb_pads, + ARRAY_SIZE(rgb_pads)); + gpio_direction_output(RGB_BACKLIGHT_GP, 1); + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0); +} + +static int detect_default(struct display_info_t const *dev) +{ + (void) dev; + return 1; +} + +struct display_info_t const displays[] = {{ + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB24, + .detect = detect_hdmi, + .enable = do_enable_hdmi, + .mode = { + .name = "HDMI", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15385, + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED +} }, { + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB666, + .detect = detect_default, + .enable = enable_rgb, + .mode = { + .name = "vga-rgb", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 33000, + .left_margin = 48, + .right_margin = 16, + .upper_margin = 31, + .lower_margin = 11, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED +} }, { + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB666, + .enable = enable_rgb, + .mode = { + .name = "wvga-rgb", + .refresh = 60, + .xres = 800, + .yres = 480, + .pixclock = 25000, + .left_margin = 40, + .right_margin = 88, + .upper_margin = 33, + .lower_margin = 10, + .hsync_len = 128, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED +} } }; +size_t display_count = ARRAY_SIZE(displays); + +static void setup_display(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + int reg; + + enable_ipu_clock(); + imx_setup_hdmi(); + /* Turn on LDB0,IPU,IPU DI0 clocks */ + reg = __raw_readl(&mxc_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_LDB_DI0_MASK; + writel(reg, &mxc_ccm->CCGR3); + + /* set LDB0, LDB1 clk select to 011/011 */ + reg = readl(&mxc_ccm->cs2cdr); + reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK + |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK); + reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) + |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET); + writel(reg, &mxc_ccm->cs2cdr); + + reg = readl(&mxc_ccm->cscmr2); + reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV; + writel(reg, &mxc_ccm->cscmr2); + + reg = readl(&mxc_ccm->chsccdr); + reg |= (CHSCCDR_CLK_SEL_LDB_DI0 + <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); + writel(reg, &mxc_ccm->chsccdr); + + reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES + |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH + |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW + |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG + |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT + |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG + |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT + |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED + |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0; + writel(reg, &iomux->gpr[2]); + + reg = readl(&iomux->gpr[3]); + reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK + |IOMUXC_GPR3_HDMI_MUX_CTL_MASK)) + | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 + <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET); + writel(reg, &iomux->gpr[3]); + + /* backlight unconditionally on for now */ + imx_iomux_v3_setup_multiple_pads(backlight_pads, + ARRAY_SIZE(backlight_pads)); + /* use 0 for EDT 7", use 1 for LG fullHD panel */ + gpio_request(RGB_BACKLIGHTPWM_GP, "PWM<A>"); + gpio_request(RGB_BACKLIGHT_GP, "BL_ON"); + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 0); + gpio_direction_output(RGB_BACKLIGHT_GP, 1); +} + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_direction_output(RGB_BACKLIGHTPWM_GP, 1); + gpio_direction_output(RGB_BACKLIGHT_GP, 0); +} +#endif /* defined(CONFIG_VIDEO_IPUV3) */ + +int board_early_init_f(void) +{ + imx_iomux_v3_setup_multiple_pads(pwr_intb_pads, + ARRAY_SIZE(pwr_intb_pads)); + setup_iomux_uart(); + + return 0; +} + +/* + * Do not overwrite the console + * Use always serial for U-Boot console + */ +int overwrite_console(void) +{ + return 1; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; +#if defined(CONFIG_FEC_MXC) + setup_fec(); +#endif +#if defined(CONFIG_VIDEO_IPUV3) + setup_display(); +#endif + +#ifdef CONFIG_TDX_CMD_IMX_MFGR + (void) pmic_init(); +#endif + +#ifdef CONFIG_SATA + setup_sata(); +#endif + + setup_iomux_gpio(); + + return 0; +} + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ +#if defined(CONFIG_REVISION_TAG) && \ + defined(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG) + char env_str[256]; + u32 rev; + + rev = get_board_rev(); + snprintf(env_str, ARRAY_SIZE(env_str), "%.4x", rev); + env_set("board_rev", env_str); +#endif + +#ifdef CONFIG_CMD_USB_SDP + if (is_boot_from_usb()) { + printf("Serial Downloader recovery mode, using sdp command\n"); + env_set("bootdelay", "0"); + env_set("bootcmd", "sdp 0"); + } +#endif /* CONFIG_CMD_USB_SDP */ + + return 0; +} +#endif /* CONFIG_BOARD_LATE_INIT */ + +int checkboard(void) +{ + char it[] = " IT"; + int minc, maxc; + + switch (get_cpu_temp_grade(&minc, &maxc)) { + case TEMP_AUTOMOTIVE: + case TEMP_INDUSTRIAL: + break; + case TEMP_EXTCOMMERCIAL: + default: + it[0] = 0; + }; + printf("Model: Toradex Colibri iMX6 %s %sMB%s\n", + is_cpu_type(MXC_CPU_MX6DL) ? "DualLite" : "Solo", + (gd->ram_size == 0x20000000) ? "512" : "256", it); + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + u32 cma_size; + + ft_common_board_setup(blob, bd); + + cma_size = env_get_ulong("cma-size", 10, 320 * 1024 * 1024); + cma_size = min((u32)(gd->ram_size >> 1), cma_size); + + fdt_setprop_u32(blob, + fdt_path_offset(blob, "/reserved-memory/linux,cma"), + "size", + cma_size); + return 0; +} +#endif + +#ifdef CONFIG_CMD_BMODE +static const struct boot_mode board_boot_modes[] = { + {"mmc", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, + {NULL, 0}, +}; +#endif + +int misc_init_r(void) +{ +#ifdef CONFIG_CMD_BMODE + add_board_boot_modes(board_boot_modes); +#endif + return 0; +} + +#ifdef CONFIG_LDO_BYPASS_CHECK +/* TODO, use external pmic, for now always ldo_enable */ +void ldo_mode_set(int ldo_bypass) +{ + return; +} +#endif + +#ifdef CONFIG_SPL_BUILD +#include <spl.h> +#include <linux/libfdt.h> +#include "asm/arch/mx6dl-ddr.h" +#include "asm/arch/iomux.h" +#include "asm/arch/crm_regs.h" + +static int mx6s_dcd_table[] = { +/* ddr-setup.cfg */ + +MX6_IOM_DRAM_SDQS0, 0x00000030, +MX6_IOM_DRAM_SDQS1, 0x00000030, +MX6_IOM_DRAM_SDQS2, 0x00000030, +MX6_IOM_DRAM_SDQS3, 0x00000030, +MX6_IOM_DRAM_SDQS4, 0x00000030, +MX6_IOM_DRAM_SDQS5, 0x00000030, +MX6_IOM_DRAM_SDQS6, 0x00000030, +MX6_IOM_DRAM_SDQS7, 0x00000030, + +MX6_IOM_GRP_B0DS, 0x00000030, +MX6_IOM_GRP_B1DS, 0x00000030, +MX6_IOM_GRP_B2DS, 0x00000030, +MX6_IOM_GRP_B3DS, 0x00000030, +MX6_IOM_GRP_B4DS, 0x00000030, +MX6_IOM_GRP_B5DS, 0x00000030, +MX6_IOM_GRP_B6DS, 0x00000030, +MX6_IOM_GRP_B7DS, 0x00000030, +MX6_IOM_GRP_ADDDS, 0x00000030, +/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ +MX6_IOM_GRP_CTLDS, 0x00000030, + +MX6_IOM_DRAM_DQM0, 0x00020030, +MX6_IOM_DRAM_DQM1, 0x00020030, +MX6_IOM_DRAM_DQM2, 0x00020030, +MX6_IOM_DRAM_DQM3, 0x00020030, +MX6_IOM_DRAM_DQM4, 0x00020030, +MX6_IOM_DRAM_DQM5, 0x00020030, +MX6_IOM_DRAM_DQM6, 0x00020030, +MX6_IOM_DRAM_DQM7, 0x00020030, + +MX6_IOM_DRAM_CAS, 0x00020030, +MX6_IOM_DRAM_RAS, 0x00020030, +MX6_IOM_DRAM_SDCLK_0, 0x00020030, +MX6_IOM_DRAM_SDCLK_1, 0x00020030, + +MX6_IOM_DRAM_RESET, 0x00020030, +MX6_IOM_DRAM_SDCKE0, 0x00003000, +MX6_IOM_DRAM_SDCKE1, 0x00003000, + +MX6_IOM_DRAM_SDODT0, 0x00003030, +MX6_IOM_DRAM_SDODT1, 0x00003030, + +/* (differential input) */ +MX6_IOM_DDRMODE_CTL, 0x00020000, +/* (differential input) */ +MX6_IOM_GRP_DDRMODE, 0x00020000, +/* disable ddr pullups */ +MX6_IOM_GRP_DDRPKE, 0x00000000, +MX6_IOM_DRAM_SDBA2, 0x00000000, +/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ +MX6_IOM_GRP_DDR_TYPE, 0x000C0000, + +/* Read data DQ Byte0-3 delay */ +MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333, + +/* + * MDMISC mirroring interleaved (row/bank/col) + */ +/* TODO: check what the RALAT field does */ +MX6_MMDC_P0_MDMISC, 0x00081740, + +/* + * MDSCR con_req + */ +MX6_MMDC_P0_MDSCR, 0x00008000, + + +/* 800mhz_2x64mx16.cfg */ + +MX6_MMDC_P0_MDPDC, 0x0002002D, +MX6_MMDC_P0_MDCFG0, 0x2C305503, +MX6_MMDC_P0_MDCFG1, 0xB66D8D63, +MX6_MMDC_P0_MDCFG2, 0x01FF00DB, +MX6_MMDC_P0_MDRWD, 0x000026D2, +MX6_MMDC_P0_MDOR, 0x00301023, +MX6_MMDC_P0_MDOTC, 0x00333030, +MX6_MMDC_P0_MDPDC, 0x0002556D, +/* CS0 End: 7MSB of ((0x10000000, + 512M) -1) >> 25 */ +MX6_MMDC_P0_MDASP, 0x00000017, +/* DDR3 DATA BUS SIZE: 64BIT */ +/* MX6_MMDC_P0_MDCTL, 0x821A0000, */ +/* DDR3 DATA BUS SIZE: 32BIT */ +MX6_MMDC_P0_MDCTL, 0x82190000, + +/* Write commands to DDR */ +/* Load Mode Registers */ +/* TODO Use Auto Self-Refresh mode (Extended Temperature)*/ +/* MX6_MMDC_P0_MDSCR, 0x04408032, */ +MX6_MMDC_P0_MDSCR, 0x04008032, +MX6_MMDC_P0_MDSCR, 0x00008033, +MX6_MMDC_P0_MDSCR, 0x00048031, +MX6_MMDC_P0_MDSCR, 0x13208030, +/* ZQ calibration */ +MX6_MMDC_P0_MDSCR, 0x04008040, + +MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003, +MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003, +MX6_MMDC_P0_MDREF, 0x00005800, + +MX6_MMDC_P0_MPODTCTRL, 0x00000000, +MX6_MMDC_P1_MPODTCTRL, 0x00000000, + +MX6_MMDC_P0_MPDGCTRL0, 0x42360232, +MX6_MMDC_P0_MPDGCTRL1, 0x021F022A, +MX6_MMDC_P1_MPDGCTRL0, 0x421E0224, +MX6_MMDC_P1_MPDGCTRL1, 0x02110218, + +MX6_MMDC_P0_MPRDDLCTL, 0x41434344, +MX6_MMDC_P1_MPRDDLCTL, 0x4345423E, +MX6_MMDC_P0_MPWRDLCTL, 0x39383339, +MX6_MMDC_P1_MPWRDLCTL, 0x3E363930, + +MX6_MMDC_P0_MPWLDECTRL0, 0x00340039, +MX6_MMDC_P0_MPWLDECTRL1, 0x002C002D, +MX6_MMDC_P1_MPWLDECTRL0, 0x00120019, +MX6_MMDC_P1_MPWLDECTRL1, 0x0012002D, + +MX6_MMDC_P0_MPMUR0, 0x00000800, +MX6_MMDC_P1_MPMUR0, 0x00000800, +MX6_MMDC_P0_MDSCR, 0x00000000, +MX6_MMDC_P0_MAPSR, 0x00011006, +}; + +static int mx6dl_dcd_table[] = { +/* ddr-setup.cfg */ + +MX6_IOM_DRAM_SDQS0, 0x00000030, +MX6_IOM_DRAM_SDQS1, 0x00000030, +MX6_IOM_DRAM_SDQS2, 0x00000030, +MX6_IOM_DRAM_SDQS3, 0x00000030, +MX6_IOM_DRAM_SDQS4, 0x00000030, +MX6_IOM_DRAM_SDQS5, 0x00000030, +MX6_IOM_DRAM_SDQS6, 0x00000030, +MX6_IOM_DRAM_SDQS7, 0x00000030, + +MX6_IOM_GRP_B0DS, 0x00000030, +MX6_IOM_GRP_B1DS, 0x00000030, +MX6_IOM_GRP_B2DS, 0x00000030, +MX6_IOM_GRP_B3DS, 0x00000030, +MX6_IOM_GRP_B4DS, 0x00000030, +MX6_IOM_GRP_B5DS, 0x00000030, +MX6_IOM_GRP_B6DS, 0x00000030, +MX6_IOM_GRP_B7DS, 0x00000030, +MX6_IOM_GRP_ADDDS, 0x00000030, +/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ +MX6_IOM_GRP_CTLDS, 0x00000030, + +MX6_IOM_DRAM_DQM0, 0x00020030, +MX6_IOM_DRAM_DQM1, 0x00020030, +MX6_IOM_DRAM_DQM2, 0x00020030, +MX6_IOM_DRAM_DQM3, 0x00020030, +MX6_IOM_DRAM_DQM4, 0x00020030, +MX6_IOM_DRAM_DQM5, 0x00020030, +MX6_IOM_DRAM_DQM6, 0x00020030, +MX6_IOM_DRAM_DQM7, 0x00020030, + +MX6_IOM_DRAM_CAS, 0x00020030, +MX6_IOM_DRAM_RAS, 0x00020030, +MX6_IOM_DRAM_SDCLK_0, 0x00020030, +MX6_IOM_DRAM_SDCLK_1, 0x00020030, + +MX6_IOM_DRAM_RESET, 0x00020030, +MX6_IOM_DRAM_SDCKE0, 0x00003000, +MX6_IOM_DRAM_SDCKE1, 0x00003000, + +MX6_IOM_DRAM_SDODT0, 0x00003030, +MX6_IOM_DRAM_SDODT1, 0x00003030, + +/* (differential input) */ +MX6_IOM_DDRMODE_CTL, 0x00020000, +/* (differential input) */ +MX6_IOM_GRP_DDRMODE, 0x00020000, +/* disable ddr pullups */ +MX6_IOM_GRP_DDRPKE, 0x00000000, +MX6_IOM_DRAM_SDBA2, 0x00000000, +/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ +MX6_IOM_GRP_DDR_TYPE, 0x000C0000, + +/* Read data DQ Byte0-3 delay */ +MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333, +MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333, +MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333, + +/* + * MDMISC mirroring interleaved (row/bank/col) + */ +/* TODO: check what the RALAT field does */ +MX6_MMDC_P0_MDMISC, 0x00081740, + +/* + * MDSCR con_req + */ +MX6_MMDC_P0_MDSCR, 0x00008000, + + +/* 800mhz_2x64mx16.cfg */ + +MX6_MMDC_P0_MDPDC, 0x0002002D, +MX6_MMDC_P0_MDCFG0, 0x2C305503, +MX6_MMDC_P0_MDCFG1, 0xB66D8D63, +MX6_MMDC_P0_MDCFG2, 0x01FF00DB, +MX6_MMDC_P0_MDRWD, 0x000026D2, +MX6_MMDC_P0_MDOR, 0x00301023, +MX6_MMDC_P0_MDOTC, 0x00333030, +MX6_MMDC_P0_MDPDC, 0x0002556D, +/* CS0 End: 7MSB of ((0x10000000, + 512M) -1) >> 25 */ +MX6_MMDC_P0_MDASP, 0x00000017, +/* DDR3 DATA BUS SIZE: 64BIT */ +MX6_MMDC_P0_MDCTL, 0x821A0000, +/* DDR3 DATA BUS SIZE: 32BIT */ +/* MX6_MMDC_P0_MDCTL, 0x82190000, */ + +/* Write commands to DDR */ +/* Load Mode Registers */ +/* TODO Use Auto Self-Refresh mode (Extended Temperature)*/ +/* MX6_MMDC_P0_MDSCR, 0x04408032, */ +MX6_MMDC_P0_MDSCR, 0x04008032, +MX6_MMDC_P0_MDSCR, 0x00008033, +MX6_MMDC_P0_MDSCR, 0x00048031, +MX6_MMDC_P0_MDSCR, 0x13208030, +/* ZQ calibration */ +MX6_MMDC_P0_MDSCR, 0x04008040, + +MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003, +MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003, +MX6_MMDC_P0_MDREF, 0x00005800, + +MX6_MMDC_P0_MPODTCTRL, 0x00000000, +MX6_MMDC_P1_MPODTCTRL, 0x00000000, + +MX6_MMDC_P0_MPDGCTRL0, 0x42360232, +MX6_MMDC_P0_MPDGCTRL1, 0x021F022A, +MX6_MMDC_P1_MPDGCTRL0, 0x421E0224, +MX6_MMDC_P1_MPDGCTRL1, 0x02110218, + +MX6_MMDC_P0_MPRDDLCTL, 0x41434344, +MX6_MMDC_P1_MPRDDLCTL, 0x4345423E, +MX6_MMDC_P0_MPWRDLCTL, 0x39383339, +MX6_MMDC_P1_MPWRDLCTL, 0x3E363930, + +MX6_MMDC_P0_MPWLDECTRL0, 0x00340039, +MX6_MMDC_P0_MPWLDECTRL1, 0x002C002D, +MX6_MMDC_P1_MPWLDECTRL0, 0x00120019, +MX6_MMDC_P1_MPWLDECTRL1, 0x0012002D, + +MX6_MMDC_P0_MPMUR0, 0x00000800, +MX6_MMDC_P1_MPMUR0, 0x00000800, +MX6_MMDC_P0_MDSCR, 0x00000000, +MX6_MMDC_P0_MAPSR, 0x00011006, +}; + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x0030FC03, &ccm->CCGR1); + writel(0x0FFFFFF3, &ccm->CCGR2); + writel(0x3FF0300F, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0000F3, &ccm->CCGR5); + writel(0x000003FF, &ccm->CCGR6); + +/* + * Setup CCM_CCOSR register as follows: + * + * cko1_en = 1 --> CKO1 enabled + * cko1_div = 111 --> divide by 8 + * cko1_sel = 1011 --> ahb_clk_root + * + * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz + */ + writel(0x000000FB, &ccm->ccosr); +} + +static void ddr_init(int *table, int size) +{ + int i; + + for (i = 0; i < size / 2 ; i++) + writel(table[2 * i + 1], table[2 * i]); +} + +static void spl_dram_init(void) +{ + int minc, maxc; + + switch (get_cpu_temp_grade(&minc, &maxc)) { + case TEMP_COMMERCIAL: + case TEMP_EXTCOMMERCIAL: + if (is_cpu_type(MXC_CPU_MX6DL)) { + puts("Commercial temperature grade DDR3 timings, 64bit bus width.\n"); + ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table)); + } else { + puts("Commercial temperature grade DDR3 timings, 32bit bus width.\n"); + ddr_init(mx6s_dcd_table, ARRAY_SIZE(mx6s_dcd_table)); + } + break; + case TEMP_INDUSTRIAL: + case TEMP_AUTOMOTIVE: + default: + if (is_cpu_type(MXC_CPU_MX6DL)) { + puts("Industrial temperature grade DDR3 timings, 64bit bus width.\n"); + ddr_init(mx6dl_dcd_table, ARRAY_SIZE(mx6dl_dcd_table)); + } else { + puts("Industrial temperature grade DDR3 timings, 32bit bus width.\n"); + ddr_init(mx6s_dcd_table, ARRAY_SIZE(mx6s_dcd_table)); + } + break; + }; + udelay(100); +} + +static iomux_v3_cfg_t const gpio_reset_pad[] = { + MX6_PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL) | + MUX_MODE_SION +#define GPIO_NRESET IMX_GPIO_NR(6, 27) +}; + +#define IMX_RESET_CAUSE_POR 0x00011 +static void nreset_out(void) +{ + int reset_cause = get_imx_reset_cause(); + + if (reset_cause != IMX_RESET_CAUSE_POR) { + imx_iomux_v3_setup_multiple_pads(gpio_reset_pad, + ARRAY_SIZE(gpio_reset_pad)); + gpio_direction_output(GPIO_NRESET, 1); + udelay(100); + gpio_direction_output(GPIO_NRESET, 0); + } +} + +void board_init_f(ulong dummy) +{ + /* setup AIPS and disable watchdog */ + arch_cpu_init(); + + ccgr_init(); + gpr_init(); + + /* iomux */ + board_early_init_f(); + + /* setup GP timer */ + timer_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); + + /* Make sure we use dte mode */ + setup_dtemode_uart(); + + /* DDR initialization */ + spl_dram_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* Assert nReset_Out */ + nreset_out(); + + /* load/boot image from boot device */ + board_init_r(NULL, 0); +} + +void reset_cpu(void) +{ +} + +#endif /* CONFIG_SPL_BUILD */ + +static struct mxc_serial_plat mxc_serial_plat = { + .reg = (struct mxc_uart *)UART1_BASE, + .use_dte = true, +}; + +U_BOOT_DRVINFO(mxc_serial) = { + .name = "serial_mxc", + .plat = &mxc_serial_plat, +}; diff --git a/roms/u-boot/board/toradex/colibri_imx6/do_fuse.c b/roms/u-boot/board/toradex/colibri_imx6/do_fuse.c new file mode 100644 index 000000000..6991b1bc1 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx6/do_fuse.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014-2016, Toradex AG + */ + +/* + * Helpers for i.MX OTP fusing during module production +*/ + +#include <common.h> +#ifndef CONFIG_SPL_BUILD +#include <command.h> +#include <console.h> +#include <fuse.h> + +static int mfgr_fuse(void) +{ + unsigned val, val6; + + fuse_sense(0, 5, &val); + printf("Fuse 0, 5: %8x\n", val); + fuse_sense(0, 6, &val6); + printf("Fuse 0, 6: %8x\n", val6); + fuse_sense(4, 3, &val); + printf("Fuse 4, 3: %8x\n", val); + fuse_sense(4, 2, &val); + printf("Fuse 4, 2: %8x\n", val); + if (val6 & 0x10) { + puts("BT_FUSE_SEL already fused, will do nothing\n"); + return CMD_RET_FAILURE; + } + /* boot cfg */ + fuse_prog(0, 5, 0x00005062); + /* BT_FUSE_SEL */ + fuse_prog(0, 6, 0x00000010); + return CMD_RET_SUCCESS; +} + +int do_mfgr_fuse(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + puts("Fusing...\n"); + ret = mfgr_fuse(); + if (ret == CMD_RET_SUCCESS) + puts("done.\n"); + else + puts("failed.\n"); + return ret; +} + +int do_updt_fuse(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + unsigned val; + int ret; + int confirmed = argc >= 1 && !strcmp(argv[1], "-y"); + + /* can be used in scripts for command availability check */ + if (argc >= 1 && !strcmp(argv[1], "-n")) + return CMD_RET_SUCCESS; + + /* boot cfg */ + fuse_sense(0, 5, &val); + printf("Fuse 0, 5: %8x\n", val); + if (val & 0x10) { + puts("Fast boot mode already fused, no need to fuse\n"); + return CMD_RET_SUCCESS; + } + if (!confirmed) { + puts("Warning: Programming fuses is an irreversible operation!\n" + " Updating to fast boot mode prevents easy\n" + " downgrading to previous BSP versions.\n" + "\nReally perform this fuse programming? <y/N>\n"); + if (!confirm_yesno()) + return CMD_RET_FAILURE; + } + puts("Fusing fast boot mode...\n"); + ret = fuse_prog(0, 5, 0x00005072); + if (ret == CMD_RET_SUCCESS) + puts("done.\n"); + else + puts("failed.\n"); + return ret; +} + +U_BOOT_CMD( + mfgr_fuse, 1, 0, do_mfgr_fuse, + "OTP fusing during module production", + "" +); + +U_BOOT_CMD( + updt_fuse, 2, 0, do_updt_fuse, + "OTP fusing during module update", + "updt_fuse [-n] [-y] - boot cfg fast boot mode fusing" +); +#endif /* CONFIG_SPL_BUILD */ diff --git a/roms/u-boot/board/toradex/colibri_imx6/pf0100.c b/roms/u-boot/board/toradex/colibri_imx6/pf0100.c new file mode 100644 index 000000000..8f08d8c73 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx6/pf0100.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014-2019, Toradex AG + */ + +/* + * Helpers for Freescale PMIC PF0100 +*/ + +#include <common.h> +#include <command.h> +#include <i2c.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux.h> +#include <asm/arch/mx6-pins.h> +#include <asm/gpio.h> +#include <asm/mach-imx/iomux-v3.h> +#include <linux/delay.h> + +#include "pf0100_otp.inc" +#include "pf0100.h" + +/* define for PMIC register dump */ +/*#define DEBUG */ + +#define WARNBAR "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n" + +/* use GPIO: EXT_IO1 to switch on VPGM, ON: 1 */ +static __maybe_unused iomux_v3_cfg_t const pmic_prog_pads[] = { + MX6_PAD_NANDF_D3__GPIO2_IO03 | MUX_PAD_CTRL(NO_PAD_CTRL), +# define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 3) +}; + +unsigned pmic_init(void) +{ + int rc; + struct udevice *dev = NULL; + unsigned programmed = 0; + uchar bus = 1; + uchar devid, revid, val; + + puts("PMIC: "); + rc = i2c_get_chip_for_busnum(bus, PFUZE100_I2C_ADDR, 1, &dev); + if (rc) { + printf("failed to get device for PMIC at address 0x%x\n", + PFUZE100_I2C_ADDR); + return 0; + } + + /* check for errors in PMIC fuses */ + if (dm_i2c_read(dev, PFUZE100_INTSTAT3, &val, 1) < 0) { + puts("i2c pmic INTSTAT3 register read failed\n"); + return 0; + } + if (val & PFUZE100_BIT_OTP_ECCI) { + puts("\n" WARNBAR); + puts("WARNING: ecc errors found in pmic fuse banks\n"); + puts(WARNBAR); + } + if (dm_i2c_read(dev, PFUZE100_OTP_ECC_SE1, &val, 1) < 0) { + puts("i2c pmic ECC_SE1 register read failed\n"); + return 0; + } + if (val & PFUZE100_BITS_ECC_SE1) { + puts(WARNBAR); + puts("WARNING: ecc has made bit corrections in banks 1 to 5\n"); + puts(WARNBAR); + } + if (dm_i2c_read(dev, PFUZE100_OTP_ECC_SE2, &val, 1) < 0) { + puts("i2c pmic ECC_SE2 register read failed\n"); + return 0; + } + if (val & PFUZE100_BITS_ECC_SE2) { + puts(WARNBAR); + puts("WARNING: ecc has made bit corrections in banks 6 to 10\n" + ); + puts(WARNBAR); + } + if (dm_i2c_read(dev, PFUZE100_OTP_ECC_DE1, &val, 1) < 0) { + puts("i2c pmic ECC_DE register read failed\n"); + return 0; + } + if (val & PFUZE100_BITS_ECC_DE1) { + puts(WARNBAR); + puts("ERROR: banks 1 to 5 have uncorrectable bits\n"); + puts(WARNBAR); + } + if (dm_i2c_read(dev, PFUZE100_OTP_ECC_DE2, &val, 1) < 0) { + puts("i2c pmic ECC_DE register read failed\n"); + return 0; + } + if (val & PFUZE100_BITS_ECC_DE2) { + puts(WARNBAR); + puts("ERROR: banks 6 to 10 have uncorrectable bits\n"); + puts(WARNBAR); + } + + /* get device ident */ + if (dm_i2c_read(dev, PFUZE100_DEVICEID, &devid, 1) < 0) { + puts("i2c pmic devid read failed\n"); + return 0; + } + if (dm_i2c_read(dev, PFUZE100_REVID, &revid, 1) < 0) { + puts("i2c pmic revid read failed\n"); + return 0; + } + printf("device id: 0x%.2x, revision id: 0x%.2x, ", devid, revid); + + /* get device programmed state */ + val = PFUZE100_PAGE_REGISTER_PAGE1; + if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) { + puts("i2c write failed\n"); + return 0; + } + if (dm_i2c_read(dev, PFUZE100_FUSE_POR1, &val, 1) < 0) { + puts("i2c fuse_por read failed\n"); + return 0; + } + if (val & PFUZE100_FUSE_POR_M) + programmed++; + + if (dm_i2c_read(dev, PFUZE100_FUSE_POR2, &val, 1) < 0) { + puts("i2c fuse_por read failed\n"); + return programmed; + } + if (val & PFUZE100_FUSE_POR_M) + programmed++; + + if (dm_i2c_read(dev, PFUZE100_FUSE_POR3, &val, 1) < 0) { + puts("i2c fuse_por read failed\n"); + return programmed; + } + if (val & PFUZE100_FUSE_POR_M) + programmed++; + + switch (programmed) { + case 0: + puts("not programmed\n"); + break; + case 3: + puts("programmed\n"); + break; + default: + puts("undefined programming state\n"); + break; + } + +#ifdef DEBUG + { + unsigned int i, j; + + for (i = 0; i < 16; i++) + printf("\t%x", i); + for (j = 0; j < 0x80; ) { + printf("\n%2x", j); + for (i = 0; i < 16; i++) { + dm_i2c_read(dev, j + i, &val, 1); + printf("\t%2x", val); + } + j += 0x10; + } + printf("\nEXT Page 1"); + + val = PFUZE100_PAGE_REGISTER_PAGE1; + if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) { + puts("i2c write failed\n"); + return 0; + } + + for (j = 0x80; j < 0x100; ) { + printf("\n%2x", j); + for (i = 0; i < 16; i++) { + dm_i2c_read(dev, j + i, &val, 1); + printf("\t%2x", val); + } + j += 0x10; + } + printf("\nEXT Page 2"); + + val = PFUZE100_PAGE_REGISTER_PAGE2; + if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) { + puts("i2c write failed\n"); + return 0; + } + + for (j = 0x80; j < 0x100; ) { + printf("\n%2x", j); + for (i = 0; i < 16; i++) { + dm_i2c_read(dev, j + i, &val, 1); + printf("\t%2x", val); + } + j += 0x10; + } + printf("\n"); + } +#endif /* DEBUG */ + + return programmed; +} + +#ifndef CONFIG_SPL_BUILD +static int pf0100_prog(void) +{ + int rc; + struct udevice *dev = NULL; + unsigned char bus = 1; + unsigned char val; + unsigned int i; + + if (pmic_init() == 3) { + puts("PMIC already programmed, exiting\n"); + return CMD_RET_FAILURE; + } + /* set up gpio to manipulate vprog, initially off */ + imx_iomux_v3_setup_multiple_pads(pmic_prog_pads, + ARRAY_SIZE(pmic_prog_pads)); + gpio_direction_output(PMIC_PROG_VOLTAGE, 0); + + rc = i2c_get_chip_for_busnum(bus, PFUZE100_I2C_ADDR, 1, &dev); + if (rc) { + printf("failed to get device for PMIC at address 0x%x\n", + PFUZE100_I2C_ADDR); + return CMD_RET_FAILURE; + } + + for (i = 0; i < ARRAY_SIZE(pmic_otp_prog); i++) { + switch (pmic_otp_prog[i].cmd) { + case pmic_i2c: + val = (unsigned char) (pmic_otp_prog[i].value & 0xff); + if (dm_i2c_write(dev, pmic_otp_prog[i].reg, &val, 1)) { + printf("i2c write failed, reg 0x%2x, value 0x%2x\n", + pmic_otp_prog[i].reg, val); + return CMD_RET_FAILURE; + } + break; + case pmic_delay: + udelay(pmic_otp_prog[i].value * 1000); + break; + case pmic_vpgm: + gpio_direction_output(PMIC_PROG_VOLTAGE, + pmic_otp_prog[i].value); + break; + case pmic_pwr: + /* TODO */ + break; + } + } + return CMD_RET_SUCCESS; +} + +static int do_pf0100_prog(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + puts("Programming PMIC OTP..."); + ret = pf0100_prog(); + if (ret == CMD_RET_SUCCESS) + puts("done.\n"); + else + puts("failed.\n"); + return ret; +} + +U_BOOT_CMD( + pf0100_otp_prog, 1, 0, do_pf0100_prog, + "Program the OTP fuses on the PMIC PF0100", + "" +); +#endif /* CONFIG_SPL_BUILD */ diff --git a/roms/u-boot/board/toradex/colibri_imx6/pf0100.h b/roms/u-boot/board/toradex/colibri_imx6/pf0100.h new file mode 100644 index 000000000..925762051 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx6/pf0100.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2014-2019, Toradex AG + */ + +/* + * Helpers for Freescale PMIC PF0100 +*/ + +#ifndef PF0100_H_ +#define PF0100_H_ + +/* bit definitions */ +#define PFUZE100_BIT_0 (0x01 << 0) +#define PFUZE100_BIT_1 (0x01 << 1) +#define PFUZE100_BIT_2 (0x01 << 2) +#define PFUZE100_BIT_3 (0x01 << 3) +#define PFUZE100_BIT_4 (0x01 << 4) +#define PFUZE100_BIT_5 (0x01 << 5) +#define PFUZE100_BIT_6 (0x01 << 6) +#define PFUZE100_BIT_7 (0x01 << 7) + +/* 7-bit I2C bus slave address */ +#define PFUZE100_I2C_ADDR (0x08) +/* Register Addresses */ +#define PFUZE100_DEVICEID (0x0) +#define PFUZE100_REVID (0x3) +#define PFUZE100_INTSTAT3 (0xe) +#define PFUZE100_BIT_OTP_ECCI PFUZE100_BIT_7 +#define PFUZE100_SW1AMODE (0x23) +#define PFUZE100_SW1ACON 36 +#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */ +#define PFUZE100_SW1ACON_SPEED_M (0x3<<6) +#define PFUZE100_SW1CCON 49 +#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */ +#define PFUZE100_SW1CCON_SPEED_M (0x3<<6) +#define PFUZE100_SW1AVOL 32 +#define PFUZE100_SW1AVOL_VSEL_M (0x3f<<0) +#define PFUZE100_SW1CVOL 46 +#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0) +#define PFUZE100_VGEN1CTL (0x6c) +#define PFUZE100_VGEN1_VAL (0x30 + 0x08) /* Always ON, 1.2V */ +#define PFUZE100_SWBSTCTL (0x66) +/* Always ON, Auto Switching Mode, 5.0V */ +#define PFUZE100_SWBST_VAL (0x40 + 0x08 + 0x00) + +/* chooses the extended page (registers 0x80..0xff) */ +#define PFUZE100_PAGE_REGISTER 0x7f +#define PFUZE100_PAGE_REGISTER_PAGE_M (0x1f << 0) +#define PFUZE100_PAGE_REGISTER_PAGE1 (0x01 & PFUZE100_PAGE_REGISTER_PAGE_M) +#define PFUZE100_PAGE_REGISTER_PAGE2 (0x02 & PFUZE100_PAGE_REGISTER_PAGE_M) + +/* extended page 1 */ +#define PFUZE100_OTP_ECC_SE1 0x8a +#define PFUZE100_BIT_ECC1_SE PFUZE100_BIT_0 +#define PFUZE100_BIT_ECC2_SE PFUZE100_BIT_1 +#define PFUZE100_BIT_ECC3_SE PFUZE100_BIT_2 +#define PFUZE100_BIT_ECC4_SE PFUZE100_BIT_3 +#define PFUZE100_BIT_ECC5_SE PFUZE100_BIT_4 +#define PFUZE100_BITS_ECC_SE1 ((PFUZE100_BIT_ECC1_SE) | \ + (PFUZE100_BIT_ECC2_SE) | \ + (PFUZE100_BIT_ECC3_SE) | \ + (PFUZE100_BIT_ECC4_SE) | \ + (PFUZE100_BIT_ECC5_SE)) +#define PFUZE100_OTP_ECC_SE2 0x8b +#define PFUZE100_BIT_ECC6_SE PFUZE100_BIT_0 +#define PFUZE100_BIT_ECC7_SE PFUZE100_BIT_1 +#define PFUZE100_BIT_ECC8_SE PFUZE100_BIT_2 +#define PFUZE100_BIT_ECC9_SE PFUZE100_BIT_3 +#define PFUZE100_BIT_ECC10_SE PFUZE100_BIT_4 +#define PFUZE100_BITS_ECC_SE2 ((PFUZE100_BIT_ECC6_SE) | \ + (PFUZE100_BIT_ECC7_SE) | \ + (PFUZE100_BIT_ECC8_SE) | \ + (PFUZE100_BIT_ECC9_SE) | \ + (PFUZE100_BIT_ECC10_SE)) +#define PFUZE100_OTP_ECC_DE1 0x8c +#define PFUZE100_BIT_ECC1_DE PFUZE100_BIT_0 +#define PFUZE100_BIT_ECC2_DE PFUZE100_BIT_1 +#define PFUZE100_BIT_ECC3_DE PFUZE100_BIT_2 +#define PFUZE100_BIT_ECC4_DE PFUZE100_BIT_3 +#define PFUZE100_BIT_ECC5_DE PFUZE100_BIT_4 +#define PFUZE100_BITS_ECC_DE1 ((PFUZE100_BIT_ECC1_DE) | \ + (PFUZE100_BIT_ECC2_DE) | \ + (PFUZE100_BIT_ECC3_DE) | \ + (PFUZE100_BIT_ECC4_DE) | \ + (PFUZE100_BIT_ECC5_DE)) +#define PFUZE100_OTP_ECC_DE2 0x8d +#define PFUZE100_BIT_ECC6_DE PFUZE100_BIT_0 +#define PFUZE100_BIT_ECC7_DE PFUZE100_BIT_1 +#define PFUZE100_BIT_ECC8_DE PFUZE100_BIT_2 +#define PFUZE100_BIT_ECC9_DE PFUZE100_BIT_3 +#define PFUZE100_BIT_ECC10_DE PFUZE100_BIT_4 +#define PFUZE100_BITS_ECC_DE2 ((PFUZE100_BIT_ECC6_DE) | \ + (PFUZE100_BIT_ECC7_DE) | \ + (PFUZE100_BIT_ECC8_DE) | \ + (PFUZE100_BIT_ECC9_DE) | \ + (PFUZE100_BIT_ECC10_DE)) +#define PFUZE100_FUSE_POR1 0xe4 +#define PFUZE100_FUSE_POR2 0xe5 +#define PFUZE100_FUSE_POR3 0xe6 +#define PFUZE100_FUSE_POR_M (0x1 << 1) + +/* output some informational messages, return the number FUSE_POR=1 */ +/* i.e. 0: unprogrammed, 3: programmed, other: undefined prog. state */ +unsigned pmic_init(void); + +#endif /* PF0100_H_ */ diff --git a/roms/u-boot/board/toradex/colibri_imx6/pf0100_otp.inc b/roms/u-boot/board/toradex/colibri_imx6/pf0100_otp.inc new file mode 100644 index 000000000..c3b1f67f8 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx6/pf0100_otp.inc @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2014-2016, Toradex AG + */ + +// Register Output for PF0100 programmer +// Customer: Toradex AG +// Program: Colibri iMX6 V1.1 +// Sample marking: +// Date: 01.05.2017 +// Time: 16:22:32 +// Generated from Spreadsheet Revision: P1.8 + +/* sed commands to get from programmer script to struct content */ +/* sed -e 's/^WRITE_I2C:\(..\):\(..\)/\{pmic_i2c, 0x\1, 0x\2\},/g' -e 's/^DELAY:\([0-9]*\)/\{pmic_delay, 0, \1\},/g' pf0100_otp_Colibri_iMX6.txt > pf0100_otp.inc + sed -i -e 's/^VPGM:ON/\{pmic_vpgm, 0, 1},/g' -e 's/^VPGM:OFF/\{pmic_vpgm, 0, 0},/g' pf0100_otp.inc + sed -i -e 's/^PWRON: HIGH/\{pmic_pwr, 0, 1},/g' -e 's/^PWRON:LOW/\{pmic_pwr, 0, 0},/g' pf0100_otp.inc +*/ + +enum { pmic_i2c, pmic_delay, pmic_vpgm, pmic_pwr }; +struct pmic_otp_prog_t{ + unsigned char cmd; + unsigned char reg; + unsigned short value; +}; + +struct pmic_otp_prog_t pmic_otp_prog[] = { +{pmic_i2c, 0x7F, 0x01}, // Access FSL EXT Page 1 +{pmic_i2c, 0xA0, 0x2B}, // Auto gen from Row94 +{pmic_i2c, 0xA1, 0x01}, // Auto gen from Row95 +{pmic_i2c, 0xA2, 0x05}, // Auto gen from Row96 +{pmic_i2c, 0xA8, 0x2B}, // Auto gen from Row102 +{pmic_i2c, 0xA9, 0x02}, // Auto gen from Row103 +{pmic_i2c, 0xAA, 0x01}, // Auto gen from Row104 +{pmic_i2c, 0xAC, 0x18}, // Auto gen from Row106 +{pmic_i2c, 0xAE, 0x01}, // Auto gen from Row108 +{pmic_i2c, 0xB0, 0x2C}, // Auto gen from Row110 +{pmic_i2c, 0xB1, 0x04}, // Auto gen from Row111 +{pmic_i2c, 0xB2, 0x01}, // Auto gen from Row112 +{pmic_i2c, 0xB4, 0x2C}, // Auto gen from Row114 +{pmic_i2c, 0xB5, 0x04}, // Auto gen from Row115 +{pmic_i2c, 0xB6, 0x01}, // Auto gen from Row116 +{pmic_i2c, 0xB8, 0x18}, // Auto gen from Row118 +{pmic_i2c, 0xBA, 0x01}, // Auto gen from Row120 +{pmic_i2c, 0xBD, 0x0E}, // Auto gen from Row123 +{pmic_i2c, 0xC0, 0x06}, // Auto gen from Row126 +{pmic_i2c, 0xC4, 0x04}, // Auto gen from Row130 +{pmic_i2c, 0xC8, 0x0E}, // Auto gen from Row134 +{pmic_i2c, 0xCC, 0x0E}, // Auto gen from Row138 +{pmic_i2c, 0xCD, 0x05}, // Auto gen from Row139 +{pmic_i2c, 0xD0, 0x0F}, // Auto gen from Row142 +{pmic_i2c, 0xD1, 0x05}, // Auto gen from Row143 +{pmic_i2c, 0xD5, 0x07}, // Auto gen from Row147 +{pmic_i2c, 0xD8, 0x07}, // Auto gen from Row150 +{pmic_i2c, 0xD9, 0x06}, // Auto gen from Row151 +{pmic_i2c, 0xDC, 0x0A}, // Auto gen from Row154 +{pmic_i2c, 0xDD, 0x03}, // Auto gen from Row155 +{pmic_i2c, 0xE0, 0x05}, // Auto gen from Row158 + +#if 0 /* TBB mode */ +{pmic_i2c, 0xE4, 0x80}, // TBB_POR = 1 +{pmic_delay, 0, 10}, +#else +// Write OTP +{pmic_i2c, 0xE4, 0x02}, // FUSE POR1=1 +{pmic_i2c, 0xE5, 0x02}, // FUSE POR2=1 +{pmic_i2c, 0xE6, 0x02}, // FUSE POR3=1 +{pmic_i2c, 0xF0, 0x1F}, // Enable ECC for fuse banks 1 to 5 by writing to OTP EN ECC0 register +{pmic_i2c, 0xF1, 0x1F}, // Enable ECC for fuse banks 6 to 10 by writing to OTP EN ECC1 register +{pmic_i2c, 0x7F, 0x02}, // Access PF0100 EXT Page2 +{pmic_i2c, 0xD0, 0x1F}, // Set Auto ECC for fuse banks 1 to 5 by writing to OTP AUTO ECC0 register +{pmic_i2c, 0xD1, 0x1F}, // Set Auto ECC for fuse banks 6 to 10 by writing to OTP AUTO ECC1 register +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +{pmic_vpgm, 0, 1}, // Turn ON 8V SWBST +//VPGM:DOWN:n +//VPGM:UP:n +{pmic_delay, 0, 500}, // Adds 500msec delay to allow VPGM time to ramp up +//----------------------------------------------------------------------------------- +// PF0100 OTP MANUAL-PROGRAMMING (BANK 1 thru 10) +//----------------------------------------------------------------------------------- +// BANK 1 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF1, 0x03}, // Set Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF1, 0x0B}, // Set Bank 1 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF1, 0x03}, // Reset Bank 1 ANTIFUSE_EN +{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 2 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF2, 0x03}, // Set Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF2, 0x0B}, // Set Bank 2 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF2, 0x03}, // Reset Bank 2 ANTIFUSE_EN +{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 3 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF3, 0x03}, // Set Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF3, 0x0B}, // Set Bank 3 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF3, 0x03}, // Reset Bank 3 ANTIFUSE_EN +{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 4 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF4, 0x03}, // Set Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF4, 0x0B}, // Set Bank 4 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF4, 0x03}, // Reset Bank 4 ANTIFUSE_EN +{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 5 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF5, 0x03}, // Set Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF5, 0x0B}, // Set Bank 5 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF5, 0x03}, // Reset Bank 5 ANTIFUSE_EN +{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 6 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF6, 0x03}, // Set Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF6, 0x0B}, // Set Bank 6 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF6, 0x03}, // Reset Bank 6 ANTIFUSE_EN +{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 7 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF7, 0x03}, // Set Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF7, 0x0B}, // Set Bank 7 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF7, 0x03}, // Reset Bank 7 ANTIFUSE_EN +{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 8 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF8, 0x03}, // Set Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF8, 0x0B}, // Set Bank 8 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF8, 0x03}, // Reset Bank 8 ANTIFUSE_EN +{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 9 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF9, 0x03}, // Set Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xF9, 0x0B}, // Set Bank 9 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xF9, 0x03}, // Reset Bank 9 ANTIFUSE_EN +{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +// BANK 10 +//----------------------------------------------------------------------------------- +{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xFA, 0x03}, // Set Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +{pmic_i2c, 0xFA, 0x0B}, // Set Bank 10 ANTIFUSE_EN +{pmic_delay, 0, 10}, // Allow time for bank programming to complete +{pmic_i2c, 0xFA, 0x03}, // Reset Bank 10 ANTIFUSE_EN +{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits +//----------------------------------------------------------------------------------- +{pmic_vpgm, 0, 0}, // Turn off 8V SWBST +{pmic_delay, 0, 500}, // Adds delay to allow VPGM to bleed off +{pmic_i2c, 0xD0, 0x00}, // Clear +{pmic_i2c, 0xD1, 0x00}, // Clear +{pmic_pwr, 0, 0}, // PWRON LOW to reload new OTP data +{pmic_delay, 0, 500}, +{pmic_pwr, 0, 1}, +#endif +}; diff --git a/roms/u-boot/board/toradex/colibri_imx7/Kconfig b/roms/u-boot/board/toradex/colibri_imx7/Kconfig new file mode 100644 index 000000000..d33ec6352 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx7/Kconfig @@ -0,0 +1,76 @@ +if TARGET_COLIBRI_IMX7 + +choice + prompt "Colibri iMX7S/D variant" + +config TARGET_COLIBRI_IMX7_NAND + bool "Support Colibri iMX7 Solo 256MB/Dual 512MB (raw NAND) modules" + imply NAND_MXS + help + Choose this option if you build for a Toradex Colibri iMX7S + 256MB or Colibri iMX7D 512MB module which do have raw NAND + on-module. + +config TARGET_COLIBRI_IMX7_EMMC + bool "Support Colibri iMX7 Dual 1GB (eMMC) modules" + help + Choose this option if you build for a Toradex Colibri iMX7D + 1GB module which does have eMMC on-module. + +endchoice + +config SYS_BOARD + default "colibri_imx7" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "colibri_imx7" + +config COLIBRI_IMX7_EXT_PHYCLK + bool "External oscillator for Ethernet PHY clock provided" + help + Select this if your module provides a external Ethernet PHY + clock source. + default y + +config TDX_CFG_BLOCK + default y + +config TDX_CFG_BLOCK_2ND_ETHADDR + default y + +if TARGET_COLIBRI_IMX7_NAND + +config TDX_HAVE_NAND + default y + +config TDX_CFG_BLOCK_OFFSET + default "2048" + +config TDX_CFG_BLOCK_OFFSET2 + default "133120" + +endif + +if TARGET_COLIBRI_IMX7_EMMC + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +endif + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/colibri_imx7/MAINTAINERS b/roms/u-boot/board/toradex/colibri_imx7/MAINTAINERS new file mode 100644 index 000000000..3d7d010d8 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx7/MAINTAINERS @@ -0,0 +1,14 @@ +Colibri iMX7 +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +W: http://developer.toradex.com/software/linux/linux-software +W: https://www.toradex.com/community +S: Maintained +F: board/toradex/colibri_imx7/ +F: doc/board/toradex/colibri_imx7.rst +F: include/configs/colibri_imx7.h +F: configs/colibri_imx7_defconfig +F: configs/colibri_imx7_emmc_defconfig +F: arch/arm/dts/imx7-colibri.dtsi +F: arch/arm/dts/imx7-colibri-u-boot.dtsi +F: arch/arm/dts/imx7-colibri-emmc.dts +F: arch/arm/dts/imx7-colibri-rawnand.dts diff --git a/roms/u-boot/board/toradex/colibri_imx7/Makefile b/roms/u-boot/board/toradex/colibri_imx7/Makefile new file mode 100644 index 000000000..b212ff0f2 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx7/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2016 Toradex AG + +obj-y := colibri_imx7.o diff --git a/roms/u-boot/board/toradex/colibri_imx7/colibri_imx7.c b/roms/u-boot/board/toradex/colibri_imx7/colibri_imx7.c new file mode 100644 index 000000000..301b07d5b --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx7/colibri_imx7.c @@ -0,0 +1,366 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016-2018 Toradex AG + */ + +#include <common.h> +#include <cpu_func.h> +#include <init.h> +#include <net.h> +#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 <asm/global_data.h> +#include <asm/gpio.h> +#include <asm/mach-imx/iomux-v3.h> +#include <asm/io.h> +#include <common.h> +#include <dm.h> +#include <dm/platform_data/serial_mxc.h> +#include <fdt_support.h> +#include <fsl_esdhc_imx.h> +#include <jffs2/load_kernel.h> +#include <linux/delay.h> +#include <linux/sizes.h> +#include <mmc.h> +#include <miiphy.h> +#include <mtd_node.h> +#include <netdev.h> +#include <power/pmic.h> +#include <power/rn5t567_pmic.h> +#include <usb.h> +#include <usb/ehci-ci.h> +#include "../common/tdx-common.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | \ + PAD_CTL_PUS_PU100KOHM | PAD_CTL_HYS) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM) +#define ENET_PAD_CTRL_MII (PAD_CTL_DSE_3P3V_32OHM) + +#define ENET_RX_PAD_CTRL (PAD_CTL_PUS_PU100KOHM | PAD_CTL_DSE_3P3V_49OHM) + +#define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_PU100KOHM | \ + PAD_CTL_DSE_3P3V_49OHM) + +#define NAND_PAD_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define NAND_PAD_READY0_CTRL (PAD_CTL_DSE_3P3V_49OHM | PAD_CTL_PUS_PU5KOHM) + +#define USB_CDET_GPIO IMX_GPIO_NR(7, 14) + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)PHYS_SDRAM, imx_ddr_size()); + + return 0; +} + +static iomux_v3_cfg_t const uart1_pads[] = { + MX7D_PAD_UART1_RX_DATA__UART1_DTE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX7D_PAD_UART1_TX_DATA__UART1_DTE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX7D_PAD_SAI2_TX_BCLK__UART1_DTE_CTS | MUX_PAD_CTRL(UART_PAD_CTRL), + MX7D_PAD_SAI2_TX_SYNC__UART1_DTE_RTS | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +#ifdef CONFIG_USB_EHCI_MX7 +static iomux_v3_cfg_t const usb_cdet_pads[] = { + MX7D_PAD_ENET1_CRS__GPIO7_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; +#endif + +#ifdef CONFIG_TARGET_COLIBRI_IMX7_NAND +static iomux_v3_cfg_t const gpmi_pads[] = { + MX7D_PAD_SD3_DATA0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_DATA7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_CLK__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_CMD__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_STROBE__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SD3_RESET_B__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SAI1_RX_DATA__NAND_CE1_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SAI1_TX_BCLK__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL), + MX7D_PAD_SAI1_TX_DATA__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_READY0_CTRL), +}; + +static void setup_gpmi_nand(void) +{ + imx_iomux_v3_setup_multiple_pads(gpmi_pads, ARRAY_SIZE(gpmi_pads)); + + /* NAND_USDHC_BUS_CLK is set in rom */ + set_clk_nand(); +} +#endif + +#ifdef CONFIG_DM_VIDEO +static iomux_v3_cfg_t const backlight_pads[] = { + /* Backlight On */ + MX7D_PAD_SD1_WP__GPIO5_IO1 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* Backlight PWM<A> (multiplexed pin) */ + MX7D_PAD_GPIO1_IO08__GPIO1_IO8 | MUX_PAD_CTRL(NO_PAD_CTRL), + MX7D_PAD_ECSPI2_MOSI__GPIO4_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +#define GPIO_BL_ON IMX_GPIO_NR(5, 1) +#define GPIO_PWM_A IMX_GPIO_NR(1, 8) + +static int setup_lcd(void) +{ + imx_iomux_v3_setup_multiple_pads(backlight_pads, ARRAY_SIZE(backlight_pads)); + + /* Set BL_ON */ + gpio_request(GPIO_BL_ON, "BL_ON"); + gpio_direction_output(GPIO_BL_ON, 1); + + /* Set PWM<A> to full brightness (assuming inversed polarity) */ + gpio_request(GPIO_PWM_A, "PWM<A>"); + gpio_direction_output(GPIO_PWM_A, 0); + + return 0; +} +#endif + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ +#ifdef CONFIG_DM_VIDEO + gpio_direction_output(GPIO_PWM_A, 1); + gpio_direction_output(GPIO_BL_ON, 0); +#endif +} + +static void setup_iomux_uart(void) +{ + imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); +} + +#ifdef CONFIG_FEC_MXC +static int setup_fec(void) +{ + struct iomuxc_gpr_base_regs *const iomuxc_gpr_regs + = (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + +#ifndef CONFIG_COLIBRI_IMX7_EXT_PHYCLK + /* + * Use 50M anatop REF_CLK1 for ENET1, clear gpr1[13], set gpr1[17] + * and output it on the pin + */ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK, + IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK); +#else + /* Use 50M external CLK for ENET1, set gpr1[13], clear gpr1[17] */ + clrsetbits_le32(&iomuxc_gpr_regs->gpr[1], + IOMUXC_GPR_GPR1_GPR_ENET1_CLK_DIR_MASK, + IOMUXC_GPR_GPR1_GPR_ENET1_TX_CLK_SEL_MASK); +#endif + + return set_clk_enet(ENET_50MHZ); +} + +#endif + +int board_early_init_f(void) +{ + setup_iomux_uart(); + + return 0; +} + +int board_init(void) +{ + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + +#ifdef CONFIG_TARGET_COLIBRI_IMX7_NAND + setup_gpmi_nand(); +#endif + +#ifdef CONFIG_USB_EHCI_MX7 + imx_iomux_v3_setup_multiple_pads(usb_cdet_pads, ARRAY_SIZE(usb_cdet_pads)); + gpio_request(USB_CDET_GPIO, "usb-cdet-gpio"); +#endif + + return 0; +} + +#ifdef CONFIG_DM_PMIC +int power_init_board(void) +{ + struct udevice *dev; + int reg, ver; + int ret; + + + ret = pmic_get("rn5t567@33", &dev); + if (ret) + return ret; + ver = pmic_reg_read(dev, RN5T567_LSIVER); + reg = pmic_reg_read(dev, RN5T567_OTPVER); + + printf("PMIC: RN5T567 LSIVER=0x%02x OTPVER=0x%02x\n", ver, reg); + + /* set judge and press timer of N_OE to minimal values */ + pmic_clrsetbits(dev, RN5T567_NOETIMSETCNT, 0x7, 0); + + /* configure sleep slot for 3.3V Ethernet */ + reg = pmic_reg_read(dev, RN5T567_LDO1_SLOT); + reg = (reg & 0xf0) | reg >> 4; + pmic_reg_write(dev, RN5T567_LDO1_SLOT, reg); + + /* disable DCDC2 discharge to avoid backfeeding through VFB2 */ + pmic_clrsetbits(dev, RN5T567_DC2CTL, 0x2, 0); + + /* configure sleep slot for ARM rail */ + reg = pmic_reg_read(dev, RN5T567_DC2_SLOT); + reg = (reg & 0xf0) | reg >> 4; + pmic_reg_write(dev, RN5T567_DC2_SLOT, reg); + + /* disable LDO2 discharge to avoid backfeeding from +V3.3_SD */ + pmic_clrsetbits(dev, RN5T567_LDODIS1, 0x2, 0); + + return 0; +} + +void reset_cpu(void) +{ + struct udevice *dev; + + pmic_get("rn5t567@33", &dev); + + /* Use PMIC to reset, set REPWRTIM to 0 and REPWRON to 1 */ + pmic_reg_write(dev, RN5T567_REPCNT, 0x1); + pmic_reg_write(dev, RN5T567_SLPCNT, 0x1); + + /* + * Re-power factor detection on PMIC side is not instant. 1ms + * proved to be enough time until reset takes effect. + */ + mdelay(1); +} +#endif + +int checkboard(void) +{ + printf("Model: Toradex Colibri iMX7%c\n", + is_cpu_type(MXC_CPU_MX7D) ? 'D' : 'S'); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ +#if defined(CONFIG_IMX_BOOTAUX) && defined(CONFIG_ARCH_FIXUP_FDT_MEMORY) + int up; + + up = arch_auxiliary_core_check_up(0); + if (up) { + int ret; + int areas = 1; + u64 start[2], size[2]; + + /* + * Reserve 1MB of memory for M4 (1MiB is also the minimum + * alignment for Linux due to MMU section size restrictions). + */ + start[0] = gd->bd->bi_dram[0].start; + size[0] = SZ_256M - SZ_1M; + + /* If needed, create a second entry for memory beyond 256M */ + if (gd->bd->bi_dram[0].size > SZ_256M) { + start[1] = gd->bd->bi_dram[0].start + SZ_256M; + size[1] = gd->bd->bi_dram[0].size - SZ_256M; + areas = 2; + } + + ret = fdt_set_usable_memory(blob, start, size, areas); + if (ret) { + eprintf("Cannot set usable memory\n"); + return ret; + } + } else { + int off; + + off = fdt_node_offset_by_compatible(blob, -1, + "fsl,imx7d-rpmsg"); + if (off > 0) + fdt_status_disabled(blob, off); + } +#endif +#if defined(CONFIG_FDT_FIXUP_PARTITIONS) + static const struct node_info nodes[] = { + { "fsl,imx7d-gpmi-nand", MTD_DEV_TYPE_NAND, }, /* NAND flash */ + { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, }, + }; + + /* Update partition nodes using info from mtdparts env var */ + puts(" Updating MTD partitions...\n"); + fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); +#endif + + return ft_common_board_setup(blob, bd); +} +#endif + +#ifdef CONFIG_USB_EHCI_MX7 +static iomux_v3_cfg_t const usb_otg2_pads[] = { + MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +int board_ehci_hcd_init(int port) +{ + switch (port) { + case 0: + break; + case 1: + if (is_cpu_type(MXC_CPU_MX7S)) + return -ENODEV; + + imx_iomux_v3_setup_multiple_pads(usb_otg2_pads, + ARRAY_SIZE(usb_otg2_pads)); + break; + default: + return -EINVAL; + } + return 0; +} + +int board_usb_phy_mode(int port) +{ + switch (port) { + case 0: + if (gpio_get_value(USB_CDET_GPIO)) + return USB_INIT_DEVICE; + else + return USB_INIT_HOST; + case 1: + default: + return USB_INIT_HOST; + } +} + +int board_late_init(void) +{ +#if defined(CONFIG_DM_VIDEO) + setup_lcd(); +#endif + return 0; +} + +#endif diff --git a/roms/u-boot/board/toradex/colibri_imx7/imximage.cfg b/roms/u-boot/board/toradex/colibri_imx7/imximage.cfg new file mode 100644 index 000000000..bdce48b7f --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_imx7/imximage.cfg @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * 2015 Toradex AG + * + * Refer doc/imx/mkimage/imximage.txt for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +#define __ASSEMBLY__ +#include <config.h> + +/* image version */ + +IMAGE_VERSION 2 + +/* + * Boot Device : sd + */ + +BOOT_FROM sd + +/* + * Secure boot support + */ +#ifdef CONFIG_IMX_HAB +CSF CONFIG_CSF_SIZE +#endif + +/* + * 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 + +/* DDR3L */ +/* assuming MEMC_FREQ_RATIO = 2 */ +/* SRC_DDRC_RCR */ +DATA 4 0x30391000 0x00000002 +/* DDRC_MSTR */ +DATA 4 0x307a0000 0x01040001 +/* DDRC_DFIUPD0 */ +DATA 4 0x307a01a0 0x80400003 +/* DDRC_DFIUPD1 */ +DATA 4 0x307a01a4 0x00100020 +/* DDRC_DFIUPD2 */ +DATA 4 0x307a01a8 0x80100004 +/* DDRC_RFSHTMG */ +DATA 4 0x307a0064 0x00400046 +/* DDRC_MP_PCTRL_0 */ +DATA 4 0x307a0490 0x00000001 +/* DDRC_INIT0 */ +DATA 4 0x307a00d0 0x00020083 +/* DDRC_INIT1 */ +DATA 4 0x307a00d4 0x00690000 +/* DDRC_INIT3 MR0/MR1 */ +DATA 4 0x307a00dc 0x09300004 +/* DDRC_INIT4 MR2/MR3 */ +DATA 4 0x307a00e0 0x04480000 +/* DDRC_INIT5 */ +DATA 4 0x307a00e4 0x00100004 +/* DDRC_RANKCTL */ +DATA 4 0x307a00f4 0x0000033f +/* DDRC_DRAMTMG0 */ +DATA 4 0x307a0100 0x0910090a +/* DDRC_DRAMTMG1 */ +DATA 4 0x307a0104 0x000d020e +/* DDRC_DRAMTMG2 */ +DATA 4 0x307a0108 0x03040307 +/* DDRC_DRAMTMG3 */ +DATA 4 0x307a010c 0x00002006 +/* DDRC_DRAMTMG4 */ +DATA 4 0x307a0110 0x04020204 +/* DDRC_DRAMTMG5 */ +DATA 4 0x307a0114 0x03030202 +/* DDRC_DRAMTMG8 */ +DATA 4 0x307a0120 0x00000803 +/* DDRC_ZQCTL0 */ +DATA 4 0x307a0180 0x00800020 +/* DDRC_ZQCTL1 */ +DATA 4 0x307a0184 0x02001000 +/* DDRC_DFITMG0 */ +DATA 4 0x307a0190 0x02098204 +/* DDRC_DFITMG1 */ +DATA 4 0x307a0194 0x00030303 +/* DDRC_ADDRMAP0 */ +DATA 4 0x307a0200 0x0000001f +/* DDRC_ADDRMAP1 */ +DATA 4 0x307a0204 0x00080808 +/* DDRC_ADDRMAP5 */ +DATA 4 0x307a0214 0x07070707 +/* DDRC_ADDRMAP6 */ +DATA 4 0x307a0218 0x07070707 +/* DDRC_ODTCFG */ +DATA 4 0x307a0240 0x06000601 +/* DDRC_ODTMAP */ +DATA 4 0x307a0244 0x00000001 +/* SRC_DDRC_RCR */ +DATA 4 0x30391000 0x00000000 +/* DDR_PHY_PHY_CON0 */ +DATA 4 0x30790000 0x17420f40 +/* DDR_PHY_PHY_CON1 */ +DATA 4 0x30790004 0x10210100 +/* DDR_PHY_PHY_CON4 */ +DATA 4 0x30790010 0x00060807 +/* DDR_PHY_MDLL_CON0 */ +DATA 4 0x307900b0 0x1010007e +/* DDR_PHY_DRVDS_CON0 */ +DATA 4 0x3079009c 0x00000d6e +/* DDR_PHY_OFFSET_RD_CON0 */ +DATA 4 0x30790020 0x08080808 +/* DDR_PHY_OFFSET_WR_CON0 */ +DATA 4 0x30790030 0x08080808 +/* DDR_PHY_CMD_SDLL_CON0 */ +DATA 4 0x30790050 0x01000010 +DATA 4 0x30790050 0x00000010 + +/* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0e407304 +DATA 4 0x307900c0 0x0e447304 +DATA 4 0x307900c0 0x0e447306 +/* DDR_PHY_ZQ_CON1 */ +CHECK_BITS_SET 4 0x307900c4 0x1 +/* DDR_PHY_ZQ_CON0 */ +DATA 4 0x307900c0 0x0e447304 +DATA 4 0x307900c0 0x0e407304 + +/* 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/roms/u-boot/board/toradex/colibri_pxa270/Kconfig b/roms/u-boot/board/toradex/colibri_pxa270/Kconfig new file mode 100644 index 000000000..f646baa3f --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_pxa270/Kconfig @@ -0,0 +1,23 @@ +if TARGET_COLIBRI_PXA270 + +config SYS_BOARD + default "colibri_pxa270" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "colibri_pxa270" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_NOR + default y + +config TDX_CFG_BLOCK_OFFSET + default "262144" + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/colibri_pxa270/MAINTAINERS b/roms/u-boot/board/toradex/colibri_pxa270/MAINTAINERS new file mode 100644 index 000000000..b378d7be5 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_pxa270/MAINTAINERS @@ -0,0 +1,6 @@ +COLIBRI_PXA270 BOARD +M: Marek Vasut <marek.vasut@gmail.com> +S: Maintained +F: board/toradex/colibri_pxa270/ +F: include/configs/colibri_pxa270.h +F: configs/colibri_pxa270_defconfig diff --git a/roms/u-boot/board/toradex/colibri_pxa270/Makefile b/roms/u-boot/board/toradex/colibri_pxa270/Makefile new file mode 100644 index 000000000..ea610cfea --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_pxa270/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Toradex Colibri PXA270 Support +# +# Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> + +obj-y := colibri_pxa270.o diff --git a/roms/u-boot/board/toradex/colibri_pxa270/colibri_pxa270.c b/roms/u-boot/board/toradex/colibri_pxa270/colibri_pxa270.c new file mode 100644 index 000000000..25fbf4120 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_pxa270/colibri_pxa270.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Toradex Colibri PXA270 Support + * + * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2016-2019 Marcel Ziswiler <marcel.ziswiler@toradex.com> + */ + +#include <common.h> +#include <cpu_func.h> +#include <dm.h> +#include <init.h> +#include <net.h> +#include <asm/arch/hardware.h> +#include <asm/arch/pxa.h> +#include <asm/arch/regs-mmc.h> +#include <asm/arch/regs-uart.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <dm/platdata.h> +#include <dm/platform_data/pxa_mmc_gen.h> +#include <dm/platform_data/serial_pxa.h> +#include <netdev.h> +#include <serial.h> +#include <usb.h> +#include <asm/mach-types.h> +#include <linux/delay.h> +#include "../common/tdx-common.h" + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + /* We have RAM, disable cache */ + dcache_disable(); + icache_disable(); + + /* arch number of Toradex Colibri PXA270 */ + gd->bd->bi_arch_number = MACH_TYPE_COLIBRI; + + /* address of boot parameters */ + gd->bd->bi_boot_params = 0xa0000100; + + return 0; +} + +int checkboard(void) +{ + puts("Model: Toradex Colibri PXA270\n"); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +int dram_init(void) +{ + pxa2xx_dram_init(); + gd->ram_size = PHYS_SDRAM_1_SIZE; + return 0; +} + +#ifdef CONFIG_CMD_USB +int board_usb_init(int index, enum usb_init_type init) +{ + writel((readl(UHCHR) | UHCHR_PCPL | UHCHR_PSPL) & + ~(UHCHR_SSEP0 | UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE), + UHCHR); + + writel(readl(UHCHR) | UHCHR_FSBIR, UHCHR); + + while (UHCHR & UHCHR_FSBIR) + ; + + writel(readl(UHCHR) & ~UHCHR_SSE, UHCHR); + writel((UHCHIE_UPRIE | UHCHIE_RWIE), UHCHIE); + + /* Clear any OTG Pin Hold */ + if (readl(PSSR) & PSSR_OTGPH) + writel(readl(PSSR) | PSSR_OTGPH, PSSR); + + writel(readl(UHCRHDA) & ~(0x200), UHCRHDA); + writel(readl(UHCRHDA) | 0x100, UHCRHDA); + + /* Set port power control mask bits, only 3 ports. */ + writel(readl(UHCRHDB) | (0x7 << 17), UHCRHDB); + + /* enable port 2 */ + writel(readl(UP2OCR) | UP2OCR_HXOE | UP2OCR_HXS | + UP2OCR_DMPDE | UP2OCR_DPPDE, UP2OCR); + + return 0; +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + return 0; +} + +void usb_board_stop(void) +{ + writel(readl(UHCHR) | UHCHR_FHR, UHCHR); + udelay(11); + writel(readl(UHCHR) & ~UHCHR_FHR, UHCHR); + + writel(readl(UHCCOMS) | 1, UHCCOMS); + udelay(10); + + writel(readl(CKEN) & ~CKEN10_USBHOST, CKEN); +} +#endif + +#ifdef CONFIG_DRIVER_DM9000 +int board_eth_init(struct bd_info *bis) +{ + return dm9000_initialize(bis); +} +#endif + +#ifdef CONFIG_CMD_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) +int board_mmc_init(struct bd_info *bis) +{ + pxa_mmc_register(0); + return 0; +} +#else /* !CONFIG_IS_ENABLED(DM_MMC) */ +static const struct pxa_mmc_plat mmc_plat = { + .base = (struct pxa_mmc_regs *)MMC0_BASE, +}; + +U_BOOT_DRVINFO(pxa_mmcs) = { + .name = "pxa_mmc", + .plat = &mmc_plat, +}; +#endif /* !CONFIG_IS_ENABLED(DM_MMC) */ +#endif + +static const struct pxa_serial_plat serial_plat = { + .base = (struct pxa_uart_regs *)FFUART_BASE, + .port = FFUART_INDEX, + .baudrate = CONFIG_BAUDRATE, +}; + +U_BOOT_DRVINFO(pxa_serials) = { + .name = "serial_pxa", + .plat = &serial_plat, +}; diff --git a/roms/u-boot/board/toradex/colibri_t20/Kconfig b/roms/u-boot/board/toradex/colibri_t20/Kconfig new file mode 100644 index 000000000..a43acddb8 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t20/Kconfig @@ -0,0 +1,23 @@ +if TARGET_COLIBRI_T20 + +config SYS_BOARD + default "colibri_t20" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "colibri_t20" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_NAND + default y + +config TDX_CFG_BLOCK_OFFSET + default "3145728" + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/colibri_t20/MAINTAINERS b/roms/u-boot/board/toradex/colibri_t20/MAINTAINERS new file mode 100644 index 000000000..61fbd2c1e --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t20/MAINTAINERS @@ -0,0 +1,7 @@ +COLIBRI_T20 +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +S: Maintained +F: board/toradex/colibri_t20/ +F: include/configs/colibri_t20.h +F: configs/colibri_t20_defconfig +F: arch/arm/dts/tegra20-colibri.dtb diff --git a/roms/u-boot/board/toradex/colibri_t20/Makefile b/roms/u-boot/board/toradex/colibri_t20/Makefile new file mode 100644 index 000000000..c5528b37b --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t20/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2012 Lucas Stach + +obj-y += colibri_t20.o diff --git a/roms/u-boot/board/toradex/colibri_t20/colibri_t20.c b/roms/u-boot/board/toradex/colibri_t20/colibri_t20.c new file mode 100644 index 000000000..73ef4d2db --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t20/colibri_t20.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2012 Lucas Stach + */ + +#include <common.h> +#include <init.h> +#include <log.h> +#include <asm/arch/clock.h> +#include <asm/arch/funcmux.h> +#include <asm/arch/pinmux.h> +#include <asm/arch-tegra/ap.h> +#include <asm/arch-tegra/board.h> +#include <asm/arch-tegra/tegra.h> +#include <asm/global_data.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <i2c.h> +#include <nand.h> +#include <linux/delay.h> +#include "../common/tdx-common.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define PMU_I2C_ADDRESS 0x34 +#define MAX_I2C_RETRY 3 +#define PMU_SUPPLYENE 0x14 +#define PMU_SUPPLYENE_SYSINEN (1<<5) +#define PMU_SUPPLYENE_EXITSLREQ (1<<1) + +int arch_misc_init(void) +{ + /* Disable PMIC sleep mode on low supply voltage */ + struct udevice *dev; + u8 addr, data[1]; + int err; + + err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); + if (err) { + debug("%s: Cannot find PMIC I2C chip\n", __func__); + return err; + } + + addr = PMU_SUPPLYENE; + + err = dm_i2c_read(dev, addr, data, 1); + if (err) { + debug("failed to get PMU_SUPPLYENE\n"); + return err; + } + + data[0] &= ~PMU_SUPPLYENE_SYSINEN; + data[0] |= PMU_SUPPLYENE_EXITSLREQ; + + err = dm_i2c_write(dev, addr, data, 1); + if (err) { + debug("failed to set PMU_SUPPLYENE\n"); + return err; + } + + /* make sure SODIMM pin 87 nRESET_OUT is released properly */ + pinmux_set_func(PMUX_PINGRP_ATA, PMUX_FUNC_GMI); + + if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) == + NVBOOTTYPE_RECOVERY) + printf("USB recovery mode\n"); + + return 0; +} + +int checkboard(void) +{ + printf("Model: Toradex Colibri T20 %dMB V%s\n", + (gd->ram_size == 0x10000000) ? 256 : 512, + (get_nand_dev_by_index(0)->erasesize >> 10 == 512) ? + ((gd->ram_size == 0x10000000) ? "1.1B" : "1.1C") : "1.2A"); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +#ifdef CONFIG_MMC_SDHCI_TEGRA +/* + * Routine: pin_mux_mmc + * Description: setup the pin muxes/tristate values for the SDMMC(s) + */ +void pin_mux_mmc(void) +{ + funcmux_select(PERIPH_ID_SDMMC4, FUNCMUX_SDMMC4_ATB_GMA_4_BIT); + pinmux_tristate_disable(PMUX_PINGRP_GMB); +} +#endif + +#ifdef CONFIG_TEGRA_NAND +void pin_mux_nand(void) +{ + funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_NDFLASH_KBC_8_BIT); + + /* + * configure pingroup ATC to something unrelated to + * avoid ATC overriding KBC + */ + pinmux_set_func(PMUX_PINGRP_ATC, PMUX_FUNC_GMI); +} +#endif + +#ifdef CONFIG_USB_EHCI_TEGRA +void pin_mux_usb(void) +{ + /* module internal USB bus to connect ethernet chipset */ + funcmux_select(PERIPH_ID_USB2, FUNCMUX_USB2_ULPI); + + /* ULPI reference clock output */ + pinmux_set_func(PMUX_PINGRP_CDEV2, PMUX_FUNC_PLLP_OUT4); + pinmux_tristate_disable(PMUX_PINGRP_CDEV2); + + /* PHY reset GPIO */ + pinmux_tristate_disable(PMUX_PINGRP_UAC); + + /* VBus GPIO */ + pinmux_tristate_disable(PMUX_PINGRP_DTE); + + /* Reset ASIX using LAN_RESET */ + gpio_request(TEGRA_GPIO(V, 4), "LAN_RESET"); + gpio_direction_output(TEGRA_GPIO(V, 4), 0); + pinmux_tristate_disable(PMUX_PINGRP_GPV); + udelay(5); + gpio_set_value(TEGRA_GPIO(V, 4), 1); + + /* USBH_PEN: USB 1 aka Tegra USB port 3 VBus */ + pinmux_tristate_disable(PMUX_PINGRP_SPIG); +} +#endif + +#ifdef CONFIG_VIDEO_TEGRA20 +/* + * Routine: pin_mux_display + * Description: setup the pin muxes/tristate values for the LCD interface) + */ +void pin_mux_display(void) +{ + /* + * Manually untristate BL_ON (PT4 - SODIMM 71) as specified through + * device-tree + */ + pinmux_tristate_disable(PMUX_PINGRP_DTA); + + pinmux_set_func(PMUX_PINGRP_SDC, PMUX_FUNC_PWM); + pinmux_tristate_disable(PMUX_PINGRP_SDC); +} + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(TEGRA_GPIO(T, 4), "BL_ON"); + gpio_direction_output(TEGRA_GPIO(T, 4), 0); +} +#endif diff --git a/roms/u-boot/board/toradex/colibri_t30/Kconfig b/roms/u-boot/board/toradex/colibri_t30/Kconfig new file mode 100644 index 000000000..68ef82b09 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t30/Kconfig @@ -0,0 +1,30 @@ +if TARGET_COLIBRI_T30 + +config SYS_BOARD + default "colibri_t30" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "colibri_t30" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/colibri_t30/MAINTAINERS b/roms/u-boot/board/toradex/colibri_t30/MAINTAINERS new file mode 100644 index 000000000..ded9e2829 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t30/MAINTAINERS @@ -0,0 +1,7 @@ +Colibri T30 +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +S: Maintained +F: board/toradex/colibri_t30/ +F: include/configs/colibri_t30.h +F: configs/colibri_t30_defconfig +F: arch/arm/dts/tegra30-colibri.dtb diff --git a/roms/u-boot/board/toradex/colibri_t30/Makefile b/roms/u-boot/board/toradex/colibri_t30/Makefile new file mode 100644 index 000000000..4242902da --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t30/Makefile @@ -0,0 +1,4 @@ +# Copyright (c) 2013-2014 Stefan Agner +# SPDX-License-Identifier: GPL-2.0+ + +obj-y += colibri_t30.o diff --git a/roms/u-boot/board/toradex/colibri_t30/colibri_t30.c b/roms/u-boot/board/toradex/colibri_t30/colibri_t30.c new file mode 100644 index 000000000..20cbb75a3 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t30/colibri_t30.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2014-2016 + * Stefan Agner <stefan@agner.ch> + */ + +#include <common.h> +#include <init.h> +#include <asm/arch/gp_padctrl.h> +#include <asm/arch/pinmux.h> +#include <asm/arch-tegra/ap.h> +#include <asm/arch-tegra/tegra.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <i2c.h> +#include <linux/delay.h> +#include "pinmux-config-colibri_t30.h" +#include "../common/tdx-common.h" + +int arch_misc_init(void) +{ + if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) == + NVBOOTTYPE_RECOVERY) + printf("USB recovery mode\n"); + + return 0; +} + +int checkboard(void) +{ + puts("Model: Toradex Colibri T30 1GB\n"); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return ft_common_board_setup(blob, bd); +} +#endif + +/* + * Routine: pinmux_init + * Description: Do individual peripheral pinmux configs + */ +void pinmux_init(void) +{ + pinmux_config_pingrp_table(tegra3_pinmux_common, + ARRAY_SIZE(tegra3_pinmux_common)); + + pinmux_config_pingrp_table(unused_pins_lowpower, + ARRAY_SIZE(unused_pins_lowpower)); + + /* Initialize any non-default pad configs (APB_MISC_GP regs) */ + pinmux_config_drvgrp_table(colibri_t30_padctrl, + ARRAY_SIZE(colibri_t30_padctrl)); +} + +/* + * Disable RS232 serial transceiver ForceOFF# pins on Iris + */ +void gpio_early_init_uart(void) +{ + gpio_request(TEGRA_GPIO(X, 6), "Force OFF# X13"); + gpio_direction_output(TEGRA_GPIO(X, 6), 1); + gpio_request(TEGRA_GPIO(X, 7), "Force OFF# X14"); + gpio_direction_output(TEGRA_GPIO(X, 7), 1); +} + +/* + * Enable AX88772B USB to LAN controller + */ +void pin_mux_usb(void) +{ + /* Reset ASIX using LAN_RESET */ + gpio_request(TEGRA_GPIO(DD, 0), "LAN_RESET"); + gpio_direction_output(TEGRA_GPIO(DD, 0), 0); + udelay(5); + gpio_set_value(TEGRA_GPIO(DD, 0), 1); +} + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(TEGRA_GPIO(V, 2), "BL_ON"); + gpio_direction_output(TEGRA_GPIO(V, 2), 0); +} diff --git a/roms/u-boot/board/toradex/colibri_t30/pinmux-config-colibri_t30.h b/roms/u-boot/board/toradex/colibri_t30/pinmux-config-colibri_t30.h new file mode 100644 index 000000000..5ac1a6da9 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_t30/pinmux-config-colibri_t30.h @@ -0,0 +1,353 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2013-2014, Stefan Agner + */ + +#ifndef _PINMUX_CONFIG_COLIBRI_T30_H_ +#define _PINMUX_CONFIG_COLIBRI_T30_H_ + +#define DEFAULT_PINMUX(_pingrp, _mux, _pull, _tri, _io) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ +/* TRISTATE here means output driver is tri-stated */ \ + .tristate = PMUX_TRI_##_tri, \ +/* INPUT here means input driver is enabled vs. OUTPUT where it is disabled */ \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_DEFAULT, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define I2C_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _od) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_##_od, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define LV_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _ioreset) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_##_ioreset \ + } + +#define DEFAULT_PADCFG(_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) \ + { \ + .drvgrp = PMUX_DRVGRP_##_drvgrp, \ + .slwf = _slwf, \ + .slwr = _slwr, \ + .drvup = _drvup, \ + .drvdn = _drvdn, \ + .lpmd = PMUX_LPMD_##_lpmd, \ + .schmt = PMUX_SCHMT_##_schmt, \ + .hsm = PMUX_HSM_##_hsm, \ + } + +static struct pmux_pingrp_config tegra3_pinmux_common[] = { + /* SDMMC1 disabled */ + DEFAULT_PINMUX(SDMMC1_CLK_PZ0, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_CMD_PZ1, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT3_PY4, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT2_PY5, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT1_PY6, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT0_PY7, RSVD1, NORMAL, NORMAL, INPUT), + + /* SDMMC3 pinmux */ + DEFAULT_PINMUX(SDMMC3_CLK_PA6, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_CMD_PA7, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT0_PB7, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT1_PB6, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT2_PB5, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT3_PB4, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT6_PD3, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT7_PD4, RSVD1, NORMAL, NORMAL, INPUT), + + /* SDMMC4 pinmux (eMMC) */ + LV_PINMUX(SDMMC4_CLK_PCC4, SDMMC4, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_CMD_PT7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT0_PAA0, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT1_PAA1, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT2_PAA2, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT3_PAA3, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT4_PAA4, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT5_PAA5, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT6_PAA6, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT7_PAA7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_RST_N_PCC3, RSVD1, DOWN, NORMAL, INPUT, DISABLE, DISABLE), + + /* I2C1 pinmux */ + I2C_PINMUX(GEN1_I2C_SCL_PC4, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(GEN1_I2C_SDA_PC5, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C2 pinmux */ + DEFAULT_PINMUX(GEN2_I2C_SCL_PT5, I2C2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GEN2_I2C_SDA_PT6, I2C2, NORMAL, NORMAL, INPUT), + + /* I2C3 pinmux, muliplexed with KB_ROW13/KB_ROW14 */ + I2C_PINMUX(CAM_I2C_SCL_PBB1, I2C3, NORMAL, TRISTATE, INPUT, DISABLE, ENABLE), + I2C_PINMUX(CAM_I2C_SDA_PBB2, I2C3, NORMAL, TRISTATE, INPUT, DISABLE, ENABLE), + + /* I2C4 pinmux */ + I2C_PINMUX(DDC_SCL_PV4, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(DDC_SDA_PV5, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* Power I2C pinmux */ + I2C_PINMUX(PWR_I2C_SCL_PZ6, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(PWR_I2C_SDA_PZ7, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + DEFAULT_PINMUX(ULPI_DATA0_PO1, UARTA, NORMAL, NORMAL, OUTPUT), + /* UARTA RX, make sure we don't get input form a floating Pin */ + DEFAULT_PINMUX(ULPI_DATA1_PO2, UARTA, UP, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA2_PO3, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA3_PO4, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA4_PO5, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA5_PO6, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA6_PO7, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA7_PO0, UARTA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(ULPI_CLK_PY0, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DIR_PY1, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_NXT_PY2, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_STP_PY3, SPI1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_FS_PP0, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_DIN_PP1, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_DOUT_PP2, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_SCLK_PP3, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PV2, OWR, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PV3, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CLK2_OUT_PW5, EXTPERIPH2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK2_REQ_PCC5, DAP, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR1_PC1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR2_PC6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SDIN_PZ2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SDOUT_PN5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_WR_N_PZ3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_CS0_N_PN4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DC0_PN6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SCK_PZ4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR0_PB2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PCLK_PB3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DE_PJ1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_HSYNC_PJ3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_VSYNC_PJ4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D0_PE0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D1_PE1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D2_PE2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D3_PE3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D4_PE4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D5_PE5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D6_PE6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D7_PE7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D8_PF0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D9_PF1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D10_PF2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D11_PF3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D12_PF4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D13_PF5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D14_PF6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D15_PF7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D16_PM0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D17_PM1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D18_PM2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D19_PM3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D20_PM4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D21_PM5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D22_PM6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D23_PM7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_CS1_N_PW0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_M1_PW1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DC1_PD2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CRT_HSYNC_PV6, CRT, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CRT_VSYNC_PV7, CRT, NORMAL, NORMAL, OUTPUT), + LV_PINMUX(VI_D0_PT4, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D1_PD5, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D2_PL0, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D3_PL1, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D4_PL2, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D5_PL3, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D7_PL5, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D10_PT2, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_MCLK_PT1, VI, UP, NORMAL, INPUT, DISABLE, DISABLE), + /* UARTC RX, make sure we don't get input form a floating Pin */ + DEFAULT_PINMUX(UART2_RXD_PC3, UARTB, UP, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_TXD_PC2, UARTB, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_RTS_N_PJ6, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_CTS_N_PJ5, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_TXD_PW6, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_RXD_PW7, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_CTS_N_PA1, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_RTS_N_PC0, GMI, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(PU0, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PU1, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU2, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PU3, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PU4, PWM1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU5, PWM2, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU6, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_FS_PP4, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_DIN_PP5, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_DOUT_PP6, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_SCLK_PP7, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK3_OUT_PEE0, EXTPERIPH3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CLK3_REQ_PEE1, DEV3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_WP_N_PC7, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_CS2_N_PK3, RSVD1, UP, NORMAL, INPUT), /* EN_VDD_BL1 */ + DEFAULT_PINMUX(GMI_AD8_PH0, PWM0, NORMAL, NORMAL, OUTPUT), /* LCD1_BL_PWM */ + DEFAULT_PINMUX(GMI_AD10_PH2, NAND, NORMAL, NORMAL, OUTPUT), /* LCD1_BL_EN */ + DEFAULT_PINMUX(GMI_A16_PJ7, UARTD, NORMAL, NORMAL, INPUT), + /* UARTB RX, make sure we don't get input form a floating Pin */ + DEFAULT_PINMUX(GMI_A17_PB0, UARTD, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A18_PB1, UARTD, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A19_PK7, UARTD, NORMAL, NORMAL, INPUT), + + /* Multiplexed with KB_ROW10/KB_ROW11/KB_ROW12/KB_ROW15 */ + DEFAULT_PINMUX(CAM_MCLK_PCC0, VI_ALT2, UP, TRISTATE, INPUT), + DEFAULT_PINMUX(PCC1, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PBB0, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PBB3, VGP3, NORMAL, TRISTATE, INPUT), + + DEFAULT_PINMUX(PBB5, VGP5, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB6, VGP6, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB7, I2S4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PCC2, I2S4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(JTAG_RTCK_PU7, RTCK, NORMAL, NORMAL, OUTPUT), + + /* KBC keys */ + DEFAULT_PINMUX(KB_ROW0_PR0, RSVD2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW1_PR1, RSVD2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW2_PR2, RSVD2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW3_PR3, RSVD2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW4_PR4, RSVD3, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW5_PR5, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW6_PR6, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW7_PR7, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW8_PS0, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW9_PS1, KBC, NORMAL, TRISTATE, INPUT), + + /* SDMMC2 pinmux */ + DEFAULT_PINMUX(KB_ROW10_PS2, SDMMC2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW11_PS3, SDMMC2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW12_PS4, SDMMC2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW13_PS5, SDMMC2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW14_PS6, SDMMC2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW15_PS7, SDMMC2, UP, NORMAL, INPUT), + + DEFAULT_PINMUX(KB_COL0_PQ0, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL1_PQ1, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL2_PQ2, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL3_PQ3, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL4_PQ4, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL5_PQ5, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL6_PQ6, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL7_PQ7, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(PV0, RSVD1, UP, NORMAL, INPUT), + + DEFAULT_PINMUX(CLK_32K_OUT_PA0, BLINK, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(SYS_CLK_REQ_PZ5, SYSCLK, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_FS_PN0, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_DIN_PN1, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_DOUT_PN2, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_SCLK_PN3, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK1_REQ_PEE2, DAP, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK1_OUT_PW4, EXTPERIPH1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPDIF_IN_PK6, SPDIF, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPDIF_OUT_PK5, SPDIF, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(DAP2_FS_PA2, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DIN_PA4, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DOUT_PA5, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_SCLK_PA3, I2S1, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(SPI2_CS1_N_PW2, SPI2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_MOSI_PX4, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_SCK_PX5, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_CS0_N_PX6, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_MISO_PX7, RSVD4, NORMAL, NORMAL, INPUT), + + /* LAN_RESET */ + DEFAULT_PINMUX(PEX_L0_PRSNT_N_PDD0, RSVD2, NORMAL, NORMAL, OUTPUT), + + DEFAULT_PINMUX(PEX_L0_RST_N_PDD1, PCIE, NORMAL, NORMAL, OUTPUT), + + /* LAN_VBUS */ + DEFAULT_PINMUX(PEX_L0_CLKREQ_N_PDD2, RSVD2, NORMAL, NORMAL, OUTPUT), + + DEFAULT_PINMUX(PEX_WAKE_N_PDD3, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L1_PRSNT_N_PDD4, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L1_RST_N_PDD5, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L1_CLKREQ_N_PDD6, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L2_PRSNT_N_PDD7, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L2_RST_N_PCC6, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L2_CLKREQ_N_PCC7, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(HDMI_CEC_PEE3, CEC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(HDMI_INT_PN7, RSVD1, NORMAL, TRISTATE, INPUT), + + /* GPIOs */ + /* SDMMC1 CD gpio */ + DEFAULT_PINMUX(GMI_IORDY_PI5, RSVD1, UP, NORMAL, INPUT), + /* SDMMC1 WP gpio */ + LV_PINMUX(VI_D11_PT3, RSVD1, UP, NORMAL, INPUT, DISABLE, DISABLE), + + /* Touch panel GPIO */ + /* Touch IRQ */ + DEFAULT_PINMUX(GMI_AD12_PH4, NAND, UP, NORMAL, INPUT), + + /* Touch RESET */ + DEFAULT_PINMUX(GMI_AD14_PH6, NAND, NORMAL, NORMAL, OUTPUT), + + /* Power rails GPIO */ + DEFAULT_PINMUX(SPI2_SCK_PX2, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB4, VGP4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW8_PS0, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT5_PD0, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT4_PD1, SDMMC3, UP, NORMAL, INPUT), + + LV_PINMUX(VI_D6_PL4, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D8_PL6, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D9_PL7, VI, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_PCLK_PT0, RSVD1, UP, TRISTATE, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_HSYNC_PD7, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_VSYNC_PD6, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), +}; + +static struct pmux_pingrp_config unused_pins_lowpower[] = { + DEFAULT_PINMUX(GMI_WAIT_PI7, NAND, UP, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_ADV_N_PK0, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CLK_PK1, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CS3_N_PK4, NAND, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_CS7_N_PI6, NAND, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD0_PG0, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD1_PG1, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD2_PG2, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD3_PG3, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD4_PG4, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD5_PG5, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD6_PG6, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD7_PG7, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD9_PH1, PWM1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD11_PH3, NAND, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD13_PH5, NAND, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_WR_N_PI0, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_OE_N_PI1, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_DQS_PI2, NAND, NORMAL, TRISTATE, OUTPUT), +}; + +static struct pmux_drvgrp_config colibri_t30_padctrl[] = { + /* (_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */ + DEFAULT_PADCFG(SDIO1, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \ + SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, DISABLE, DISABLE), +}; +#endif /* _PINMUX_CONFIG_COLIBRI_T30_H_ */ diff --git a/roms/u-boot/board/toradex/colibri_vf/Kconfig b/roms/u-boot/board/toradex/colibri_vf/Kconfig new file mode 100644 index 000000000..5f7129dd3 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_vf/Kconfig @@ -0,0 +1,26 @@ +if TARGET_COLIBRI_VF + +config SYS_BOARD + default "colibri_vf" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "colibri_vf" + +config TDX_CFG_BLOCK + default y + +config TDX_HAVE_NAND + default y + +config TDX_CFG_BLOCK_OFFSET + default "2048" + +config TDX_CFG_BLOCK_2ND_ETHADDR + default y + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/colibri_vf/MAINTAINERS b/roms/u-boot/board/toradex/colibri_vf/MAINTAINERS new file mode 100644 index 000000000..c6627654a --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_vf/MAINTAINERS @@ -0,0 +1,12 @@ +Colibri VFxx +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +W: http://developer.toradex.com/software/linux/linux-software +W: https://www.toradex.com/community +S: Maintained +F: board/toradex/colibri_vf/ +F: include/configs/colibri_vf.h +F: configs/colibri_vf_defconfig +F: arch/arm/dts/vf-colibri.dtsi +F: arch/arm/dts/vf-colibri-u-boot.dtsi +F: arch/arm/dts/vf500-colibri.dts +F: arch/arm/dts/vf610-colibri.dts diff --git a/roms/u-boot/board/toradex/colibri_vf/Makefile b/roms/u-boot/board/toradex/colibri_vf/Makefile new file mode 100644 index 000000000..6272a7749 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_vf/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2013 Freescale Semiconductor, Inc. + +obj-y := colibri_vf.o +obj-$(CONFIG_VIDEO_FSL_DCU_FB) += dcu.o diff --git a/roms/u-boot/board/toradex/colibri_vf/colibri_vf.c b/roms/u-boot/board/toradex/colibri_vf/colibri_vf.c new file mode 100644 index 000000000..e9c5bc063 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_vf/colibri_vf.c @@ -0,0 +1,465 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2015-2019 Toradex, Inc. + * + * Based on vf610twr.c: + * Copyright 2013 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <init.h> +#include <asm/global_data.h> + +#include <asm/arch/clock.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/ddrmc-vf610.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux-vf610.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <env.h> +#include <fdt_support.h> +#include <fsl_dcu_fb.h> +#include <g_dnl.h> +#include <jffs2/load_kernel.h> +#include <mtd_node.h> +#include <usb.h> + +#include "../common/tdx-common.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define PTC0_GPIO_45 45 + +static struct ddrmc_cr_setting colibri_vf_cr_settings[] = { + { DDRMC_CR79_CTLUPD_AREF(1), 79 }, + /* sets manual values for read lvl. (gate) delay of data slice 0/1 */ + { DDRMC_CR105_RDLVL_DL_0(28), 105 }, + { DDRMC_CR106_RDLVL_GTDL_0(24), 106 }, + { DDRMC_CR110_RDLVL_DL_1(28) | DDRMC_CR110_RDLVL_GTDL_1(24), 110 }, + { DDRMC_CR102_RDLVL_GT_REGEN | DDRMC_CR102_RDLVL_REG_EN, 102 }, + + /* AXI */ + { DDRMC_CR117_AXI0_W_PRI(0) | DDRMC_CR117_AXI0_R_PRI(0), 117 }, + { DDRMC_CR118_AXI1_W_PRI(1) | DDRMC_CR118_AXI1_R_PRI(1), 118 }, + { DDRMC_CR120_AXI0_PRI1_RPRI(2) | + DDRMC_CR120_AXI0_PRI0_RPRI(2), 120 }, + { DDRMC_CR121_AXI0_PRI3_RPRI(2) | + DDRMC_CR121_AXI0_PRI2_RPRI(2), 121 }, + { DDRMC_CR122_AXI1_PRI1_RPRI(1) | DDRMC_CR122_AXI1_PRI0_RPRI(1) | + DDRMC_CR122_AXI0_PRIRLX(100), 122 }, + { DDRMC_CR123_AXI1_P_ODR_EN | DDRMC_CR123_AXI1_PRI3_RPRI(1) | + DDRMC_CR123_AXI1_PRI2_RPRI(1), 123 }, + { DDRMC_CR124_AXI1_PRIRLX(100), 124 }, + { DDRMC_CR126_PHY_RDLAT(8), 126 }, + { DDRMC_CR132_WRLAT_ADJ(5) | + DDRMC_CR132_RDLAT_ADJ(6), 132 }, + { DDRMC_CR137_PHYCTL_DL(2), 137 }, + { DDRMC_CR138_PHY_WRLV_MXDL(256) | + DDRMC_CR138_PHYDRAM_CK_EN(1), 138 }, + { DDRMC_CR139_PHY_WRLV_RESPLAT(4) | DDRMC_CR139_PHY_WRLV_LOAD(7) | + DDRMC_CR139_PHY_WRLV_DLL(3) | + DDRMC_CR139_PHY_WRLV_EN(3), 139 }, + { DDRMC_CR140_PHY_WRLV_WW(64), 140 }, + { DDRMC_CR143_RDLV_GAT_MXDL(1536) | + DDRMC_CR143_RDLV_MXDL(128), 143 }, + { DDRMC_CR144_PHY_RDLVL_RES(4) | DDRMC_CR144_PHY_RDLV_LOAD(7) | + DDRMC_CR144_PHY_RDLV_DLL(3) | + DDRMC_CR144_PHY_RDLV_EN(3), 144 }, + { DDRMC_CR145_PHY_RDLV_RR(64), 145 }, + { DDRMC_CR146_PHY_RDLVL_RESP(64), 146 }, + { DDRMC_CR147_RDLV_RESP_MASK(983040), 147 }, + { DDRMC_CR148_RDLV_GATE_RESP_MASK(983040), 148 }, + { DDRMC_CR151_RDLV_GAT_DQ_ZERO_CNT(1) | + DDRMC_CR151_RDLVL_DQ_ZERO_CNT(1), 151 }, + + { DDRMC_CR154_PAD_ZQ_EARLY_CMP_EN_TIMER(13) | + DDRMC_CR154_PAD_ZQ_MODE(1) | + DDRMC_CR154_DDR_SEL_PAD_CONTR(3) | + DDRMC_CR154_PAD_ZQ_HW_FOR(1), 154 }, + { DDRMC_CR155_PAD_ODT_BYTE1(2) | DDRMC_CR155_PAD_ODT_BYTE0(2), 155 }, + { DDRMC_CR158_TWR(6), 158 }, + { DDRMC_CR161_ODT_EN(1) | DDRMC_CR161_TODTH_RD(2) | + DDRMC_CR161_TODTH_WR(2), 161 }, + /* end marker */ + { 0, -1 } +}; + +int dram_init(void) +{ + static const struct ddr3_jedec_timings timings = { + .tinit = 5, + .trst_pwron = 80000, + .cke_inactive = 200000, + .wrlat = 5, + .caslat_lin = 12, + .trc = 21, + .trrd = 4, + .tccd = 4, + .tbst_int_interval = 0, + .tfaw = 20, + .trp = 6, + .twtr = 4, + .tras_min = 15, + .tmrd = 4, + .trtp = 4, + .tras_max = 28080, + .tmod = 12, + .tckesr = 4, + .tcke = 3, + .trcd_int = 6, + .tras_lockout = 0, + .tdal = 12, + .bstlen = 3, + .tdll = 512, /* not applicable since freq. scaling + * is not used + */ + .trp_ab = 6, + .tref = 3120, + .trfc = 64, + .tref_int = 0, + .tpdex = 3, + .txpdll = 10, + .txsnr = 68, /* changed to conform to JEDEC + * specifications + */ + .txsr = 506, /* changed to conform to JEDEC + * specifications + */ + .cksrx = 5, + .cksre = 5, + .freq_chg_en = 0, + .zqcl = 256, + .zqinit = 512, + .zqcs = 64, + .ref_per_zq = 64, + .zqcs_rotate = 0, + .aprebit = 10, + .cmd_age_cnt = 64, + .age_cnt = 64, + .q_fullness = 7, + .odt_rd_mapcs0 = 0, + .odt_wr_mapcs0 = 1, + .wlmrd = 40, + .wldqsen = 25, + }; + + ddrmc_ctrl_init_ddr3(&timings, colibri_vf_cr_settings, NULL, 1, 2); + gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + + return 0; +} + +#ifdef CONFIG_VYBRID_GPIO +static void setup_iomux_gpio(void) +{ + static const iomux_v3_cfg_t gpio_pads[] = { + VF610_PAD_PTA17__GPIO_7, + VF610_PAD_PTA20__GPIO_10, + VF610_PAD_PTA21__GPIO_11, + VF610_PAD_PTA30__GPIO_20, + VF610_PAD_PTA31__GPIO_21, + VF610_PAD_PTB0__GPIO_22, + VF610_PAD_PTB1__GPIO_23, + VF610_PAD_PTB6__GPIO_28, + VF610_PAD_PTB7__GPIO_29, + VF610_PAD_PTB8__GPIO_30, + VF610_PAD_PTB9__GPIO_31, + VF610_PAD_PTB12__GPIO_34, + VF610_PAD_PTB13__GPIO_35, + VF610_PAD_PTB16__GPIO_38, + VF610_PAD_PTB17__GPIO_39, + VF610_PAD_PTB18__GPIO_40, + VF610_PAD_PTB21__GPIO_43, + VF610_PAD_PTB22__GPIO_44, + VF610_PAD_PTC0__GPIO_45, + VF610_PAD_PTC1__GPIO_46, + VF610_PAD_PTC2__GPIO_47, + VF610_PAD_PTC3__GPIO_48, + VF610_PAD_PTC4__GPIO_49, + VF610_PAD_PTC5__GPIO_50, + VF610_PAD_PTC6__GPIO_51, + VF610_PAD_PTC7__GPIO_52, + VF610_PAD_PTC8__GPIO_53, + VF610_PAD_PTD31__GPIO_63, + VF610_PAD_PTD30__GPIO_64, + VF610_PAD_PTD29__GPIO_65, + VF610_PAD_PTD28__GPIO_66, + VF610_PAD_PTD27__GPIO_67, + VF610_PAD_PTD26__GPIO_68, + VF610_PAD_PTD25__GPIO_69, + VF610_PAD_PTD24__GPIO_70, + VF610_PAD_PTD9__GPIO_88, + VF610_PAD_PTD10__GPIO_89, + VF610_PAD_PTD11__GPIO_90, + VF610_PAD_PTD12__GPIO_91, + VF610_PAD_PTD13__GPIO_92, + VF610_PAD_PTB23__GPIO_93, + VF610_PAD_PTB26__GPIO_96, + VF610_PAD_PTB28__GPIO_98, + VF610_PAD_PTC30__GPIO_103, + VF610_PAD_PTA7__GPIO_134, + }; + + imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads)); +} +#endif + +#ifdef CONFIG_VIDEO_FSL_DCU_FB +static void setup_iomux_fsl_dcu(void) +{ + static const iomux_v3_cfg_t dcu0_pads[] = { + VF610_PAD_PTE0__DCU0_HSYNC, + VF610_PAD_PTE1__DCU0_VSYNC, + VF610_PAD_PTE2__DCU0_PCLK, + VF610_PAD_PTE4__DCU0_DE, + VF610_PAD_PTE5__DCU0_R0, + VF610_PAD_PTE6__DCU0_R1, + VF610_PAD_PTE7__DCU0_R2, + VF610_PAD_PTE8__DCU0_R3, + VF610_PAD_PTE9__DCU0_R4, + VF610_PAD_PTE10__DCU0_R5, + VF610_PAD_PTE11__DCU0_R6, + VF610_PAD_PTE12__DCU0_R7, + VF610_PAD_PTE13__DCU0_G0, + VF610_PAD_PTE14__DCU0_G1, + VF610_PAD_PTE15__DCU0_G2, + VF610_PAD_PTE16__DCU0_G3, + VF610_PAD_PTE17__DCU0_G4, + VF610_PAD_PTE18__DCU0_G5, + VF610_PAD_PTE19__DCU0_G6, + VF610_PAD_PTE20__DCU0_G7, + VF610_PAD_PTE21__DCU0_B0, + VF610_PAD_PTE22__DCU0_B1, + VF610_PAD_PTE23__DCU0_B2, + VF610_PAD_PTE24__DCU0_B3, + VF610_PAD_PTE25__DCU0_B4, + VF610_PAD_PTE26__DCU0_B5, + VF610_PAD_PTE27__DCU0_B6, + VF610_PAD_PTE28__DCU0_B7, + }; + + imx_iomux_v3_setup_multiple_pads(dcu0_pads, ARRAY_SIZE(dcu0_pads)); +} + +static void setup_tcon(void) +{ + setbits_le32(TCON0_BASE_ADDR, (1 << 29)); +} +#endif + +static inline int is_colibri_vf61(void) +{ + struct mscm *mscm = (struct mscm *)MSCM_BASE_ADDR; + + /* + * Detect board type by Level 2 Cache: VF50 don't have any + * Level 2 Cache. + */ + return !!mscm->cpxcfg1; +} + +static void clock_init(void) +{ + struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR; + struct anadig_reg *anadig = (struct anadig_reg *)ANADIG_BASE_ADDR; + u32 pfd_clk_sel, ddr_clk_sel; + + clrsetbits_le32(&ccm->ccgr0, CCM_REG_CTRL_MASK, + CCM_CCGR0_UART0_CTRL_MASK); +#ifdef CONFIG_FSL_DSPI + setbits_le32(&ccm->ccgr0, CCM_CCGR0_DSPI1_CTRL_MASK); +#endif + clrsetbits_le32(&ccm->ccgr1, CCM_REG_CTRL_MASK, + CCM_CCGR1_PIT_CTRL_MASK | CCM_CCGR1_WDOGA5_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr2, CCM_REG_CTRL_MASK, + CCM_CCGR2_IOMUXC_CTRL_MASK | CCM_CCGR2_PORTA_CTRL_MASK | + CCM_CCGR2_PORTB_CTRL_MASK | CCM_CCGR2_PORTC_CTRL_MASK | + CCM_CCGR2_PORTD_CTRL_MASK | CCM_CCGR2_PORTE_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr3, CCM_REG_CTRL_MASK, + CCM_CCGR3_ANADIG_CTRL_MASK | CCM_CCGR3_SCSC_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr4, CCM_REG_CTRL_MASK, + CCM_CCGR4_WKUP_CTRL_MASK | CCM_CCGR4_CCM_CTRL_MASK | + CCM_CCGR4_GPC_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr6, CCM_REG_CTRL_MASK, + CCM_CCGR6_OCOTP_CTRL_MASK | CCM_CCGR6_DDRMC_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr7, CCM_REG_CTRL_MASK, + CCM_CCGR7_SDHC1_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr9, CCM_REG_CTRL_MASK, + CCM_CCGR9_FEC0_CTRL_MASK | CCM_CCGR9_FEC1_CTRL_MASK); + clrsetbits_le32(&ccm->ccgr10, CCM_REG_CTRL_MASK, + CCM_CCGR10_NFC_CTRL_MASK); + +#ifdef CONFIG_USB_EHCI_VF + setbits_le32(&ccm->ccgr1, CCM_CCGR1_USBC0_CTRL_MASK); + setbits_le32(&ccm->ccgr7, CCM_CCGR7_USBC1_CTRL_MASK); + + clrsetbits_le32(&anadig->pll3_ctrl, ANADIG_PLL3_CTRL_BYPASS | + ANADIG_PLL3_CTRL_POWERDOWN | + ANADIG_PLL3_CTRL_DIV_SELECT, + ANADIG_PLL3_CTRL_ENABLE); + clrsetbits_le32(&anadig->pll7_ctrl, ANADIG_PLL7_CTRL_BYPASS | + ANADIG_PLL7_CTRL_POWERDOWN | + ANADIG_PLL7_CTRL_DIV_SELECT, + ANADIG_PLL7_CTRL_ENABLE); +#endif + + clrsetbits_le32(&anadig->pll5_ctrl, ANADIG_PLL5_CTRL_BYPASS | + ANADIG_PLL5_CTRL_POWERDOWN, ANADIG_PLL5_CTRL_ENABLE | + ANADIG_PLL5_CTRL_DIV_SELECT); + + if (is_colibri_vf61()) { + clrsetbits_le32(&anadig->pll2_ctrl, ANADIG_PLL5_CTRL_BYPASS | + ANADIG_PLL2_CTRL_POWERDOWN, + ANADIG_PLL2_CTRL_ENABLE | + ANADIG_PLL2_CTRL_DIV_SELECT); + } + + clrsetbits_le32(&anadig->pll1_ctrl, ANADIG_PLL1_CTRL_POWERDOWN, + ANADIG_PLL1_CTRL_ENABLE | ANADIG_PLL1_CTRL_DIV_SELECT); + + clrsetbits_le32(&ccm->ccr, CCM_CCR_OSCNT_MASK, + CCM_CCR_FIRC_EN | CCM_CCR_OSCNT(5)); + + /* See "Typical PLL Configuration" */ + if (is_colibri_vf61()) { + pfd_clk_sel = CCM_CCSR_PLL1_PFD_CLK_SEL(1); + ddr_clk_sel = CCM_CCSR_DDRC_CLK_SEL(0); + } else { + pfd_clk_sel = CCM_CCSR_PLL1_PFD_CLK_SEL(3); + ddr_clk_sel = CCM_CCSR_DDRC_CLK_SEL(1); + } + + clrsetbits_le32(&ccm->ccsr, CCM_REG_CTRL_MASK, pfd_clk_sel | + CCM_CCSR_PLL2_PFD4_EN | CCM_CCSR_PLL2_PFD3_EN | + CCM_CCSR_PLL2_PFD2_EN | CCM_CCSR_PLL2_PFD1_EN | + CCM_CCSR_PLL1_PFD4_EN | CCM_CCSR_PLL1_PFD3_EN | + CCM_CCSR_PLL1_PFD2_EN | CCM_CCSR_PLL1_PFD1_EN | + ddr_clk_sel | CCM_CCSR_FAST_CLK_SEL(1) | + CCM_CCSR_SYS_CLK_SEL(4)); + + clrsetbits_le32(&ccm->cacrr, CCM_REG_CTRL_MASK, + CCM_CACRR_IPG_CLK_DIV(1) | CCM_CACRR_BUS_CLK_DIV(2) | + CCM_CACRR_ARM_CLK_DIV(0)); + clrsetbits_le32(&ccm->cscmr1, CCM_REG_CTRL_MASK, + CCM_CSCMR1_ESDHC1_CLK_SEL(3) | + CCM_CSCMR1_NFC_CLK_SEL(0)); + clrsetbits_le32(&ccm->cscdr1, CCM_REG_CTRL_MASK, + CCM_CSCDR1_RMII_CLK_EN); + clrsetbits_le32(&ccm->cscdr2, CCM_REG_CTRL_MASK, + CCM_CSCDR2_ESDHC1_EN | CCM_CSCDR2_ESDHC1_CLK_DIV(0) | + CCM_CSCDR2_NFC_EN); + clrsetbits_le32(&ccm->cscdr3, CCM_REG_CTRL_MASK, + CCM_CSCDR3_NFC_PRE_DIV(3)); + clrsetbits_le32(&ccm->cscmr2, CCM_REG_CTRL_MASK, + CCM_CSCMR2_RMII_CLK_SEL(2)); + +#ifdef CONFIG_VIDEO_FSL_DCU_FB + setbits_le32(&ccm->ccgr1, CCM_CCGR1_TCON0_CTRL_MASK); + setbits_le32(&ccm->ccgr3, CCM_CCGR3_DCU0_CTRL_MASK); +#endif +} + +static void mscm_init(void) +{ + struct mscm_ir *mscmir = (struct mscm_ir *)MSCM_IR_BASE_ADDR; + int i; + + for (i = 0; i < MSCM_IRSPRC_NUM; i++) + writew(MSCM_IRSPRC_CP0_EN, &mscmir->irsprc[i]); +} + +int board_early_init_f(void) +{ + clock_init(); + mscm_init(); + +#ifdef CONFIG_VYBRID_GPIO + setup_iomux_gpio(); +#endif + +#ifdef CONFIG_VIDEO_FSL_DCU_FB + setup_tcon(); + setup_iomux_fsl_dcu(); +#endif + + return 0; +} + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ + struct src *src = (struct src *)SRC_BASE_ADDR; + + if (((src->sbmr2 & SRC_SBMR2_BMOD_MASK) >> SRC_SBMR2_BMOD_SHIFT) + == SRC_SBMR2_BMOD_SERIAL) { + printf("Serial Downloader recovery mode, disable autoboot\n"); + env_set("bootdelay", "-1"); + } + + return 0; +} +#endif /* CONFIG_BOARD_LATE_INIT */ + +int board_init(void) +{ + struct scsc_reg *scsc = (struct scsc_reg *)SCSC_BASE_ADDR; + + /* address of boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + + /* + * Enable external 32K Oscillator + * + * The internal clock experiences significant drift + * so we must use the external oscillator in order + * to maintain correct time in the hwclock + */ + setbits_le32(&scsc->sosc_ctr, SCSC_SOSC_CTR_SOSC_EN); + + return 0; +} + +int checkboard(void) +{ + if (is_colibri_vf61()) + puts("Model: Toradex Colibri VF61\n"); + else + puts("Model: Toradex Colibri VF50\n"); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ +#ifndef CONFIG_DM_VIDEO + int ret = 0; +#endif +#ifdef CONFIG_FDT_FIXUP_PARTITIONS + static const struct node_info nodes[] = { + { "fsl,vf610-nfc", MTD_DEV_TYPE_NAND, }, /* NAND flash */ + }; + + /* Update partition nodes using info from mtdparts env var */ + puts(" Updating MTD partitions...\n"); + fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); +#endif +#if defined(CONFIG_VIDEO_FSL_DCU_FB) && !defined(CONFIG_DM_VIDEO) + ret = fsl_dcu_fixedfb_setup(blob); + if (ret) + return ret; +#endif + + return ft_common_board_setup(blob, bd); +} +#endif + +/* + * Backlight off before OS handover + */ +void board_preboot_os(void) +{ + gpio_request(PTC0_GPIO_45, "BL_ON"); + gpio_direction_output(PTC0_GPIO_45, 0); +} diff --git a/roms/u-boot/board/toradex/colibri_vf/dcu.c b/roms/u-boot/board/toradex/colibri_vf/dcu.c new file mode 100644 index 000000000..c688ed79f --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_vf/dcu.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2017 Toradex AG + * + * FSL DCU platform driver + */ + +#include <asm/arch/crm_regs.h> +#include <asm/io.h> +#include <common.h> +#include <fsl_dcu_fb.h> +#include "div64.h" + +unsigned int dcu_set_pixel_clock(unsigned int pixclock) +{ + struct ccm_reg *ccm = (struct ccm_reg *)CCM_BASE_ADDR; + unsigned long long div; + + clrbits_le32(&ccm->cscmr1, CCM_CSCMR1_DCU0_CLK_SEL); + clrsetbits_le32(&ccm->cscdr3, + CCM_CSCDR3_DCU0_DIV_MASK | CCM_CSCDR3_DCU0_EN, + CCM_CSCDR3_DCU0_DIV(0) | CCM_CSCDR3_DCU0_EN); + div = (unsigned long long)(PLL1_PFD2_FREQ / 1000); + do_div(div, pixclock); + + return div; +} + +int platform_dcu_init(struct fb_info *fbinfo, + unsigned int xres, + unsigned int yres, + const char *port, + struct fb_videomode *dcu_fb_videomode) +{ + fsl_dcu_init(fbinfo, xres, yres, 32); + + return 0; +} diff --git a/roms/u-boot/board/toradex/colibri_vf/imximage.cfg b/roms/u-boot/board/toradex/colibri_vf/imximage.cfg new file mode 100644 index 000000000..7e629d2f9 --- /dev/null +++ b/roms/u-boot/board/toradex/colibri_vf/imximage.cfg @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2014 Toradex, Inc. + * + * Refer doc/imx/mkimage/imximage.txt for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ +#include <asm/mach-imx/imximage.cfg> + +/* image version */ +IMAGE_VERSION 2 + +/* Boot Offset 0x400, valid for both SD and NAND boot */ +BOOT_OFFSET FLASH_OFFSET_STANDARD diff --git a/roms/u-boot/board/toradex/common/Kconfig b/roms/u-boot/board/toradex/common/Kconfig new file mode 100644 index 000000000..36068d2e3 --- /dev/null +++ b/roms/u-boot/board/toradex/common/Kconfig @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Toradex, Inc. + +menuconfig TDX_CFG_BLOCK + bool "Enable Toradex config block support" + select OF_BOARD_SETUP + help + The Toradex config block stored production data on the on-module + flash device (NAND, NOR or eMMC). The area is normally preserved by + software and contains the serial number (out of which the MAC + address is generated) and the exact module type. + +# Helper config to determine the correct default location of the cfg block +config TDX_HAVE_MMC + bool + +config TDX_HAVE_NAND + bool + +config TDX_HAVE_NOR + bool + +config TDX_HAVE_EEPROM + bool + +config TDX_HAVE_EEPROM_EXTRA + bool + +if TDX_CFG_BLOCK + +config TDX_CFG_BLOCK_IS_IN_MMC + bool + depends on TDX_HAVE_MMC + default y + +config TDX_CFG_BLOCK_IS_IN_NAND + bool + depends on TDX_HAVE_NAND + default y + +config TDX_CFG_BLOCK_IS_IN_NOR + bool + depends on TDX_HAVE_NOR + default y + +config TDX_CFG_BLOCK_IS_IN_EEPROM + bool + depends on TDX_HAVE_EEPROM + default y + +config TDX_CFG_BLOCK_DEV + int "Toradex config block eMMC device ID" + depends on TDX_CFG_BLOCK_IS_IN_MMC + +config TDX_CFG_BLOCK_PART + int "Toradex config block eMMC partition ID" + depends on TDX_CFG_BLOCK_IS_IN_MMC + +config TDX_CFG_BLOCK_OFFSET + int "Toradex config block offset" + help + Specify the byte offset of the Toradex config block within the flash + device the config block is stored on. + +config TDX_CFG_BLOCK_OFFSET2 + int "Toradex config block offset, second instance" + default 0 + help + Specify the byte offset of the 2nd instance of the Toradex config block + within the flash device the config block is stored on. + Set to 0 on modules which have no 2nd instance. + +config TDX_CFG_BLOCK_2ND_ETHADDR + bool "Set the second Ethernet address" + help + For each serial number two Ethernet addresses are available for dual + Ethernet carrier boards. This options enables the code to set the + second Ethernet address as environment variable (eth1addr). + +config TDX_CFG_BLOCK_EXTRA + bool "Support for additional EEPROMs (carrier board, display adapter)" + depends on TDX_HAVE_EEPROM_EXTRA + help + Enables fetching auxilary config blocks from carrier board/display + adapter EEPROMs. + +endif diff --git a/roms/u-boot/board/toradex/common/Makefile b/roms/u-boot/board/toradex/common/Makefile new file mode 100644 index 000000000..7b19b6e4c --- /dev/null +++ b/roms/u-boot/board/toradex/common/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2016 Toradex, Inc. + +# Common for all Toradex modules +ifeq ($(CONFIG_SPL_BUILD),y) +# Necessary to create built-in.o +obj- := __dummy__.o +else +obj-$(CONFIG_TDX_CFG_BLOCK) += tdx-cfg-block.o +obj-y += tdx-common.o +obj-y += tdx-eeprom.o +endif diff --git a/roms/u-boot/board/toradex/common/tdx-cfg-block.c b/roms/u-boot/board/toradex/common/tdx-cfg-block.c new file mode 100644 index 000000000..93eb20cf6 --- /dev/null +++ b/roms/u-boot/board/toradex/common/tdx-cfg-block.c @@ -0,0 +1,1011 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2016-2020 Toradex + */ + +#include <common.h> +#include <asm/global_data.h> +#include "tdx-cfg-block.h" +#include "tdx-eeprom.h" + +#include <command.h> +#include <asm/cache.h> + +#if defined(CONFIG_TARGET_APALIS_IMX6) || \ + defined(CONFIG_TARGET_APALIS_IMX8) || \ + defined(CONFIG_TARGET_APALIS_IMX8X) || \ + defined(CONFIG_TARGET_COLIBRI_IMX6) || \ + defined(CONFIG_TARGET_COLIBRI_IMX8X) || \ + defined(CONFIG_TARGET_VERDIN_IMX8MM) || \ + defined(CONFIG_TARGET_VERDIN_IMX8MN) || \ + defined(CONFIG_TARGET_VERDIN_IMX8MP) +#include <asm/arch/sys_proto.h> +#else +#define is_cpu_type(cpu) (0) +#endif +#if defined(CONFIG_CPU_PXA27X) +#include <asm/arch-pxa/pxa.h> +#else +#define cpu_is_pxa27x(cpu) (0) +#endif +#include <cli.h> +#include <console.h> +#include <env.h> +#include <flash.h> +#include <malloc.h> +#include <mmc.h> +#include <nand.h> +#include <asm/mach-types.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define TAG_VALID 0xcf01 +#define TAG_MAC 0x0000 +#define TAG_CAR_SERIAL 0x0021 +#define TAG_HW 0x0008 +#define TAG_INVALID 0xffff + +#define TAG_FLAG_VALID 0x1 + +#define TDX_EEPROM_ID_MODULE 0 +#define TDX_EEPROM_ID_CARRIER 1 + +#if defined(CONFIG_TDX_CFG_BLOCK_IS_IN_MMC) +#define TDX_CFG_BLOCK_MAX_SIZE 512 +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NAND) +#define TDX_CFG_BLOCK_MAX_SIZE 64 +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NOR) +#define TDX_CFG_BLOCK_MAX_SIZE 64 +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_EEPROM) +#define TDX_CFG_BLOCK_MAX_SIZE 64 +#else +#error Toradex config block location not set +#endif + +#ifdef CONFIG_TDX_CFG_BLOCK_EXTRA +#define TDX_CFG_BLOCK_EXTRA_MAX_SIZE 64 +#endif + +struct toradex_tag { + u32 len:14; + u32 flags:2; + u32 id:16; +}; + +bool valid_cfgblock; +struct toradex_hw tdx_hw_tag; +struct toradex_eth_addr tdx_eth_addr; +u32 tdx_serial; +#ifdef CONFIG_TDX_CFG_BLOCK_EXTRA +u32 tdx_car_serial; +bool valid_cfgblock_carrier; +struct toradex_hw tdx_car_hw_tag; +#endif + +const char * const toradex_modules[] = { + [0] = "UNKNOWN MODULE", + [1] = "Colibri PXA270 312MHz", + [2] = "Colibri PXA270 520MHz", + [3] = "Colibri PXA320 806MHz", + [4] = "Colibri PXA300 208MHz", + [5] = "Colibri PXA310 624MHz", + [6] = "Colibri PXA320 806MHz IT", + [7] = "Colibri PXA300 208MHz XT", + [8] = "Colibri PXA270 312MHz", + [9] = "Colibri PXA270 520MHz", + [10] = "Colibri VF50 128MB", /* not currently on sale */ + [11] = "Colibri VF61 256MB", + [12] = "Colibri VF61 256MB IT", + [13] = "Colibri VF50 128MB IT", + [14] = "Colibri iMX6 Solo 256MB", + [15] = "Colibri iMX6 DualLite 512MB", + [16] = "Colibri iMX6 Solo 256MB IT", + [17] = "Colibri iMX6 DualLite 512MB IT", + [18] = "UNKNOWN MODULE", + [19] = "UNKNOWN MODULE", + [20] = "Colibri T20 256MB", + [21] = "Colibri T20 512MB", + [22] = "Colibri T20 512MB IT", + [23] = "Colibri T30 1GB", + [24] = "Colibri T20 256MB IT", + [25] = "Apalis T30 2GB", + [26] = "Apalis T30 1GB", + [27] = "Apalis iMX6 Quad 1GB", + [28] = "Apalis iMX6 Quad 2GB IT", + [29] = "Apalis iMX6 Dual 512MB", + [30] = "Colibri T30 1GB IT", + [31] = "Apalis T30 1GB IT", + [32] = "Colibri iMX7 Solo 256MB", + [33] = "Colibri iMX7 Dual 512MB", + [34] = "Apalis TK1 2GB", + [35] = "Apalis iMX6 Dual 1GB IT", + [36] = "Colibri iMX6ULL 256MB", + [37] = "Apalis iMX8 QuadMax 4GB Wi-Fi / BT IT", + [38] = "Colibri iMX8 QuadXPlus 2GB Wi-Fi / BT IT", + [39] = "Colibri iMX7 Dual 1GB (eMMC)", + [40] = "Colibri iMX6ULL 512MB Wi-Fi / BT IT", + [41] = "Colibri iMX7 Dual 512MB EPDC", + [42] = "Apalis TK1 4GB", + [43] = "Colibri T20 512MB IT SETEK", + [44] = "Colibri iMX6ULL 512MB IT", + [45] = "Colibri iMX6ULL 512MB Wi-Fi / Bluetooth", + [46] = "Apalis iMX8 QuadXPlus 2GB Wi-Fi / BT IT", + [47] = "Apalis iMX8 QuadMax 4GB IT", + [48] = "Apalis iMX8 QuadPlus 2GB Wi-Fi / BT", + [49] = "Apalis iMX8 QuadPlus 2GB", + [50] = "Colibri iMX8 QuadXPlus 2GB IT", + [51] = "Colibri iMX8 DualX 1GB Wi-Fi / Bluetooth", + [52] = "Colibri iMX8 DualX 1GB", + [53] = "Apalis iMX8 QuadXPlus 2GB ECC IT", + [54] = "Apalis iMX8 DualXPlus 1GB", + [55] = "Verdin iMX8M Mini Quad 2GB Wi-Fi / BT IT", + [56] = "Verdin iMX8M Nano Quad 1GB Wi-Fi / BT", /* not currently on sale */ + [57] = "Verdin iMX8M Mini DualLite 1GB", + [58] = "Verdin iMX8M Plus Quad 4GB Wi-Fi / BT IT", + [59] = "Verdin iMX8M Mini Quad 2GB IT", + [60] = "Verdin iMX8M Mini DualLite 1GB WB IT", + [61] = "Verdin iMX8M Plus Quad 2GB", +}; + +const char * const toradex_carrier_boards[] = { + [0] = "UNKNOWN CARRIER BOARD", + [155] = "Dahlia", + [156] = "Verdin Development Board", +}; + +const char * const toradex_display_adapters[] = { + [0] = "UNKNOWN DISPLAY ADAPTER", + [157] = "Verdin DSI to HDMI Adapter", + [159] = "Verdin DSI to LVDS Adapter", +}; + +#ifdef CONFIG_TDX_CFG_BLOCK_IS_IN_MMC +static int tdx_cfg_block_mmc_storage(u8 *config_block, int write) +{ + struct mmc *mmc; + int dev = CONFIG_TDX_CFG_BLOCK_DEV; + int offset = CONFIG_TDX_CFG_BLOCK_OFFSET; + uint part = CONFIG_TDX_CFG_BLOCK_PART; + uint blk_start; + int ret = 0; + + /* Read production parameter config block from eMMC */ + mmc = find_mmc_device(dev); + if (!mmc) { + puts("No MMC card found\n"); + ret = -ENODEV; + goto out; + } + if (mmc_init(mmc)) { + puts("MMC init failed\n"); + return -EINVAL; + } + if (part != mmc_get_blk_desc(mmc)->hwpart) { + if (blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part)) { + puts("MMC partition switch failed\n"); + ret = -ENODEV; + goto out; + } + } + if (offset < 0) + offset += mmc->capacity; + blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len; + + if (!write) { + /* Careful reads a whole block of 512 bytes into config_block */ + if (blk_dread(mmc_get_blk_desc(mmc), blk_start, 1, + (unsigned char *)config_block) != 1) { + ret = -EIO; + goto out; + } + } else { + /* Just writing one 512 byte block */ + if (blk_dwrite(mmc_get_blk_desc(mmc), blk_start, 1, + (unsigned char *)config_block) != 1) { + ret = -EIO; + goto out; + } + } + +out: + /* Switch back to regular eMMC user partition */ + blk_select_hwpart_devnum(IF_TYPE_MMC, 0, 0); + + return ret; +} +#endif + +#ifdef CONFIG_TDX_CFG_BLOCK_IS_IN_NAND +static int read_tdx_cfg_block_from_nand(unsigned char *config_block) +{ + size_t size = TDX_CFG_BLOCK_MAX_SIZE; + struct mtd_info *mtd = get_nand_dev_by_index(0); + + if (!mtd) + return -ENODEV; + + /* Read production parameter config block from NAND page */ + return nand_read_skip_bad(mtd, CONFIG_TDX_CFG_BLOCK_OFFSET, + &size, NULL, TDX_CFG_BLOCK_MAX_SIZE, + config_block); +} + +static int write_tdx_cfg_block_to_nand(unsigned char *config_block) +{ + size_t size = TDX_CFG_BLOCK_MAX_SIZE; + + /* Write production parameter config block to NAND page */ + return nand_write_skip_bad(get_nand_dev_by_index(0), + CONFIG_TDX_CFG_BLOCK_OFFSET, + &size, NULL, TDX_CFG_BLOCK_MAX_SIZE, + config_block, WITH_WR_VERIFY); +} +#endif + +#ifdef CONFIG_TDX_CFG_BLOCK_IS_IN_NOR +static int read_tdx_cfg_block_from_nor(unsigned char *config_block) +{ + /* Read production parameter config block from NOR flash */ + memcpy(config_block, (void *)CONFIG_TDX_CFG_BLOCK_OFFSET, + TDX_CFG_BLOCK_MAX_SIZE); + return 0; +} + +static int write_tdx_cfg_block_to_nor(unsigned char *config_block) +{ + /* Write production parameter config block to NOR flash */ + return flash_write((void *)config_block, CONFIG_TDX_CFG_BLOCK_OFFSET, + TDX_CFG_BLOCK_MAX_SIZE); +} +#endif + +#ifdef CONFIG_TDX_CFG_BLOCK_IS_IN_EEPROM +static int read_tdx_cfg_block_from_eeprom(unsigned char *config_block) +{ + return read_tdx_eeprom_data(TDX_EEPROM_ID_MODULE, 0x0, config_block, + TDX_CFG_BLOCK_MAX_SIZE); +} + +static int write_tdx_cfg_block_to_eeprom(unsigned char *config_block) +{ + return write_tdx_eeprom_data(TDX_EEPROM_ID_MODULE, 0x0, config_block, + TDX_CFG_BLOCK_MAX_SIZE); +} +#endif + +int read_tdx_cfg_block(void) +{ + int ret = 0; + u8 *config_block = NULL; + struct toradex_tag *tag; + size_t size = TDX_CFG_BLOCK_MAX_SIZE; + int offset; + + /* Allocate RAM area for config block */ + config_block = memalign(ARCH_DMA_MINALIGN, size); + if (!config_block) { + printf("Not enough malloc space available!\n"); + return -ENOMEM; + } + + memset(config_block, 0, size); + +#if defined(CONFIG_TDX_CFG_BLOCK_IS_IN_MMC) + ret = tdx_cfg_block_mmc_storage(config_block, 0); +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NAND) + ret = read_tdx_cfg_block_from_nand(config_block); +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NOR) + ret = read_tdx_cfg_block_from_nor(config_block); +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_EEPROM) + ret = read_tdx_cfg_block_from_eeprom(config_block); +#else + ret = -EINVAL; +#endif + if (ret) + goto out; + + /* Expect a valid tag first */ + tag = (struct toradex_tag *)config_block; + if (tag->flags != TAG_FLAG_VALID || tag->id != TAG_VALID) { + valid_cfgblock = false; + ret = -EINVAL; + goto out; + } + valid_cfgblock = true; + offset = 4; + + /* + * check if there is enough space for storing tag and value of the + * biggest element + */ + while (offset + sizeof(struct toradex_tag) + + sizeof(struct toradex_hw) < TDX_CFG_BLOCK_MAX_SIZE) { + tag = (struct toradex_tag *)(config_block + offset); + offset += 4; + if (tag->id == TAG_INVALID) + break; + + if (tag->flags == TAG_FLAG_VALID) { + switch (tag->id) { + case TAG_MAC: + memcpy(&tdx_eth_addr, config_block + offset, + 6); + + /* NIC part of MAC address is serial number */ + tdx_serial = ntohl(tdx_eth_addr.nic) >> 8; + break; + case TAG_HW: + memcpy(&tdx_hw_tag, config_block + offset, 8); + break; + } + } + + /* Get to next tag according to current tags length */ + offset += tag->len * 4; + } + + /* Cap product id to avoid issues with a yet unknown one */ + if (tdx_hw_tag.prodid >= (sizeof(toradex_modules) / + sizeof(toradex_modules[0]))) + tdx_hw_tag.prodid = 0; + +out: + free(config_block); + return ret; +} + +static int get_cfgblock_interactive(void) +{ + char message[CONFIG_SYS_CBSIZE]; + char *soc; + char it = 'n'; + char wb = 'n'; + int len = 0; + + /* Unknown module by default */ + tdx_hw_tag.prodid = 0; + + if (cpu_is_pxa27x()) + sprintf(message, "Is the module the 312 MHz version? [y/N] "); + else + it = 'y'; + +#if defined(CONFIG_TARGET_APALIS_IMX8) || \ + defined(CONFIG_TARGET_APALIS_IMX8X) || \ + defined(CONFIG_TARGET_COLIBRI_IMX6ULL) || \ + defined(CONFIG_TARGET_COLIBRI_IMX8X) || \ + defined(CONFIG_TARGET_VERDIN_IMX8MM) || \ + defined(CONFIG_TARGET_VERDIN_IMX8MP) + sprintf(message, "Does the module have Wi-Fi / Bluetooth? [y/N] "); + len = cli_readline(message); + wb = console_buffer[0]; +#endif + + soc = env_get("soc"); + if (!strcmp("mx6", soc)) { +#ifdef CONFIG_TARGET_APALIS_IMX6 + if (it == 'y' || it == 'Y') { + if (is_cpu_type(MXC_CPU_MX6Q)) + tdx_hw_tag.prodid = APALIS_IMX6Q_IT; + else + tdx_hw_tag.prodid = APALIS_IMX6D_IT; + } else { + if (is_cpu_type(MXC_CPU_MX6Q)) + tdx_hw_tag.prodid = APALIS_IMX6Q; + else + tdx_hw_tag.prodid = APALIS_IMX6D; + } +#elif CONFIG_TARGET_COLIBRI_IMX6 + if (it == 'y' || it == 'Y') { + if (is_cpu_type(MXC_CPU_MX6DL)) + tdx_hw_tag.prodid = COLIBRI_IMX6DL_IT; + else if (is_cpu_type(MXC_CPU_MX6SOLO)) + tdx_hw_tag.prodid = COLIBRI_IMX6S_IT; + } else { + if (is_cpu_type(MXC_CPU_MX6DL)) + tdx_hw_tag.prodid = COLIBRI_IMX6DL; + else if (is_cpu_type(MXC_CPU_MX6SOLO)) + tdx_hw_tag.prodid = COLIBRI_IMX6S; + } +#elif CONFIG_TARGET_COLIBRI_IMX6ULL + if (it == 'y' || it == 'Y') { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = COLIBRI_IMX6ULL_WIFI_BT_IT; + else + tdx_hw_tag.prodid = COLIBRI_IMX6ULL_IT; + } else { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = COLIBRI_IMX6ULL_WIFI_BT; + else + tdx_hw_tag.prodid = COLIBRI_IMX6ULL; + } +#endif + } else if (!strcmp("imx7d", soc)) + tdx_hw_tag.prodid = COLIBRI_IMX7D; + else if (!strcmp("imx7s", soc)) + tdx_hw_tag.prodid = COLIBRI_IMX7S; + else if (is_cpu_type(MXC_CPU_IMX8QM)) { + if (it == 'y' || it == 'Y') { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = APALIS_IMX8QM_WIFI_BT_IT; + else + tdx_hw_tag.prodid = APALIS_IMX8QM_IT; + } else { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = APALIS_IMX8QP_WIFI_BT; + else + tdx_hw_tag.prodid = APALIS_IMX8QP; + } + } else if (is_cpu_type(MXC_CPU_IMX8QXP)) { +#ifdef CONFIG_TARGET_APALIS_IMX8X + if (it == 'y' || it == 'Y' || wb == 'y' || wb == 'Y') { + tdx_hw_tag.prodid = APALIS_IMX8QXP_WIFI_BT_IT; + } else { + if (gd->ram_size == 0x40000000) + tdx_hw_tag.prodid = APALIS_IMX8DXP; + else + tdx_hw_tag.prodid = APALIS_IMX8QXP; + } +#elif CONFIG_TARGET_COLIBRI_IMX8X + if (it == 'y' || it == 'Y') { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = COLIBRI_IMX8QXP_WIFI_BT_IT; + else + tdx_hw_tag.prodid = COLIBRI_IMX8QXP_IT; + } else { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = COLIBRI_IMX8DX_WIFI_BT; + else + tdx_hw_tag.prodid = COLIBRI_IMX8DX; + } +#endif + } else if (is_cpu_type(MXC_CPU_IMX8MMDL)) { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = VERDIN_IMX8MMDL_WIFI_BT_IT; + else + tdx_hw_tag.prodid = VERDIN_IMX8MMDL; + } else if (is_cpu_type(MXC_CPU_IMX8MM)) { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = VERDIN_IMX8MMQ_WIFI_BT_IT; + else + tdx_hw_tag.prodid = VERDIN_IMX8MMQ_IT; + } else if (is_cpu_type(MXC_CPU_IMX8MN)) { + tdx_hw_tag.prodid = VERDIN_IMX8MNQ_WIFI_BT; + } else if (is_cpu_type(MXC_CPU_IMX8MP)) { + if (wb == 'y' || wb == 'Y') + tdx_hw_tag.prodid = VERDIN_IMX8MPQ_WIFI_BT_IT; + else + tdx_hw_tag.prodid = VERDIN_IMX8MPQ; + } else if (!strcmp("tegra20", soc)) { + if (it == 'y' || it == 'Y') + if (gd->ram_size == 0x10000000) + tdx_hw_tag.prodid = COLIBRI_T20_256MB_IT; + else + tdx_hw_tag.prodid = COLIBRI_T20_512MB_IT; + else + if (gd->ram_size == 0x10000000) + tdx_hw_tag.prodid = COLIBRI_T20_256MB; + else + tdx_hw_tag.prodid = COLIBRI_T20_512MB; + } else if (cpu_is_pxa27x()) { + if (it == 'y' || it == 'Y') + tdx_hw_tag.prodid = COLIBRI_PXA270_312MHZ; + else + tdx_hw_tag.prodid = COLIBRI_PXA270_520MHZ; + } +#ifdef CONFIG_MACH_TYPE + else if (!strcmp("tegra30", soc)) { + if (CONFIG_MACH_TYPE == MACH_TYPE_APALIS_T30) { + if (it == 'y' || it == 'Y') + tdx_hw_tag.prodid = APALIS_T30_IT; + else + if (gd->ram_size == 0x40000000) + tdx_hw_tag.prodid = APALIS_T30_1GB; + else + tdx_hw_tag.prodid = APALIS_T30_2GB; + } else { + if (it == 'y' || it == 'Y') + tdx_hw_tag.prodid = COLIBRI_T30_IT; + else + tdx_hw_tag.prodid = COLIBRI_T30; + } + } +#endif /* CONFIG_MACH_TYPE */ + else if (!strcmp("tegra124", soc)) { + tdx_hw_tag.prodid = APALIS_TK1_2GB; + } else if (!strcmp("vf500", soc)) { + if (it == 'y' || it == 'Y') + tdx_hw_tag.prodid = COLIBRI_VF50_IT; + else + tdx_hw_tag.prodid = COLIBRI_VF50; + } else if (!strcmp("vf610", soc)) { + if (it == 'y' || it == 'Y') + tdx_hw_tag.prodid = COLIBRI_VF61_IT; + else + tdx_hw_tag.prodid = COLIBRI_VF61; + } + + if (!tdx_hw_tag.prodid) { + printf("Module type not detectable due to unknown SoC\n"); + return -1; + } + + while (len < 4) { + sprintf(message, "Enter the module version (e.g. V1.1B): V"); + len = cli_readline(message); + } + + tdx_hw_tag.ver_major = console_buffer[0] - '0'; + tdx_hw_tag.ver_minor = console_buffer[2] - '0'; + tdx_hw_tag.ver_assembly = console_buffer[3] - 'A'; + + if (cpu_is_pxa27x() && tdx_hw_tag.ver_major == 1) + tdx_hw_tag.prodid -= (COLIBRI_PXA270_312MHZ - + COLIBRI_PXA270_V1_312MHZ); + + while (len < 8) { + sprintf(message, "Enter module serial number: "); + len = cli_readline(message); + } + + tdx_serial = simple_strtoul(console_buffer, NULL, 10); + + return 0; +} + +static int get_cfgblock_barcode(char *barcode, struct toradex_hw *tag, + u32 *serial) +{ + char revision[3] = {barcode[6], barcode[7], '\0'}; + + if (strlen(barcode) < 16) { + printf("Argument too short, barcode is 16 chars long\n"); + return -1; + } + + /* Get hardware information from the first 8 digits */ + tag->ver_major = barcode[4] - '0'; + tag->ver_minor = barcode[5] - '0'; + tag->ver_assembly = simple_strtoul(revision, NULL, 10); + + barcode[4] = '\0'; + tag->prodid = simple_strtoul(barcode, NULL, 10); + + /* Parse second part of the barcode (serial number */ + barcode += 8; + *serial = simple_strtoul(barcode, NULL, 10); + + return 0; +} + +static int write_tag(u8 *config_block, int *offset, int tag_id, + u8 *tag_data, size_t tag_data_size) +{ + struct toradex_tag *tag; + + if (!offset || !config_block) + return -EINVAL; + + tag = (struct toradex_tag *)(config_block + *offset); + tag->id = tag_id; + tag->flags = TAG_FLAG_VALID; + /* len is provided as number of 32bit values after the tag */ + tag->len = (tag_data_size + sizeof(u32) - 1) / sizeof(u32); + *offset += sizeof(struct toradex_tag); + if (tag_data && tag_data_size) { + memcpy(config_block + *offset, tag_data, + tag_data_size); + *offset += tag_data_size; + } + + return 0; +} + +#ifdef CONFIG_TDX_CFG_BLOCK_EXTRA +int read_tdx_cfg_block_carrier(void) +{ + int ret = 0; + u8 *config_block = NULL; + struct toradex_tag *tag; + size_t size = TDX_CFG_BLOCK_EXTRA_MAX_SIZE; + int offset; + + /* Allocate RAM area for carrier config block */ + config_block = memalign(ARCH_DMA_MINALIGN, size); + if (!config_block) { + printf("Not enough malloc space available!\n"); + return -ENOMEM; + } + + memset(config_block, 0, size); + + ret = read_tdx_eeprom_data(TDX_EEPROM_ID_CARRIER, 0x0, config_block, + size); + if (ret) + return ret; + + /* Expect a valid tag first */ + tag = (struct toradex_tag *)config_block; + if (tag->flags != TAG_FLAG_VALID || tag->id != TAG_VALID) { + valid_cfgblock_carrier = false; + ret = -EINVAL; + goto out; + } + valid_cfgblock_carrier = true; + offset = 4; + + while (offset + sizeof(struct toradex_tag) + + sizeof(struct toradex_hw) < TDX_CFG_BLOCK_MAX_SIZE) { + tag = (struct toradex_tag *)(config_block + offset); + offset += 4; + if (tag->id == TAG_INVALID) + break; + + if (tag->flags == TAG_FLAG_VALID) { + switch (tag->id) { + case TAG_CAR_SERIAL: + memcpy(&tdx_car_serial, config_block + offset, + sizeof(tdx_car_serial)); + break; + case TAG_HW: + memcpy(&tdx_car_hw_tag, config_block + + offset, 8); + break; + } + } + + /* Get to next tag according to current tags length */ + offset += tag->len * 4; + } +out: + free(config_block); + return ret; +} + +int check_pid8_sanity(char *pid8) +{ + char s_carrierid_verdin_dev[5]; + char s_carrierid_dahlia[5]; + + sprintf(s_carrierid_verdin_dev, "0%d", VERDIN_DEVELOPMENT_BOARD); + sprintf(s_carrierid_dahlia, "0%d", DAHLIA); + + /* sane value check, first 4 chars which represent carrier id */ + if (!strncmp(pid8, s_carrierid_verdin_dev, 4)) + return 0; + + if (!strncmp(pid8, s_carrierid_dahlia, 4)) + return 0; + + return -EINVAL; +} + +int try_migrate_tdx_cfg_block_carrier(void) +{ + char pid8[8]; + int offset = 0; + int ret = CMD_RET_SUCCESS; + size_t size = TDX_CFG_BLOCK_EXTRA_MAX_SIZE; + u8 *config_block; + + memset(pid8, 0x0, 8); + ret = read_tdx_eeprom_data(TDX_EEPROM_ID_CARRIER, 0x0, (u8 *)pid8, 8); + if (ret) + return ret; + + if (check_pid8_sanity(pid8)) + return -EINVAL; + + /* Allocate RAM area for config block */ + config_block = memalign(ARCH_DMA_MINALIGN, size); + if (!config_block) { + printf("Not enough malloc space available!\n"); + return CMD_RET_FAILURE; + } + + memset(config_block, 0xff, size); + /* we try parse PID8 concatenating zeroed serial number */ + tdx_car_hw_tag.ver_major = pid8[4] - '0'; + tdx_car_hw_tag.ver_minor = pid8[5] - '0'; + tdx_car_hw_tag.ver_assembly = pid8[7] - '0'; + + pid8[4] = '\0'; + tdx_car_hw_tag.prodid = simple_strtoul(pid8, NULL, 10); + + /* Valid Tag */ + write_tag(config_block, &offset, TAG_VALID, NULL, 0); + + /* Product Tag */ + write_tag(config_block, &offset, TAG_HW, (u8 *)&tdx_car_hw_tag, + sizeof(tdx_car_hw_tag)); + + /* Serial Tag */ + write_tag(config_block, &offset, TAG_CAR_SERIAL, (u8 *)&tdx_car_serial, + sizeof(tdx_car_serial)); + + memset(config_block + offset, 0, 32 - offset); + ret = write_tdx_eeprom_data(TDX_EEPROM_ID_CARRIER, 0x0, config_block, + size); + if (ret) { + printf("Failed to write Toradex Extra config block: %d\n", + ret); + ret = CMD_RET_FAILURE; + goto out; + } + + printf("Successfully migrated to Toradex Config Block from PID8\n"); + +out: + free(config_block); + return ret; +} + +static int get_cfgblock_carrier_interactive(void) +{ + char message[CONFIG_SYS_CBSIZE]; + int len; + + printf("Supported carrier boards:\n"); + printf("CARRIER BOARD NAME\t\t [ID]\n"); + for (int i = 0; i < sizeof(toradex_carrier_boards) / + sizeof(toradex_carrier_boards[0]); i++) + if (toradex_carrier_boards[i]) + printf("%s \t\t [%d]\n", toradex_carrier_boards[i], i); + + sprintf(message, "Choose your carrier board (provide ID): "); + len = cli_readline(message); + tdx_car_hw_tag.prodid = simple_strtoul(console_buffer, NULL, 10); + + do { + sprintf(message, "Enter carrier board version (e.g. V1.1B): V"); + len = cli_readline(message); + } while (len < 4); + + tdx_car_hw_tag.ver_major = console_buffer[0] - '0'; + tdx_car_hw_tag.ver_minor = console_buffer[2] - '0'; + tdx_car_hw_tag.ver_assembly = console_buffer[3] - 'A'; + + while (len < 8) { + sprintf(message, "Enter carrier board serial number: "); + len = cli_readline(message); + } + + tdx_car_serial = simple_strtoul(console_buffer, NULL, 10); + + return 0; +} + +static int do_cfgblock_carrier_create(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) +{ + u8 *config_block; + size_t size = TDX_CFG_BLOCK_EXTRA_MAX_SIZE; + int offset = 0; + int ret = CMD_RET_SUCCESS; + int err; + int force_overwrite = 0; + + if (argc >= 3) { + if (argv[2][0] == '-' && argv[2][1] == 'y') + force_overwrite = 1; + } + + /* Allocate RAM area for config block */ + config_block = memalign(ARCH_DMA_MINALIGN, size); + if (!config_block) { + printf("Not enough malloc space available!\n"); + return CMD_RET_FAILURE; + } + + memset(config_block, 0xff, size); + read_tdx_cfg_block_carrier(); + if (valid_cfgblock_carrier && !force_overwrite) { + char message[CONFIG_SYS_CBSIZE]; + + sprintf(message, "A valid Toradex Carrier config block is present, still recreate? [y/N] "); + + if (!cli_readline(message)) + goto out; + + if (console_buffer[0] != 'y' && + console_buffer[0] != 'Y') + goto out; + } + + if (argc < 3 || (force_overwrite && argc < 4)) { + err = get_cfgblock_carrier_interactive(); + } else { + if (force_overwrite) + err = get_cfgblock_barcode(argv[3], &tdx_car_hw_tag, + &tdx_car_serial); + else + err = get_cfgblock_barcode(argv[2], &tdx_car_hw_tag, + &tdx_car_serial); + } + + if (err) { + ret = CMD_RET_FAILURE; + goto out; + } + + /* Valid Tag */ + write_tag(config_block, &offset, TAG_VALID, NULL, 0); + + /* Product Tag */ + write_tag(config_block, &offset, TAG_HW, (u8 *)&tdx_car_hw_tag, + sizeof(tdx_car_hw_tag)); + + /* Serial Tag */ + write_tag(config_block, &offset, TAG_CAR_SERIAL, (u8 *)&tdx_car_serial, + sizeof(tdx_car_serial)); + + memset(config_block + offset, 0, 32 - offset); + err = write_tdx_eeprom_data(TDX_EEPROM_ID_CARRIER, 0x0, config_block, + size); + if (err) { + printf("Failed to write Toradex Extra config block: %d\n", + ret); + ret = CMD_RET_FAILURE; + goto out; + } + + printf("Toradex Extra config block successfully written\n"); + +out: + free(config_block); + return ret; +} + +#endif /* CONFIG_TDX_CFG_BLOCK_EXTRA */ + +static int do_cfgblock_create(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) +{ + u8 *config_block; + size_t size = TDX_CFG_BLOCK_MAX_SIZE; + int offset = 0; + int ret = CMD_RET_SUCCESS; + int err; + int force_overwrite = 0; + + if (argc >= 3) { +#ifdef CONFIG_TDX_CFG_BLOCK_EXTRA + if (!strcmp(argv[2], "carrier")) + return do_cfgblock_carrier_create(cmdtp, flag, + --argc, ++argv); +#endif /* CONFIG_TDX_CFG_BLOCK_EXTRA */ + if (argv[2][0] == '-' && argv[2][1] == 'y') + force_overwrite = 1; + } + + /* Allocate RAM area for config block */ + config_block = memalign(ARCH_DMA_MINALIGN, size); + if (!config_block) { + printf("Not enough malloc space available!\n"); + return CMD_RET_FAILURE; + } + + memset(config_block, 0xff, size); + + read_tdx_cfg_block(); + if (valid_cfgblock) { +#if defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NAND) + /* + * On NAND devices, recreation is only allowed if the page is + * empty (config block invalid...) + */ + printf("NAND erase block %d need to be erased before creating a Toradex config block\n", + CONFIG_TDX_CFG_BLOCK_OFFSET / + get_nand_dev_by_index(0)->erasesize); + goto out; +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NOR) + /* + * On NOR devices, recreation is only allowed if the sector is + * empty and write protection is off (config block invalid...) + */ + printf("NOR sector at offset 0x%02x need to be erased and unprotected before creating a Toradex config block\n", + CONFIG_TDX_CFG_BLOCK_OFFSET); + goto out; +#else + if (!force_overwrite) { + char message[CONFIG_SYS_CBSIZE]; + + sprintf(message, + "A valid Toradex config block is present, still recreate? [y/N] "); + + if (!cli_readline(message)) + goto out; + + if (console_buffer[0] != 'y' && + console_buffer[0] != 'Y') + goto out; + } +#endif + } + + /* Parse new Toradex config block data... */ + if (argc < 3 || (force_overwrite && argc < 4)) { + err = get_cfgblock_interactive(); + } else { + if (force_overwrite) + err = get_cfgblock_barcode(argv[3], &tdx_hw_tag, + &tdx_serial); + else + err = get_cfgblock_barcode(argv[2], &tdx_hw_tag, + &tdx_serial); + } + if (err) { + ret = CMD_RET_FAILURE; + goto out; + } + + /* Convert serial number to MAC address (the storage format) */ + tdx_eth_addr.oui = htonl(0x00142dUL << 8); + tdx_eth_addr.nic = htonl(tdx_serial << 8); + + /* Valid Tag */ + write_tag(config_block, &offset, TAG_VALID, NULL, 0); + + /* Product Tag */ + write_tag(config_block, &offset, TAG_HW, (u8 *)&tdx_hw_tag, + sizeof(tdx_hw_tag)); + + /* MAC Tag */ + write_tag(config_block, &offset, TAG_MAC, (u8 *)&tdx_eth_addr, + sizeof(tdx_eth_addr)); + + memset(config_block + offset, 0, 32 - offset); +#if defined(CONFIG_TDX_CFG_BLOCK_IS_IN_MMC) + err = tdx_cfg_block_mmc_storage(config_block, 1); +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NAND) + err = write_tdx_cfg_block_to_nand(config_block); +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NOR) + err = write_tdx_cfg_block_to_nor(config_block); +#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_EEPROM) + err = write_tdx_cfg_block_to_eeprom(config_block); +#else + err = -EINVAL; +#endif + if (err) { + printf("Failed to write Toradex config block: %d\n", ret); + ret = CMD_RET_FAILURE; + goto out; + } + + printf("Toradex config block successfully written\n"); + +out: + free(config_block); + return ret; +} + +static int do_cfgblock(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + if (argc < 2) + return CMD_RET_USAGE; + + if (!strcmp(argv[1], "create")) { + return do_cfgblock_create(cmdtp, flag, argc, argv); + } else if (!strcmp(argv[1], "reload")) { + ret = read_tdx_cfg_block(); + if (ret) { + printf("Failed to reload Toradex config block: %d\n", + ret); + return CMD_RET_FAILURE; + } + return CMD_RET_SUCCESS; + } + + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + cfgblock, 5, 0, do_cfgblock, + "Toradex config block handling commands", + "create [-y] [barcode] - (Re-)create Toradex config block\n" + "create carrier [-y] [barcode] - (Re-)create Toradex Carrier config block\n" + "cfgblock reload - Reload Toradex config block from flash" +); diff --git a/roms/u-boot/board/toradex/common/tdx-cfg-block.h b/roms/u-boot/board/toradex/common/tdx-cfg-block.h new file mode 100644 index 000000000..9debd5f04 --- /dev/null +++ b/roms/u-boot/board/toradex/common/tdx-cfg-block.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2016-2020 Toradex + */ + +#ifndef _TDX_CFG_BLOCK_H +#define _TDX_CFG_BLOCK_H + +#include "tdx-common.h" + +struct toradex_hw { + u16 ver_major; + u16 ver_minor; + u16 ver_assembly; + u16 prodid; +}; + +struct toradex_eth_addr { + u32 oui:24; + u32 nic:24; +} __attribute__((__packed__)); + +enum { + COLIBRI_PXA270_V1_312MHZ = 1, + COLIBRI_PXA270_V1_520MHZ, + COLIBRI_PXA320, + COLIBRI_PXA300, + COLIBRI_PXA310, /* 5 */ + COLIBRI_PXA320_IT, + COLIBRI_PXA300_XT, + COLIBRI_PXA270_312MHZ, + COLIBRI_PXA270_520MHZ, + COLIBRI_VF50, /* 10 */ + COLIBRI_VF61, /* not currently on sale */ + COLIBRI_VF61_IT, + COLIBRI_VF50_IT, + COLIBRI_IMX6S, + COLIBRI_IMX6DL, /* 15 */ + COLIBRI_IMX6S_IT, + COLIBRI_IMX6DL_IT, + /* 18 */ + /* 19 */ + COLIBRI_T20_256MB = 20, + COLIBRI_T20_512MB, + COLIBRI_T20_512MB_IT, + COLIBRI_T30, + COLIBRI_T20_256MB_IT, + APALIS_T30_2GB, /* 25 */ + APALIS_T30_1GB, + APALIS_IMX6Q, + APALIS_IMX6Q_IT, + APALIS_IMX6D, + COLIBRI_T30_IT, /* 30 */ + APALIS_T30_IT, + COLIBRI_IMX7S, + COLIBRI_IMX7D, + APALIS_TK1_2GB, + APALIS_IMX6D_IT, /* 35 */ + COLIBRI_IMX6ULL, + APALIS_IMX8QM_WIFI_BT_IT, + COLIBRI_IMX8QXP_WIFI_BT_IT, + COLIBRI_IMX7D_EMMC, + COLIBRI_IMX6ULL_WIFI_BT_IT, /* 40 */ + COLIBRI_IMX7D_EPDC, + APALIS_TK1_4GB, /* not currently on sale */ + COLIBRI_T20_512MB_IT_SETEK, + COLIBRI_IMX6ULL_IT, + COLIBRI_IMX6ULL_WIFI_BT, /* 45 */ + APALIS_IMX8QXP_WIFI_BT_IT, + APALIS_IMX8QM_IT, + APALIS_IMX8QP_WIFI_BT, + APALIS_IMX8QP, + COLIBRI_IMX8QXP_IT, /* 50 */ + COLIBRI_IMX8DX_WIFI_BT, + COLIBRI_IMX8DX, + APALIS_IMX8QXP, + APALIS_IMX8DXP, + VERDIN_IMX8MMQ_WIFI_BT_IT, /* 55 */ + VERDIN_IMX8MNQ_WIFI_BT, + VERDIN_IMX8MMDL, + VERDIN_IMX8MPQ_WIFI_BT_IT, + VERDIN_IMX8MMQ_IT, + VERDIN_IMX8MMDL_WIFI_BT_IT, /* 60 */ + VERDIN_IMX8MPQ, +}; + +enum { + DAHLIA = 155, + VERDIN_DEVELOPMENT_BOARD = 156, +}; + +enum { + VERDIN_DSI_TO_HDMI_ADAPTER = 157, + VERDIN_DSI_TO_LVDS_ADAPTER = 159, +}; + +extern const char * const toradex_modules[]; +extern const char * const toradex_carrier_boards[]; +extern bool valid_cfgblock; +extern struct toradex_hw tdx_hw_tag; +extern struct toradex_hw tdx_car_hw_tag; +extern struct toradex_eth_addr tdx_eth_addr; +extern u32 tdx_serial; +extern u32 tdx_car_serial; + +int read_tdx_cfg_block(void); +int read_tdx_cfg_block_carrier(void); + +int try_migrate_tdx_cfg_block_carrier(void); + +#endif /* _TDX_CFG_BLOCK_H */ diff --git a/roms/u-boot/board/toradex/common/tdx-common.c b/roms/u-boot/board/toradex/common/tdx-common.c new file mode 100644 index 000000000..a3d287ed5 --- /dev/null +++ b/roms/u-boot/board/toradex/common/tdx-common.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2016 Toradex, Inc. + */ + +#include <common.h> +#include <env.h> +#include <g_dnl.h> +#include <init.h> +#include <linux/libfdt.h> + +#ifdef CONFIG_DM_VIDEO +#include <bmp_logo.h> +#include <dm.h> +#include <splash.h> +#include <video.h> +#endif + +#include "tdx-cfg-block.h" +#include <asm/setup.h> +#include "tdx-common.h" + +#define TORADEX_OUI 0x00142dUL + +#ifdef CONFIG_TDX_CFG_BLOCK +static char tdx_serial_str[9]; +static char tdx_board_rev_str[6]; + +#ifdef CONFIG_TDX_CFG_BLOCK_EXTRA +static char tdx_car_serial_str[9]; +static char tdx_car_rev_str[6]; +static char *tdx_carrier_board_name; +#endif + +#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void) +{ + /* Check validity */ + if (!tdx_hw_tag.ver_major) + return 0; + + return ((tdx_hw_tag.ver_major & 0xff) << 8) | + ((tdx_hw_tag.ver_minor & 0xf) << 4) | + ((tdx_hw_tag.ver_assembly & 0xf) + 0xa); +} +#endif /* CONFIG_TDX_CFG_BLOCK */ + +#ifdef CONFIG_SERIAL_TAG +void get_board_serial(struct tag_serialnr *serialnr) +{ + int array[8]; + unsigned int serial = tdx_serial; + int i; + + serialnr->low = 0; + serialnr->high = 0; + + /* Check validity */ + if (serial) { + /* + * Convert to Linux serial number format (hexadecimal coded + * decimal) + */ + i = 7; + while (serial) { + array[i--] = serial % 10; + serial /= 10; + } + while (i >= 0) + array[i--] = 0; + serial = array[0]; + for (i = 1; i < 8; i++) { + serial *= 16; + serial += array[i]; + } + + serialnr->low = serial; + } +} +#endif /* CONFIG_SERIAL_TAG */ + +int show_board_info(void) +{ + unsigned char ethaddr[6]; + + if (read_tdx_cfg_block()) { + printf("MISSING TORADEX CONFIG BLOCK\n"); + tdx_eth_addr.oui = htonl(TORADEX_OUI << 8); + tdx_eth_addr.nic = htonl(tdx_serial << 8); + checkboard(); + } else { + sprintf(tdx_serial_str, "%08u", tdx_serial); + sprintf(tdx_board_rev_str, "V%1d.%1d%c", + tdx_hw_tag.ver_major, + tdx_hw_tag.ver_minor, + (char)tdx_hw_tag.ver_assembly + 'A'); + + env_set("serial#", tdx_serial_str); + + printf("Model: Toradex %s %s, Serial# %s\n", + toradex_modules[tdx_hw_tag.prodid], + tdx_board_rev_str, + tdx_serial_str); +#ifdef CONFIG_TDX_CFG_BLOCK_EXTRA + if (read_tdx_cfg_block_carrier()) { + printf("MISSING TORADEX CARRIER CONFIG BLOCKS\n"); + try_migrate_tdx_cfg_block_carrier(); + } else { + tdx_carrier_board_name = (char *) + toradex_carrier_boards[tdx_car_hw_tag.prodid]; + + sprintf(tdx_car_serial_str, "%08u", tdx_car_serial); + sprintf(tdx_car_rev_str, "V%1d.%1d%c", + tdx_car_hw_tag.ver_major, + tdx_car_hw_tag.ver_minor, + (char)tdx_car_hw_tag.ver_assembly + + 'A'); + + env_set("carrier_serial#", tdx_car_serial_str); + printf("Carrier: Toradex %s %s, Serial# %s\n", + tdx_carrier_board_name, + tdx_car_rev_str, + tdx_car_serial_str); + } +#endif + } + + /* + * Check if environment contains a valid MAC address, + * set the one from config block if not + */ + if (!eth_env_get_enetaddr("ethaddr", ethaddr)) + eth_env_set_enetaddr("ethaddr", (u8 *)&tdx_eth_addr); + +#ifdef CONFIG_TDX_CFG_BLOCK_2ND_ETHADDR + if (!eth_env_get_enetaddr("eth1addr", ethaddr)) { + /* + * Secondary MAC address is allocated from block + * 0x100000 higher then the first MAC address + */ + memcpy(ethaddr, &tdx_eth_addr, 6); + ethaddr[3] += 0x10; + eth_env_set_enetaddr("eth1addr", ethaddr); + } +#endif + + return 0; +} + +#ifdef CONFIG_USB_GADGET_DOWNLOAD +int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) +{ + unsigned short usb_pid; + + usb_pid = TORADEX_USB_PRODUCT_NUM_OFFSET + tdx_hw_tag.prodid; + put_unaligned(usb_pid, &dev->idProduct); + + return 0; +} +#endif + +#if defined(CONFIG_OF_LIBFDT) +int ft_common_board_setup(void *blob, struct bd_info *bd) +{ + if (tdx_serial) { + fdt_setprop(blob, 0, "serial-number", tdx_serial_str, + strlen(tdx_serial_str) + 1); + } + + if (tdx_hw_tag.ver_major) { + char prod_id[5]; + + sprintf(prod_id, "%04u", tdx_hw_tag.prodid); + fdt_setprop(blob, 0, "toradex,product-id", prod_id, 5); + + fdt_setprop(blob, 0, "toradex,board-rev", tdx_board_rev_str, + strlen(tdx_board_rev_str) + 1); + } + + return 0; +} +#endif + +#else /* CONFIG_TDX_CFG_BLOCK */ + +#ifdef CONFIG_REVISION_TAG +u32 get_board_rev(void) +{ + return 0; +} +#endif /* CONFIG_REVISION_TAG */ + +#ifdef CONFIG_SERIAL_TAG +u32 get_board_serial(void) +{ + return 0; +} +#endif /* CONFIG_SERIAL_TAG */ + +int ft_common_board_setup(void *blob, struct bd_info *bd) +{ + return 0; +} + +#endif /* CONFIG_TDX_CFG_BLOCK */ diff --git a/roms/u-boot/board/toradex/common/tdx-common.h b/roms/u-boot/board/toradex/common/tdx-common.h new file mode 100644 index 000000000..8020df5b4 --- /dev/null +++ b/roms/u-boot/board/toradex/common/tdx-common.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2016 Toradex, Inc. + */ + +#ifndef _TDX_COMMON_H +#define _TDX_COMMON_H + +#define TORADEX_USB_PRODUCT_NUM_OFFSET 0x4000 +#define TDX_USB_VID 0x1B67 + +int ft_common_board_setup(void *blob, struct bd_info *bd); + +#if defined(CONFIG_DM_VIDEO) +int show_boot_logo(void); +#endif + +#endif /* _TDX_COMMON_H */ diff --git a/roms/u-boot/board/toradex/common/tdx-eeprom.c b/roms/u-boot/board/toradex/common/tdx-eeprom.c new file mode 100644 index 000000000..81bd9e68c --- /dev/null +++ b/roms/u-boot/board/toradex/common/tdx-eeprom.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020 Toradex + */ + +#include <dm.h> +#include <i2c_eeprom.h> +#include <asm/global_data.h> +#include <linux/errno.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int get_tdx_eeprom(u32 eeprom_id, struct udevice **devp) +{ + int ret = 0; + int node; + ofnode eeprom; + char eeprom_str[16]; + const char *path; + + if (!gd->fdt_blob) { + printf("%s: don't have a valid gd->fdt_blob!\n", __func__); + return -EFAULT; + } + + node = fdt_path_offset(gd->fdt_blob, "/aliases"); + if (node < 0) + return -ENODEV; + + sprintf(eeprom_str, "eeprom%d", eeprom_id); + + path = fdt_getprop(gd->fdt_blob, node, eeprom_str, NULL); + if (!path) { + printf("%s: no alias for %s\n", __func__, eeprom_str); + return -ENODEV; + } + + eeprom = ofnode_path(path); + if (!ofnode_valid(eeprom)) { + printf("%s: invalid hardware path to EEPROM\n", __func__); + return -ENODEV; + } + + ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, devp); + if (ret) { + printf("%s: cannot find EEPROM by node\n", __func__); + return ret; + } + + return ret; +} + +int read_tdx_eeprom_data(u32 eeprom_id, int offset, u8 *buf, + int size) +{ + struct udevice *dev; + int ret; + + ret = get_tdx_eeprom(eeprom_id, &dev); + if (ret) + return ret; + + ret = i2c_eeprom_read(dev, 0x0, buf, size); + if (ret) { + printf("%s: error reading data from EEPROM id: %d!, ret = %d\n", + __func__, eeprom_id, ret); + return ret; + } + + return ret; +} + +int write_tdx_eeprom_data(u32 eeprom_id, int offset, u8 *buf, + int size) +{ + struct udevice *dev; + int ret; + + ret = get_tdx_eeprom(eeprom_id, &dev); + if (ret) + return ret; + + ret = i2c_eeprom_write(dev, 0x0, buf, size); + if (ret) { + printf("%s: error writing data to EEPROM id: %d, ret = %d\n", + __func__, eeprom_id, ret); + return ret; + } + + return ret; +} diff --git a/roms/u-boot/board/toradex/common/tdx-eeprom.h b/roms/u-boot/board/toradex/common/tdx-eeprom.h new file mode 100644 index 000000000..a6772d2f3 --- /dev/null +++ b/roms/u-boot/board/toradex/common/tdx-eeprom.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2020 Toradex + */ + +#ifndef _TDX_EEPROM_H +#define _TDX_EEPROM_H + +#include <i2c_eeprom.h> + +int read_tdx_eeprom_data(u32 eeprom_id, int offset, uint8_t *buf, int size); +int write_tdx_eeprom_data(u32 eeprom_id, int offset, uint8_t *buf, int size); + +#endif /* _TDX_EEPROM_H */ diff --git a/roms/u-boot/board/toradex/verdin-imx8mm/Kconfig b/roms/u-boot/board/toradex/verdin-imx8mm/Kconfig new file mode 100644 index 000000000..149aed6da --- /dev/null +++ b/roms/u-boot/board/toradex/verdin-imx8mm/Kconfig @@ -0,0 +1,36 @@ +if TARGET_VERDIN_IMX8MM + +config SYS_BOARD + default "verdin-imx8mm" + +config SYS_VENDOR + default "toradex" + +config SYS_CONFIG_NAME + default "verdin-imx8mm" + +config TDX_CFG_BLOCK + default y + +config TDX_CFG_BLOCK_EXTRA + default y + +config TDX_HAVE_MMC + default y + +config TDX_HAVE_EEPROM_EXTRA + default y + +config TDX_CFG_BLOCK_DEV + default "0" + +config TDX_CFG_BLOCK_PART + default "1" + +# Toradex config block in eMMC, at the end of 1st "boot sector" +config TDX_CFG_BLOCK_OFFSET + default "-512" + +source "board/toradex/common/Kconfig" + +endif diff --git a/roms/u-boot/board/toradex/verdin-imx8mm/MAINTAINERS b/roms/u-boot/board/toradex/verdin-imx8mm/MAINTAINERS new file mode 100644 index 000000000..08c370178 --- /dev/null +++ b/roms/u-boot/board/toradex/verdin-imx8mm/MAINTAINERS @@ -0,0 +1,10 @@ +Verdin iMX8M Mini +M: Oleksandr Suvorov <oleksandr.suvorov@toradex.com> +W: https://www.toradex.com/computer-on-modules/verdin-arm-family/nxp-imx-8m-mini +S: Maintained +F: arch/arm/dts/imx8mm-verdin.dts +F: arch/arm/dts/imx8mm-verdin-u-boot.dtsi +F: board/toradex/verdin-imx8mm/ +F: configs/verdin-imx8mm_defconfig +F: doc/board/toradex/verdin-imx8mm.rst +F: include/configs/verdin-imx8mm.h diff --git a/roms/u-boot/board/toradex/verdin-imx8mm/Makefile b/roms/u-boot/board/toradex/verdin-imx8mm/Makefile new file mode 100644 index 000000000..b38054254 --- /dev/null +++ b/roms/u-boot/board/toradex/verdin-imx8mm/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2020 Toradex +# + +obj-y += verdin-imx8mm.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o +endif diff --git a/roms/u-boot/board/toradex/verdin-imx8mm/imximage.cfg b/roms/u-boot/board/toradex/verdin-imx8mm/imximage.cfg new file mode 100644 index 000000000..b8b25ff42 --- /dev/null +++ b/roms/u-boot/board/toradex/verdin-imx8mm/imximage.cfg @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Toradex + */ + +#define __ASSEMBLY__ + +FIT +BOOT_FROM emmc_fastboot +LOADER spl/u-boot-spl-ddr.bin 0x7E1000 +SECOND_LOADER u-boot.itb 0x40200000 0x60000 + +DDR_FW lpddr4_pmu_train_1d_imem.bin +DDR_FW lpddr4_pmu_train_1d_dmem.bin +DDR_FW lpddr4_pmu_train_2d_imem.bin +DDR_FW lpddr4_pmu_train_2d_dmem.bin diff --git a/roms/u-boot/board/toradex/verdin-imx8mm/lpddr4_timing.c b/roms/u-boot/board/toradex/verdin-imx8mm/lpddr4_timing.c new file mode 100644 index 000000000..d114abf9d --- /dev/null +++ b/roms/u-boot/board/toradex/verdin-imx8mm/lpddr4_timing.c @@ -0,0 +1,1850 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Toradex + * + * Generated code from MX8M_DDR_tool + * Align with uboot-imx_v2018.03_4.14.78_1.0.0_ga + * + * DDR calibration created with mscale_ddr_tool_v210_setup.exe using + * MX8M_Mini_LPDDR4_RPA_v14 Verdin iMX8MM V1.0.xlsx as of 1. Nov. 2019. + */ + +#include <linux/kernel.h> +#include <asm/arch/ddr.h> + +struct dram_cfg_param ddr_ddrc_cfg[] = { + /** Initialize DDRC registers **/ + {0x3d400304, 0x1}, + {0x3d400030, 0x1}, + {0x3d400000, 0xa1080020}, + {0x3d400020, 0x203}, + {0x3d400024, 0x3a980}, + {0x3d400064, 0x5b00d2}, + {0x3d4000d0, 0xc00305ba}, + {0x3d4000d4, 0x940000}, + {0x3d4000dc, 0xd4002d}, + {0x3d4000e0, 0x310000}, + {0x3d4000e8, 0x66004d}, + {0x3d4000ec, 0x16004d}, + {0x3d400100, 0x191e1920}, + {0x3d400104, 0x60630}, + {0x3d40010c, 0xb0b000}, + {0x3d400110, 0xe04080e}, + {0x3d400114, 0x2040c0c}, + {0x3d400118, 0x1010007}, + {0x3d40011c, 0x401}, + {0x3d400130, 0x20600}, + {0x3d400134, 0xc100002}, + {0x3d400138, 0xd8}, + {0x3d400144, 0x96004b}, + {0x3d400180, 0x2ee0017}, + {0x3d400184, 0x2605b8e}, + {0x3d400188, 0x0}, + {0x3d400190, 0x497820a}, + {0x3d400194, 0x80303}, + {0x3d4001b4, 0x170a}, + {0x3d4001a0, 0xe0400018}, + {0x3d4001a4, 0xdf00e4}, + {0x3d4001a8, 0x80000000}, + {0x3d4001b0, 0x11}, + {0x3d4001c0, 0x1}, + {0x3d4001c4, 0x1}, + {0x3d4000f4, 0xc99}, + {0x3d400108, 0x70e1617}, + {0x3d400200, 0x1f}, + {0x3d40020c, 0x0}, + {0x3d400210, 0x1f1f}, + {0x3d400204, 0x80808}, + {0x3d400214, 0x7070707}, + {0x3d400218, 0x7070707}, + {0x3d400250, 0x29001701}, + {0x3d400254, 0x2c}, + {0x3d40025c, 0x4000030}, + {0x3d400264, 0x900093e7}, + {0x3d40026c, 0x2005574}, + {0x3d400400, 0x111}, + {0x3d400408, 0x72ff}, + {0x3d400494, 0x2100e07}, + {0x3d400498, 0x620096}, + {0x3d40049c, 0x1100e07}, + {0x3d4004a0, 0xc8012c}, + {0x3d402020, 0x1}, + {0x3d402024, 0x7d00}, + {0x3d402050, 0x20d040}, + {0x3d402064, 0xc001c}, + {0x3d4020dc, 0x840000}, + {0x3d4020e0, 0x310000}, + {0x3d4020e8, 0x66004d}, + {0x3d4020ec, 0x16004d}, + {0x3d402100, 0xa040305}, + {0x3d402104, 0x30407}, + {0x3d402108, 0x203060b}, + {0x3d40210c, 0x505000}, + {0x3d402110, 0x2040202}, + {0x3d402114, 0x2030202}, + {0x3d402118, 0x1010004}, + {0x3d40211c, 0x301}, + {0x3d402130, 0x20300}, + {0x3d402134, 0xa100002}, + {0x3d402138, 0x1d}, + {0x3d402144, 0x14000a}, + {0x3d402180, 0x640004}, + {0x3d402190, 0x3818200}, + {0x3d402194, 0x80303}, + {0x3d4021b4, 0x100}, + {0x3d4020f4, 0xc99}, + {0x3d403020, 0x1}, + {0x3d403024, 0x1f40}, + {0x3d403050, 0x20d040}, + {0x3d403064, 0x30007}, + {0x3d4030dc, 0x840000}, + {0x3d4030e0, 0x310000}, + {0x3d4030e8, 0x66004d}, + {0x3d4030ec, 0x16004d}, + {0x3d403100, 0xa010102}, + {0x3d403104, 0x30404}, + {0x3d403108, 0x203060b}, + {0x3d40310c, 0x505000}, + {0x3d403110, 0x2040202}, + {0x3d403114, 0x2030202}, + {0x3d403118, 0x1010004}, + {0x3d40311c, 0x301}, + {0x3d403130, 0x20300}, + {0x3d403134, 0xa100002}, + {0x3d403138, 0x8}, + {0x3d403144, 0x50003}, + {0x3d403180, 0x190004}, + {0x3d403190, 0x3818200}, + {0x3d403194, 0x80303}, + {0x3d4031b4, 0x100}, + {0x3d4030f4, 0xc99}, + {0x3d400028, 0x0}, +}; + +/* PHY Initialize Configuration */ +struct dram_cfg_param ddr_ddrphy_cfg[] = { + {0x100a0, 0x0}, + {0x100a1, 0x1}, + {0x100a2, 0x2}, + {0x100a3, 0x3}, + {0x100a4, 0x4}, + {0x100a5, 0x5}, + {0x100a6, 0x6}, + {0x100a7, 0x7}, + {0x110a0, 0x0}, + {0x110a1, 0x1}, + {0x110a2, 0x3}, + {0x110a3, 0x4}, + {0x110a4, 0x5}, + {0x110a5, 0x2}, + {0x110a6, 0x6}, + {0x110a7, 0x7}, + {0x120a0, 0x0}, + {0x120a1, 0x1}, + {0x120a2, 0x3}, + {0x120a3, 0x4}, + {0x120a4, 0x5}, + {0x120a5, 0x2}, + {0x120a6, 0x6}, + {0x120a7, 0x7}, + {0x130a0, 0x0}, + {0x130a1, 0x1}, + {0x130a2, 0x2}, + {0x130a3, 0x3}, + {0x130a4, 0x4}, + {0x130a5, 0x5}, + {0x130a6, 0x6}, + {0x130a7, 0x7}, + {0x1005f, 0x1ff}, + {0x1015f, 0x1ff}, + {0x1105f, 0x1ff}, + {0x1115f, 0x1ff}, + {0x1205f, 0x1ff}, + {0x1215f, 0x1ff}, + {0x1305f, 0x1ff}, + {0x1315f, 0x1ff}, + {0x11005f, 0x1ff}, + {0x11015f, 0x1ff}, + {0x11105f, 0x1ff}, + {0x11115f, 0x1ff}, + {0x11205f, 0x1ff}, + {0x11215f, 0x1ff}, + {0x11305f, 0x1ff}, + {0x11315f, 0x1ff}, + {0x21005f, 0x1ff}, + {0x21015f, 0x1ff}, + {0x21105f, 0x1ff}, + {0x21115f, 0x1ff}, + {0x21205f, 0x1ff}, + {0x21215f, 0x1ff}, + {0x21305f, 0x1ff}, + {0x21315f, 0x1ff}, + {0x55, 0x1ff}, + {0x1055, 0x1ff}, + {0x2055, 0x1ff}, + {0x3055, 0x1ff}, + {0x4055, 0x1ff}, + {0x5055, 0x1ff}, + {0x6055, 0x1ff}, + {0x7055, 0x1ff}, + {0x8055, 0x1ff}, + {0x9055, 0x1ff}, + {0x200c5, 0x19}, + {0x1200c5, 0x7}, + {0x2200c5, 0x7}, + {0x2002e, 0x2}, + {0x12002e, 0x2}, + {0x22002e, 0x2}, + {0x90204, 0x0}, + {0x190204, 0x0}, + {0x290204, 0x0}, + {0x20024, 0x1ab}, + {0x2003a, 0x0}, + {0x120024, 0x1ab}, + {0x2003a, 0x0}, + {0x220024, 0x1ab}, + {0x2003a, 0x0}, + {0x20056, 0x3}, + {0x120056, 0xa}, + {0x220056, 0xa}, + {0x1004d, 0xe00}, + {0x1014d, 0xe00}, + {0x1104d, 0xe00}, + {0x1114d, 0xe00}, + {0x1204d, 0xe00}, + {0x1214d, 0xe00}, + {0x1304d, 0xe00}, + {0x1314d, 0xe00}, + {0x11004d, 0xe00}, + {0x11014d, 0xe00}, + {0x11104d, 0xe00}, + {0x11114d, 0xe00}, + {0x11204d, 0xe00}, + {0x11214d, 0xe00}, + {0x11304d, 0xe00}, + {0x11314d, 0xe00}, + {0x21004d, 0xe00}, + {0x21014d, 0xe00}, + {0x21104d, 0xe00}, + {0x21114d, 0xe00}, + {0x21204d, 0xe00}, + {0x21214d, 0xe00}, + {0x21304d, 0xe00}, + {0x21314d, 0xe00}, + {0x10049, 0xeba}, + {0x10149, 0xeba}, + {0x11049, 0xeba}, + {0x11149, 0xeba}, + {0x12049, 0xeba}, + {0x12149, 0xeba}, + {0x13049, 0xeba}, + {0x13149, 0xeba}, + {0x110049, 0xeba}, + {0x110149, 0xeba}, + {0x111049, 0xeba}, + {0x111149, 0xeba}, + {0x112049, 0xeba}, + {0x112149, 0xeba}, + {0x113049, 0xeba}, + {0x113149, 0xeba}, + {0x210049, 0xeba}, + {0x210149, 0xeba}, + {0x211049, 0xeba}, + {0x211149, 0xeba}, + {0x212049, 0xeba}, + {0x212149, 0xeba}, + {0x213049, 0xeba}, + {0x213149, 0xeba}, + {0x43, 0x63}, + {0x1043, 0x63}, + {0x2043, 0x63}, + {0x3043, 0x63}, + {0x4043, 0x63}, + {0x5043, 0x63}, + {0x6043, 0x63}, + {0x7043, 0x63}, + {0x8043, 0x63}, + {0x9043, 0x63}, + {0x20018, 0x3}, + {0x20075, 0x4}, + {0x20050, 0x0}, + {0x20008, 0x2ee}, + {0x120008, 0x64}, + {0x220008, 0x19}, + {0x20088, 0x9}, + {0x200b2, 0xdc}, + {0x10043, 0x5a1}, + {0x10143, 0x5a1}, + {0x11043, 0x5a1}, + {0x11143, 0x5a1}, + {0x12043, 0x5a1}, + {0x12143, 0x5a1}, + {0x13043, 0x5a1}, + {0x13143, 0x5a1}, + {0x1200b2, 0xdc}, + {0x110043, 0x5a1}, + {0x110143, 0x5a1}, + {0x111043, 0x5a1}, + {0x111143, 0x5a1}, + {0x112043, 0x5a1}, + {0x112143, 0x5a1}, + {0x113043, 0x5a1}, + {0x113143, 0x5a1}, + {0x2200b2, 0xdc}, + {0x210043, 0x5a1}, + {0x210143, 0x5a1}, + {0x211043, 0x5a1}, + {0x211143, 0x5a1}, + {0x212043, 0x5a1}, + {0x212143, 0x5a1}, + {0x213043, 0x5a1}, + {0x213143, 0x5a1}, + {0x200fa, 0x1}, + {0x1200fa, 0x1}, + {0x2200fa, 0x1}, + {0x20019, 0x1}, + {0x120019, 0x1}, + {0x220019, 0x1}, + {0x200f0, 0x660}, + {0x200f1, 0x0}, + {0x200f2, 0x4444}, + {0x200f3, 0x8888}, + {0x200f4, 0x5665}, + {0x200f5, 0x0}, + {0x200f6, 0x0}, + {0x200f7, 0xf000}, + {0x20025, 0x0}, + {0x2002d, 0x0}, + {0x12002d, 0x0}, + {0x22002d, 0x0}, + {0x200c7, 0x21}, + {0x1200c7, 0x21}, + {0x2200c7, 0x21}, + {0x200ca, 0x24}, + {0x1200ca, 0x24}, + {0x2200ca, 0x24}, +}; + +/* ddr phy trained csr */ +struct dram_cfg_param ddr_ddrphy_trained_csr[] = { + { 0x200b2, 0x0 }, + { 0x1200b2, 0x0 }, + { 0x2200b2, 0x0 }, + { 0x200cb, 0x0 }, + { 0x10043, 0x0 }, + { 0x110043, 0x0 }, + { 0x210043, 0x0 }, + { 0x10143, 0x0 }, + { 0x110143, 0x0 }, + { 0x210143, 0x0 }, + { 0x11043, 0x0 }, + { 0x111043, 0x0 }, + { 0x211043, 0x0 }, + { 0x11143, 0x0 }, + { 0x111143, 0x0 }, + { 0x211143, 0x0 }, + { 0x12043, 0x0 }, + { 0x112043, 0x0 }, + { 0x212043, 0x0 }, + { 0x12143, 0x0 }, + { 0x112143, 0x0 }, + { 0x212143, 0x0 }, + { 0x13043, 0x0 }, + { 0x113043, 0x0 }, + { 0x213043, 0x0 }, + { 0x13143, 0x0 }, + { 0x113143, 0x0 }, + { 0x213143, 0x0 }, + { 0x80, 0x0 }, + { 0x100080, 0x0 }, + { 0x200080, 0x0 }, + { 0x1080, 0x0 }, + { 0x101080, 0x0 }, + { 0x201080, 0x0 }, + { 0x2080, 0x0 }, + { 0x102080, 0x0 }, + { 0x202080, 0x0 }, + { 0x3080, 0x0 }, + { 0x103080, 0x0 }, + { 0x203080, 0x0 }, + { 0x4080, 0x0 }, + { 0x104080, 0x0 }, + { 0x204080, 0x0 }, + { 0x5080, 0x0 }, + { 0x105080, 0x0 }, + { 0x205080, 0x0 }, + { 0x6080, 0x0 }, + { 0x106080, 0x0 }, + { 0x206080, 0x0 }, + { 0x7080, 0x0 }, + { 0x107080, 0x0 }, + { 0x207080, 0x0 }, + { 0x8080, 0x0 }, + { 0x108080, 0x0 }, + { 0x208080, 0x0 }, + { 0x9080, 0x0 }, + { 0x109080, 0x0 }, + { 0x209080, 0x0 }, + { 0x10080, 0x0 }, + { 0x110080, 0x0 }, + { 0x210080, 0x0 }, + { 0x10180, 0x0 }, + { 0x110180, 0x0 }, + { 0x210180, 0x0 }, + { 0x11080, 0x0 }, + { 0x111080, 0x0 }, + { 0x211080, 0x0 }, + { 0x11180, 0x0 }, + { 0x111180, 0x0 }, + { 0x211180, 0x0 }, + { 0x12080, 0x0 }, + { 0x112080, 0x0 }, + { 0x212080, 0x0 }, + { 0x12180, 0x0 }, + { 0x112180, 0x0 }, + { 0x212180, 0x0 }, + { 0x13080, 0x0 }, + { 0x113080, 0x0 }, + { 0x213080, 0x0 }, + { 0x13180, 0x0 }, + { 0x113180, 0x0 }, + { 0x213180, 0x0 }, + { 0x10081, 0x0 }, + { 0x110081, 0x0 }, + { 0x210081, 0x0 }, + { 0x10181, 0x0 }, + { 0x110181, 0x0 }, + { 0x210181, 0x0 }, + { 0x11081, 0x0 }, + { 0x111081, 0x0 }, + { 0x211081, 0x0 }, + { 0x11181, 0x0 }, + { 0x111181, 0x0 }, + { 0x211181, 0x0 }, + { 0x12081, 0x0 }, + { 0x112081, 0x0 }, + { 0x212081, 0x0 }, + { 0x12181, 0x0 }, + { 0x112181, 0x0 }, + { 0x212181, 0x0 }, + { 0x13081, 0x0 }, + { 0x113081, 0x0 }, + { 0x213081, 0x0 }, + { 0x13181, 0x0 }, + { 0x113181, 0x0 }, + { 0x213181, 0x0 }, + { 0x100d0, 0x0 }, + { 0x1100d0, 0x0 }, + { 0x2100d0, 0x0 }, + { 0x101d0, 0x0 }, + { 0x1101d0, 0x0 }, + { 0x2101d0, 0x0 }, + { 0x110d0, 0x0 }, + { 0x1110d0, 0x0 }, + { 0x2110d0, 0x0 }, + { 0x111d0, 0x0 }, + { 0x1111d0, 0x0 }, + { 0x2111d0, 0x0 }, + { 0x120d0, 0x0 }, + { 0x1120d0, 0x0 }, + { 0x2120d0, 0x0 }, + { 0x121d0, 0x0 }, + { 0x1121d0, 0x0 }, + { 0x2121d0, 0x0 }, + { 0x130d0, 0x0 }, + { 0x1130d0, 0x0 }, + { 0x2130d0, 0x0 }, + { 0x131d0, 0x0 }, + { 0x1131d0, 0x0 }, + { 0x2131d0, 0x0 }, + { 0x100d1, 0x0 }, + { 0x1100d1, 0x0 }, + { 0x2100d1, 0x0 }, + { 0x101d1, 0x0 }, + { 0x1101d1, 0x0 }, + { 0x2101d1, 0x0 }, + { 0x110d1, 0x0 }, + { 0x1110d1, 0x0 }, + { 0x2110d1, 0x0 }, + { 0x111d1, 0x0 }, + { 0x1111d1, 0x0 }, + { 0x2111d1, 0x0 }, + { 0x120d1, 0x0 }, + { 0x1120d1, 0x0 }, + { 0x2120d1, 0x0 }, + { 0x121d1, 0x0 }, + { 0x1121d1, 0x0 }, + { 0x2121d1, 0x0 }, + { 0x130d1, 0x0 }, + { 0x1130d1, 0x0 }, + { 0x2130d1, 0x0 }, + { 0x131d1, 0x0 }, + { 0x1131d1, 0x0 }, + { 0x2131d1, 0x0 }, + { 0x10068, 0x0 }, + { 0x10168, 0x0 }, + { 0x10268, 0x0 }, + { 0x10368, 0x0 }, + { 0x10468, 0x0 }, + { 0x10568, 0x0 }, + { 0x10668, 0x0 }, + { 0x10768, 0x0 }, + { 0x10868, 0x0 }, + { 0x11068, 0x0 }, + { 0x11168, 0x0 }, + { 0x11268, 0x0 }, + { 0x11368, 0x0 }, + { 0x11468, 0x0 }, + { 0x11568, 0x0 }, + { 0x11668, 0x0 }, + { 0x11768, 0x0 }, + { 0x11868, 0x0 }, + { 0x12068, 0x0 }, + { 0x12168, 0x0 }, + { 0x12268, 0x0 }, + { 0x12368, 0x0 }, + { 0x12468, 0x0 }, + { 0x12568, 0x0 }, + { 0x12668, 0x0 }, + { 0x12768, 0x0 }, + { 0x12868, 0x0 }, + { 0x13068, 0x0 }, + { 0x13168, 0x0 }, + { 0x13268, 0x0 }, + { 0x13368, 0x0 }, + { 0x13468, 0x0 }, + { 0x13568, 0x0 }, + { 0x13668, 0x0 }, + { 0x13768, 0x0 }, + { 0x13868, 0x0 }, + { 0x10069, 0x0 }, + { 0x10169, 0x0 }, + { 0x10269, 0x0 }, + { 0x10369, 0x0 }, + { 0x10469, 0x0 }, + { 0x10569, 0x0 }, + { 0x10669, 0x0 }, + { 0x10769, 0x0 }, + { 0x10869, 0x0 }, + { 0x11069, 0x0 }, + { 0x11169, 0x0 }, + { 0x11269, 0x0 }, + { 0x11369, 0x0 }, + { 0x11469, 0x0 }, + { 0x11569, 0x0 }, + { 0x11669, 0x0 }, + { 0x11769, 0x0 }, + { 0x11869, 0x0 }, + { 0x12069, 0x0 }, + { 0x12169, 0x0 }, + { 0x12269, 0x0 }, + { 0x12369, 0x0 }, + { 0x12469, 0x0 }, + { 0x12569, 0x0 }, + { 0x12669, 0x0 }, + { 0x12769, 0x0 }, + { 0x12869, 0x0 }, + { 0x13069, 0x0 }, + { 0x13169, 0x0 }, + { 0x13269, 0x0 }, + { 0x13369, 0x0 }, + { 0x13469, 0x0 }, + { 0x13569, 0x0 }, + { 0x13669, 0x0 }, + { 0x13769, 0x0 }, + { 0x13869, 0x0 }, + { 0x1008c, 0x0 }, + { 0x11008c, 0x0 }, + { 0x21008c, 0x0 }, + { 0x1018c, 0x0 }, + { 0x11018c, 0x0 }, + { 0x21018c, 0x0 }, + { 0x1108c, 0x0 }, + { 0x11108c, 0x0 }, + { 0x21108c, 0x0 }, + { 0x1118c, 0x0 }, + { 0x11118c, 0x0 }, + { 0x21118c, 0x0 }, + { 0x1208c, 0x0 }, + { 0x11208c, 0x0 }, + { 0x21208c, 0x0 }, + { 0x1218c, 0x0 }, + { 0x11218c, 0x0 }, + { 0x21218c, 0x0 }, + { 0x1308c, 0x0 }, + { 0x11308c, 0x0 }, + { 0x21308c, 0x0 }, + { 0x1318c, 0x0 }, + { 0x11318c, 0x0 }, + { 0x21318c, 0x0 }, + { 0x1008d, 0x0 }, + { 0x11008d, 0x0 }, + { 0x21008d, 0x0 }, + { 0x1018d, 0x0 }, + { 0x11018d, 0x0 }, + { 0x21018d, 0x0 }, + { 0x1108d, 0x0 }, + { 0x11108d, 0x0 }, + { 0x21108d, 0x0 }, + { 0x1118d, 0x0 }, + { 0x11118d, 0x0 }, + { 0x21118d, 0x0 }, + { 0x1208d, 0x0 }, + { 0x11208d, 0x0 }, + { 0x21208d, 0x0 }, + { 0x1218d, 0x0 }, + { 0x11218d, 0x0 }, + { 0x21218d, 0x0 }, + { 0x1308d, 0x0 }, + { 0x11308d, 0x0 }, + { 0x21308d, 0x0 }, + { 0x1318d, 0x0 }, + { 0x11318d, 0x0 }, + { 0x21318d, 0x0 }, + { 0x100c0, 0x0 }, + { 0x1100c0, 0x0 }, + { 0x2100c0, 0x0 }, + { 0x101c0, 0x0 }, + { 0x1101c0, 0x0 }, + { 0x2101c0, 0x0 }, + { 0x102c0, 0x0 }, + { 0x1102c0, 0x0 }, + { 0x2102c0, 0x0 }, + { 0x103c0, 0x0 }, + { 0x1103c0, 0x0 }, + { 0x2103c0, 0x0 }, + { 0x104c0, 0x0 }, + { 0x1104c0, 0x0 }, + { 0x2104c0, 0x0 }, + { 0x105c0, 0x0 }, + { 0x1105c0, 0x0 }, + { 0x2105c0, 0x0 }, + { 0x106c0, 0x0 }, + { 0x1106c0, 0x0 }, + { 0x2106c0, 0x0 }, + { 0x107c0, 0x0 }, + { 0x1107c0, 0x0 }, + { 0x2107c0, 0x0 }, + { 0x108c0, 0x0 }, + { 0x1108c0, 0x0 }, + { 0x2108c0, 0x0 }, + { 0x110c0, 0x0 }, + { 0x1110c0, 0x0 }, + { 0x2110c0, 0x0 }, + { 0x111c0, 0x0 }, + { 0x1111c0, 0x0 }, + { 0x2111c0, 0x0 }, + { 0x112c0, 0x0 }, + { 0x1112c0, 0x0 }, + { 0x2112c0, 0x0 }, + { 0x113c0, 0x0 }, + { 0x1113c0, 0x0 }, + { 0x2113c0, 0x0 }, + { 0x114c0, 0x0 }, + { 0x1114c0, 0x0 }, + { 0x2114c0, 0x0 }, + { 0x115c0, 0x0 }, + { 0x1115c0, 0x0 }, + { 0x2115c0, 0x0 }, + { 0x116c0, 0x0 }, + { 0x1116c0, 0x0 }, + { 0x2116c0, 0x0 }, + { 0x117c0, 0x0 }, + { 0x1117c0, 0x0 }, + { 0x2117c0, 0x0 }, + { 0x118c0, 0x0 }, + { 0x1118c0, 0x0 }, + { 0x2118c0, 0x0 }, + { 0x120c0, 0x0 }, + { 0x1120c0, 0x0 }, + { 0x2120c0, 0x0 }, + { 0x121c0, 0x0 }, + { 0x1121c0, 0x0 }, + { 0x2121c0, 0x0 }, + { 0x122c0, 0x0 }, + { 0x1122c0, 0x0 }, + { 0x2122c0, 0x0 }, + { 0x123c0, 0x0 }, + { 0x1123c0, 0x0 }, + { 0x2123c0, 0x0 }, + { 0x124c0, 0x0 }, + { 0x1124c0, 0x0 }, + { 0x2124c0, 0x0 }, + { 0x125c0, 0x0 }, + { 0x1125c0, 0x0 }, + { 0x2125c0, 0x0 }, + { 0x126c0, 0x0 }, + { 0x1126c0, 0x0 }, + { 0x2126c0, 0x0 }, + { 0x127c0, 0x0 }, + { 0x1127c0, 0x0 }, + { 0x2127c0, 0x0 }, + { 0x128c0, 0x0 }, + { 0x1128c0, 0x0 }, + { 0x2128c0, 0x0 }, + { 0x130c0, 0x0 }, + { 0x1130c0, 0x0 }, + { 0x2130c0, 0x0 }, + { 0x131c0, 0x0 }, + { 0x1131c0, 0x0 }, + { 0x2131c0, 0x0 }, + { 0x132c0, 0x0 }, + { 0x1132c0, 0x0 }, + { 0x2132c0, 0x0 }, + { 0x133c0, 0x0 }, + { 0x1133c0, 0x0 }, + { 0x2133c0, 0x0 }, + { 0x134c0, 0x0 }, + { 0x1134c0, 0x0 }, + { 0x2134c0, 0x0 }, + { 0x135c0, 0x0 }, + { 0x1135c0, 0x0 }, + { 0x2135c0, 0x0 }, + { 0x136c0, 0x0 }, + { 0x1136c0, 0x0 }, + { 0x2136c0, 0x0 }, + { 0x137c0, 0x0 }, + { 0x1137c0, 0x0 }, + { 0x2137c0, 0x0 }, + { 0x138c0, 0x0 }, + { 0x1138c0, 0x0 }, + { 0x2138c0, 0x0 }, + { 0x100c1, 0x0 }, + { 0x1100c1, 0x0 }, + { 0x2100c1, 0x0 }, + { 0x101c1, 0x0 }, + { 0x1101c1, 0x0 }, + { 0x2101c1, 0x0 }, + { 0x102c1, 0x0 }, + { 0x1102c1, 0x0 }, + { 0x2102c1, 0x0 }, + { 0x103c1, 0x0 }, + { 0x1103c1, 0x0 }, + { 0x2103c1, 0x0 }, + { 0x104c1, 0x0 }, + { 0x1104c1, 0x0 }, + { 0x2104c1, 0x0 }, + { 0x105c1, 0x0 }, + { 0x1105c1, 0x0 }, + { 0x2105c1, 0x0 }, + { 0x106c1, 0x0 }, + { 0x1106c1, 0x0 }, + { 0x2106c1, 0x0 }, + { 0x107c1, 0x0 }, + { 0x1107c1, 0x0 }, + { 0x2107c1, 0x0 }, + { 0x108c1, 0x0 }, + { 0x1108c1, 0x0 }, + { 0x2108c1, 0x0 }, + { 0x110c1, 0x0 }, + { 0x1110c1, 0x0 }, + { 0x2110c1, 0x0 }, + { 0x111c1, 0x0 }, + { 0x1111c1, 0x0 }, + { 0x2111c1, 0x0 }, + { 0x112c1, 0x0 }, + { 0x1112c1, 0x0 }, + { 0x2112c1, 0x0 }, + { 0x113c1, 0x0 }, + { 0x1113c1, 0x0 }, + { 0x2113c1, 0x0 }, + { 0x114c1, 0x0 }, + { 0x1114c1, 0x0 }, + { 0x2114c1, 0x0 }, + { 0x115c1, 0x0 }, + { 0x1115c1, 0x0 }, + { 0x2115c1, 0x0 }, + { 0x116c1, 0x0 }, + { 0x1116c1, 0x0 }, + { 0x2116c1, 0x0 }, + { 0x117c1, 0x0 }, + { 0x1117c1, 0x0 }, + { 0x2117c1, 0x0 }, + { 0x118c1, 0x0 }, + { 0x1118c1, 0x0 }, + { 0x2118c1, 0x0 }, + { 0x120c1, 0x0 }, + { 0x1120c1, 0x0 }, + { 0x2120c1, 0x0 }, + { 0x121c1, 0x0 }, + { 0x1121c1, 0x0 }, + { 0x2121c1, 0x0 }, + { 0x122c1, 0x0 }, + { 0x1122c1, 0x0 }, + { 0x2122c1, 0x0 }, + { 0x123c1, 0x0 }, + { 0x1123c1, 0x0 }, + { 0x2123c1, 0x0 }, + { 0x124c1, 0x0 }, + { 0x1124c1, 0x0 }, + { 0x2124c1, 0x0 }, + { 0x125c1, 0x0 }, + { 0x1125c1, 0x0 }, + { 0x2125c1, 0x0 }, + { 0x126c1, 0x0 }, + { 0x1126c1, 0x0 }, + { 0x2126c1, 0x0 }, + { 0x127c1, 0x0 }, + { 0x1127c1, 0x0 }, + { 0x2127c1, 0x0 }, + { 0x128c1, 0x0 }, + { 0x1128c1, 0x0 }, + { 0x2128c1, 0x0 }, + { 0x130c1, 0x0 }, + { 0x1130c1, 0x0 }, + { 0x2130c1, 0x0 }, + { 0x131c1, 0x0 }, + { 0x1131c1, 0x0 }, + { 0x2131c1, 0x0 }, + { 0x132c1, 0x0 }, + { 0x1132c1, 0x0 }, + { 0x2132c1, 0x0 }, + { 0x133c1, 0x0 }, + { 0x1133c1, 0x0 }, + { 0x2133c1, 0x0 }, + { 0x134c1, 0x0 }, + { 0x1134c1, 0x0 }, + { 0x2134c1, 0x0 }, + { 0x135c1, 0x0 }, + { 0x1135c1, 0x0 }, + { 0x2135c1, 0x0 }, + { 0x136c1, 0x0 }, + { 0x1136c1, 0x0 }, + { 0x2136c1, 0x0 }, + { 0x137c1, 0x0 }, + { 0x1137c1, 0x0 }, + { 0x2137c1, 0x0 }, + { 0x138c1, 0x0 }, + { 0x1138c1, 0x0 }, + { 0x2138c1, 0x0 }, + { 0x10020, 0x0 }, + { 0x110020, 0x0 }, + { 0x210020, 0x0 }, + { 0x11020, 0x0 }, + { 0x111020, 0x0 }, + { 0x211020, 0x0 }, + { 0x12020, 0x0 }, + { 0x112020, 0x0 }, + { 0x212020, 0x0 }, + { 0x13020, 0x0 }, + { 0x113020, 0x0 }, + { 0x213020, 0x0 }, + { 0x20072, 0x0 }, + { 0x20073, 0x0 }, + { 0x20074, 0x0 }, + { 0x100aa, 0x0 }, + { 0x110aa, 0x0 }, + { 0x120aa, 0x0 }, + { 0x130aa, 0x0 }, + { 0x20010, 0x0 }, + { 0x120010, 0x0 }, + { 0x220010, 0x0 }, + { 0x20011, 0x0 }, + { 0x120011, 0x0 }, + { 0x220011, 0x0 }, + { 0x100ae, 0x0 }, + { 0x1100ae, 0x0 }, + { 0x2100ae, 0x0 }, + { 0x100af, 0x0 }, + { 0x1100af, 0x0 }, + { 0x2100af, 0x0 }, + { 0x110ae, 0x0 }, + { 0x1110ae, 0x0 }, + { 0x2110ae, 0x0 }, + { 0x110af, 0x0 }, + { 0x1110af, 0x0 }, + { 0x2110af, 0x0 }, + { 0x120ae, 0x0 }, + { 0x1120ae, 0x0 }, + { 0x2120ae, 0x0 }, + { 0x120af, 0x0 }, + { 0x1120af, 0x0 }, + { 0x2120af, 0x0 }, + { 0x130ae, 0x0 }, + { 0x1130ae, 0x0 }, + { 0x2130ae, 0x0 }, + { 0x130af, 0x0 }, + { 0x1130af, 0x0 }, + { 0x2130af, 0x0 }, + { 0x20020, 0x0 }, + { 0x120020, 0x0 }, + { 0x220020, 0x0 }, + { 0x100a0, 0x0 }, + { 0x100a1, 0x0 }, + { 0x100a2, 0x0 }, + { 0x100a3, 0x0 }, + { 0x100a4, 0x0 }, + { 0x100a5, 0x0 }, + { 0x100a6, 0x0 }, + { 0x100a7, 0x0 }, + { 0x110a0, 0x0 }, + { 0x110a1, 0x0 }, + { 0x110a2, 0x0 }, + { 0x110a3, 0x0 }, + { 0x110a4, 0x0 }, + { 0x110a5, 0x0 }, + { 0x110a6, 0x0 }, + { 0x110a7, 0x0 }, + { 0x120a0, 0x0 }, + { 0x120a1, 0x0 }, + { 0x120a2, 0x0 }, + { 0x120a3, 0x0 }, + { 0x120a4, 0x0 }, + { 0x120a5, 0x0 }, + { 0x120a6, 0x0 }, + { 0x120a7, 0x0 }, + { 0x130a0, 0x0 }, + { 0x130a1, 0x0 }, + { 0x130a2, 0x0 }, + { 0x130a3, 0x0 }, + { 0x130a4, 0x0 }, + { 0x130a5, 0x0 }, + { 0x130a6, 0x0 }, + { 0x130a7, 0x0 }, + { 0x2007c, 0x0 }, + { 0x12007c, 0x0 }, + { 0x22007c, 0x0 }, + { 0x2007d, 0x0 }, + { 0x12007d, 0x0 }, + { 0x22007d, 0x0 }, + { 0x400fd, 0x0 }, + { 0x400c0, 0x0 }, + { 0x90201, 0x0 }, + { 0x190201, 0x0 }, + { 0x290201, 0x0 }, + { 0x90202, 0x0 }, + { 0x190202, 0x0 }, + { 0x290202, 0x0 }, + { 0x90203, 0x0 }, + { 0x190203, 0x0 }, + { 0x290203, 0x0 }, + { 0x90204, 0x0 }, + { 0x190204, 0x0 }, + { 0x290204, 0x0 }, + { 0x90205, 0x0 }, + { 0x190205, 0x0 }, + { 0x290205, 0x0 }, + { 0x90206, 0x0 }, + { 0x190206, 0x0 }, + { 0x290206, 0x0 }, + { 0x90207, 0x0 }, + { 0x190207, 0x0 }, + { 0x290207, 0x0 }, + { 0x90208, 0x0 }, + { 0x190208, 0x0 }, + { 0x290208, 0x0 }, + { 0x10062, 0x0 }, + { 0x10162, 0x0 }, + { 0x10262, 0x0 }, + { 0x10362, 0x0 }, + { 0x10462, 0x0 }, + { 0x10562, 0x0 }, + { 0x10662, 0x0 }, + { 0x10762, 0x0 }, + { 0x10862, 0x0 }, + { 0x11062, 0x0 }, + { 0x11162, 0x0 }, + { 0x11262, 0x0 }, + { 0x11362, 0x0 }, + { 0x11462, 0x0 }, + { 0x11562, 0x0 }, + { 0x11662, 0x0 }, + { 0x11762, 0x0 }, + { 0x11862, 0x0 }, + { 0x12062, 0x0 }, + { 0x12162, 0x0 }, + { 0x12262, 0x0 }, + { 0x12362, 0x0 }, + { 0x12462, 0x0 }, + { 0x12562, 0x0 }, + { 0x12662, 0x0 }, + { 0x12762, 0x0 }, + { 0x12862, 0x0 }, + { 0x13062, 0x0 }, + { 0x13162, 0x0 }, + { 0x13262, 0x0 }, + { 0x13362, 0x0 }, + { 0x13462, 0x0 }, + { 0x13562, 0x0 }, + { 0x13662, 0x0 }, + { 0x13762, 0x0 }, + { 0x13862, 0x0 }, + { 0x20077, 0x0 }, + { 0x10001, 0x0 }, + { 0x11001, 0x0 }, + { 0x12001, 0x0 }, + { 0x13001, 0x0 }, + { 0x10040, 0x0 }, + { 0x10140, 0x0 }, + { 0x10240, 0x0 }, + { 0x10340, 0x0 }, + { 0x10440, 0x0 }, + { 0x10540, 0x0 }, + { 0x10640, 0x0 }, + { 0x10740, 0x0 }, + { 0x10840, 0x0 }, + { 0x10030, 0x0 }, + { 0x10130, 0x0 }, + { 0x10230, 0x0 }, + { 0x10330, 0x0 }, + { 0x10430, 0x0 }, + { 0x10530, 0x0 }, + { 0x10630, 0x0 }, + { 0x10730, 0x0 }, + { 0x10830, 0x0 }, + { 0x11040, 0x0 }, + { 0x11140, 0x0 }, + { 0x11240, 0x0 }, + { 0x11340, 0x0 }, + { 0x11440, 0x0 }, + { 0x11540, 0x0 }, + { 0x11640, 0x0 }, + { 0x11740, 0x0 }, + { 0x11840, 0x0 }, + { 0x11030, 0x0 }, + { 0x11130, 0x0 }, + { 0x11230, 0x0 }, + { 0x11330, 0x0 }, + { 0x11430, 0x0 }, + { 0x11530, 0x0 }, + { 0x11630, 0x0 }, + { 0x11730, 0x0 }, + { 0x11830, 0x0 }, + { 0x12040, 0x0 }, + { 0x12140, 0x0 }, + { 0x12240, 0x0 }, + { 0x12340, 0x0 }, + { 0x12440, 0x0 }, + { 0x12540, 0x0 }, + { 0x12640, 0x0 }, + { 0x12740, 0x0 }, + { 0x12840, 0x0 }, + { 0x12030, 0x0 }, + { 0x12130, 0x0 }, + { 0x12230, 0x0 }, + { 0x12330, 0x0 }, + { 0x12430, 0x0 }, + { 0x12530, 0x0 }, + { 0x12630, 0x0 }, + { 0x12730, 0x0 }, + { 0x12830, 0x0 }, + { 0x13040, 0x0 }, + { 0x13140, 0x0 }, + { 0x13240, 0x0 }, + { 0x13340, 0x0 }, + { 0x13440, 0x0 }, + { 0x13540, 0x0 }, + { 0x13640, 0x0 }, + { 0x13740, 0x0 }, + { 0x13840, 0x0 }, + { 0x13030, 0x0 }, + { 0x13130, 0x0 }, + { 0x13230, 0x0 }, + { 0x13330, 0x0 }, + { 0x13430, 0x0 }, + { 0x13530, 0x0 }, + { 0x13630, 0x0 }, + { 0x13730, 0x0 }, + { 0x13830, 0x0 }, +}; + +/* P0 message block paremeter for training firmware */ +struct dram_cfg_param ddr_fsp0_cfg[] = { + {0xd0000, 0x0}, + {0x54003, 0xbb8}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x131f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4d66}, + {0x5401c, 0x4d00}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4d66}, + {0x54022, 0x4d00}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x4d}, + {0x54036, 0x4d}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x4d}, + {0x5403c, 0x4d}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P1 message block paremeter for training firmware */ +struct dram_cfg_param ddr_fsp1_cfg[] = { + {0xd0000, 0x0}, + {0x54002, 0x101}, + {0x54003, 0x190}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x121f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x84}, + {0x5401a, 0x31}, + {0x5401b, 0x4d66}, + {0x5401c, 0x4d00}, + {0x5401e, 0x16}, + {0x5401f, 0x84}, + {0x54020, 0x31}, + {0x54021, 0x4d66}, + {0x54022, 0x4d00}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0x8400}, + {0x54033, 0x3100}, + {0x54034, 0x6600}, + {0x54035, 0x4d}, + {0x54036, 0x4d}, + {0x54037, 0x1600}, + {0x54038, 0x8400}, + {0x54039, 0x3100}, + {0x5403a, 0x6600}, + {0x5403b, 0x4d}, + {0x5403c, 0x4d}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P2 message block paremeter for training firmware */ +struct dram_cfg_param ddr_fsp2_cfg[] = { + {0xd0000, 0x0}, + {0x54002, 0x102}, + {0x54003, 0x64}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x121f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x84}, + {0x5401a, 0x31}, + {0x5401b, 0x4d66}, + {0x5401c, 0x4d00}, + {0x5401e, 0x16}, + {0x5401f, 0x84}, + {0x54020, 0x31}, + {0x54021, 0x4d66}, + {0x54022, 0x4d00}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0x8400}, + {0x54033, 0x3100}, + {0x54034, 0x6600}, + {0x54035, 0x4d}, + {0x54036, 0x4d}, + {0x54037, 0x1600}, + {0x54038, 0x8400}, + {0x54039, 0x3100}, + {0x5403a, 0x6600}, + {0x5403b, 0x4d}, + {0x5403c, 0x4d}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P0 2D message block paremeter for training firmware */ +struct dram_cfg_param ddr_fsp0_2d_cfg[] = { + {0xd0000, 0x0}, + {0x54003, 0xbb8}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x61}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400f, 0x100}, + {0x54010, 0x1f7f}, + {0x54012, 0x110}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4d66}, + {0x5401c, 0x4d00}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4d66}, + {0x54022, 0x4d00}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x4d}, + {0x54036, 0x4d}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x4d}, + {0x5403c, 0x4d}, + {0x5403d, 0x1600}, + { 0xd0000, 0x1 }, +}; + +/* DRAM PHY init engine image */ +struct dram_cfg_param ddr_phy_pie[] = { + {0xd0000, 0x0}, + {0x90000, 0x10}, + {0x90001, 0x400}, + {0x90002, 0x10e}, + {0x90003, 0x0}, + {0x90004, 0x0}, + {0x90005, 0x8}, + {0x90029, 0xb}, + {0x9002a, 0x480}, + {0x9002b, 0x109}, + {0x9002c, 0x8}, + {0x9002d, 0x448}, + {0x9002e, 0x139}, + {0x9002f, 0x8}, + {0x90030, 0x478}, + {0x90031, 0x109}, + {0x90032, 0x0}, + {0x90033, 0xe8}, + {0x90034, 0x109}, + {0x90035, 0x2}, + {0x90036, 0x10}, + {0x90037, 0x139}, + {0x90038, 0xf}, + {0x90039, 0x7c0}, + {0x9003a, 0x139}, + {0x9003b, 0x44}, + {0x9003c, 0x630}, + {0x9003d, 0x159}, + {0x9003e, 0x14f}, + {0x9003f, 0x630}, + {0x90040, 0x159}, + {0x90041, 0x47}, + {0x90042, 0x630}, + {0x90043, 0x149}, + {0x90044, 0x4f}, + {0x90045, 0x630}, + {0x90046, 0x179}, + {0x90047, 0x8}, + {0x90048, 0xe0}, + {0x90049, 0x109}, + {0x9004a, 0x0}, + {0x9004b, 0x7c8}, + {0x9004c, 0x109}, + {0x9004d, 0x0}, + {0x9004e, 0x1}, + {0x9004f, 0x8}, + {0x90050, 0x0}, + {0x90051, 0x45a}, + {0x90052, 0x9}, + {0x90053, 0x0}, + {0x90054, 0x448}, + {0x90055, 0x109}, + {0x90056, 0x40}, + {0x90057, 0x630}, + {0x90058, 0x179}, + {0x90059, 0x1}, + {0x9005a, 0x618}, + {0x9005b, 0x109}, + {0x9005c, 0x40c0}, + {0x9005d, 0x630}, + {0x9005e, 0x149}, + {0x9005f, 0x8}, + {0x90060, 0x4}, + {0x90061, 0x48}, + {0x90062, 0x4040}, + {0x90063, 0x630}, + {0x90064, 0x149}, + {0x90065, 0x0}, + {0x90066, 0x4}, + {0x90067, 0x48}, + {0x90068, 0x40}, + {0x90069, 0x630}, + {0x9006a, 0x149}, + {0x9006b, 0x10}, + {0x9006c, 0x4}, + {0x9006d, 0x18}, + {0x9006e, 0x0}, + {0x9006f, 0x4}, + {0x90070, 0x78}, + {0x90071, 0x549}, + {0x90072, 0x630}, + {0x90073, 0x159}, + {0x90074, 0xd49}, + {0x90075, 0x630}, + {0x90076, 0x159}, + {0x90077, 0x94a}, + {0x90078, 0x630}, + {0x90079, 0x159}, + {0x9007a, 0x441}, + {0x9007b, 0x630}, + {0x9007c, 0x149}, + {0x9007d, 0x42}, + {0x9007e, 0x630}, + {0x9007f, 0x149}, + {0x90080, 0x1}, + {0x90081, 0x630}, + {0x90082, 0x149}, + {0x90083, 0x0}, + {0x90084, 0xe0}, + {0x90085, 0x109}, + {0x90086, 0xa}, + {0x90087, 0x10}, + {0x90088, 0x109}, + {0x90089, 0x9}, + {0x9008a, 0x3c0}, + {0x9008b, 0x149}, + {0x9008c, 0x9}, + {0x9008d, 0x3c0}, + {0x9008e, 0x159}, + {0x9008f, 0x18}, + {0x90090, 0x10}, + {0x90091, 0x109}, + {0x90092, 0x0}, + {0x90093, 0x3c0}, + {0x90094, 0x109}, + {0x90095, 0x18}, + {0x90096, 0x4}, + {0x90097, 0x48}, + {0x90098, 0x18}, + {0x90099, 0x4}, + {0x9009a, 0x58}, + {0x9009b, 0xa}, + {0x9009c, 0x10}, + {0x9009d, 0x109}, + {0x9009e, 0x2}, + {0x9009f, 0x10}, + {0x900a0, 0x109}, + {0x900a1, 0x5}, + {0x900a2, 0x7c0}, + {0x900a3, 0x109}, + {0x900a4, 0x10}, + {0x900a5, 0x10}, + {0x900a6, 0x109}, + {0x40000, 0x811}, + {0x40020, 0x880}, + {0x40040, 0x0}, + {0x40060, 0x0}, + {0x40001, 0x4008}, + {0x40021, 0x83}, + {0x40041, 0x4f}, + {0x40061, 0x0}, + {0x40002, 0x4040}, + {0x40022, 0x83}, + {0x40042, 0x51}, + {0x40062, 0x0}, + {0x40003, 0x811}, + {0x40023, 0x880}, + {0x40043, 0x0}, + {0x40063, 0x0}, + {0x40004, 0x720}, + {0x40024, 0xf}, + {0x40044, 0x1740}, + {0x40064, 0x0}, + {0x40005, 0x16}, + {0x40025, 0x83}, + {0x40045, 0x4b}, + {0x40065, 0x0}, + {0x40006, 0x716}, + {0x40026, 0xf}, + {0x40046, 0x2001}, + {0x40066, 0x0}, + {0x40007, 0x716}, + {0x40027, 0xf}, + {0x40047, 0x2800}, + {0x40067, 0x0}, + {0x40008, 0x716}, + {0x40028, 0xf}, + {0x40048, 0xf00}, + {0x40068, 0x0}, + {0x40009, 0x720}, + {0x40029, 0xf}, + {0x40049, 0x1400}, + {0x40069, 0x0}, + {0x4000a, 0xe08}, + {0x4002a, 0xc15}, + {0x4004a, 0x0}, + {0x4006a, 0x0}, + {0x4000b, 0x623}, + {0x4002b, 0x15}, + {0x4004b, 0x0}, + {0x4006b, 0x0}, + {0x4000c, 0x4028}, + {0x4002c, 0x80}, + {0x4004c, 0x0}, + {0x4006c, 0x0}, + {0x4000d, 0xe08}, + {0x4002d, 0xc1a}, + {0x4004d, 0x0}, + {0x4006d, 0x0}, + {0x4000e, 0x623}, + {0x4002e, 0x1a}, + {0x4004e, 0x0}, + {0x4006e, 0x0}, + {0x4000f, 0x4040}, + {0x4002f, 0x80}, + {0x4004f, 0x0}, + {0x4006f, 0x0}, + {0x40010, 0x2604}, + {0x40030, 0x15}, + {0x40050, 0x0}, + {0x40070, 0x0}, + {0x40011, 0x708}, + {0x40031, 0x5}, + {0x40051, 0x0}, + {0x40071, 0x2002}, + {0x40012, 0x8}, + {0x40032, 0x80}, + {0x40052, 0x0}, + {0x40072, 0x0}, + {0x40013, 0x2604}, + {0x40033, 0x1a}, + {0x40053, 0x0}, + {0x40073, 0x0}, + {0x40014, 0x708}, + {0x40034, 0xa}, + {0x40054, 0x0}, + {0x40074, 0x2002}, + {0x40015, 0x4040}, + {0x40035, 0x80}, + {0x40055, 0x0}, + {0x40075, 0x0}, + {0x40016, 0x60a}, + {0x40036, 0x15}, + {0x40056, 0x1200}, + {0x40076, 0x0}, + {0x40017, 0x61a}, + {0x40037, 0x15}, + {0x40057, 0x1300}, + {0x40077, 0x0}, + {0x40018, 0x60a}, + {0x40038, 0x1a}, + {0x40058, 0x1200}, + {0x40078, 0x0}, + {0x40019, 0x642}, + {0x40039, 0x1a}, + {0x40059, 0x1300}, + {0x40079, 0x0}, + {0x4001a, 0x4808}, + {0x4003a, 0x880}, + {0x4005a, 0x0}, + {0x4007a, 0x0}, + {0x900a7, 0x0}, + {0x900a8, 0x790}, + {0x900a9, 0x11a}, + {0x900aa, 0x8}, + {0x900ab, 0x7aa}, + {0x900ac, 0x2a}, + {0x900ad, 0x10}, + {0x900ae, 0x7b2}, + {0x900af, 0x2a}, + {0x900b0, 0x0}, + {0x900b1, 0x7c8}, + {0x900b2, 0x109}, + {0x900b3, 0x10}, + {0x900b4, 0x2a8}, + {0x900b5, 0x129}, + {0x900b6, 0x8}, + {0x900b7, 0x370}, + {0x900b8, 0x129}, + {0x900b9, 0xa}, + {0x900ba, 0x3c8}, + {0x900bb, 0x1a9}, + {0x900bc, 0xc}, + {0x900bd, 0x408}, + {0x900be, 0x199}, + {0x900bf, 0x14}, + {0x900c0, 0x790}, + {0x900c1, 0x11a}, + {0x900c2, 0x8}, + {0x900c3, 0x4}, + {0x900c4, 0x18}, + {0x900c5, 0xe}, + {0x900c6, 0x408}, + {0x900c7, 0x199}, + {0x900c8, 0x8}, + {0x900c9, 0x8568}, + {0x900ca, 0x108}, + {0x900cb, 0x18}, + {0x900cc, 0x790}, + {0x900cd, 0x16a}, + {0x900ce, 0x8}, + {0x900cf, 0x1d8}, + {0x900d0, 0x169}, + {0x900d1, 0x10}, + {0x900d2, 0x8558}, + {0x900d3, 0x168}, + {0x900d4, 0x70}, + {0x900d5, 0x788}, + {0x900d6, 0x16a}, + {0x900d7, 0x1ff8}, + {0x900d8, 0x85a8}, + {0x900d9, 0x1e8}, + {0x900da, 0x50}, + {0x900db, 0x798}, + {0x900dc, 0x16a}, + {0x900dd, 0x60}, + {0x900de, 0x7a0}, + {0x900df, 0x16a}, + {0x900e0, 0x8}, + {0x900e1, 0x8310}, + {0x900e2, 0x168}, + {0x900e3, 0x8}, + {0x900e4, 0xa310}, + {0x900e5, 0x168}, + {0x900e6, 0xa}, + {0x900e7, 0x408}, + {0x900e8, 0x169}, + {0x900e9, 0x6e}, + {0x900ea, 0x0}, + {0x900eb, 0x68}, + {0x900ec, 0x0}, + {0x900ed, 0x408}, + {0x900ee, 0x169}, + {0x900ef, 0x0}, + {0x900f0, 0x8310}, + {0x900f1, 0x168}, + {0x900f2, 0x0}, + {0x900f3, 0xa310}, + {0x900f4, 0x168}, + {0x900f5, 0x1ff8}, + {0x900f6, 0x85a8}, + {0x900f7, 0x1e8}, + {0x900f8, 0x68}, + {0x900f9, 0x798}, + {0x900fa, 0x16a}, + {0x900fb, 0x78}, + {0x900fc, 0x7a0}, + {0x900fd, 0x16a}, + {0x900fe, 0x68}, + {0x900ff, 0x790}, + {0x90100, 0x16a}, + {0x90101, 0x8}, + {0x90102, 0x8b10}, + {0x90103, 0x168}, + {0x90104, 0x8}, + {0x90105, 0xab10}, + {0x90106, 0x168}, + {0x90107, 0xa}, + {0x90108, 0x408}, + {0x90109, 0x169}, + {0x9010a, 0x58}, + {0x9010b, 0x0}, + {0x9010c, 0x68}, + {0x9010d, 0x0}, + {0x9010e, 0x408}, + {0x9010f, 0x169}, + {0x90110, 0x0}, + {0x90111, 0x8b10}, + {0x90112, 0x168}, + {0x90113, 0x0}, + {0x90114, 0xab10}, + {0x90115, 0x168}, + {0x90116, 0x0}, + {0x90117, 0x1d8}, + {0x90118, 0x169}, + {0x90119, 0x80}, + {0x9011a, 0x790}, + {0x9011b, 0x16a}, + {0x9011c, 0x18}, + {0x9011d, 0x7aa}, + {0x9011e, 0x6a}, + {0x9011f, 0xa}, + {0x90120, 0x0}, + {0x90121, 0x1e9}, + {0x90122, 0x8}, + {0x90123, 0x8080}, + {0x90124, 0x108}, + {0x90125, 0xf}, + {0x90126, 0x408}, + {0x90127, 0x169}, + {0x90128, 0xc}, + {0x90129, 0x0}, + {0x9012a, 0x68}, + {0x9012b, 0x9}, + {0x9012c, 0x0}, + {0x9012d, 0x1a9}, + {0x9012e, 0x0}, + {0x9012f, 0x408}, + {0x90130, 0x169}, + {0x90131, 0x0}, + {0x90132, 0x8080}, + {0x90133, 0x108}, + {0x90134, 0x8}, + {0x90135, 0x7aa}, + {0x90136, 0x6a}, + {0x90137, 0x0}, + {0x90138, 0x8568}, + {0x90139, 0x108}, + {0x9013a, 0xb7}, + {0x9013b, 0x790}, + {0x9013c, 0x16a}, + {0x9013d, 0x1f}, + {0x9013e, 0x0}, + {0x9013f, 0x68}, + {0x90140, 0x8}, + {0x90141, 0x8558}, + {0x90142, 0x168}, + {0x90143, 0xf}, + {0x90144, 0x408}, + {0x90145, 0x169}, + {0x90146, 0xc}, + {0x90147, 0x0}, + {0x90148, 0x68}, + {0x90149, 0x0}, + {0x9014a, 0x408}, + {0x9014b, 0x169}, + {0x9014c, 0x0}, + {0x9014d, 0x8558}, + {0x9014e, 0x168}, + {0x9014f, 0x8}, + {0x90150, 0x3c8}, + {0x90151, 0x1a9}, + {0x90152, 0x3}, + {0x90153, 0x370}, + {0x90154, 0x129}, + {0x90155, 0x20}, + {0x90156, 0x2aa}, + {0x90157, 0x9}, + {0x90158, 0x0}, + {0x90159, 0x400}, + {0x9015a, 0x10e}, + {0x9015b, 0x8}, + {0x9015c, 0xe8}, + {0x9015d, 0x109}, + {0x9015e, 0x0}, + {0x9015f, 0x8140}, + {0x90160, 0x10c}, + {0x90161, 0x10}, + {0x90162, 0x8138}, + {0x90163, 0x10c}, + {0x90164, 0x8}, + {0x90165, 0x7c8}, + {0x90166, 0x101}, + {0x90167, 0x8}, + {0x90168, 0x0}, + {0x90169, 0x8}, + {0x9016a, 0x8}, + {0x9016b, 0x448}, + {0x9016c, 0x109}, + {0x9016d, 0xf}, + {0x9016e, 0x7c0}, + {0x9016f, 0x109}, + {0x90170, 0x0}, + {0x90171, 0xe8}, + {0x90172, 0x109}, + {0x90173, 0x47}, + {0x90174, 0x630}, + {0x90175, 0x109}, + {0x90176, 0x8}, + {0x90177, 0x618}, + {0x90178, 0x109}, + {0x90179, 0x8}, + {0x9017a, 0xe0}, + {0x9017b, 0x109}, + {0x9017c, 0x0}, + {0x9017d, 0x7c8}, + {0x9017e, 0x109}, + {0x9017f, 0x8}, + {0x90180, 0x8140}, + {0x90181, 0x10c}, + {0x90182, 0x0}, + {0x90183, 0x1}, + {0x90184, 0x8}, + {0x90185, 0x8}, + {0x90186, 0x4}, + {0x90187, 0x8}, + {0x90188, 0x8}, + {0x90189, 0x7c8}, + {0x9018a, 0x101}, + {0x90006, 0x0}, + {0x90007, 0x0}, + {0x90008, 0x8}, + {0x90009, 0x0}, + {0x9000a, 0x0}, + {0x9000b, 0x0}, + {0xd00e7, 0x400}, + {0x90017, 0x0}, + {0x9001f, 0x2a}, + {0x90026, 0x6a}, + {0x400d0, 0x0}, + {0x400d1, 0x101}, + {0x400d2, 0x105}, + {0x400d3, 0x107}, + {0x400d4, 0x10f}, + {0x400d5, 0x202}, + {0x400d6, 0x20a}, + {0x400d7, 0x20b}, + {0x2003a, 0x2}, + {0x2000b, 0x5d}, + {0x2000c, 0xbb}, + {0x2000d, 0x753}, + {0x2000e, 0x2c}, + {0x12000b, 0xc}, + {0x12000c, 0x19}, + {0x12000d, 0xfa}, + {0x12000e, 0x10}, + {0x22000b, 0x3}, + {0x22000c, 0x6}, + {0x22000d, 0x3e}, + {0x22000e, 0x10}, + {0x9000c, 0x0}, + {0x9000d, 0x173}, + {0x9000e, 0x60}, + {0x9000f, 0x6110}, + {0x90010, 0x2152}, + {0x90011, 0xdfbd}, + {0x90012, 0x60}, + {0x90013, 0x6152}, + {0x20010, 0x5a}, + {0x20011, 0x3}, + {0x120010, 0x5a}, + {0x120011, 0x3}, + {0x220010, 0x5a}, + {0x220011, 0x3}, + {0x40080, 0xe0}, + {0x40081, 0x12}, + {0x40082, 0xe0}, + {0x40083, 0x12}, + {0x40084, 0xe0}, + {0x40085, 0x12}, + {0x140080, 0xe0}, + {0x140081, 0x12}, + {0x140082, 0xe0}, + {0x140083, 0x12}, + {0x140084, 0xe0}, + {0x140085, 0x12}, + {0x240080, 0xe0}, + {0x240081, 0x12}, + {0x240082, 0xe0}, + {0x240083, 0x12}, + {0x240084, 0xe0}, + {0x240085, 0x12}, + {0x400fd, 0xf}, + {0x10011, 0x1}, + {0x10012, 0x1}, + {0x10013, 0x180}, + {0x10018, 0x1}, + {0x10002, 0x6209}, + {0x100b2, 0x1}, + {0x101b4, 0x1}, + {0x102b4, 0x1}, + {0x103b4, 0x1}, + {0x104b4, 0x1}, + {0x105b4, 0x1}, + {0x106b4, 0x1}, + {0x107b4, 0x1}, + {0x108b4, 0x1}, + {0x11011, 0x1}, + {0x11012, 0x1}, + {0x11013, 0x180}, + {0x11018, 0x1}, + {0x11002, 0x6209}, + {0x110b2, 0x1}, + {0x111b4, 0x1}, + {0x112b4, 0x1}, + {0x113b4, 0x1}, + {0x114b4, 0x1}, + {0x115b4, 0x1}, + {0x116b4, 0x1}, + {0x117b4, 0x1}, + {0x118b4, 0x1}, + {0x12011, 0x1}, + {0x12012, 0x1}, + {0x12013, 0x180}, + {0x12018, 0x1}, + {0x12002, 0x6209}, + {0x120b2, 0x1}, + {0x121b4, 0x1}, + {0x122b4, 0x1}, + {0x123b4, 0x1}, + {0x124b4, 0x1}, + {0x125b4, 0x1}, + {0x126b4, 0x1}, + {0x127b4, 0x1}, + {0x128b4, 0x1}, + {0x13011, 0x1}, + {0x13012, 0x1}, + {0x13013, 0x180}, + {0x13018, 0x1}, + {0x13002, 0x6209}, + {0x130b2, 0x1}, + {0x131b4, 0x1}, + {0x132b4, 0x1}, + {0x133b4, 0x1}, + {0x134b4, 0x1}, + {0x135b4, 0x1}, + {0x136b4, 0x1}, + {0x137b4, 0x1}, + {0x138b4, 0x1}, + {0x2003a, 0x2}, + {0xc0080, 0x2}, + {0xd0000, 0x1} +}; + +struct dram_fsp_msg ddr_dram_fsp_msg[] = { + { + /* P0 3000mts 1D */ + .drate = 3000, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), + }, + { + /* P1 400mts 1D */ + .drate = 400, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), + }, + { + /* P2 100mts 1D */ + .drate = 100, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp2_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg), + }, + { + /* P0 3000mts 2D */ + .drate = 3000, + .fw_type = FW_2D_IMAGE, + .fsp_cfg = ddr_fsp0_2d_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg), + }, +}; + +/* ddr timing config params */ +struct dram_timing_info dram_timing = { + .ddrc_cfg = ddr_ddrc_cfg, + .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), + .ddrphy_cfg = ddr_ddrphy_cfg, + .ddrphy_cfg_num = ARRAY_SIZE(ddr_ddrphy_cfg), + .fsp_msg = ddr_dram_fsp_msg, + .fsp_msg_num = ARRAY_SIZE(ddr_dram_fsp_msg), + .ddrphy_trained_csr = ddr_ddrphy_trained_csr, + .ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr), + .ddrphy_pie = ddr_phy_pie, + .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie), + .fsp_table = { 3000, 400, 100, }, +}; diff --git a/roms/u-boot/board/toradex/verdin-imx8mm/spl.c b/roms/u-boot/board/toradex/verdin-imx8mm/spl.c new file mode 100644 index 000000000..97d6a31da --- /dev/null +++ b/roms/u-boot/board/toradex/verdin-imx8mm/spl.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Toradex + */ + +#include <common.h> +#include <command.h> +#include <image.h> +#include <init.h> +#include <log.h> +#include <asm/arch/clock.h> +#include <asm/arch/ddr.h> +#include <asm/arch/imx8mm_pins.h> +#include <asm/arch/sys_proto.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/iomux-v3.h> +#include <cpu_func.h> +#include <dm/device.h> +#include <dm/device-internal.h> +#include <dm/uclass.h> +#include <dm/uclass-internal.h> +#include <hang.h> +#include <i2c.h> +#include <power/bd71837.h> +#include <power/pca9450.h> +#include <power/pmic.h> +#include <spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define I2C_PMIC_BUS_ID 1 + +int spl_board_boot_device(enum boot_device boot_dev_spl) +{ + switch (boot_dev_spl) { + case MMC1_BOOT: + return BOOT_DEVICE_MMC1; + case SD2_BOOT: + case MMC2_BOOT: + return BOOT_DEVICE_MMC2; + case SD3_BOOT: + case MMC3_BOOT: + return BOOT_DEVICE_MMC1; + case USB_BOOT: + return BOOT_DEVICE_BOARD; + default: + return BOOT_DEVICE_NONE; + } +} + +void spl_dram_init(void) +{ + ddr_init(&dram_timing); +} + +void spl_board_init(void) +{ + /* Serial download mode */ + if (is_usb_boot()) { + puts("Back to ROM, SDP\n"); + restore_boot_params(); + } + puts("Normal Boot\n"); +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif + +#define UART_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PE | PAD_CTL_DSE4) +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) + +/* Verdin UART_3, Console/Debug UART */ +static iomux_v3_cfg_t const uart_pads[] = { + IMX8MM_PAD_SAI2_RXFS_UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MM_PAD_SAI2_RXC_UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static iomux_v3_cfg_t const wdog_pads[] = { + IMX8MM_PAD_GPIO1_IO02_WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), +}; + +int board_early_init_f(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; + + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); + + set_wdog_reset(wdog); + + imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); + + return 0; +} + +int power_init_board(void) +{ + struct udevice *dev; + int ret; + + if (IS_ENABLED(CONFIG_SPL_DM_PMIC_PCA9450)) { + ret = pmic_get("pmic", &dev); + if (ret == -ENODEV) { + puts("No pmic found\n"); + return ret; + } + + if (ret != 0) + return ret; + + /* BUCKxOUT_DVS0/1 control BUCK123 output, clear PRESET_EN */ + pmic_reg_write(dev, PCA9450_BUCK123_DVS, 0x29); + + /* increase VDD_DRAM to 0.975v for 1.5Ghz DDR */ + pmic_reg_write(dev, PCA9450_BUCK3OUT_DVS0, 0x1c); + + /* set WDOG_B_CFG to cold reset */ + pmic_reg_write(dev, PCA9450_RESET_CTRL, 0xA1); + + pmic_reg_write(dev, PCA9450_CONFIG2, 0x1); + + return 0; + } + + return 0; +} + +void board_init_f(ulong dummy) +{ + struct udevice *dev; + int ret; + + arch_cpu_init(); + + init_uart_clk(0); + + board_early_init_f(); + + timer_init(); + + preloader_console_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + ret = spl_early_init(); + if (ret) { + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + + ret = uclass_get_device_by_name(UCLASS_CLK, + "clock-controller@30380000", + &dev); + if (ret < 0) { + printf("Failed to find clock node. Check device tree\n"); + hang(); + } + + enable_tzc380(); + + power_init_board(); + + /* DDR initialization */ + spl_dram_init(); + + board_init_r(NULL, 0); +} diff --git a/roms/u-boot/board/toradex/verdin-imx8mm/verdin-imx8mm.c b/roms/u-boot/board/toradex/verdin-imx8mm/verdin-imx8mm.c new file mode 100644 index 000000000..76f4a1e20 --- /dev/null +++ b/roms/u-boot/board/toradex/verdin-imx8mm/verdin-imx8mm.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Toradex + */ + +#include <common.h> +#include <init.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <i2c.h> +#include <miiphy.h> +#include <netdev.h> +#include <micrel.h> + +#include "../common/tdx-cfg-block.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define I2C_PMIC 0 + +enum pcb_rev_t { + PCB_VERSION_1_0, + PCB_VERSION_1_1 +}; + +#if IS_ENABLED(CONFIG_FEC_MXC) +static int setup_fec(void) +{ + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + /* Use 125M anatop REF_CLK1 for ENET1, not from external */ + clrsetbits_le32(&gpr->gpr[1], 0x2000, 0); + + return 0; +} + +int board_phy_config(struct phy_device *phydev) +{ + int tmp; + + switch (ksz9xx1_phy_get_id(phydev) & MII_KSZ9x31_SILICON_REV_MASK) { + case PHY_ID_KSZ9031: + /* + * The PHY adds 1.2ns for the RXC and 0ns for TXC clock by + * default. The MAC and the layout don't add a skew between + * clock and data. + * Add 0.3ns for the RXC path and 0.96 + 0.42 ns (1.38 ns) for + * the TXC path to get the required clock skews. + */ + /* control data pad skew - devaddr = 0x02, register = 0x04 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x0070); + /* rx data pad skew - devaddr = 0x02, register = 0x05 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x7777); + /* tx data pad skew - devaddr = 0x02, register = 0x06 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x0000); + /* gtx and rx clock pad skew - devaddr = 0x02,register = 0x08 */ + ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, + MII_KSZ9031_MOD_DATA_NO_POST_INC, + 0x03f4); + break; + case PHY_ID_KSZ9131: + default: + /* read rxc dll control - devaddr = 0x2, register = 0x4c */ + tmp = ksz9031_phy_extended_read(phydev, 0x02, + MII_KSZ9131_EXT_RGMII_2NS_SKEW_RXDLL, + MII_KSZ9031_MOD_DATA_NO_POST_INC); + /* disable rxdll bypass (enable 2ns skew delay on RXC) */ + tmp &= ~MII_KSZ9131_RXTXDLL_BYPASS; + /* rxc data pad skew 2ns - devaddr = 0x02, register = 0x4c */ + tmp = ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9131_EXT_RGMII_2NS_SKEW_RXDLL, + MII_KSZ9031_MOD_DATA_NO_POST_INC, tmp); + /* read txc dll control - devaddr = 0x02, register = 0x4d */ + tmp = ksz9031_phy_extended_read(phydev, 0x02, + MII_KSZ9131_EXT_RGMII_2NS_SKEW_TXDLL, + MII_KSZ9031_MOD_DATA_NO_POST_INC); + /* disable txdll bypass (enable 2ns skew delay on TXC) */ + tmp &= ~MII_KSZ9131_RXTXDLL_BYPASS; + /* rxc data pad skew 2ns - devaddr = 0x02, register = 0x4d */ + tmp = ksz9031_phy_extended_write(phydev, 0x02, + MII_KSZ9131_EXT_RGMII_2NS_SKEW_TXDLL, + MII_KSZ9031_MOD_DATA_NO_POST_INC, tmp); + break; + } + + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif + +int board_init(void) +{ + if (IS_ENABLED(CONFIG_FEC_MXC)) + setup_fec(); + + return 0; +} + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} + +static enum pcb_rev_t get_pcb_revision(void) +{ + struct udevice *bus; + struct udevice *i2c_dev = NULL; + int ret; + u8 is_bd71837 = 0; + + ret = uclass_get_device_by_seq(UCLASS_I2C, I2C_PMIC, &bus); + if (!ret) + ret = dm_i2c_probe(bus, 0x4b, 0, &i2c_dev); + if (!ret) + ret = dm_i2c_read(i2c_dev, 0x0, &is_bd71837, 1); + + /* BD71837_REV, High Nibble is major version, fix 1010 */ + is_bd71837 = !ret && ((is_bd71837 & 0xf0) == 0xa0); + return is_bd71837 ? PCB_VERSION_1_0 : PCB_VERSION_1_1; +} + +static void select_dt_from_module_version(void) +{ + char variant[32]; + char *env_variant = env_get("variant"); + int is_wifi = 0; + + if (IS_ENABLED(CONFIG_TDX_CFG_BLOCK)) { + /* + * If we have a valid config block and it says we are a + * module with Wi-Fi/Bluetooth make sure we use the -wifi + * device tree. + */ + is_wifi = (tdx_hw_tag.prodid == VERDIN_IMX8MMQ_WIFI_BT_IT) || + (tdx_hw_tag.prodid == VERDIN_IMX8MMDL_WIFI_BT_IT); + } + + switch (get_pcb_revision()) { + case PCB_VERSION_1_0: + printf("Detected a V1.0 module\n"); + if (is_wifi) + strncpy(&variant[0], "wifi", sizeof(variant)); + else + strncpy(&variant[0], "nonwifi", sizeof(variant)); + break; + default: + if (is_wifi) + strncpy(&variant[0], "wifi-v1.1", sizeof(variant)); + else + strncpy(&variant[0], "nonwifi-v1.1", sizeof(variant)); + break; + } + + if (strcmp(variant, env_variant)) { + printf("Setting variant to %s\n", variant); + env_set("variant", variant); + + if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE)) + env_save(); + } +} + +int board_late_init(void) +{ + select_dt_from_module_version(); + + return 0; +} + +int board_phys_sdram_size(phys_size_t *size) +{ + if (!size) + return -EINVAL; + + *size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return 0; +} +#endif |