Commit 7c02bc9649f6d3afd272ac4a94b280495473834c

Authored by Tom Warren
1 parent 808e19362f

ARM: tegra: Add NVIDIA Jetson Nano Developer Kit support

The Jetson Nano Developer Kit is a Tegra X1-based development board. It
is similar to Jetson TX1 but it is not pin compatible. It features 4GB
of LPDDR4, a SPI NOR flash for early boot firmware and an SD card slot
used for storage.

HDMI 2.0 or DP 1.2 are available for display, four USB ports (3 USB 2.0
and 1 USB 3.0) can be used to attach a variety of peripherals and a PCI
Ethernet controller provides onboard network connectivity. NVMe support
has also been added. Env save is at the end of QSPI (4MB-8K).

A 40-pin header on the board can be used to extend the capabilities and
exposed interfaces of the Jetson Nano.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Tom Warren <twarren@nvidia.com>
Tested-by: Peter Robinson <pbrobinson@gmail.com>

Showing 10 changed files with 495 additions and 1 deletions Side-by-side Diff

arch/arm/dts/Makefile
... ... @@ -180,7 +180,8 @@
180 180 tegra210-e2220-1170.dtb \
181 181 tegra210-p2371-0000.dtb \
182 182 tegra210-p2371-2180.dtb \
183   - tegra210-p2571.dtb
  183 + tegra210-p2571.dtb \
  184 + tegra210-p3450-0000.dtb
184 185  
185 186 dtb-$(CONFIG_ARCH_MVEBU) += \
186 187 armada-3720-db.dtb \
arch/arm/dts/tegra210-p3450-0000.dts
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * (C) Copyright 2019-2020 NVIDIA Corporation <www.nvidia.com>
  4 + */
  5 +/dts-v1/;
  6 +
  7 +#include "tegra210.dtsi"
  8 +
  9 +/ {
  10 + model = "NVIDIA Jetson Nano Developer Kit";
  11 + compatible = "nvidia,p3450-0000", "nvidia,tegra210";
  12 +
  13 + chosen {
  14 + stdout-path = &uarta;
  15 + };
  16 +
  17 + aliases {
  18 + ethernet = "/pcie@1003000/pci@2,0/ethernet@0,0";
  19 + i2c0 = "/i2c@7000d000";
  20 + i2c2 = "/i2c@7000c400";
  21 + i2c3 = "/i2c@7000c500";
  22 + i2c4 = "/i2c@7000c700";
  23 + mmc0 = "/sdhci@700b0600";
  24 + mmc1 = "/sdhci@700b0000";
  25 + spi0 = "/spi@70410000";
  26 + usb0 = "/usb@7d000000";
  27 + };
  28 +
  29 + memory {
  30 + reg = <0x0 0x80000000 0x0 0xc0000000>;
  31 + };
  32 +
  33 + pcie@1003000 {
  34 + status = "okay";
  35 +
  36 + pci@1,0 {
  37 + status = "okay";
  38 + };
  39 +
  40 + pci@2,0 {
  41 + status = "okay";
  42 +
  43 + ethernet@0,0 {
  44 + reg = <0x000000 0 0 0 0>;
  45 + local-mac-address = [ 00 00 00 00 00 00 ];
  46 + };
  47 + };
  48 + };
  49 +
  50 + serial@70006000 {
  51 + status = "okay";
  52 + };
  53 +
  54 + padctl@7009f000 {
  55 + pinctrl-0 = <&padctl_default>;
  56 + pinctrl-names = "default";
  57 +
  58 + padctl_default: pinmux {
  59 + xusb {
  60 + nvidia,lanes = "otg-1", "otg-2";
  61 + nvidia,function = "xusb";
  62 + nvidia,iddq = <0>;
  63 + };
  64 +
  65 + usb3 {
  66 + nvidia,lanes = "pcie-5", "pcie-6";
  67 + nvidia,function = "usb3";
  68 + nvidia,iddq = <0>;
  69 + };
  70 +
  71 + pcie-x1 {
  72 + nvidia,lanes = "pcie-0";
  73 + nvidia,function = "pcie-x1";
  74 + nvidia,iddq = <0>;
  75 + };
  76 +
  77 + pcie-x4 {
  78 + nvidia,lanes = "pcie-1", "pcie-2",
  79 + "pcie-3", "pcie-4";
  80 + nvidia,function = "pcie-x4";
  81 + nvidia,iddq = <0>;
  82 + };
  83 +
  84 + sata {
  85 + nvidia,lanes = "sata-0";
  86 + nvidia,function = "sata";
  87 + nvidia,iddq = <0>;
  88 + };
  89 + };
  90 + };
  91 +
  92 + sdhci@700b0000 {
  93 + status = "okay";
  94 + cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
  95 + power-gpios = <&gpio TEGRA_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
  96 + bus-width = <4>;
  97 + };
  98 +
  99 + sdhci@700b0600 {
  100 + status = "okay";
  101 + bus-width = <8>;
  102 + non-removable;
  103 + };
  104 +
  105 + i2c@7000c400 {
  106 + status = "okay";
  107 + clock-frequency = <400000>;
  108 + };
  109 +
  110 + i2c@7000c500 {
  111 + status = "okay";
  112 + clock-frequency = <400000>;
  113 + };
  114 +
  115 + i2c@7000c700 {
  116 + status = "okay";
  117 + clock-frequency = <400000>;
  118 + };
  119 +
  120 + i2c@7000d000 {
  121 + status = "okay";
  122 + clock-frequency = <400000>;
  123 + };
  124 +
  125 + spi@70410000 {
  126 + status = "okay";
  127 + spi-max-frequency = <80000000>;
  128 + };
  129 +
  130 + usb@7d000000 {
  131 + status = "okay";
  132 + dr_mode = "peripheral";
  133 + };
  134 +
  135 + clocks {
  136 + compatible = "simple-bus";
  137 + #address-cells = <1>;
  138 + #size-cells = <0>;
  139 +
  140 + clk32k_in: clock@0 {
  141 + compatible = "fixed-clock";
  142 + reg = <0>;
  143 + #clock-cells = <0>;
  144 + clock-frequency = <32768>;
  145 + };
  146 + };
  147 +};
