diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 95ebc114c4..5426fb9108 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -406,6 +406,14 @@ config TARGET_AM335X_NMHW21 select DM_SERIAL select DM_GPIO +config TARGET_AM335X_NMHW24 + bool "Support am335x_nmhw24" + select CPU_V7 + select SUPPORT_SPL + select DM + select DM_SERIAL + select DM_GPIO + config TARGET_AM335X_SL50 bool "Support am335x_sl50" select CPU_V7 @@ -906,6 +914,7 @@ source "board/nm/netbird/Kconfig" source "board/nm/netbird_v2/Kconfig" source "board/nm/nrhw20/Kconfig" source "board/nm/nmhw21/Kconfig" +source "board/nm/nmhw24/Kconfig" source "board/olimex/mx23_olinuxino/Kconfig" source "board/phytec/pcm051/Kconfig" source "board/phytec/pcm052/Kconfig" diff --git a/board/nm/nmhw24/Kconfig b/board/nm/nmhw24/Kconfig new file mode 100644 index 0000000000..900e1835f8 --- /dev/null +++ b/board/nm/nmhw24/Kconfig @@ -0,0 +1,26 @@ +if TARGET_AM335X_NMHW24 + +config SYS_BOARD + default "nmhw24" + +config SYS_VENDOR + default "nm" + +config SYS_SOC + default "am33xx" + +config SYS_CONFIG_NAME + default "am335x_nmhw24" + +config CONS_INDEX + int "UART used for console" + range 1 6 + default 2 + help + The AM335x SoC has a total of 6 UARTs (UART0 to UART5 as referenced + in documentation, etc) available to it. Depending on your specific + board you may want something other than UART0 as for example the IDK + uses UART3 so enter 4 here. + +endif + diff --git a/board/nm/nmhw24/Makefile b/board/nm/nmhw24/Makefile new file mode 100644 index 0000000000..3fd6fd7737 --- /dev/null +++ b/board/nm/nmhw24/Makefile @@ -0,0 +1,13 @@ +# +# Makefile +# +# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),) +obj-y := mux.o +endif + +obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o fileaccess.o da9063.o diff --git a/board/nm/nmhw24/board.c b/board/nm/nmhw24/board.c new file mode 100644 index 0000000000..e9957fd6c6 --- /dev/null +++ b/board/nm/nmhw24/board.c @@ -0,0 +1,1167 @@ +/* + * board.c + * + * Board functions for Netmodule nmhw24 board, based on AM335x EVB + * + * Copyright (C) 2018-2019 NetModule AG - http://www.netmodule.com/ + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/bdparser.h" +#include "../common/board_descriptor.h" +#include "board.h" +#include "da9063.h" +#if 0 +#include "shield.h" +#include "shield_can.h" +#include "shield_comio.h" +#endif +#include "fileaccess.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* + * CPU GPIOs + * + * (A17) GPIO0_2: RST_GNSS~ + * (A16) GPIO0_5: EXTINT_GNSS + * + * (J18) GPIO0_16: RST_PHY~ + * (U12) GPIO0_27: RST_SHIELD~ + * + * (R14) GPIO1_20: BT_EN + * (V15) GPIO1_21: GSM_PWR_EN + * (U16) GPIO1_25: RST_GSM + * (T16) GPIO1_26: WLAN_EN + * (V17) GPIO1_27: WLAN_IRQ + * + * (C12) GPIO3_17: SIM_SEL + */ + +#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) + +#define GPIO_RST_GSM GPIO_TO_PIN(1, 25) +#define GPIO_PWR_GSM GPIO_TO_PIN(1, 21) + +#define GPIO_WLAN_EN GPIO_TO_PIN(1, 26) +#define GPIO_BT_EN GPIO_TO_PIN(1, 20) +#define GPIO_RST_GNSS GPIO_TO_PIN(0, 2) + +#define GPIO_RST_ETH_N GPIO_TO_PIN(0, 16) + +#define GPIO_SIM_SEL GPIO_TO_PIN(3, 17) + +/* + * PMIC GPIOs + * + * GPIO_7: EN_SUPPLY_GSM + * GPIO_8: EN_SUPPLY_WIFI + * GPIO_10: LED.LWR + * GPIO_11: LED.UPR + */ + +#define PMIC_GSM_SUPPLY_EN_IO 7 +#define PMIC_WIFI_SUPPLY_EN_IO 8 +#define PMIC_LED0 10 +#define PMIC_LED1 11 + + +#define DDR3_CLOCK_FREQUENCY (400) + + +#if !defined(CONFIG_SPL_BUILD) +/* Hardware version information of mainboard, loaded by get_hw_version() */ +static int hw_ver = -1; +static int hw_rev = -1; +static int hw_patch = -1; +static char hw_variant_name[64]; +#endif + +#if !defined(CONFIG_SPL_BUILD) +static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; +#endif + +#define I2C_BD_EEPROM_BUS (2) +#define BD_EEPROM_ADDR (0x50) /* CPU BD EEPROM (8kByte) is at 50 (A0) */ +#define BD_ADDRESS (0x0000) /* Board descriptor at beginning of EEPROM */ +#define PD_ADDRESS (0x0200) /* Product descriptor */ +#define PARTITION_ADDRESS (0x0600) /* Partition Table */ + +#define SHIELD_COM_IO 0 +#define SHIELD_DUALCAN 1 + + +static BD_Context bdctx[3]; /* The descriptor contexts */ + +// #define CONFIG_OF_BOARD_SETUP +// TODO: Why is this here, would belong to .h file + + +static void request_and_set_gpio(int gpio, const char *name, int value) +{ + int ret; + + ret = gpio_request(gpio, name); + if (ret < 0) { + printf("%s: Unable to request %s\n", __func__, name); + return; + } + + ret = gpio_direction_output(gpio, value); + if (ret < 0) { + printf("%s: Unable to set %s as output\n", __func__, name); + goto err_free_gpio; + } + + return; + +err_free_gpio: + gpio_free(gpio); +} + +#define REQUEST_AND_SET_GPIO(N) request_and_set_gpio(N, #N, 1); +#define REQUEST_AND_CLEAR_GPIO(N) request_and_set_gpio(N, #N, 0); + + +static void init_leds(void) +{ +} + +// TODO: Only green color available +static void set_status_led(int red, int green) +{ + /* LED outputs are active low, invert state */ + da9063_set_gpio(PMIC_LED0, red | green); +} + +// TODO: Remove? +static void set_indicator_led(int red, int green) +{ + da9063_set_gpio(PMIC_LED1, red | green); +} + + +static void init_i2c(void) +{ + // TODO: Create define for i2c busses + // #define I2C_BUS_PMIC 0 + // #define I2C_BUS_EEPROM 2 + i2c_set_bus_num(0); + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + i2c_set_bus_num(2); + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + i2c_set_bus_num(0); +} + +static int _bd_init(void) +{ + int old_bus; + + old_bus = i2c_get_bus_num(); + i2c_set_bus_num(I2C_BD_EEPROM_BUS); + + if (bd_get_context(&bdctx[0], BD_EEPROM_ADDR, BD_ADDRESS) != 0) { + printf("%s() no valid bd found\n", __func__); + return -1; + } + + if (bd_get_context(&bdctx[1], BD_EEPROM_ADDR, PD_ADDRESS) != 0) { + printf("%s() no valid pd found\n", __func__); + return -1; + } + +/* TODO: Check if we can finally remove this... + if (bd_get_context(&bdctx[2], BD_EEPROM_ADDR, PARTITION_ADDRESS) != 0) { + printf("%s() no valid partition table found\n", __func__); + return -1; + } +*/ + + bd_register_context_list(bdctx, ARRAY_SIZE(bdctx)); + + i2c_set_bus_num(old_bus); + + return 0; +} + +static bool is_jtag_boot(uint32_t address) +{ + char* jtag_token = (char*)address; + + if (strcmp(jtag_token, "JTAGBOOT") == 0) { + strcpy(jtag_token, "jtagboot"); + return true; + } + else { + return false; + } +} + +/* + * Read header information from EEPROM into global structure. + */ +static inline int __maybe_unused read_eeprom(void) +{ + return _bd_init(); +} + +/* + * Selects console for SPL. + * U-Boot console is defined by CONFIG_CONS_INDEX (via menuconfig) + */ +struct serial_device *default_serial_console(void) +{ + /* Provide UART on UART2 regardless of boot mode */ + enable_uart1_pin_mux(); + return &eserial2_device; + +#if 0 /* TODO: Check whether really required */ + if (spl_boot_device() == BOOT_DEVICE_UART) { + enable_uart0_pin_mux(); + return &eserial1_device; + } + else { + enable_uart1_pin_mux(); + return &eserial2_device; + } +#endif +} + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + +// TODO: Double check ! +static const struct ddr_data ddr3_data = { + /* Ratios were optimized by DDR3 training software from TI */ + /* TODO: Evaluate new values and update */ + .datardsratio0 = 0x39, /* 0x39 */ + .datawdsratio0 = 0x3f, /* 0x40 */ /* 3f */ + .datafwsratio0 = 0x98, /* 0x96 */ /* 98 */ + .datawrsratio0 = 0x7d, /* 0x7d */ +}; + +static const struct cmd_control ddr3_cmd_ctrl_data = { + .cmd0csratio = MT41K256M16HA125E_RATIO, + .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, + + .cmd1csratio = MT41K256M16HA125E_RATIO, + .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT, + + .cmd2csratio = MT41K256M16HA125E_RATIO, + .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, +}; + +static struct emif_regs ddr3_emif_reg_data = { + .sdram_config = MT41K256M16HA125E_EMIF_SDCFG, + .ref_ctrl = 0x61A, /* 32ms > 85°C */ + .sdram_tim1 = 0x0AAAE51B, + .sdram_tim2 = 0x246B7FDA, + .sdram_tim3 = 0x50FFE67F, + .zq_config = MT41K256M16HA125E_ZQ_CFG, + .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY, +}; + + +#define OSC (V_OSCK/1000000) + +struct dpll_params dpll_ddr = { + DDR3_CLOCK_FREQUENCY, OSC-1, 1, -1, -1, -1, -1 +}; + +static void pmic_fix_config(void) +{ + /* TODO: Update later, currently no fixes are required */ + +#if 0 + int rc; + uint8_t val; + + /* Workaround for pre v1.3 config (reports ID 0x3e -> 3.14) */ + rc = da9063_get_reg(PMIC_REG_CONFIG_ID, &val); + if (!rc && ((val == 0x3E) || (val == 0x12))) { + printf("Detected pre v1.3 PMIC config. Fixing registers\n"); + + /* Include +3V3_SENSORS (LDO3) in sequencing and enable manually */ + (void)da9063_set_reg(PMIC_REG_ID_4_3, 0x07 /* Slot 7 */); + (void)da9063_set_reg(PMIC_REG_LDO3_CONT, PMIC_LDOx_EN_MASK); + + /* + * Set AUTO Bit for sequencer controlled supplies, so that they get + * enabled when leaving power down state + */ + (void)da9063_set_reg(PMIC_REG_CONFIG_E, 0x3B); + (void)da9063_set_reg(PMIC_REG_CONFIG_G, 0x44); + + /* + * Clear sequencer target state bit (xxx_CONT::xxx_CONF bit), so that + * regulators are disabled when entering power down state. + * Keep EN bit enabled in order not to disable supply. + */ + (void)da9063_set_reg(PMIC_REG_LDO3_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_LDO7_CONT, PMIC_LDOx_EN_MASK); + + (void)da9063_set_reg(PMIC_REG_BCORE1_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_BCORE2_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_BPERI_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_BIO_CONT, PMIC_LDOx_EN_MASK); + (void)da9063_set_reg(PMIC_REG_BMEM_CONT, PMIC_LDOx_EN_MASK); + } +#endif +} + +static void pmic_ignition_gate_on(void) +{ + uint8_t val; + + /* Configure GPIO15 to permanent high, so that ignition sense signal is readable */ + + (void)da9063_set_reg(PMIC_REG_GPIO14_15, 0xCC); /* GPIO14/15 = Outputs open drain */ + + (void)da9063_get_reg(PMIC_REG_CONFIG_L, &val); /* Enable pull ups on GPIO14/15 */ + val |= 0xC0; + (void)da9063_set_reg(PMIC_REG_CONFIG_L, val); + + (void)da9063_get_reg(PMIC_REG_CONTROL_D, &val); /* No blinking, state selected by GPIOxx_MODE */ + val &= ~0xF8; + (void)da9063_set_reg(PMIC_REG_CONTROL_D, val); + + (void)da9063_get_reg(PMIC_REG_GPIO_MODE8_15, &val); /* Set to GPIO14,15 to high */ + val |= 0xC0; + (void)da9063_set_reg(PMIC_REG_GPIO_MODE8_15, val); +} + +static void init_pmic_spl(void) +{ + int bus; + + /* PMIC basic configuration */ + da9063_init(CONFIG_PMIC_I2C_BUS); + + bus = da9063_claim_i2c_bus(); + + /* Fix old configs (mainly prototype boards) */ + pmic_fix_config(); + + /* Enable +3V3_GNSS (LDO6) */ + (void)da9063_set_reg(PMIC_REG_LDO6_CONT, PMIC_LDOx_EN_MASK); + mdelay(2); + + pmic_ignition_gate_on(); + + /* Trim RTC to compensate +18ppm crystal deviation */ + // TODO: Check, caps have been changed + (void)da9063_set_reg(PMIC_REG_TRIM_CLDR, (-18*10)/19); + + da9063_release_i2c_bus(bus); +} + +void am33xx_spl_board_init(void) +{ + /* Set CPU speed to 600 MHz (fix) */ + dpll_mpu_opp100.m = MPUPLL_M_600; + + /* Set CORE Frequencies to OPP100 (600MHz) */ + do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); + + /* Configure I2C busses */ + init_i2c(); + + /* Setup PMIC */ + init_pmic_spl(); + + init_leds(); + set_status_led(1, 0); /* Red */ + set_indicator_led(1, 0); /* Red */ + + /* Set MPU Frequency to what we detected now that voltages are set */ + do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100); + + /* Debugger can place marker at end of SRAM to stop boot here */ + if (is_jtag_boot(CONFIG_JTAG_MARKER_SPL)) + { + puts("Detected JTAG boot, executing bkpt #0\n"); + + __asm__ __volatile__ ("bkpt #0"); + } +} + +const struct dpll_params *get_dpll_ddr_params(void) +{ + dpll_ddr.n = (get_osclk() / 1000000) - 1; + return &dpll_ddr; +} + +void set_uart_mux_conf(void) +{ + /* TODO: Set depending on boot mode (SPL/UBoot, eMMC/UART) */ + enable_uart0_pin_mux(); + enable_uart1_pin_mux(); +} + +void set_mux_conf_regs(void) +{ + enable_board_pin_mux(); +} + + +const struct ctrl_ioregs ioregs = { + .cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, + .cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, + .cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE, + .dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, + .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE +}; + +void sdram_init(void) +{ + config_ddr(DDR3_CLOCK_FREQUENCY, &ioregs, + &ddr3_data, + &ddr3_cmd_ctrl_data, + &ddr3_emif_reg_data, 0); +} + +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ + +#if !defined(CONFIG_SPL_BUILD) + +// TODO: required? +/* + * Override for Ethernet link timeout definition, + * with option to specify via environment variable linktimeout + */ +int eth_phy_timeout(void) +{ + const char* timeout_env = NULL; + int timeout; + + timeout = PHY_ANEG_DEFAULT_TIMEOUT; + + /* + * Check if timeout has been defined by environment. + * Valid range: 1000..10000 milliseconds + */ + timeout_env = getenv("linktimeout"); + if (timeout_env != NULL) { + timeout = simple_strtoul(timeout_env, NULL, 10); + if (timeout == 0) { + timeout = PHY_ANEG_DEFAULT_TIMEOUT; + } else if (timeout < 1000) { + timeout = 1000; + } else if (timeout > 10000) { + timeout = 10000; + } + } + + return timeout; +} + +#endif /* !defined(CONFIG_SPL_BUILD) */ + +#if !defined(CONFIG_SPL_BUILD) + +static void init_ethernet(void) +{ + REQUEST_AND_CLEAR_GPIO(GPIO_RST_ETH_N); + /* Minimum Reset Pulse = 100us (SMSC8720) */ + mdelay(1); + gpio_set_value(GPIO_RST_ETH_N, 1); + + // TODO: Check + /* Give clocks time to stabilize */ + mdelay(1); +} + +static void init_sim_mux(void) +{ + /* + * Switch onboard SIM to onboard modem (Mux = 1) + */ + REQUEST_AND_CLEAR_GPIO(GPIO_SIM_SEL); +} + +static void init_gsm(void) +{ + /* + * Perform power up sequence for TOBY-L2 modem. + * + * TOBY-L2 series can be switched on in one of the following ways: + * - Rising edge on the VCC pin to a valid voltage for module supply, + * i.e. applying module supply + * - Low level on the PWR_ON pin, which is normally set high by an + * internal pull-up, for a valid time period when the applied VCC + * voltage is within the valid operating range (see section 4.2.8). + * - Low level on the RESET_N pin, which is normally set high by an + * internal pull-up, for a valid time period when the applied VCC + * voltage is within the valid operating range (see section 4.2.9). + * + * PWR_ON low time: 5 ms - Low time to switch-on the module + * RESET_N low time: 18..800 ms - Low time to switch-on the module + * 2.1..15 s - Low time to reset the module + * 16 s - Low time to switch-off the module + * + * References: + * - uBlox TOBY-L2 Datasheet UBX-13004573 - R24 + * 2.3.1 Module power-on + * 4.2.8 PWR_ON pin + * 4.2.9 RESET_N pin + * + * Functionality: + * - Leave GSM power enable as is (default at power up = off) + * - Set reset line inactive (note: inverter logic in HW present) + * - Leave button unpressed (note: inverter logic in HW present) + * - Modem shall be enabled by Linux system by enabling GSM power + * supply + */ + + puts("GSM: "); + + REQUEST_AND_CLEAR_GPIO(GPIO_RST_GSM); /* Set reset inactive (active high) */ + REQUEST_AND_CLEAR_GPIO(GPIO_PWR_GSM); /* Set power switch inactive/released (active high) */ + + puts("init\n"); +} + +static void init_gnss(void) +{ + /* + * Release GNSS reset line, so that module starts up early + */ + REQUEST_AND_SET_GPIO(GPIO_RST_GNSS); +} + +#endif /* !defined(CONFIG_SPL_BUILD) */ + + +/* + * Basic board specific setup. Pinmux has been handled already. + * Not called in SPL build. + */ +int board_init(void) +{ +#if defined(CONFIG_HW_WATCHDOG) + hw_watchdog_init(); +#endif + + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + + /* Configure I2C busses */ + init_i2c(); + + da9063_init(CONFIG_PMIC_I2C_BUS); + + /* Let user know we're starting */ + init_leds(); + set_status_led(1, 1); /* Orange */ + set_indicator_led(1, 1); /* Orange */ + + printf("OSC: %lu MHz\n", get_osclk()/1000000); + + return 0; +} + +#if !defined(CONFIG_SPL_BUILD) + +void set_console(void) +{ + const char *defaultconsole = getenv("defaultconsole"); + + if (defaultconsole == 0) { + /* Use the default console */ + setenv("defaultconsole", "ttyS1"); + } + +#if 0 + const char *defaultconsole = getenv("defaultconsole"); + char buf[8]; + + /* Set default console to ttyS1 if not yet defined in env */ + if (defaultconsole == 0) { + setenv("defaultconsole", "ttyS1"); + } + + /* If consoledev file is present, take the tty defined in it as console */ + if (read_file("/root/boot/consoledev",buf, 5) == 5) { + if (strstr(buf, "tty") == buf) { + buf[5] = 0; + setenv("defaultconsole", buf); + } + } +#endif +} + +static void set_devicetree_name(void) +{ + char devicetreename[64]; + + /* add hardware versions to environment */ + if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) { + printf("Devicetree name not found, using default name\n"); + strcpy(devicetreename, "am335x-nmhw24-prod1.dtb"); + } + + setenv("fdt_image", devicetreename); +} + +static void set_root_partition(void) +{ + int boot_partition; + + /* add active root partition to environment */ + boot_partition = bd_get_boot_partition(); + if (boot_partition > 1) { + boot_partition = 0; + } + + /* mmcblk0p1 => root0, mmcblk0p2 => root1 so +1 */ + setenv_ulong("root_part", boot_partition + 1); +} + +static void get_variant_name(void) +{ + bd_get_variantname(hw_variant_name, sizeof(hw_variant_name)); + + printf("SYS: %s\n", hw_variant_name); +} + +static void get_hw_version(void) +{ + bd_get_hw_version(&hw_ver, &hw_rev); + bd_get_hw_patch(&hw_patch); + + printf("MB: V%d.%d\n", hw_ver, hw_rev); + // TODO: Which one + // printf("HW24: V%d.%d\n", hw_ver, hw_rev); + +} + +static void get_pmic_version(void) +{ + uint8_t val = 0x00; + uint8_t ver, rev; + int bus; + int rc; + + bus = da9063_claim_i2c_bus(); + + rc = da9063_get_reg(PMIC_REG_CONFIG_ID, &val); + if (!rc) { + ver = (val >> 4) & 0xF; + rev = (val >> 0) & 0xF; + } else { + ver = 0; + rev = 0; + } + + da9063_release_i2c_bus(bus); + + printf("PMIC: V%d.%d\n", ver, rev); +} + + +static void check_jtag_boot(void) +{ + if (is_jtag_boot(CONFIG_JTAG_MARKER_UBOOT)) { + setenv ("bootcmd", ""); + puts("Detected JTAG boot. Waiting on command line\n"); + } +} + +static void check_fct(void) +{ + /* + * Check whether an I2C device (EEPROM) is present at address 0xA2/0x51 + * In this case we are connected to the factory test station. + * Clear the bootcmd, so that test system can easily connect. + */ + + int old_bus; + + old_bus = i2c_get_bus_num(); + i2c_set_bus_num(I2C_BD_EEPROM_BUS); + + /* If probe fails we are sure no eeprom is connected */ + if (i2c_probe(0x51) == 0) { + setenv ("bootcmd", ""); + puts("Detected factory test system. Waiting on command line\n"); + } + + i2c_set_bus_num(old_bus); +} + +// TODO: activate +#if 0 + +struct shield_command { + int shield_id; + const char *name; + const char *default_shieldcmd; + void (*init)(void); +}; + +static struct shield_command known_shield_commands[] = { + { + SHIELD_COM_IO, + "comio", + "shield comio mode rs232", + comio_shield_init + }, + { + SHIELD_DUALCAN, + "dualcan", + "shield dualcan termination off off", + can_shield_init + }, +}; + +static const struct shield_command* get_shield_command(int shield_id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(known_shield_commands); i++) { + if (known_shield_commands[i].shield_id == shield_id) { + return &known_shield_commands[i]; + } + } + + return NULL; +} + +static void shield_config(void) +{ +#define MAX_SHIELD_CMD_LEN 128 + + char shieldcmd_linux[MAX_SHIELD_CMD_LEN]; + const char *shieldcmd; + const struct shield_command *cmd; + int len; + + int shield_id = bd_get_shield(0); + if (shield_id < 0) { + debug("No shield found in bd\n"); + return; + } + + cmd = get_shield_command(shield_id); + if (cmd == NULL) { + printf ("Unknown shield id %d\n", shield_id); + return; + } + + printf("Shield:%s\n", cmd->name); + + cmd->init(); + shieldcmd = cmd->default_shieldcmd; + + /* If a shield configuration is set by Linux, take it without bd check. + * We asume that Linux knows what to do. + */ + len = read_file("/root/boot/shieldcmd", shieldcmd_linux, MAX_SHIELD_CMD_LEN); + if (len > 0) { + debug("Shield command found in file, using it\n"); + shieldcmd = shieldcmd_linux; + } + + setenv("shieldcmd", shieldcmd); +} + +static void shield_init(void) +{ + shield_config(); +} + +#endif + +static bool get_button_state(void) +{ + uint8_t state = 0x00; + bool pressed = false; + int bus; + int rc; + + bus = da9063_claim_i2c_bus(); + rc = da9063_get_reg(PMIC_REG_STATUS_A, &state); + da9063_release_i2c_bus(bus); + + if (!rc) { + pressed = (state & 0x01) == 0x01; + } + + return pressed; +} + +static void blink_led(void) +{ + const int pulse_width = 400*1000; /* 400ms */ + + /* Assumes status LED is orange */ + udelay(pulse_width); + set_status_led(0, 0); /* Off */ + + udelay(pulse_width); + set_status_led(1, 1); /* Orange */ +} + +static void check_reset_button(void) +{ + int counter = 0; + + /* Check how long button is pressed */ + do { + if (!get_button_state()) + break; + + udelay(100*1000); /* 100ms */ + counter += 100; + + if (counter == 2000) { + /* Indicate factory reset threshold */ + blink_led(); + } + else if (counter == 12000) { + /* Indicate recovery boot threshold */ + blink_led(); + blink_led(); + } + } while (counter < 12000); + + if (counter < 2000) { + /* Don't do anything for duration < 2s */ + } + else if (counter < 12000) + { + /* Do factory reset for duration between 2s and 12s */ + char new_bootargs[512]; + char *bootargs = getenv("bootargs"); + + if (bootargs == 0) bootargs = ""; + + puts("Do factory reset during boot...\n"); + + strncpy(new_bootargs, bootargs, sizeof(new_bootargs)); + strncat(new_bootargs, " factory-reset", sizeof(new_bootargs)); + + setenv("bootargs", new_bootargs); + } + else + { + /* Boot into recovery for duration > 12s */ + puts("Booting recovery image...\n"); + + /* Set consoledev to external port */ + setenv("defaultconsole", "ttyS1"); + + /* Set bootcmd to run recovery */ + setenv("bootcmd", "run recovery"); + } +} + +#endif /* !defined(CONFIG_SPL_BUILD) */ + +int board_late_init(void) +{ +#if !defined(CONFIG_SPL_BUILD) + if (read_eeprom() < 0) { + puts("Could not get board ID.\n"); + } + + get_variant_name(); + get_hw_version(); + get_pmic_version(); + + // TODO + //set_root_partition(); + //set_devicetree_name(); + + /* Initialize pins */ + REQUEST_AND_CLEAR_GPIO(GPIO_WLAN_EN); + REQUEST_AND_CLEAR_GPIO(GPIO_BT_EN); + + init_ethernet(); + init_sim_mux(); + init_gsm(); + init_gnss(); + + // TODO: Check and activate if required + // Move to some other place? PMIC init() + /* Enable charging of RTC backup capacitor (1mA, 3.1V) */ + //(void)da9063_set_reg(PMIC_REG_BBAT_CONT, 0xCF); + + /* + * Check if a user action is requested + * - Short press: factory reset + * - Long press: recovery boot + */ + check_reset_button(); + + set_console(); + // TODO: + // shield_init(); + + set_status_led(1, 1); /* Orange */ + set_indicator_led(0, 0); /* Off */ + + check_fct(); + check_jtag_boot(); +#endif + + return 0; +} + + +#ifndef CONFIG_DM_ETH + +#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \ + (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)) +static void cpsw_control(int enabled) +{ + /* VTP can be added here */ + + return; +} + +static struct cpsw_slave_data cpsw_slaves[] = { + { + .slave_reg_ofs = 0x208, + .sliver_reg_ofs = 0xd80, + .phy_if = PHY_INTERFACE_MODE_RMII, + .phy_addr = 0 + } +}; + +static struct cpsw_platform_data cpsw_data = { + .mdio_base = CPSW_MDIO_BASE, + .cpsw_base = CPSW_BASE, + .mdio_div = 0xff, + .channels = 8, + .cpdma_reg_ofs = 0x800, + .slaves = 1, + .slave_data = cpsw_slaves, + .ale_reg_ofs = 0xd00, + .ale_entries = 1024, + .host_port_reg_ofs = 0x108, + .hw_stats_reg_ofs = 0x900, + .bd_ram_ofs = 0x2000, + .mac_control = (1 << 5), + .control = cpsw_control, + .host_port_num = 0, + .version = CPSW_CTRL_VERSION_2, +}; +#endif + +#if ((defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USBETH_SUPPORT)) &&\ + defined(CONFIG_SPL_BUILD)) || \ + ((defined(CONFIG_DRIVER_TI_CPSW) || \ + defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET)) && \ + !defined(CONFIG_SPL_BUILD)) + +static void set_mac_address(int index, uchar mac[6]) +{ + /* Then take mac from bd */ + if (is_valid_ethaddr(mac)) { + eth_setenv_enetaddr_by_index("eth", index, mac); + } + else { + printf("Trying to set invalid MAC address"); + } +} + +/* TODO: Update doc */ +/* + * This function will: + * Read the eFuse for MAC addresses, and set ethaddr/eth1addr/usbnet_devaddr + * in the environment + * Perform fixups to the PHY present on certain boards. We only need this + * function in: + * - SPL with either CPSW or USB ethernet support + * - Full U-Boot, with either CPSW or USB ethernet + * Build in only these cases to avoid warnings about unused variables + * when we build an SPL that has neither option but full U-Boot will. + */ +int board_eth_init(bd_t *bis) +{ + int n = 0; + __maybe_unused uint8_t mac_addr0[6] = {02,00,00,00,00,01}; +#if !defined(CONFIG_SPL_BUILD) +#ifdef CONFIG_DRIVER_TI_CPSW + cpsw_data.mdio_div = 0x3E; + + bd_get_mac(0, mac_addr0, sizeof(mac_addr0)); + set_mac_address(0, mac_addr0); + + writel(RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE, &cdev->miisel); + + { + int rv = cpsw_register(&cpsw_data); + if (rv < 0) + { + printf("Error %d registering CPSW switch\n", rv); + } else { + n += rv; + } + } +#endif +#endif + +#if defined(CONFIG_USB_ETHER) && \ + (!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT)) + if (is_valid_ethaddr(mac_addr0)) { + eth_setenv_enetaddr("usbnet_devaddr", mac_addr0); + } + + { + int rv = usb_eth_initialize(bis); + if (rv < 0) + { + printf("Error %d registering USB_ETHER\n", rv); + } else { + n += rv; + } + } +#endif + + return n; +} +#endif + +#endif /* CONFIG_DM_ETH */ + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + return 0; +} +#endif + +#if defined(CONFIG_OF_BOARD_SETUP) && !defined(CONFIG_SPL_BUILD) + +static void ft_enable_node(void* blob, const char* name) +{ + int node_ofs = -1; + + node_ofs = fdt_path_offset(blob, name); + if (node_ofs >= 0) { + fdt_setprop_string(blob, node_ofs, "status", "okay"); + } +} + +static void ft_dio(void *blob, int shield_type) +{ + // TODO: Move switch case to calling function + switch (shield_type) { + /* If COM/IO shield is present enable its I/Os */ + case SHIELD_COM_IO: + ft_enable_node(blob, "/netbox_dio_comio"); + break; + + default: + ft_enable_node(blob, "/netbox_dio_default"); + break; + } +} + +static void ft_serial(void *blob, int shield_type) +{ + // TODO: Move switch case to calling function + switch (shield_type) { + /* If COM/IO shield is present enable uart1 (ttyS0) */ + case SHIELD_COM_IO: + /* TODO: Should use alias serial0 */ + ft_enable_node(blob, "/ocp/serial@44e09000"); + break; + + default: + break; + } +} + +static void ft_dcan(void *blob, int shield_type) +{ + // TODO: Move switch case to calling function + + switch (shield_type) { + /* If Dual CAN shield is present enable dcan0, dcan1N1 */ + case SHIELD_DUALCAN: + /* TODO: Should use alias d_can0, d_can1 */ + ft_enable_node(blob, "/ocp/can@481cc000"); + ft_enable_node(blob, "/ocp/can@481d0000"); + break; + + default: + break; + } +} + +static void ft_bootloader_version(void *blob) +{ + int node_offset; + static const char version_string[] = U_BOOT_VERSION_STRING; + + node_offset = fdt_path_offset(blob, "/"); + if (node_offset != -1) { + fdt_setprop_string(blob, node_offset, "nm,bootloader,version", version_string); + } +} + +static void ft_hw_info(void *blob) +{ + int node_offset; + char hw_version[16]; + + snprintf(hw_version, sizeof(hw_version), "%d.%d.%d", hw_ver, hw_rev, hw_patch); + + node_offset = fdt_path_offset(blob, "/"); + if (node_offset != -1) { + fdt_setprop_string(blob, node_offset, "model", hw_variant_name); + fdt_setprop_string(blob, node_offset, "nm,carrierboard,version", hw_version); + } +} + +int ft_board_setup(void *blob, bd_t *bd) +{ +#if 0 + int shield_type = -1; +#endif + + ft_bootloader_version(blob); + ft_hw_info(blob); + +#if 0 + shield_type = bd_get_shield(0); + + // TODO: Add switch case here + ft_dio(blob, shield_type); + ft_serial(blob, shield_type); + ft_dcan(blob, shield_type); +#endif + + return 0; +} + +#endif diff --git a/board/nm/nmhw24/board.h b/board/nm/nmhw24/board.h new file mode 100644 index 0000000000..ba3a2feca3 --- /dev/null +++ b/board/nm/nmhw24/board.h @@ -0,0 +1,28 @@ +/* + * board.h + * + * TI AM335x boards information header + * + * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/* + * We have three pin mux functions that must exist. We must be able to enable + * uart0, for initial output and i2c2 to read the main EEPROM. We then have a + * main pinmux function that can be overridden to enable all other pinmux that + * is required on the board. + */ +void enable_uart0_pin_mux(void); +void disable_uart0_pin_mux(void); +void enable_uart1_pin_mux(void); + +void enable_board_pin_mux(void); + +#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) + +#endif diff --git a/board/nm/nmhw24/da9063.c b/board/nm/nmhw24/da9063.c new file mode 100644 index 0000000000..76f3d866c3 --- /dev/null +++ b/board/nm/nmhw24/da9063.c @@ -0,0 +1,139 @@ +/* + * da9063.c + * + * Dialog DA9063 PMIC + * + * Copyright (C) 2018-2019 NetModule AG - http://www.netmodule.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#include "da9063.h" + + +static int da9063_i2c_bus = 0; +static int bus_claimed = 0; + + +static int switch_i2c_bus(void) +{ + int old_bus; + + old_bus = i2c_get_bus_num(); + if (old_bus != da9063_i2c_bus) { + i2c_set_bus_num(da9063_i2c_bus); + } + + bus_claimed++; + + return old_bus; +} + +static void revert_i2c_bus(int bus) +{ + if (da9063_i2c_bus != bus) { + i2c_set_bus_num(bus); + } + + bus_claimed--; +} + + +void da9063_init(int i2c_bus) +{ + da9063_i2c_bus = i2c_bus; +} + +int da9063_claim_i2c_bus(void) +{ + return switch_i2c_bus(); +} + +void da9063_release_i2c_bus(int bus) +{ + revert_i2c_bus(bus); +} + +int da9063_get_reg(uint32_t reg, u8* val) +{ + int ret; + u8 temp; + + /* Argument check */ + if ((reg >= 0x200) || (val==0)) { + return -1; + } + + /* State check. Has bus been claimed */ + if (bus_claimed == 0) { + return -2; + } + + *val = 0; + if (reg < 0x100) { + ret = i2c_read(CONFIG_PMIC_I2C_ADDR+0, reg & 0xFF, 1, &temp, 1); + } else { + ret = i2c_read(CONFIG_PMIC_I2C_ADDR+1, reg & 0xFF, 1, &temp, 1); + } + + if (ret == 0) + *val = temp; + + return ret; +} + +int da9063_set_reg(uint32_t reg, u8 val) +{ + int ret; + + /* Argument check */ + if (reg >= 0x200) { + return -1; + } + + /* State check. Has bus been claimed */ + if (bus_claimed == 0) { + return -2; + } + + if (reg < 0x100) { + ret = i2c_write(CONFIG_PMIC_I2C_ADDR+0, reg & 0xFF, 1, &val, 1); + } else { + ret = i2c_write(CONFIG_PMIC_I2C_ADDR+1, reg & 0xFF, 1, &val, 1); + } + + if (ret != 0) + puts("da9063 write error\n"); + + return ret; +} + +void da9063_set_gpio(unsigned bit, int state) +{ + int pmic_reg; + int ret; + u8 bitmask; + u8 reg = 0x00; + + if (bit <= 7) { + pmic_reg = PMIC_REG_GPIO_MODE0_7; + bitmask = 1U << (bit-0); + } + else { + pmic_reg = PMIC_REG_GPIO_MODE8_15; + bitmask = 1U << (bit-8); + } + + ret = da9063_get_reg(pmic_reg, ®); + + if (ret == 0) { + if (state) reg |= bitmask; + else reg &= ~bitmask; + + (void)da9063_set_reg(pmic_reg, reg); + } +} diff --git a/board/nm/nmhw24/da9063.h b/board/nm/nmhw24/da9063.h new file mode 100644 index 0000000000..4ccf955a81 --- /dev/null +++ b/board/nm/nmhw24/da9063.h @@ -0,0 +1,68 @@ +/* + * da9063.c + * + * Dialog DA9063 PMIC + * + * Copyright (C) 2018-2019 NetModule AG - http://www.netmodule.com/ + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef DA9063_H +#define DA9063_H + +// TODO: Add include for uint32_t (stdtypes.h) + + +#define CONFIG_PMIC_I2C_BUS 0 +#define CONFIG_PMIC_I2C_ADDR 0x58 /* Pages 0 and 1, Pages 2 and 3 -> 0x59 */ + +#define PMIC_REG_STATUS_A 0x01 /* Status of ON_KEY, WAKE, COMP1V2, DVC */ +#define PMIC_REG_CONTROL_D 0x11 /* Control register for blink/watchdog */ +#define PMIC_REG_GPIO14_15 0x1C /* Configuration of GPIO14/15 (mode, wake) */ +#define PMIC_REG_GPIO_MODE0_7 0x1D /* Control register for GPIOs 0..7 */ +#define PMIC_REG_GPIO_MODE8_15 0x1E /* Control register for GPIOs 8..15 */ + +#define PMIC_REG_BCORE1_CONT 0x21 /* Control register of BCORE1 */ +#define PMIC_REG_BCORE2_CONT 0x20 /* Control register of BCORE2 */ +#define PMIC_REG_BPERI_CONT 0x25 /* Control register of BPERI */ +#define PMIC_REG_BIO_CONT 0x24 /* Control register of BIO */ +#define PMIC_REG_BMEM_CONT 0x23 /* Control register of BMEM */ + +#define PMIC_REG_LDO3_CONT 0x28 /* Control register of LDO3 */ +#define PMIC_REG_LDO6_CONT 0x2B /* Control register of LDO6 */ +#define PMIC_REG_LDO7_CONT 0x2C /* Control register of LDO7 */ +#define PMIC_REG_LDO11_CONT 0x30 /* Control register of LDO11 */ + +#define PMIC_LDOx_EN_MASK 0x01 +#define PMIC_LDOx_CONF_MASK 0x80 + +#define PMIC_REG_ID_4_3 0x84 + +#define PMIC_REG_BUCK_ILIM_A 0x9A +#define PMIC_REG_BUCK_ILIM_B 0x9B +#define PMIC_REG_BUCK_ILIM_C 0x9C + +#define PMIC_REG_BBAT_CONT 0xC5 /* Control register for backup battery */ + +#define PMIC_REG_CONFIG_E 0x10A +#define PMIC_REG_CONFIG_G 0x10C +#define PMIC_REG_CONFIG_L 0x111 + +#define PMIC_REG_TRIM_CLDR 0x120 /* Calendar Trim register, 2's complement, 1.9ppm per bit */ + +#define PMIC_REG_CONFIG_ID 0x184 /* OTP Config ID */ + + +extern void da9063_init(int i2c_bus); + +extern int da9063_claim_i2c_bus(void); +extern void da9063_release_i2c_bus(int bus); + +extern int da9063_get_reg(uint32_t reg, u8* val); +extern int da9063_set_reg(uint32_t reg, u8 val); + +extern void da9063_set_gpio(unsigned bit, int state); + + +#endif /* DA9063_H */ diff --git a/board/nm/nmhw24/fileaccess.c b/board/nm/nmhw24/fileaccess.c new file mode 100644 index 0000000000..13768b032e --- /dev/null +++ b/board/nm/nmhw24/fileaccess.c @@ -0,0 +1,42 @@ +#include +#include + +#define OVERLAY_PART "1:3" + +int read_file(const char* filename, char *buf, int size) +{ + loff_t filesize = 0; + loff_t len; + int ret; + + /* If consoldev is set take this as productive conosle instead of default console */ + if (fs_set_blk_dev("mmc", OVERLAY_PART, FS_TYPE_EXT) != 0) { + puts("Error, can not set blk device\n"); + return -1; + } + + + /* File does not exist, do not print an error message */ + if (fs_size(filename, &filesize)) { + return -1; + } + + if (filesize < size) + size = filesize; + + /* If consoldev is set take this as productive conosle instead of default console */ + if (fs_set_blk_dev("mmc", OVERLAY_PART, FS_TYPE_EXT) != 0) { + puts("Error, can not set blk device\n"); + return -1; + } + + + if ((ret = fs_read(filename, (ulong)buf, 0, size, &len))) { + printf("Can't read file %s (size %d, len %lld, ret %d)\n", filename, size, len, ret); + return -1; + } + + buf[len] = 0; + + return len; +} diff --git a/board/nm/nmhw24/fileaccess.h b/board/nm/nmhw24/fileaccess.h new file mode 100644 index 0000000000..00bbaaea04 --- /dev/null +++ b/board/nm/nmhw24/fileaccess.h @@ -0,0 +1,14 @@ +/**@file /home/eichenberger/projects/nbhw16/u-boot/board/nm/netbird_v2/fileaccess.h + * @author eichenberger + * @version 704 + * @date + * Created: Tue 06 Jun 2017 02:02:33 PM CEST \n + * Last Update: Tue 06 Jun 2017 02:02:33 PM CEST + */ +#ifndef FILEACCESS_H +#define FILEACCESS_H + +void fs_set_console(void); +int read_file(const char* filename, char *buf, int size); + +#endif // FILEACCESS_H diff --git a/board/nm/nmhw24/mux.c b/board/nm/nmhw24/mux.c new file mode 100644 index 0000000000..db14c7fc7d --- /dev/null +++ b/board/nm/nmhw24/mux.c @@ -0,0 +1,231 @@ +/* + * mux.c + * + * Copyright (C) 2018-2019 NetModule AG - http://www.netmodule.com/ + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "board.h" + +static struct module_pin_mux gpio_pin_mux[] = { + /* + * CPU GPIOs + * + * (A17) GPIO0_2: RST_GNSS~ + * (A16) GPIO0_5: EXTINT_GNSS + * (C18) GPIO0_7: PWM / SHIELD LATCH + * (J18) GPIO0_16: RST_PHY~ + * (U12) GPIO0_27: RST_SHIELD~ + * + * (R14) GPIO1_20: BT_EN + * (V15) GPIO1_21: GSM_PWR_EN + * (U16) GPIO1_25: RST_GSM + * (T16) GPIO1_26: WLAN_EN + * (V17) GPIO1_27: WLAN_IRQ + * + * (C12) GPIO3_17: SIM_SEL + */ + + /* Bank 0 */ + {OFFSET(spi0_sclk), (MODE(7) | PULLUDDIS)}, /* (A17) gpio0[2] */ /* RST_GNSS */ + {OFFSET(spi0_cs0), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, /* (A16) gpio0[5] */ /* EXTINT_GNSS */ + {OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (C18) gpio0[7] */ /* IO_SHIELD */ + {OFFSET(mii1_txd3), (MODE(7) | PULLUDDIS)}, /* (J18) gpio0[16] */ /* RST_PHY~ */ + {OFFSET(gpmc_ad11), (MODE(7) | PULLUDDIS)}, /* (U12) gpio0[27] */ /* RST_SHIELD~ */ + + /* Bank 1 */ + {OFFSET(gpmc_a4), (MODE(7) | PULLUDDIS)}, /* (R14) gpio1[20] */ /* BT_EN */ + {OFFSET(gpmc_a5), (MODE(7) | PULLUDDIS)}, /* (V15) gpio1[21] */ /* GSM_PWR_EN */ + {OFFSET(gpmc_a9), (MODE(7) | PULLUDDIS)}, /* (U16) gpio1[25] */ /* RST_GSM */ + {OFFSET(gpmc_a10), (MODE(7) | PULLUDDIS)}, /* (T16) gpio1[26] */ /* WLAN_EN */ + {OFFSET(gpmc_a11), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (V17) gpio1[27] */ /* WLAN_IRQ */ + + /* TODO: What about all the unused GPMC pins ? */ + + /* Bank 2 */ +#if 0 + /* TODO: What is this meant for? */ + {OFFSET(lcd_data3), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (R4) gpio2[9] */ /* SYSBOOT_3 */ + {OFFSET(lcd_data4), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (T1) gpio2[10] */ /* SYSBOOT_4 */ + + /* TODO: Check other unued pins from sysboot block */ + /* Ensure PU/PD does not work against external signal */ + /* + * SYSBOOT 0,1,5,12,13 = Low + * SYSBOOT 2 = High + */ +#endif + + /* Bank 3 */ + {OFFSET(mcasp0_ahclkr), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, /* (C12) gpio3[17] */ /* SIM_SEL */ + {-1} +}; + +/* I2C0 PMIC */ +static struct module_pin_mux i2c0_pin_mux[] = { + {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (C17) I2C0_SDA */ + {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (C16) I2C0_SCL */ + {-1} +}; + +/* I2C2 System */ +static struct module_pin_mux i2c2_pin_mux[] = { + {OFFSET(uart1_rtsn), (MODE(3) | RXACTIVE | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (D17) I2C2_SCL */ + {OFFSET(uart1_ctsn), (MODE(3) | RXACTIVE | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (D18) I2C2_SDA */ + {-1}, +}; + +/* RMII1: Ethernet Switch */ +static struct module_pin_mux rmii1_pin_mux[] = { + /* RMII */ + {OFFSET(mii1_crs), MODE(1) | PULLUDDIS | RXACTIVE}, /* (H17) rmii1_crs */ + {OFFSET(mii1_rxerr), MODE(7) | PULLUDEN | PULLDOWN_EN | RXACTIVE}, /* (J15) gpio */ + {OFFSET(mii1_rxd0), MODE(1) | PULLUDDIS | RXACTIVE}, /* (M16) rmii1_rxd0 */ + {OFFSET(mii1_rxd1), MODE(1) | PULLUDDIS | RXACTIVE}, /* (L15) rmii1_rxd1 */ + {OFFSET(mii1_txen), MODE(1) | PULLUDDIS}, /* (J16) rmii1_txen */ + {OFFSET(mii1_txd0), MODE(1) | PULLUDDIS}, /* (K17) rmii1_txd0 */ + {OFFSET(mii1_txd1), MODE(1) | PULLUDDIS}, /* (K16) rmii1_txd1 */ + {OFFSET(rmii1_refclk), MODE(0) | PULLUDDIS | RXACTIVE}, /* (H18) rmii1_refclk */ + + /* SMI */ + {OFFSET(mdio_clk), MODE(0) | PULLUDDIS}, /* (M18) mdio_clk */ + {OFFSET(mdio_data), MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE}, /* (M17) mdio_data */ + + /* 25MHz Clock Output */ + {OFFSET(xdma_event_intr0), MODE(3)}, /* (A15) clkout1 (25 MHz clk for PHY) */ + {-1} +}; + +/* MMC0: WiFi */ +static struct module_pin_mux mmc0_sdio_pin_mux[] = { + {OFFSET(mmc0_clk), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (G17) MMC0_CLK */ + {OFFSET(mmc0_cmd), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (G18) MMC0_CMD */ + {OFFSET(mmc0_dat0), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (G16) MMC0_DAT0 */ + {OFFSET(mmc0_dat1), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (G15) MMC0_DAT1 */ + {OFFSET(mmc0_dat2), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (F18) MMC0_DAT2 */ + {OFFSET(mmc0_dat3), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (F17) MMC0_DAT3 */ + {-1} +}; + +/* MMC1: eMMC */ +static struct module_pin_mux mmc1_emmc_pin_mux[] = { + {OFFSET(gpmc_csn1), (MODE(2) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (U9) MMC1_CLK */ + {OFFSET(gpmc_csn2), (MODE(2) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (V9) MMC1_CMD */ + {OFFSET(gpmc_ad0), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (U7) MMC1_DAT0 */ + {OFFSET(gpmc_ad1), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (V7) MMC1_DAT1 */ + {OFFSET(gpmc_ad2), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (R8) MMC1_DAT2 */ + {OFFSET(gpmc_ad3), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (T8) MMC1_DAT3 */ + {OFFSET(gpmc_ad4), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (U8) MMC1_DAT4 */ + {OFFSET(gpmc_ad5), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (V8) MMC1_DAT5 */ + {OFFSET(gpmc_ad6), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (R9) MMC1_DAT6 */ + {OFFSET(gpmc_ad7), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (T9) MMC1_DAT7 */ + {-1} +}; + +/* USB_DRVBUS not used -> configure as GPIO */ +static struct module_pin_mux usb_pin_mux[] = { + {OFFSET(usb0_drvvbus), (MODE(7) | PULLUDDIS)}, /* (F16) USB0_DRVVBUS */ + {OFFSET(usb1_drvvbus), (MODE(7) | PULLUDDIS)}, /* (F15) USB1_DRVVBUS */ + {-1} +}; + +/* UART0: RS232/RS485 shield mode */ +static struct module_pin_mux uart0_pin_mux[] = { + {OFFSET(uart0_rxd), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (E15) UART0_RXD */ + {OFFSET(uart0_txd), (MODE(0) | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (E16) UART0_TXD */ + {-1}, +}; + +/* UART0: Shield I/F (UART, CAN) */ +/* Leave UART0 unconfigured because we want to configure it as needed by Linux (can/spi/uart/etc) */ +/* Mode 7 = GPIO */ +static struct module_pin_mux uart0_disabled_pin_mux[] = { + {OFFSET(uart0_rxd), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E15) GPIO1_10 */ + {OFFSET(uart0_txd), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E16) GPIO1_11 */ + {OFFSET(uart0_ctsn), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E18) GPIO1_8 */ + {OFFSET(uart0_rtsn), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (E17) GPIO1_9 */ + {-1}, +}; + +/* UART1: User (Debug/Console) */ +static struct module_pin_mux uart1_pin_mux[] = { + {OFFSET(uart1_rxd), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (D16) uart1_rxd */ + {OFFSET(uart1_txd), (MODE(0) | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (D15) uart1_txd */ + {-1}, +}; + +/* UART3: GNSS */ +static struct module_pin_mux uart3_pin_mux[] = { + {OFFSET(mii1_rxd3), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (L17) UART3_RXD */ + {OFFSET(mii1_rxd2), (MODE(1) | PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* (L16) UART3_TXD */ + {-1} +}; + +/* UART5: Highspeed UART for Bluetooth (no SLEWCTRL) */ +static struct module_pin_mux uart5_pin_mux[] = { + {OFFSET(lcd_data9), (MODE(4) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (U2) UART5_RXD */ + {OFFSET(lcd_data8), (MODE(4) | PULLUDEN | PULLUP_EN)}, /* (U1) UART5_TXD */ + {OFFSET(lcd_data14), (MODE(6) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (V4) uart5_ctsn */ + {OFFSET(lcd_data15), (MODE(6) | PULLUDEN | PULLUP_EN)}, /* (T5) uart5_rtsn */ + {-1} +}; + +static struct module_pin_mux unused_pin_mux[] = { + /* SYSBOOT6, 7, 10, 11: Not used pulldown active, receiver disabled */ + {OFFSET(lcd_data6), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, + {OFFSET(lcd_data7), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, + {OFFSET(lcd_data10), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, + {OFFSET(lcd_data11), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, + + /* TODO: GPMCA1..3, A6..8 */ + + {-1} +}; + + +void enable_board_pin_mux(void) +{ + configure_module_pin_mux(gpio_pin_mux); + + configure_module_pin_mux(rmii1_pin_mux); + configure_module_pin_mux(mmc0_sdio_pin_mux); + configure_module_pin_mux(mmc1_emmc_pin_mux); + configure_module_pin_mux(usb_pin_mux); + + configure_module_pin_mux(i2c0_pin_mux); + configure_module_pin_mux(i2c2_pin_mux); + + configure_module_pin_mux(uart3_pin_mux); + configure_module_pin_mux(uart5_pin_mux); + + configure_module_pin_mux(unused_pin_mux); +} + +void enable_uart0_pin_mux(void) +{ + configure_module_pin_mux(uart0_pin_mux); +} + +void disable_uart0_pin_mux(void) +{ + configure_module_pin_mux(uart0_disabled_pin_mux); +} + +void enable_uart1_pin_mux(void) +{ + configure_module_pin_mux(uart1_pin_mux); +} diff --git a/board/nm/nmhw24/u-boot.lds b/board/nm/nmhw24/u-boot.lds new file mode 100644 index 0000000000..965898ba25 --- /dev/null +++ b/board/nm/nmhw24/u-boot.lds @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2004-2008 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + *(.__image_copy_start) + *(.vectors) + CPUDIR/start.o (.text*) + board/nm/nmhw24/built-in.o (.text*) + *(.text*) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = ALIGN(4); + + . = .; + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = ALIGN(4); + + .__efi_runtime_start : { + *(.__efi_runtime_start) + } + + .efi_runtime : { + *(efi_runtime_text) + *(efi_runtime_data) + } + + .__efi_runtime_stop : { + *(.__efi_runtime_stop) + } + + .efi_runtime_rel_start : + { + *(.__efi_runtime_rel_start) + } + + .efi_runtime_rel : { + *(.relefi_runtime_text) + *(.relefi_runtime_data) + } + + .efi_runtime_rel_stop : + { + *(.__efi_runtime_rel_stop) + } + + . = ALIGN(4); + + .image_copy_end : + { + *(.__image_copy_end) + } + + .rel_dyn_start : + { + *(.__rel_dyn_start) + } + + .rel.dyn : { + *(.rel*) + } + + .rel_dyn_end : + { + *(.__rel_dyn_end) + } + + .hash : { *(.hash*) } + + .end : + { + *(.__end) + } + + _image_binary_end = .; + + /* + * Deprecated: this MMU section is used by pxa at present but + * should not be used by new boards/CPUs. + */ + . = ALIGN(4096); + .mmutable : { + *(.mmutable) + } + +/* + * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c + * __bss_base and __bss_limit are for linker only (overlay ordering) + */ + + .bss_start __rel_dyn_start (OVERLAY) : { + KEEP(*(.__bss_start)); + __bss_base = .; + } + + .bss __bss_base (OVERLAY) : { + *(.bss*) + . = ALIGN(4); + __bss_limit = .; + } + + .bss_end __bss_limit (OVERLAY) : { + KEEP(*(.__bss_end)); + } + + .dynsym _image_binary_end : { *(.dynsym) } + .dynbss : { *(.dynbss) } + .dynstr : { *(.dynstr*) } + .dynamic : { *(.dynamic*) } + .gnu.hash : { *(.gnu.hash) } + .plt : { *(.plt*) } + .interp : { *(.interp*) } + .gnu : { *(.gnu*) } + .ARM.exidx : { *(.ARM.exidx*) } +} diff --git a/configs/am335x_nmhw24_defconfig b/configs/am335x_nmhw24_defconfig new file mode 100644 index 0000000000..2b71316531 --- /dev/null +++ b/configs/am335x_nmhw24_defconfig @@ -0,0 +1,49 @@ +CONFIG_ARM=y +CONFIG_TARGET_AM335X_NMHW24=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_SPL=y +CONFIG_SPL_STACK_R=y +CONFIG_FIT=y +CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT" +CONFIG_HUSH_PARSER=y +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_PROMPT="Press s to abort autoboot in %d seconds\n" +CONFIG_AUTOBOOT_STOP_STR="s" +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_ASKENV=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_DFU_TFTP=y +CONFIG_SYS_NS16550=y +CONFIG_USB=y +CONFIG_USB_MUSB_HOST=y +CONFIG_USB_MUSB_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_G_DNL_MANUFACTURER="Texas Instruments" +CONFIG_G_DNL_VENDOR_NUM=0x0451 +CONFIG_G_DNL_PRODUCT_NUM=0xd022 +CONFIG_OF_LIBFDT=y +# CONFIG_BOOTP_PXE_CLIENTARCH is not set +# CONFIG_CMD_PXE is not set +# CONFIG_CMD_BOOTEFI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_ELF is not set +# CONFIG_FPGA is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_CMD_PMIC is not set +# CONFIG_EFI_LOADER is not set +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set diff --git a/include/configs/am335x_nmhw24.h b/include/configs/am335x_nmhw24.h new file mode 100644 index 0000000000..1546254c8f --- /dev/null +++ b/include/configs/am335x_nmhw24.h @@ -0,0 +1,302 @@ +/* + * am335x_nmhw24.h + * + * Copyright (C) 2018-2019 NetModule AG - http://www.netmodule.com/ + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __CONFIG_AM335X_NMHW24_H +#define __CONFIG_AM335X_NMHW24_H + +#include + +#undef CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC + +#undef CONFIG_HW_WATCHDOG +#undef CONFIG_OMPAP_WATCHDOG +#undef CONFIG_SPL_WATCHDOG_SUPPORT + +#ifndef CONFIG_SPL_BUILD +# define CONFIG_TIMESTAMP +# define CONFIG_LZO +#endif + +#define CONFIG_SYS_BOOTM_LEN (16 << 20) + +#define MACH_TYPE_TIAM335EVM 3589 /* Until the next sync */ +#define CONFIG_MACH_TYPE MACH_TYPE_TIAM335EVM +#define CONFIG_BOARD_LATE_INIT + +/* Clock Defines */ +#define V_OSCK 0 /* 0 means detect from sysboot1 config */ +#define V_SCLK (V_OSCK) + +#include + +/* Dynamic override for PHY_ANEG_TIMEOUT value */ +#ifndef CONFIG_SPL_BUILD +# ifndef __ASSEMBLER__ +int eth_phy_timeout(void); +# endif +#endif +#define PHY_ANEG_TIMEOUT eth_phy_timeout() +#define PHY_ANEG_DEFAULT_TIMEOUT 5000 + +#define CONFIG_ARP_TIMEOUT 200 +#undef CONFIG_NET_RETRY_COUNT +#define CONFIG_NET_RETRY_COUNT 5 +#define CONFIG_BOOTP_MAY_FAIL + +#ifndef CONFIG_SPL_BUILD + + +/* + * Memory map for booting Linux + * + * 0x80000000 63MB KERNEL_ADDR (kernel_addr), kernel execution address + * 0x83F00000 1MB FDT_ADDR (fdt_addr_r), device tree loading address if not included in kernel + * 0x84000000 126MB RD_ADDR (ramdisk_addr_r), ramdisc loading address + * 0x8BE00000 2MB PXE_ADDR (pxefile_addr_r), pxe configuration file (pxe get command) + * 0x8C000000 1MB LOAD_ADDR (load_addr), loading address for generic files + * 0x8C100000 63MB KERNEL_ADDR_R (kernel_addr_r), kernel loading address (will be relocated to kernel_addr) + * 0x90000000 256MB <>, Free space 512MB systems + * 0xA0000000 512MB <>, Free space, 1GB systems only + * 0xC0000000 End of RAM + */ + +#define KERNEL_ADDR "0x80000000" +#define FDT_ADDR "0x83F00000" +#define RD_ADDR "0x84000000" +#define PXE_ADDR "0x8BE00000" +#define LOAD_ADDR "0x8C000000" +#define KERNEL_ADDR_R "0x8C100000" + +#if 0 // HW20 differences +#define LOAD_ADDR "0x83000000" 8c0000 +#define FDT_ADDR "0x82000000" 83f000 +#define PXE_ADDR "0x82800000" 8be000 +#define FDT_HIGH_ADDR "0x87000000" +#define INIT_RD_ADDR "0x88000000" +#endif + + +/* + * Avoid copying ramdisc and dtb above 512MB, as it breaks Linux boot. + * -1 means "do not copy" to high address, use in place. + */ +#define INITRD_HIGH_ADDR "0x84000000" +#define FDT_HIGH_ADDR "0xffffffff" + +// TODO: Check big differences to NMHW20 +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_image=am335x-nmhw24-prod1.dtb\0" \ + "fdt_addr_r=" FDT_ADDR "\0" \ + "fdt_high=" FDT_HIGH_ADDR "\0" \ + "initrd_high=" INITRD_HIGH_ADDR "\0" \ + "kernel_addr=" KERNEL_ADDR "\0" \ + "kernel_addr_r=" KERNEL_ADDR_R "\0" \ + "load_addr=" LOAD_ADDR "\0" \ + "pxefile_addr_r=" PXE_ADDR "\0" \ + "ramdisk_addr_r=" RD_ADDR "\0" \ + "defaultconsole=ttyS1\0" \ + "fdt_skip_update=yes\0" \ + "ethprime=cpsw\0" \ + "ethopts=ti_cpsw.rx_packet_max=1526\0" \ + "bootcmd_otenv=ext4load mmc 1:1 $load_addr /boot/loader/uEnv.txt; " \ + "env import -t $load_addr $filesize; " \ + "setenv bootargs $bootargs root=/dev/ram0 console=$defaultconsole,115200 " \ + "$ethopts rw ostree_root=/dev/mmcblk1p1\0" \ + "bootcmd_rd_in_mmc=ext4load mmc 1:1 $kernel_addr_r /boot$kernel_image; " \ + "bootm $kernel_addr_r\0" \ + "bootcmd=run bootcmd_otenv; run bootcmd_rd_in_mmc\0" \ + "bootdelay=0\0" \ + "ipaddr=192.168.1.1\0" \ + "serverip=192.168.1.254\0" \ + "tftptimeout=2000\0" \ + "tftptimeoutcountmax=5\0" \ + "bootpretryperiod=10000\0" \ + "autoload=false\0" \ + "tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr_r recovery-dtb; " \ + "setenv bootargs rdinit=/etc/preinit console=$defaultconsole,115200 " \ + "debug ethopts; " \ + "bootz $kernel_addr - $fdt_addr_r\0" \ + "pxe_recovery=mdio up $ethprime && dhcp && pxe get && pxe boot\0" \ + "recovery=run pxe_recovery || setenv ipaddr $ipaddr; setenv serverip $serverip; run tftp_recovery\0" \ + /* setenv ipaddr and serverip is necessary, because dhclient can destroy the IPs internally */ + + +#if 0 +#define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_image=kernel.bin\0" \ + "fdt_image=openwrt-nrhw20-nb1601.dtb\0"\ + "modeboot=sdboot\0" \ + "fdt_addr=" FDT_ADDR "\0" \ + "kernel_addr=" KERNEL_ADDR "\0" \ + "load_addr=" LOAD_ADDR "\0" \ + "root_part=1\0" /* Default root partition, overwritten in board file */ \ + "defaultconsole=ttyS1\0" /* Default output console */ \ + "add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk1p$root_part rootfstype=ext4 " \ + "console=$defaultconsole,115200 rootwait loglevel=4 ti_cpsw.rx_packet_max=1526\0" \ + "add_version_bootargs=setenv bootargs $bootargs\0" \ + "fdt_skip_update=yes\0" \ + "ethprime=cpsw\0" \ + "sdbringup=echo Try bringup boot && ext4load mmc 1:$root_part $kernel_addr /boot/zImage && " \ + "ext4load mmc 1:$root_part $fdt_addr /boot/$fdt_image && setenv bootargs $bootargs rw;\0" \ + "sdprod=ext4load mmc 1:$root_part $kernel_addr /boot/$kernel_image && " \ + "ext4load mmc 1:$root_part $fdt_addr /boot/$fdt_image && setenv bootargs $bootargs ro;\0" \ + "sdboot=if mmc dev 1; then echo Copying Linux from SD to RAM...; "\ + "if test -e mmc 1:$root_part /boot/$kernel_image; then run sdprod; " \ + "else run sdbringup; fi; " \ + "run add_sd_bootargs; run add_version_bootargs; run shieldcmd; " \ + "bootz $kernel_addr - $fdt_addr; fi\0" \ + "bootcmd_otenv=ext4load mmc 1:1 $load_addr /boot/loader/uEnv.txt; " \ + "env import -t $load_addr $filesize; " \ + "setenv bootargs $bootargs root=/dev/ram0 console=$defaultconsole,115200 " \ + "$ethopts rw ostree_root=/dev/mmcblk1p1\0" \ + "bootcmd_rd_in_mmc=ext4load mmc 1:1 $kernel_addr_r /boot$kernel_image; " \ + "bootm $kernel_addr_r\0" \ + "bootcmd=run bootcmd_otenv; run bootcmd_rd_in_mmc\0" \ + "ipaddr=192.168.1.1\0" \ + "serverip=192.168.1.254\0" \ + "pxefile_addr_r=" PXE_ADDR "\0" \ + "fdt_addr_r=" FDT_ADDR "\0" \ + "fdt_high=" FDT_HIGH_ADDR "\0" \ + "kernel_addr_r=" KERNEL_ADDR "\0" \ + "ramdisk_addr_r=" LOAD_ADDR "\0" \ + "initrd_high=" INIT_RD_ADDR "\0" \ + "bootpretryperiod=1000\0" \ + "tftptimeout=2000\0" \ + "tftptimeoutcountmax=5\0" \ + "bootpretryperiod=2000\0" \ + "autoload=false\0" \ + "shieldcmd=\0" \ + "tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; " \ + "setenv bootargs rdinit=/etc/preinit console=$defaultconsole,115200 " \ + "debug ti_cpsw.rx_packet_max=1526; run shieldcmd; " \ + "bootz $kernel_addr - $fdt_addr\0" \ + "pxe_recovery=sleep 3 && dhcp && pxe get && pxe boot\0" \ + "recovery=run pxe_recovery || setenv ipaddr $ipaddr; setenv serverip $serverip; run tftp_recovery\0" \ + /* setenv ipaddr and serverip is necessary, because dhclient can destroy the IPs inernally */ + +#endif + +#endif + +// TODO: Check if ok? +#define CONFIG_ZERO_BOOTDELAY_CHECK + +/* UART Configuration */ +#define CONFIG_SYS_NS16550_COM1 0x44e09000 /* UART0: XModem Boot */ +#define CONFIG_SYS_NS16550_COM2 0x48022000 /* UART1: eMMC Boot, User UART */ + +#define CONFIG_I2C +#define CONFIG_I2C_MULTI_BUS + +#define CONFIG_CMD_EEPROM +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* Main EEPROM */ +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 4 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 50 /* TODO: Can this be reduced to 20ms */ + +/* Put Environment in eMMC */ +#define CONFIG_ENV_OFFSET (512 * 128) /* @ 512*256 SPL starts */ +#define CONFIG_ENV_SIZE (4 * 1024) +#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_SYS_MMC_ENV_DEV 1 + +#undef CONFIG_SPL_ENV_SUPPORT +#undef CONFIG_SPL_NAND_SUPPORT +#undef CONFIG_SPL_ONENAND_SUPPORT + +/* We need to disable SPI to not confuse the eeprom env driver */ +#undef CONFIG_SPI +#undef CONFIG_SPI_BOOT +#undef CONFIG_SPL_OS_BOOT + +#define CONFIG_SPL_YMODEM_SUPPORT + +#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/am33xx/u-boot-spl.lds" + +#define CONFIG_SUPPORT_EMMC_BOOT + +/* + * USB configuration. We enable MUSB support, both for host and for + * gadget. We set USB0 as peripheral and USB1 as host, based on the + * board schematic and physical port wired to each. Then for host we + * add mass storage support and for gadget we add both RNDIS ethernet + * and DFU. + */ +#define CONFIG_USB_MUSB_DSPS +#define CONFIG_ARCH_MISC_INIT +#define CONFIG_USB_MUSB_PIO_ONLY +#define CONFIG_USB_MUSB_DISABLE_BULK_COMBINE_SPLIT +#define CONFIG_AM335X_USB0 +#define CONFIG_AM335X_USB0_MODE MUSB_HOST + +/* To support eMMC booting */ +#define CONFIG_STORAGE_EMMC +#define CONFIG_FASTBOOT_FLASH_MMC_DEV 1 + +#ifdef CONFIG_USB_MUSB_HOST +#define CONFIG_USB_STORAGE +#endif + +#ifdef CONFIG_USB_MUSB_GADGET +/* Removing USB gadget and can be enabled adter adding support usb DM */ +#ifndef CONFIG_DM_ETH +#define CONFIG_USB_ETHER +#define CONFIG_USB_ETH_RNDIS +#define CONFIG_USBNET_HOST_ADDR "de:ad:be:af:00:00" +#endif /* CONFIG_DM_ETH */ +#endif /* CONFIG_USB_MUSB_GADGET */ + + +/* + * Disable MMC DM for SPL build and can be re-enabled after adding + * DM support in SPL + */ +#ifdef CONFIG_SPL_BUILD +#undef CONFIG_DM_MMC +#undef CONFIG_TIMER +#endif + +#if defined(CONFIG_SPL_BUILD) +/* Remove other SPL modes. */ +#undef CONFIG_SPL_NAND_SUPPORT +#define CONFIG_ENV_IS_NOWHERE +#undef CONFIG_PARTITION_UUIDS +#undef CONFIG_EFI_PARTITION +#endif + +/* Network. */ +#define CONFIG_PHYLIB +#define CONFIG_PHY_SMSC + +#define CONFIG_CMD_MEMTEST +#define CONFIG_SYS_MEMTEST_START 0x84000000 +#define CONFIG_SYS_MEMTEST_END 0x87900000 + +#define CONFIG_CMD_PXE + +#define CONFIG_OF_BOARD_SETUP + +#define CONFIG_JTAG_MARKER_SPL 0x402FFF00 +#define CONFIG_JTAG_MARKER_UBOOT 0x807FFF00 + +/* SPL command is not needed */ +#undef CONFIG_CMD_SPL + +/* Never enable ISO it is broken and can lead to a crash */ +#undef CONFIG_ISO_PARTITION + +#endif /* ! __CONFIG_AM335X_NMHW24_H */