diff options
Diffstat (limited to 'roms/u-boot/board/toradex/apalis-tk1/apalis-tk1.c')
-rw-r--r-- | roms/u-boot/board/toradex/apalis-tk1/apalis-tk1.c | 302 |
1 files changed, 302 insertions, 0 deletions
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); +} |