arch/arm/mach-tegra/board2.c
... ... @@ -217,6 +217,31 @@
217 217 arch_timer_init();
218 218 #endif
219 219  
  220 +#if defined(CONFIG_DISABLE_SDMMC1_EARLY)
  221 + /*
  222 + * Turn off (reset/disable) SDMMC1 on Nano here, before GPIO INIT.
  223 + * We do this because earlier bootloaders have enabled power to
  224 + * SDMMC1 on Nano, and toggling power-gpio (PZ3) in pinmux_init()
  225 + * results in power being back-driven into the SD-card and SDMMC1
  226 + * HW, which is 'bad' as per the HW team.
  227 + *
  228 + * From the HW team: "LDO2 from the PMIC has already been set to 3.3v in
  229 + * nvtboot/CBoot on Nano (for SD-card boot). So when U-Boot's GPIO_INIT
  230 + * table sets PZ3 to OUT0 as per the pinmux spreadsheet, it turns off
  231 + * the loadswitch. When PZ3 is 0 and not driving, essentially the SDCard
  232 + * voltage turns off. Since the SDCard voltage is no longer there, the
  233 + * SDMMC CLK/DAT lines are backdriving into what essentially is a
  234 + * powered-off SDCard, that's why the voltage drops from 3.3V to ~1.6V"
  235 + *
  236 + * Note that this can probably be removed when we change over to storing
  237 + * all BL components on QSPI on Nano, and U-Boot then becomes the first
  238 + * one to turn on SDMMC1 power. Another fix would be to have CBoot
  239 + * disable power/gate SDMMC1 off before handing off to U-Boot/kernel.
  240 + */
  241 + reset_set_enable(PERIPH_ID_SDMMC1, 1);
  242 + clock_set_enable(PERIPH_ID_SDMMC1, 0);
  243 +#endif /* CONFIG_DISABLE_SDMMC1_EARLY */
  244 +
