diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 9c593b2c98..820ee9733a 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -180,7 +180,8 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \ tegra210-e2220-1170.dtb \ tegra210-p2371-0000.dtb \ tegra210-p2371-2180.dtb \ - tegra210-p2571.dtb + tegra210-p2571.dtb \ + tegra210-p3450-0000.dtb dtb-$(CONFIG_ARCH_MVEBU) += \ armada-3720-db.dtb \ diff --git a/arch/arm/dts/tegra210-p3450-0000.dts b/arch/arm/dts/tegra210-p3450-0000.dts new file mode 100644 index 0000000000..9ef744ac8b --- /dev/null +++ b/arch/arm/dts/tegra210-p3450-0000.dts @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019-2020 NVIDIA Corporation + */ +/dts-v1/; + +#include "tegra210.dtsi" + +/ { + model = "NVIDIA Jetson Nano Developer Kit"; + compatible = "nvidia,p3450-0000", "nvidia,tegra210"; + + chosen { + stdout-path = &uarta; + }; + + aliases { + ethernet = "/pcie@1003000/pci@2,0/ethernet@0,0"; + i2c0 = "/i2c@7000d000"; + i2c2 = "/i2c@7000c400"; + i2c3 = "/i2c@7000c500"; + i2c4 = "/i2c@7000c700"; + mmc0 = "/sdhci@700b0600"; + mmc1 = "/sdhci@700b0000"; + spi0 = "/spi@70410000"; + usb0 = "/usb@7d000000"; + }; + + memory { + reg = <0x0 0x80000000 0x0 0xc0000000>; + }; + + pcie@1003000 { + status = "okay"; + + pci@1,0 { + status = "okay"; + }; + + pci@2,0 { + status = "okay"; + + ethernet@0,0 { + reg = <0x000000 0 0 0 0>; + local-mac-address = [ 00 00 00 00 00 00 ]; + }; + }; + }; + + serial@70006000 { + status = "okay"; + }; + + padctl@7009f000 { + pinctrl-0 = <&padctl_default>; + pinctrl-names = "default"; + + padctl_default: pinmux { + xusb { + nvidia,lanes = "otg-1", "otg-2"; + nvidia,function = "xusb"; + nvidia,iddq = <0>; + }; + + usb3 { + nvidia,lanes = "pcie-5", "pcie-6"; + nvidia,function = "usb3"; + nvidia,iddq = <0>; + }; + + pcie-x1 { + nvidia,lanes = "pcie-0"; + nvidia,function = "pcie-x1"; + nvidia,iddq = <0>; + }; + + pcie-x4 { + nvidia,lanes = "pcie-1", "pcie-2", + "pcie-3", "pcie-4"; + nvidia,function = "pcie-x4"; + nvidia,iddq = <0>; + }; + + sata { + nvidia,lanes = "sata-0"; + nvidia,function = "sata"; + nvidia,iddq = <0>; + }; + }; + }; + + sdhci@700b0000 { + status = "okay"; + cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>; + power-gpios = <&gpio TEGRA_GPIO(Z, 3) GPIO_ACTIVE_HIGH>; + bus-width = <4>; + }; + + sdhci@700b0600 { + status = "okay"; + bus-width = <8>; + non-removable; + }; + + i2c@7000c400 { + status = "okay"; + clock-frequency = <400000>; + }; + + i2c@7000c500 { + status = "okay"; + clock-frequency = <400000>; + }; + + i2c@7000c700 { + status = "okay"; + clock-frequency = <400000>; + }; + + i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + }; + + spi@70410000 { + status = "okay"; + spi-max-frequency = <80000000>; + }; + + usb@7d000000 { + status = "okay"; + dr_mode = "peripheral"; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + clk32k_in: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; +}; diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index 787ff97420..224efc97c5 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -217,6 +217,31 @@ int board_early_init_f(void) arch_timer_init(); #endif +#if defined(CONFIG_DISABLE_SDMMC1_EARLY) + /* + * Turn off (reset/disable) SDMMC1 on Nano here, before GPIO INIT. + * We do this because earlier bootloaders have enabled power to + * SDMMC1 on Nano, and toggling power-gpio (PZ3) in pinmux_init() + * results in power being back-driven into the SD-card and SDMMC1 + * HW, which is 'bad' as per the HW team. + * + * From the HW team: "LDO2 from the PMIC has already been set to 3.3v in + * nvtboot/CBoot on Nano (for SD-card boot). So when U-Boot's GPIO_INIT + * table sets PZ3 to OUT0 as per the pinmux spreadsheet, it turns off + * the loadswitch. When PZ3 is 0 and not driving, essentially the SDCard + * voltage turns off. Since the SDCard voltage is no longer there, the + * SDMMC CLK/DAT lines are backdriving into what essentially is a + * powered-off SDCard, that's why the voltage drops from 3.3V to ~1.6V" + * + * Note that this can probably be removed when we change over to storing + * all BL components on QSPI on Nano, and U-Boot then becomes the first + * one to turn on SDMMC1 power. Another fix would be to have CBoot + * disable power/gate SDMMC1 off before handing off to U-Boot/kernel. + */ + reset_set_enable(PERIPH_ID_SDMMC1, 1); + clock_set_enable(PERIPH_ID_SDMMC1, 0); +#endif /* CONFIG_DISABLE_SDMMC1_EARLY */ + pinmux_init(); board_init_uart_f(); diff --git a/arch/arm/mach-tegra/tegra210/Kconfig b/arch/arm/mach-tegra/tegra210/Kconfig index 3637473051..97ed8e05f4 100644 --- a/arch/arm/mach-tegra/tegra210/Kconfig +++ b/arch/arm/mach-tegra/tegra210/Kconfig @@ -35,6 +35,12 @@ config TARGET_P2571 help P2571 is a P2530 married to a P1963 I/O board +config TARGET_P3450_0000 + bool "NVIDIA Jetson Nano Developer Kit" + select BOARD_LATE_INIT + help + P3450-0000 is a P3448 CPU board married to a P3449 I/O board. + endchoice config SYS_SOC @@ -44,5 +50,6 @@ source "board/nvidia/e2220-1170/Kconfig" source "board/nvidia/p2371-0000/Kconfig" source "board/nvidia/p2371-2180/Kconfig" source "board/nvidia/p2571/Kconfig" +source "board/nvidia/p3450-0000/Kconfig" endif diff --git a/board/nvidia/p3450-0000/Kconfig b/board/nvidia/p3450-0000/Kconfig new file mode 100644 index 0000000000..7a08cd8867 --- /dev/null +++ b/board/nvidia/p3450-0000/Kconfig @@ -0,0 +1,12 @@ +if TARGET_P3450_0000 + +config SYS_BOARD + default "p3450-0000" + +config SYS_VENDOR + default "nvidia" + +config SYS_CONFIG_NAME + default "p3450-0000" + +endif diff --git a/board/nvidia/p3450-0000/MAINTAINERS b/board/nvidia/p3450-0000/MAINTAINERS new file mode 100644 index 0000000000..40700066bf --- /dev/null +++ b/board/nvidia/p3450-0000/MAINTAINERS @@ -0,0 +1,6 @@ +P3450-0000 BOARD +M: Tom Warren +S: Maintained +F: board/nvidia/p3450-0000/ +F: include/configs/p3450-0000.h +F: configs/p3450-0000_defconfig diff --git a/board/nvidia/p3450-0000/Makefile b/board/nvidia/p3450-0000/Makefile new file mode 100644 index 0000000000..993c506d82 --- /dev/null +++ b/board/nvidia/p3450-0000/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2018 +# NVIDIA Corporation +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += p3450-0000.o diff --git a/board/nvidia/p3450-0000/p3450-0000.c b/board/nvidia/p3450-0000/p3450-0000.c new file mode 100644 index 0000000000..f4212ab822 --- /dev/null +++ b/board/nvidia/p3450-0000/p3450-0000.c @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018-2019 + * NVIDIA Corporation + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../p2571/max77620_init.h" + +void pin_mux_mmc(void) +{ + struct udevice *dev; + uchar val; + int ret; + + /* Turn on MAX77620 LDO2 to 3.3V for SD card power */ + debug("%s: Set LDO2 for VDDIO_SDMMC_AP power to 3.3V\n", __func__); + ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev); + if (ret) { + printf("%s: Cannot find MAX77620 I2C chip\n", __func__); + return; + } + /* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val = 0xF2; + ret = dm_i2c_write(dev, MAX77620_CNFG1_L2_REG, &val, 1); + if (ret) + printf("i2c_write 0 0x3c 0x27 failed: %d\n", ret); + + /* Disable LDO4 discharge */ + ret = dm_i2c_read(dev, MAX77620_CNFG2_L4_REG, &val, 1); + if (ret) { + printf("i2c_read 0 0x3c 0x2c failed: %d\n", ret); + } else { + val &= ~BIT(1); /* ADE */ + ret = dm_i2c_write(dev, MAX77620_CNFG2_L4_REG, &val, 1); + if (ret) + printf("i2c_write 0 0x3c 0x2c failed: %d\n", ret); + } + + /* Set MBLPD */ + ret = dm_i2c_read(dev, MAX77620_CNFGGLBL1_REG, &val, 1); + if (ret) { + printf("i2c_write 0 0x3c 0x00 failed: %d\n", ret); + } else { + val |= BIT(6); /* MBLPD */ + ret = dm_i2c_write(dev, MAX77620_CNFGGLBL1_REG, &val, 1); + if (ret) + printf("i2c_write 0 0x3c 0x00 failed: %d\n", ret); + } +} + +#ifdef CONFIG_PCI_TEGRA +int tegra_pcie_board_init(void) +{ + struct udevice *dev; + uchar val; + int ret; + + /* Turn on MAX77620 LDO1 to 1.05V for PEX power */ + debug("%s: Set LDO1 for PEX power to 1.05V\n", __func__); + ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev); + if (ret) { + printf("%s: Cannot find MAX77620 I2C chip\n", __func__); + return -1; + } + /* 0xCA for 1.05v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val = 0xCA; + ret = dm_i2c_write(dev, MAX77620_CNFG1_L1_REG, &val, 1); + if (ret) + printf("i2c_write 0 0x3c 0x25 failed: %d\n", ret); + + return 0; +} +#endif /* PCI */ + +static void ft_mac_address_setup(void *fdt) +{ + const void *cboot_fdt = (const void *)cboot_boot_x0; + uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN]; + const char *path; + int offset, err; + + err = cboot_get_ethaddr(cboot_fdt, local_mac); + if (err < 0) + memset(local_mac, 0, ETH_ALEN); + + path = fdt_get_alias(fdt, "ethernet"); + if (!path) + return; + + debug("ethernet alias found: %s\n", path); + + offset = fdt_path_offset(fdt, path); + if (offset < 0) { + printf("ethernet alias points to absent node %s\n", path); + return; + } + + if (is_valid_ethaddr(local_mac)) { + err = fdt_setprop(fdt, offset, "local-mac-address", local_mac, + ETH_ALEN); + if (!err) + debug("Local MAC address set: %pM\n", local_mac); + } + + if (eth_env_get_enetaddr("ethaddr", mac)) { + if (memcmp(local_mac, mac, ETH_ALEN) != 0) { + err = fdt_setprop(fdt, offset, "mac-address", mac, + ETH_ALEN); + if (!err) + debug("MAC address set: %pM\n", mac); + } + } +} + +static int ft_copy_carveout(void *dst, const void *src, const char *node) +{ + struct fdt_memory fb; + int err; + + err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb); + if (err < 0) { + if (err != -FDT_ERR_NOTFOUND) + printf("failed to get carveout for %s: %d\n", node, + err); + + return err; + } + + err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer", + &fb); + if (err < 0) { + printf("failed to set carveout for %s: %d\n", node, err); + return err; + } + + return 0; +} + +static void ft_carveout_setup(void *fdt) +{ + const void *cboot_fdt = (const void *)cboot_boot_x0; + static const char * const nodes[] = { + "/host1x@50000000/dc@54200000", + "/host1x@50000000/dc@54240000", + }; + unsigned int i; + int err; + + for (i = 0; i < ARRAY_SIZE(nodes); i++) { + printf("copying carveout for %s...\n", nodes[i]); + + err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]); + if (err < 0) { + if (err != -FDT_ERR_NOTFOUND) + printf("failed to copy carveout for %s: %d\n", + nodes[i], err); + + continue; + } + } +} + +int ft_board_setup(void *fdt, bd_t *bd) +{ + ft_mac_address_setup(fdt); + ft_carveout_setup(fdt); + + return 0; +} diff --git a/configs/p3450-0000_defconfig b/configs/p3450-0000_defconfig new file mode 100644 index 0000000000..f78e1d3867 --- /dev/null +++ b/configs/p3450-0000_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_TEGRA=y +CONFIG_SYS_TEXT_BASE=0x80080000 +CONFIG_TEGRA210=y +CONFIG_TARGET_P3450_0000=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_CONSOLE_MUX=y +CONFIG_SYS_STDIO_DEREGISTER=y +CONFIG_SYS_PROMPT="Tegra210 (P3450-0000) # " +# CONFIG_CMD_IMI is not set +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_EXT4_WRITE=y +CONFIG_OF_LIVE=y +CONFIG_DEFAULT_DEVICE_TREE="tegra210-p3450-0000" +CONFIG_DFU_MMC=y +CONFIG_DFU_RAM=y +CONFIG_DFU_SF=y +CONFIG_SYS_I2C_TEGRA=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_USE_4K_SECTORS=y +CONFIG_SF_DEFAULT_MODE=0 +CONFIG_SF_DEFAULT_SPEED=24000000 +CONFIG_RTL8169=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCI_TEGRA=y +CONFIG_SYS_NS16550=y +CONFIG_TEGRA114_SPI=y +CONFIG_TEGRA210_QSPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_TEGRA=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" +CONFIG_USB_GADGET_VENDOR_NUM=0x0955 +CONFIG_USB_GADGET_PRODUCT_NUM=0x701a +CONFIG_CI_UDC=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +# CONFIG_ENV_IS_IN_MMC is not set +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_SIZE=0x2000 +CONFIG_ENV_SECT_SIZE=0x1000 +CONFIG_ENV_OFFSET=0xFFFFE000 +CONFIG_BOOTP_PREFER_SERVERIP=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_DISABLE_SDMMC1_EARLY=y diff --git a/include/configs/p3450-0000.h b/include/configs/p3450-0000.h new file mode 100644 index 0000000000..7f05bebbcd --- /dev/null +++ b/include/configs/p3450-0000.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2018-2019 NVIDIA Corporation. + */ + +#ifndef _P3450_0000_H +#define _P3450_0000_H + +#include + +#include "tegra210-common.h" + +/* High-level configuration options */ +#define CONFIG_TEGRA_BOARD_STRING "NVIDIA P3450-0000" + +/* Board-specific serial config */ +#define CONFIG_TEGRA_ENABLE_UARTA + +/* Only MMC/PXE/DHCP for now, add USB back in later when supported */ +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 1) \ + func(MMC, mmc, 0) \ + func(PXE, pxe, na) \ + func(DHCP, dhcp, na) + +/* Environment at end of QSPI, in the VER partition */ +#define CONFIG_ENV_SPI_MAX_HZ 48000000 +#define CONFIG_ENV_SPI_MODE SPI_MODE_0 +#define CONFIG_SPI_FLASH_SIZE (4 << 20) + +#define CONFIG_PREBOOT + +#define BOARD_EXTRA_ENV_SETTINGS \ + "preboot=if test -e mmc 1:1 /u-boot-preboot.scr; then " \ + "load mmc 1:1 ${scriptaddr} /u-boot-preboot.scr; " \ + "source ${scriptaddr}; " \ + "fi\0" + +/* General networking support */ +#include "tegra-common-usb-gadget.h" +#include "tegra-common-post.h" + +/* Crystal is 38.4MHz. clk_m runs at half that rate */ +#define COUNTER_FREQUENCY 19200000 + +#endif /* _P3450_0000_H */