From 7c02bc9649f6d3afd272ac4a94b280495473834c Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Fri, 28 Feb 2020 16:17:07 -0700 Subject: 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 Signed-off-by: Tom Warren Tested-by: Peter Robinson --- board/nvidia/p3450-0000/Kconfig | 12 +++ board/nvidia/p3450-0000/MAINTAINERS | 6 ++ board/nvidia/p3450-0000/Makefile | 8 ++ board/nvidia/p3450-0000/p3450-0000.c | 178 +++++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 board/nvidia/p3450-0000/Kconfig create mode 100644 board/nvidia/p3450-0000/MAINTAINERS create mode 100644 board/nvidia/p3450-0000/Makefile create mode 100644 board/nvidia/p3450-0000/p3450-0000.c (limited to 'board/nvidia/p3450-0000') diff --git a/board/nvidia/p3450-0000/Kconfig b/board/nvidia/p3450-0000/Kconfig new file mode 100644 index 0000000..7a08cd8 --- /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 0000000..4070006 --- /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 0000000..993c506 --- /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 0000000..f4212ab --- /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; +} -- cgit v1.1