220 245 pinmux_init();
221 246 board_init_uart_f();
222 247  
arch/arm/mach-tegra/tegra210/Kconfig
... ... @@ -35,6 +35,12 @@
35 35 help
36 36 P2571 is a P2530 married to a P1963 I/O board
37 37  
  38 +config TARGET_P3450_0000
  39 + bool "NVIDIA Jetson Nano Developer Kit"
  40 + select BOARD_LATE_INIT
  41 + help
  42 + P3450-0000 is a P3448 CPU board married to a P3449 I/O board.
  43 +
38 44 endchoice
39 45  
40 46 config SYS_SOC
... ... @@ -44,6 +50,7 @@
44 50 source "board/nvidia/p2371-0000/Kconfig"
45 51 source "board/nvidia/p2371-2180/Kconfig"
46 52 source "board/nvidia/p2571/Kconfig"
  53 +source "board/nvidia/p3450-0000/Kconfig"
47 54  
48 55 endif
board/nvidia/p3450-0000/Kconfig
  1 +if TARGET_P3450_0000
  2 +
  3 +config SYS_BOARD
  4 + default "p3450-0000"
  5 +
  6 +config SYS_VENDOR
  7 + default "nvidia"
  8 +
  9 +config SYS_CONFIG_NAME
  10 + default "p3450-0000"
  11 +
  12 +endif
board/nvidia/p3450-0000/MAINTAINERS
  1 +P3450-0000 BOARD
  2 +M: Tom Warren <twarren@nvidia.com>
  3 +S: Maintained
  4 +F: board/nvidia/p3450-0000/
  5 +F: include/configs/p3450-0000.h
  6 +F: configs/p3450-0000_defconfig
board/nvidia/p3450-0000/Makefile
  1 +#
  2 +# (C) Copyright 2018
  3 +# NVIDIA Corporation <www.nvidia.com>
  4 +#
  5 +# SPDX-License-Identifier: GPL-2.0+
  6 +#
  7 +
  8 +obj-y += p3450-0000.o
board/nvidia/p3450-0000/p3450-0000.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * (C) Copyright 2018-2019
  4 + * NVIDIA Corporation <www.nvidia.com>
  5 + *
  6 + */
  7 +
  8 +#include <common.h>
  9 +#include <fdtdec.h>
  10 +#include <i2c.h>
  11 +#include <linux/libfdt.h>
  12 +#include <pca953x.h>
  13 +#include <asm/arch-tegra/cboot.h>
  14 +#include <asm/arch/gpio.h>
  15 +#include <asm/arch/pinmux.h>
  16 +#include "../p2571/max77620_init.h"
  17 +
  18 +void pin_mux_mmc(void)
  19 +{
  20 + struct udevice *dev;
  21 + uchar val;
  22 + int ret;
  23 +
  24 + /* Turn on MAX77620 LDO2 to 3.3V for SD card power */
  25 + debug("%s: Set LDO2 for VDDIO_SDMMC_AP power to 3.3V\n", __func__);
  26 + ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev);
  27 + if (ret) {
  28 + printf("%s: Cannot find MAX77620 I2C chip\n", __func__);
  29 + return;
  30 + }
  31 + /* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
  32 + val = 0xF2;
  33 + ret = dm_i2c_write(dev, MAX77620_CNFG1_L2_REG, &val, 1);
  34 + if (ret)
  35 + printf("i2c_write 0 0x3c 0x27 failed: %d\n", ret);
  36 +
  37 + /* Disable LDO4 discharge */
  38 + ret = dm_i2c_read(dev, MAX77620_CNFG2_L4_REG, &val, 1);
  39 + if (ret) {
  40 + printf("i2c_read 0 0x3c 0x2c failed: %d\n", ret);
  41 + } else {
  42 + val &= ~BIT(1); /* ADE */
  43 + ret = dm_i2c_write(dev, MAX77620_CNFG2_L4_REG, &val, 1);
  44 + if (ret)
  45 + printf("i2c_write 0 0x3c 0x2c failed: %d\n", ret);
  46 + }
  47 +
  48 + /* Set MBLPD */
  49 + ret = dm_i2c_read(dev, MAX77620_CNFGGLBL1_REG, &val, 1);
  50 + if (ret) {
  51 + printf("i2c_write 0 0x3c 0x00 failed: %d\n", ret);
  52 + } else {
  53 + val |= BIT(6); /* MBLPD */
  54 + ret = dm_i2c_write(dev, MAX77620_CNFGGLBL1_REG, &val, 1);
  55 + if (ret)
  56 + printf("i2c_write 0 0x3c 0x00 failed: %d\n", ret);
  57 + }
  58 +}
  59 +
  60 +#ifdef CONFIG_PCI_TEGRA
  61 +int tegra_pcie_board_init(void)
  62 +{
  63 + struct udevice *dev;
  64 + uchar val;
  65 + int ret;
  66 +
  67 + /* Turn on MAX77620 LDO1 to 1.05V for PEX power */
  68 + debug("%s: Set LDO1 for PEX power to 1.05V\n", __func__);
  69 + ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev);
  70 + if (ret) {
  71 + printf("%s: Cannot find MAX77620 I2C chip\n", __func__);
  72 + return -1;
  73 + }
  74 + /* 0xCA for 1.05v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
  75 + val = 0xCA;
  76 + ret = dm_i2c_write(dev, MAX77620_CNFG1_L1_REG, &val, 1);
  77 + if (ret)
  78 + printf("i2c_write 0 0x3c 0x25 failed: %d\n", ret);
  79 +
  80 + return 0;
  81 +}
  82 +#endif /* PCI */
  83 +
  84 +static void ft_mac_address_setup(void *fdt)
  85 +{
  86 + const void *cboot_fdt = (const void *)cboot_boot_x0;
  87 + uint8_t mac[ETH_ALEN], local_mac[ETH_ALEN];
  88 + const char *path;
  89 + int offset, err;
  90 +
  91 + err = cboot_get_ethaddr(cboot_fdt, local_mac);
  92 + if (err < 0)
  93 + memset(local_mac, 0, ETH_ALEN);
  94 +
  95 + path = fdt_get_alias(fdt, "ethernet");
  96 + if (!path)
  97 + return;
  98 +
  99 + debug("ethernet alias found: %s\n", path);
  100 +
  101 + offset = fdt_path_offset(fdt, path);
  102 + if (offset < 0) {
  103 + printf("ethernet alias points to absent node %s\n", path);
  104 + return;
  105 + }
  106 +
  107 + if (is_valid_ethaddr(local_mac)) {
  108 + err = fdt_setprop(fdt, offset, "local-mac-address", local_mac,
  109 + ETH_ALEN);
  110 + if (!err)
  111 + debug("Local MAC address set: %pM\n", local_mac);
  112 + }
  113 +
  114 + if (eth_env_get_enetaddr("ethaddr", mac)) {
  115 + if (memcmp(local_mac, mac, ETH_ALEN) != 0) {
  116 + err = fdt_setprop(fdt, offset, "mac-address", mac,
  117 + ETH_ALEN);
  118 + if (!err)
  119 + debug("MAC address set: %pM\n", mac);
  120 + }
  121 + }
  122 +}
  123 +
  124 +static int ft_copy_carveout(void *dst, const void *src, const char *node)
  125 +{
  126 + struct fdt_memory fb;
  127 + int err;
  128 +
  129 + err = fdtdec_get_carveout(src, node, "memory-region", 0, &fb);
  130 + if (err < 0) {
  131 + if (err != -FDT_ERR_NOTFOUND)
  132 + printf("failed to get carveout for %s: %d\n", node,
  133 + err);
  134 +
  135 + return err;
  136 + }
  137 +
  138 + err = fdtdec_set_carveout(dst, node, "memory-region", 0, "framebuffer",
  139 + &fb);
  140 + if (err < 0) {
  141 + printf("failed to set carveout for %s: %d\n", node, err);
  142 + return err;
  143 + }
  144 +
  145 + return 0;
  146 +}
  147 +
  148 +static void ft_carveout_setup(void *fdt)
  149 +{
  150 + const void *cboot_fdt = (const void *)cboot_boot_x0;
  151 + static const char * const nodes[] = {
  152 + "/host1x@50000000/dc@54200000",
  153 + "/host1x@50000000/dc@54240000",
  154 + };
  155 + unsigned int i;
  156 + int err;
  157 +
  158 + for (i = 0; i < ARRAY_SIZE(nodes); i++) {
  159 + printf("copying carveout for %s...\n", nodes[i]);
  160 +
  161 + err = ft_copy_carveout(fdt, cboot_fdt, nodes[i]);
  162 + if (err < 0) {
  163 + if (err != -FDT_ERR_NOTFOUND)
  164 + printf("failed to copy carveout for %s: %d\n",
  165 + nodes[i], err);
  166 +
  167 + continue;
  168 + }
  169 + }
  170 +}
  171 +
  172 +int ft_board_setup(void *fdt, bd_t *bd)
  173 +{
  174 + ft_mac_address_setup(fdt);
  175 + ft_carveout_setup(fdt);
  176 +
  177 + return 0;
  178 +}
configs/p3450-0000_defconfig
  1 +CONFIG_ARM=y
  2 +CONFIG_TEGRA=y
  3 +CONFIG_SYS_TEXT_BASE=0x80080000
  4 +CONFIG_TEGRA210=y
  5 +CONFIG_TARGET_P3450_0000=y
  6 +CONFIG_NR_DRAM_BANKS=2
  7 +CONFIG_OF_SYSTEM_SETUP=y
  8 +CONFIG_OF_BOARD_SETUP=y
  9 +CONFIG_CONSOLE_MUX=y
  10 +CONFIG_SYS_STDIO_DEREGISTER=y
  11 +CONFIG_SYS_PROMPT="Tegra210 (P3450-0000) # "
  12 +# CONFIG_CMD_IMI is not set
  13 +CONFIG_CMD_DFU=y
  14 +# CONFIG_CMD_FLASH is not set
  15 +CONFIG_CMD_GPIO=y
  16 +CONFIG_CMD_I2C=y
  17 +CONFIG_CMD_MMC=y
  18 +CONFIG_CMD_PCI=y
  19 +CONFIG_CMD_SF=y
  20 +CONFIG_CMD_SPI=y
  21 +CONFIG_CMD_USB=y
  22 +CONFIG_CMD_USB_MASS_STORAGE=y
  23 +# CONFIG_CMD_SETEXPR is not set
  24 +# CONFIG_CMD_NFS is not set
  25 +CONFIG_CMD_EXT4_WRITE=y
  26 +CONFIG_OF_LIVE=y
  27 +CONFIG_DEFAULT_DEVICE_TREE="tegra210-p3450-0000"
  28 +CONFIG_DFU_MMC=y
  29 +CONFIG_DFU_RAM=y
  30 +CONFIG_DFU_SF=y
  31 +CONFIG_SYS_I2C_TEGRA=y
  32 +CONFIG_SPI_FLASH=y
  33 +CONFIG_SPI_FLASH_MACRONIX=y
  34 +CONFIG_SPI_FLASH_USE_4K_SECTORS=y
  35 +CONFIG_SF_DEFAULT_MODE=0
  36 +CONFIG_SF_DEFAULT_SPEED=24000000
  37 +CONFIG_RTL8169=y
  38 +CONFIG_PCI=y
  39 +CONFIG_DM_PCI=y
  40 +CONFIG_DM_PCI_COMPAT=y
  41 +CONFIG_PCI_TEGRA=y
  42 +CONFIG_SYS_NS16550=y
  43 +CONFIG_TEGRA114_SPI=y
  44 +CONFIG_TEGRA210_QSPI=y
  45 +CONFIG_USB=y
  46 +CONFIG_DM_USB=y
  47 +CONFIG_USB_EHCI_HCD=y
  48 +CONFIG_USB_EHCI_TEGRA=y
  49 +CONFIG_USB_GADGET=y
  50 +CONFIG_USB_GADGET_MANUFACTURER="NVIDIA"
  51 +CONFIG_USB_GADGET_VENDOR_NUM=0x0955
  52 +CONFIG_USB_GADGET_PRODUCT_NUM=0x701a
  53 +CONFIG_CI_UDC=y
  54 +CONFIG_USB_GADGET_DOWNLOAD=y
  55 +CONFIG_USB_HOST_ETHER=y
  56 +CONFIG_USB_ETHER_ASIX=y
  57 +# CONFIG_ENV_IS_IN_MMC is not set
  58 +CONFIG_ENV_IS_IN_SPI_FLASH=y
  59 +CONFIG_ENV_SIZE=0x2000
  60 +CONFIG_ENV_SECT_SIZE=0x1000
  61 +CONFIG_ENV_OFFSET=0xFFFFE000
  62 +CONFIG_BOOTP_PREFER_SERVERIP=y
  63 +CONFIG_POSITION_INDEPENDENT=y
  64 +CONFIG_DISABLE_SDMMC1_EARLY=y
include/configs/p3450-0000.h
  1 +/* SPDX-License-Identifier: GPL-2.0+ */
  2 +/*
  3 + * (C) Copyright 2018-2019 NVIDIA Corporation.
  4 + */
  5 +
  6 +#ifndef _P3450_0000_H
  7 +#define _P3450_0000_H
  8 +
  9 +#include <linux/sizes.h>
  10 +
  11 +#include "tegra210-common.h"
  12 +
  13 +/* High-level configuration options */
  14 +#define CONFIG_TEGRA_BOARD_STRING "NVIDIA P3450-0000"
  15 +
  16 +/* Board-specific serial config */
  17 +#define CONFIG_TEGRA_ENABLE_UARTA
  18 +
  19 +/* Only MMC/PXE/DHCP for now, add USB back in later when supported */
  20 +#define BOOT_TARGET_DEVICES(func) \
  21 + func(MMC, mmc, 1) \
  22 + func(MMC, mmc, 0) \
  23 + func(PXE, pxe, na) \
  24 + func(DHCP, dhcp, na)
  25 +
  26 +/* Environment at end of QSPI, in the VER partition */
  27 +#define CONFIG_ENV_SPI_MAX_HZ 48000000
  28 +#define CONFIG_ENV_SPI_MODE SPI_MODE_0
  29 +#define CONFIG_SPI_FLASH_SIZE (4 << 20)
  30 +
  31 +#define CONFIG_PREBOOT
  32 +
  33 +#define BOARD_EXTRA_ENV_SETTINGS \
  34 + "preboot=if test -e mmc 1:1 /u-boot-preboot.scr; then " \
  35 + "load mmc 1:1 ${scriptaddr} /u-boot-preboot.scr; " \
  36 + "source ${scriptaddr}; " \
  37 + "fi\0"
  38 +
  39 +/* General networking support */
  40 +#include "tegra-common-usb-gadget.h"
  41 +#include "tegra-common-post.h"
  42 +
  43 +/* Crystal is 38.4MHz. clk_m runs at half that rate */
  44 +#define COUNTER_FREQUENCY 19200000
  45 +
  46 +#endif /* _P3450_0000_H */