From 7518ca5631273ba5d65160adde3a756dcf6b10bc Mon Sep 17 00:00:00 2001 From: Rene Straub Date: Fri, 15 Dec 2017 15:00:24 +0100 Subject: [PATCH] nrhw20: initial commit --- arch/arm/Kconfig | 9 + board/nm/nrhw20/Kconfig | 26 + board/nm/nrhw20/Makefile | 13 + board/nm/nrhw20/board.c | 831 ++++++++++++++++++++++++++++++++ board/nm/nrhw20/board.h | 30 ++ board/nm/nrhw20/fileaccess.c | 43 ++ board/nm/nrhw20/fileaccess.h | 14 + board/nm/nrhw20/mux.c | 229 +++++++++ board/nm/nrhw20/shield.c | 73 +++ board/nm/nrhw20/shield.h | 21 + board/nm/nrhw20/shield_can.c | 193 ++++++++ board/nm/nrhw20/shield_can.h | 9 + board/nm/nrhw20/shield_comio.c | 251 ++++++++++ board/nm/nrhw20/shield_comio.h | 6 + board/nm/nrhw20/u-boot.lds | 158 ++++++ configs/am335x_nrhw20_defconfig | 49 ++ include/configs/am335x_nrhw20.h | 247 ++++++++++ 17 files changed, 2202 insertions(+) create mode 100644 board/nm/nrhw20/Kconfig create mode 100644 board/nm/nrhw20/Makefile create mode 100644 board/nm/nrhw20/board.c create mode 100644 board/nm/nrhw20/board.h create mode 100644 board/nm/nrhw20/fileaccess.c create mode 100644 board/nm/nrhw20/fileaccess.h create mode 100644 board/nm/nrhw20/mux.c create mode 100644 board/nm/nrhw20/shield.c create mode 100644 board/nm/nrhw20/shield.h create mode 100644 board/nm/nrhw20/shield_can.c create mode 100644 board/nm/nrhw20/shield_can.h create mode 100644 board/nm/nrhw20/shield_comio.c create mode 100644 board/nm/nrhw20/shield_comio.h create mode 100644 board/nm/nrhw20/u-boot.lds create mode 100644 configs/am335x_nrhw20_defconfig create mode 100644 include/configs/am335x_nrhw20.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c865dfab99..cdeb779f85 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -390,6 +390,14 @@ config TARGET_AM335X_NETBIRD_V2 select DM_SERIAL select DM_GPIO +config TARGET_AM335X_NRHW20 + bool "Support am335x_nrhw20" + 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 @@ -888,6 +896,7 @@ source "board/isee/igep0033/Kconfig" source "board/mpl/vcma9/Kconfig" source "board/nm/netbird/Kconfig" source "board/nm/netbird_v2/Kconfig" +source "board/nm/nrhw20/Kconfig" source "board/olimex/mx23_olinuxino/Kconfig" source "board/phytec/pcm051/Kconfig" source "board/phytec/pcm052/Kconfig" diff --git a/board/nm/nrhw20/Kconfig b/board/nm/nrhw20/Kconfig new file mode 100644 index 0000000000..b7d13ee3ee --- /dev/null +++ b/board/nm/nrhw20/Kconfig @@ -0,0 +1,26 @@ +if TARGET_AM335X_NRHW20 + +config SYS_BOARD + default "nrhw20" + +config SYS_VENDOR + default "nm" + +config SYS_SOC + default "am33xx" + +config SYS_CONFIG_NAME + default "am335x_nrhw20" + +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/nrhw20/Makefile b/board/nm/nrhw20/Makefile new file mode 100644 index 0000000000..c4b21a1d3a --- /dev/null +++ b/board/nm/nrhw20/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 shield.o shield_can.o shield_comio.o fileaccess.o diff --git a/board/nm/nrhw20/board.c b/board/nm/nrhw20/board.c new file mode 100644 index 0000000000..c5864a1f2c --- /dev/null +++ b/board/nm/nrhw20/board.c @@ -0,0 +1,831 @@ +/* + * board.c + * + * Board functions for TI AM335X based boards + * + * 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 +#include "../common/bdparser.h" +#include "../common/board_descriptor.h" +#include "board.h" +#include "shield.h" +#include "shield_can.h" +#include "shield_comio.h" +#include "fileaccess.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* GPIO that controls power to DDR on EVM-SK */ +#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) +#define GPIO_DDR_VTT_EN GPIO_TO_PIN(0, 7) +#define ICE_GPIO_DDR_VTT_EN GPIO_TO_PIN(0, 18) +#define GPIO_PR1_MII_CTRL GPIO_TO_PIN(3, 4) +#define GPIO_MUX_MII_CTRL GPIO_TO_PIN(3, 10) +#define GPIO_FET_SWITCH_CTRL GPIO_TO_PIN(0, 7) +#define GPIO_PHY_RESET GPIO_TO_PIN(2, 5) + +#define NETBIRD_GPIO_RST_PHY_N GPIO_TO_PIN(0, 16) +#define NETBIRD_GPIO_PWR_GSM GPIO_TO_PIN(1, 21) +#define NETBIRD_GPIO_SUPPLY_GSM GPIO_TO_PIN(0, 31) +#define NETBIRD_GPIO_RST_GSM GPIO_TO_PIN(1, 25) +#define NETBIRD_GPIO_WLAN_EN GPIO_TO_PIN(3, 10) +#define NETBIRD_GPIO_BT_EN GPIO_TO_PIN(3, 4) +#define NETBIRD_GPIO_EN_GPS_ANT GPIO_TO_PIN(2, 24) +#define NETBIRD_GPIO_LED_A GPIO_TO_PIN(1, 14) +#define NETBIRD_GPIO_LED_B GPIO_TO_PIN(1, 15) +#define NETBIRD_GPIO_RESET_BUTTON GPIO_TO_PIN(0, 2) +#define NETBIRD_GPIO_USB_PWR_EN GPIO_TO_PIN(1, 27) +#define NETBIRD_GPIO_USB_PWR_EN_2 GPIO_TO_PIN(2, 4) // On new version this gpio is used + +#define DDR3_CLOCK_FREQUENCY (400) + +#if defined(CONFIG_SPL_BUILD) || \ + (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_DM_ETH)) +static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; +#endif + +#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 */ + +static BD_Context bdctx[3]; /* The descriptor context */ + +#define SHIELD_COM_IO 0 +#define SHIELD_DUALCAN 1 + +static int _bd_init(void) +{ + 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 (legacy support)\n", __func__); + } + + if (bd_get_context(&bdctx[2], BD_EEPROM_ADDR, PARTITION_ADDRESS) != 0) { + printf("%s() no valid partition table found\n", __func__); + } + + bd_register_context_list(bdctx, ARRAY_SIZE(bdctx)); + return 0; +} + +/* + * Read header information from EEPROM into global structure. + */ +static inline int __maybe_unused read_eeprom(void) +{ + return _bd_init(); +} + +struct serial_device *default_serial_console(void) +{ + if (spl_boot_device() == BOOT_DEVICE_UART) { + enable_uart0_pin_mux(); + return &eserial1_device; + } + else { + return &eserial2_device; + } +} + +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + +static const struct ddr_data ddr3_netbird_data = { + /* Ratios were optimized by DDR3 training software from TI */ + .datardsratio0 = 0x39, + .datawdsratio0 = 0x3f, + .datafwsratio0 = 0x98, + .datawrsratio0 = 0x7d, +}; + +static const struct cmd_control ddr3_netbird_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_netbird_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, +}; + + +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + /* break into full u-boot on 'c' */ + if (serial_tstc() && serial_getc() == 'c') + return 1; + +#ifdef CONFIG_SPL_ENV_SUPPORT + env_init(); + env_relocate_spec(); + if (getenv_yesno("boot_os") != 1) + return 1; +#endif + + return 0; +} +#endif + +#define OSC (V_OSCK/1000000) +struct dpll_params dpll_ddr_nbhw16= { + DDR3_CLOCK_FREQUENCY, OSC-1, 1, -1, -1, -1, -1}; + +void am33xx_spl_board_init(void) +{ + /* Get the frequency */ + dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev); + + /* Set CPU speed to 600 MHZ */ + dpll_mpu_opp100.m = MPUPLL_M_600; + + /* Set CORE Frequencies to OPP100 */ + do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); + + /* TODO: Check PMIC settings */ + + /* Clear th PFM Flag on DCDC4 */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_DCDC4, 0x00, 0x80)) { + puts ("tps65218_reg_write failure (DCDC4 clear PFM Flag)\n"); + }; + + /* Disable DCDC2 because it is not used and could make noise */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_ENABLE1, 0, 0x02)) { + puts ("tps65218_reg_write failure (DCDC2 disable)\n"); + }; + + /* Set MPU Frequency to what we detected now that voltages are set */ + do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100); + + if (read_eeprom() < 0) + puts("Could not get board ID.\n"); +} + +const struct dpll_params *get_dpll_ddr_params(void) +{ + dpll_ddr_nbhw16.n = (get_osclk() / 1000000) - 1; + return &dpll_ddr_nbhw16; +} + +void set_uart_mux_conf(void) +{ + enable_uart0_disabled_pin_mux(); + enable_uart1_pin_mux(); +} + +void set_mux_conf_regs(void) +{ + enable_board_pin_mux(); +} + + +const struct ctrl_ioregs ioregs_netbird = { + .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_netbird, + &ddr3_netbird_data, + &ddr3_netbird_cmd_ctrl_data, + &ddr3_netbird_emif_reg_data, 0); +} + +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ + +static void request_and_set_gpio(int gpio, 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, 0); + if (ret < 0) { + printf("%s: Unable to set %s as output\n", __func__, name); + goto err_free_gpio; + } + + gpio_set_value(gpio, value); + + 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); + + +int check_reset_button(void) +{ + int counter = 0; + int ret; + + ret = gpio_request(NETBIRD_GPIO_RESET_BUTTON, "reset button"); + if (ret < 0) { + printf("Unable to request reset button gpio\n"); + return -1; + } + + ret = gpio_direction_input(NETBIRD_GPIO_RESET_BUTTON); + if (ret < 0) { + printf("Unable to set reset button as input\n"); + return -1; + } + + /* Check if reset button is pressed for at least 2 seconds ≃ ~5s */ + do { + if (gpio_get_value(NETBIRD_GPIO_RESET_BUTTON) != 0) break; + udelay(100000); /* 100ms */ + counter++; + + if (counter==20) {/* Indicate factory reset threshold */ + gpio_set_value(NETBIRD_GPIO_LED_A, 0); + gpio_set_value(NETBIRD_GPIO_LED_B, 0); + udelay(400000); /* 400ms */ + /* let LED blink up once */ + gpio_set_value(NETBIRD_GPIO_LED_A, 1); + gpio_set_value(NETBIRD_GPIO_LED_B, 1); + udelay(400000); /* 400ms */ + gpio_set_value(NETBIRD_GPIO_LED_A, 0); + gpio_set_value(NETBIRD_GPIO_LED_B, 0); + } else if (counter==120) { /* Indicate recovery boot threshold */ + /* let LED blink up twice */ + gpio_set_value(NETBIRD_GPIO_LED_A, 1); + gpio_set_value(NETBIRD_GPIO_LED_B, 1); + udelay(400000); /* 400ms */ + gpio_set_value(NETBIRD_GPIO_LED_A, 0); + gpio_set_value(NETBIRD_GPIO_LED_B, 0); + udelay(400000); /* 400ms */ + gpio_set_value(NETBIRD_GPIO_LED_A, 1); + gpio_set_value(NETBIRD_GPIO_LED_B, 1); + udelay(400000); /* 400ms */ + gpio_set_value(NETBIRD_GPIO_LED_A, 0); + gpio_set_value(NETBIRD_GPIO_LED_B, 0); + } + } while (counter<120); + + if (counter < 20) return 0; /* Don't do anything for duration < 2s */ + + if (counter < 120) /* Do factory reset for duration between ~5s and ~15s */ + { + char new_bootargs[512]; + char *bootargs = getenv("bootargs"); + + if (bootargs==0) bootargs=""; + + printf("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); + + printf("bootargs = %s\n", new_bootargs); + + return 1; + } else { /* Boot into recovery for duration > 15s */ + /* set consoledev to external port */ + setenv("consoledev", "ttyS1"); + + printf("Booting recovery image...\n"); + + /* Set bootcmd to run recovery */ + setenv("bootcmd", "run recovery"); + + return 0; + } + return 0; +} + +/* TODO: Rework to use USB Hub */ +static void enable_ext_usb(void) +{ + REQUEST_AND_CLEAR_GPIO(NETBIRD_GPIO_USB_PWR_EN); + REQUEST_AND_CLEAR_GPIO(NETBIRD_GPIO_USB_PWR_EN_2); + /* Disable LS2 */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_ENABLE2, 0x00, 0x04)) { + puts ("tps65218_reg_write failure (LS2 enable)\n"); + }; + + /* Discharge LS2 to have proper 0V at the output */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_CONFIG3, 0x02, 0x02)) { + puts ("tps65218_reg_write failure (LS2 discharge)\n"); + }; + + mdelay(10); + + gpio_set_value(NETBIRD_GPIO_USB_PWR_EN, 1); + gpio_set_value(NETBIRD_GPIO_USB_PWR_EN_2, 1); + + mdelay(50); + + /* Disable discharge LS2 */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_CONFIG3, 0x00, 0x02)) { + puts ("tps65218_reg_write failure (LS2 discharge)\n"); + }; + + /* Configure 500mA on LS2 */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_CONFIG2, 0x02, 0x03)) { + puts ("tps65218_reg_write failure (LS2 enable)\n"); + }; + + /* Enable LS2 */ + if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_ENABLE2, 0x04, 0x04)) { + puts ("tps65218_reg_write failure (LS2 enable)\n"); + }; +} + +/* + * Basic board specific setup. Pinmux has been handled already. + */ +int board_init(void) +{ +#if defined(CONFIG_HW_WATCHDOG) + hw_watchdog_init(); +#endif + + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; +#if defined(CONFIG_NOR) || defined(CONFIG_NAND) + gpmc_init(); +#endif + + /* Remove power, and make sure reset is set once */ + REQUEST_AND_CLEAR_GPIO(NETBIRD_GPIO_SUPPLY_GSM); + REQUEST_AND_SET_GPIO(NETBIRD_GPIO_RST_GSM); + REQUEST_AND_CLEAR_GPIO(NETBIRD_GPIO_PWR_GSM); + mdelay(20); + /* Enable gsm supply */ + gpio_set_value(NETBIRD_GPIO_SUPPLY_GSM, 1); + mdelay(20); + /* Take modem out of reset, we have to wait 300ms afterwards */ + gpio_set_value(NETBIRD_GPIO_RST_GSM, 0); + mdelay(300); + /* Do power up sequence, this modem has a special power up sequence + * where we have to pull PWR for > 1s but < 7s (see manual) */ + gpio_set_value(NETBIRD_GPIO_PWR_GSM, 1); + mdelay(1200); + gpio_set_value(NETBIRD_GPIO_PWR_GSM, 0); + + REQUEST_AND_CLEAR_GPIO(NETBIRD_GPIO_LED_A); + REQUEST_AND_SET_GPIO(NETBIRD_GPIO_LED_B); + REQUEST_AND_SET_GPIO(NETBIRD_GPIO_RST_PHY_N); + REQUEST_AND_CLEAR_GPIO(NETBIRD_GPIO_WLAN_EN); + REQUEST_AND_CLEAR_GPIO(NETBIRD_GPIO_BT_EN); + + /* There are two funcions on the same mux mode for MMC2_DAT7 we want + * to use RMII2_CRS_DV so we need to set SMA2 Register to 1 + * See SPRS717J site 49 (10)*/ + #define SMA2_REGISTER (CTRL_BASE + 0x1320) + writel(0x01, SMA2_REGISTER); /* Select RMII2_CRS_DV instead of MMC2_DAT7 */ + + enable_ext_usb(); + + printf("OSC: %lu Hz\n", get_osclk()); + + return 0; +} + +/* TODO: Can most likely be removed. */ + +/* Enable the ecap2 pwm see siemens/pxm2 */ +static int enable_pwm(void) +{ +#define PWM_TICKS 0xBEB +#define PWM_DUTY 0x5F5 +#define AM33XX_ECAP2_BASE 0x48304100 +#define PWMSS2_BASE 0x48304000 + struct pwmss_regs *pwmss = (struct pwmss_regs *)PWMSS2_BASE; + struct pwmss_ecap_regs *ecap; + int ticks = PWM_TICKS; + int duty = PWM_DUTY; + + ecap = (struct pwmss_ecap_regs *)AM33XX_ECAP2_BASE; + /* enable clock */ + setbits_le32(&pwmss->clkconfig, ECAP_CLK_EN); + /* TimeStamp Counter register */ + writel(0x0, &ecap->ctrphs); + + setbits_le16(&ecap->ecctl2, + (ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK)); + + /* config period */ + writel(ticks - 1, &ecap->cap3); + writel(ticks - 1, &ecap->cap1); + /* config duty */ + writel(duty, &ecap->cap2); + writel(duty, &ecap->cap4); + /* start */ + setbits_le16(&ecap->ecctl2, ECTRL2_CTRSTP_FREERUN); + return 0; +} + +/* Enable the input clock for ecap2 and then enable the pwm */ +static void enable_wlan_clock(void) +{ + struct cm_perpll *const cmper = (struct cm_perpll*)CM_PER; + struct ctrl_dev *const cdev= (struct ctrl_dev*)CTRL_DEVICE_BASE; + u32 *const clk_domains[] = { 0 }; + + u32 *const clk_modules_nmspecific[] = { + &cmper->epwmss2clkctrl, + 0 + }; + + do_enable_clocks(clk_domains, clk_modules_nmspecific, 1); + + /* Enable timebase clock for pwmss2 */ + writel(0x04, &cdev->pwmssctrl); + + enable_pwm(); +} + +#if !defined(CONFIG_SPL_BUILD) + +void set_console(void) +{ + char buf[8]; + char *defaultconsole = getenv("defaultconsole"); + int shield_id = bd_get_shield(0); + + if (defaultconsole == 0) { + /* Use the default console */ + setenv("defaultconsole", "ttyS1"); + } + + /* Don't allow changing to ttyS0 because ttyS0 is not available in the + * kernel if no comio shield is available */ + if (shield_id != SHIELD_COM_IO) { + return; + } + + /* With comio shield the defaultconsole should be ttyS0 and not ttyS1 */ + setenv("defaultconsole", "ttyS0"); + + /* If consoldev is set take this as productive conosle instead of default console */ + if (read_file("/root/boot/consoledev", buf, 5) != 5) { + puts("Invalid file consoledev\n"); + return; + } + + if (strstr(buf, "tty")==buf) { + buf[5] = 0; + setenv("defaultconsole", buf); + } +} + +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, use legacy name\n"); + strcpy(devicetreename, "am335x-nbhw16-prod2.dtb"); + } + + setenv("fdt_image", devicetreename); +} + +static void get_hw_version(void) +{ + int hw_ver, hw_rev; + char hw_versions[16]; + char new_env[256]; + + /* add hardware versions to environment */ + bd_get_hw_version(&hw_ver, &hw_rev); + printf("HW16: V%d.%d\n", hw_ver, hw_rev); + snprintf(hw_versions, sizeof(hw_versions), "CP=%d.%d", hw_ver, hw_rev); + snprintf(new_env, sizeof(new_env), "setenv bootargs $bootargs %s", hw_versions); + setenv("add_version_bootargs", new_env); +} + +static void check_fct(void) +{ + /* TODO: Documentation ! */ + + // EEPROM at 0x51 means FCT test station + + /* If probe fails we are sure no eeprom is connected */ + if (i2c_probe(0x51) == 0) { + printf("Entering fct mode\n"); + setenv ("bootcmd", ""); + } +} + +static void set_fdtshieldcmd(const char *fdt_cmd) +{ + setenv("fdtshieldcmd", fdt_cmd); +} + +struct shield_command { + int shield_id; + const char *name; + const char *default_shieldcmd; + const char *fdtshieldcmd; + void (*init)(void); +}; + +static struct shield_command known_shield_commands[] = { + { + SHIELD_COM_IO, + "comio", + "shield comio mode rs232", + "fdt get value serial0 /aliases serial0;" \ + "fdt set $serial0 status okay", + comio_shield_init + }, + { + SHIELD_DUALCAN, + "dualcan", + "shield dualcan termination off off", + "fdt get value can0 /aliases d_can0;" \ + "fdt get value can1 /aliases d_can1;" \ + "fdt set $can0 status okay;" \ + "fdt set $can1 status okay;", + 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 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); + + set_fdtshieldcmd(cmd->fdtshieldcmd); +} + +static void shield_init(void) +{ + shield_config(); +} +#endif + +#ifdef CONFIG_BOARD_LATE_INIT +int board_late_init(void) +{ +#if !defined(CONFIG_SPL_BUILD) + int boot_partition; + + if (read_eeprom() < 0) + puts("Could not get board ID.\n"); + + /* 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); + + check_reset_button(); + + get_hw_version(); + + set_devicetree_name(); + + set_console(); +#endif + +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + int rc; + char *name = NULL; + + set_board_info_env(name); +#endif + + enable_wlan_clock(); + +#if !defined(CONFIG_SPL_BUILD) + shield_init(); + + check_fct(); + +#endif + + return 0; +} +#endif + +#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_addr = 0, + }, + { + .slave_reg_ofs = 0x308, + .sliver_reg_ofs = 0xdc0, + .phy_addr = 1, + }, +}; + +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"); + } +} + +/* + * 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 rv, n = 0; + uint8_t mac_addr0[6] = {02,00,00,00,00,01}; + __maybe_unused struct ti_am_eeprom *header; + +#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); + cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RMII; + cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_RMII; + cpsw_slaves[0].phy_addr = 0; + cpsw_slaves[1].phy_addr = 1; + + 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); + + 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 diff --git a/board/nm/nrhw20/board.h b/board/nm/nrhw20/board.h new file mode 100644 index 0000000000..fd16233e37 --- /dev/null +++ b/board/nm/nrhw20/board.h @@ -0,0 +1,30 @@ +/* + * 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 i2c0 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 enable_uart0_disabled_pin_mux(void); +void enable_uart1_pin_mux(void); +void enable_uart2_pin_mux(void); +void enable_uart3_pin_mux(void); +void enable_uart4_pin_mux(void); +void enable_uart5_pin_mux(void); +void enable_i2c0_pin_mux(void); +void enable_board_pin_mux(void); + +#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio)) +#endif diff --git a/board/nm/nrhw20/fileaccess.c b/board/nm/nrhw20/fileaccess.c new file mode 100644 index 0000000000..78723ac1e2 --- /dev/null +++ b/board/nm/nrhw20/fileaccess.c @@ -0,0 +1,43 @@ +#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/nrhw20/fileaccess.h b/board/nm/nrhw20/fileaccess.h new file mode 100644 index 0000000000..00bbaaea04 --- /dev/null +++ b/board/nm/nrhw20/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/nrhw20/mux.c b/board/nm/nrhw20/mux.c new file mode 100644 index 0000000000..749ab79180 --- /dev/null +++ b/board/nm/nrhw20/mux.c @@ -0,0 +1,229 @@ +/* + * mux.c + * + * 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 +#include "board.h" + +static struct module_pin_mux uart2_pin_mux[] = { + {OFFSET(spi0_sclk), (MODE(1) | PULLUP_EN | RXACTIVE)}, /* UART2_RXD */ + {OFFSET(spi0_d0), (MODE(1) | PULLUDEN)}, /* UART2_TXD */ + {-1}, +}; + +static struct module_pin_mux uart3_pin_mux[] = { + {OFFSET(spi0_cs1), (MODE(1) | PULLUP_EN | RXACTIVE)}, /* UART3_RXD */ + {OFFSET(ecap0_in_pwm0_out), (MODE(1) | PULLUDEN)}, /* UART3_TXD */ + {-1}, +}; + +static struct module_pin_mux uart4_pin_mux[] = { + {OFFSET(gpmc_wait0), (MODE(6) | PULLUP_EN | RXACTIVE)}, /* UART4_RXD */ + {OFFSET(gpmc_wpn), (MODE(6) | PULLUDEN)}, /* UART4_TXD */ + {-1}, +}; + +static struct module_pin_mux uart5_pin_mux[] = { + {OFFSET(lcd_data9), (MODE(4) | PULLUP_EN | RXACTIVE)}, /* UART5_RXD */ + {OFFSET(lcd_data8), (MODE(4) | PULLUDEN)}, /* UART5_TXD */ + {-1}, +}; + +static struct module_pin_mux i2c0_pin_mux[] = { + {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | + PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* I2C_DATA */ + {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | + PULLUDEN | PULLUP_EN | SLEWCTRL)}, /* I2C_SCLK */ + {-1}, +}; + +/* V2OK */ +static struct module_pin_mux uart0_disabled_netbird_pin_mux[] = { + /* Leave UART0 unconfigured because we want to configure it as needed by linux (can/spi/uart/etc) */ + {OFFSET(uart0_rxd), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E15) UART0_RXD */ + {OFFSET(uart0_txd), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E16) UART0_TXD */ + {OFFSET(uart0_ctsn), (MODE(7) | PULLUDDIS | RXACTIVE )}, /* (E18) UART0_CTSN */ + {OFFSET(uart0_rtsn), (MODE(7) | PULLUDEN | PULLUP_EN )}, /* (E17) UART0_RTSN */ + {-1}, +}; + +static struct module_pin_mux uart0_netbird_pin_mux[] = { + /* Leave UART0 unconfigured because we want to configure it as needed by linux (can/spi/uart/etc) */ + {OFFSET(uart0_rxd), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (E15) UART0_RXD */ + {OFFSET(uart0_txd), (MODE(0) | PULLUDEN | PULLUP_EN)}, /* (E16) UART0_TXD */ + {-1}, +}; + +/* V2OK */ +static struct module_pin_mux uart1_netbird_pin_mux[] = { + {OFFSET(uart1_rxd), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (D16) uart1_rxd.uart1_rxd */ + {OFFSET(uart1_txd), (MODE(0) | PULLUDEN | PULLUP_EN)}, /* (D15) uart1_txd.uart1_txd */ + {-1}, +}; + +/* V2OK */ +static struct module_pin_mux rmii1_netbird_pin_mux[] = { + {OFFSET(mii1_crs), MODE(1) | PULLUDDIS | RXACTIVE}, /* (H17) mii1_crs.rmii1_crs */ + {OFFSET(mii1_rxerr), MODE(1) | PULLUDDIS | RXACTIVE}, /* (J15) mii1_rxerr.rmii1_rxerr */ + {OFFSET(mii1_txen), MODE(1) | PULLUDDIS }, /* (J16) mii1_txen.rmii1_txen */ + {OFFSET(mii1_txd0), MODE(1) | PULLUDDIS }, /* (K17) mii1_txd0.rmii1_txd0 */ + {OFFSET(mii1_txd1), MODE(1) | PULLUDDIS }, /* (K16) mii1_txd1.rmii1_txd1 */ + {OFFSET(mii1_rxd0), MODE(1) | PULLUDDIS | RXACTIVE }, /* (M16) mii1_rxd0.rmii1_rxd0 */ + {OFFSET(mii1_rxd1), MODE(1) | PULLUDDIS | RXACTIVE }, /* (L15) mii1_rxd1.rmii1_rxd1 */ + {OFFSET(rmii1_refclk), MODE(0) | PULLUDDIS | RXACTIVE}, /* (H18) rmii1_refclk.rmii1_refclk */ + {OFFSET(mdio_clk), MODE(0) | PULLUDDIS }, /* (M18) mdio_clk.mdio_clk */ + {OFFSET(mdio_data), MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE }, /* (M17) mido_data.mdio_data */ + {OFFSET(xdma_event_intr0), MODE(3) }, /* (A15) xdma_event_intr0.clkout1 (25 MHz clk for MDIO) */ + {-1}, +}; + +static struct module_pin_mux mmc0_sdio_netbird_pin_mux[] = { + {OFFSET(mmc0_clk), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* MMC0_CLK */ + {OFFSET(mmc0_cmd), (MODE(0) | PULLUDEN | PULLUP_EN)}, /* MMC0_CMD */ + {OFFSET(mmc0_dat0), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC0_DAT0 */ + {OFFSET(mmc0_dat1), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC0_DAT1 */ + {OFFSET(mmc0_dat2), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC0_DAT2 */ + {OFFSET(mmc0_dat3), (MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC0_DAT3 */ + {-1}, +}; + +static struct module_pin_mux mmc1_emmc_netbird_pin_mux[] = { + {OFFSET(gpmc_csn1), (MODE(2) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* MMC1_CLK */ + {OFFSET(gpmc_csn2), (MODE(2) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* MMC1_CMD */ + {OFFSET(gpmc_ad0), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC1_DAT0 */ + {OFFSET(gpmc_ad1), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC1_DAT1 */ + {OFFSET(gpmc_ad2), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC1_DAT2 */ + {OFFSET(gpmc_ad3), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC1_DAT3 */ + {OFFSET(gpmc_ad4), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC1_DAT3 */ + {OFFSET(gpmc_ad5), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC1_DAT3 */ + {OFFSET(gpmc_ad6), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC1_DAT3 */ + {OFFSET(gpmc_ad7), (MODE(1) | PULLUDEN | PULLUP_EN | RXACTIVE )}, /* MMC1_DAT3 */ + {-1}, +}; + +static struct module_pin_mux gpio_netbird_pin_mux[] = { + /* Bank 0 */ + {OFFSET(spi0_sclk), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, /* (A17) spi0_sclk.gpio0[2] */ /* BUTTON */ + {OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (C18) eCAP0_in_PWM0_out.gpio0[7] */ /* PWM */ + {OFFSET(mii1_txd3), (MODE(7) | PULLUDDIS)}, /* (J18) gmii1_txd3.gpio0[16] */ /* RST_PHY~ */ + {OFFSET(gpmc_ad11), (MODE(7) | PULLUDDIS)}, /* (U12) gpmc_ad11.gpio0[27] */ /* RST_EXT~ */ + /* Bank 1 */ + {OFFSET(gpmc_ad14), (MODE(7) | PULLUDDIS)}, /* (V13) gpmc_ad14.gpio1[14] */ /* LED_A */ + {OFFSET(gpmc_ad15), (MODE(7) | PULLUDDIS)}, /* (U13) gpmc_ad15.gpio1[15] */ /* LED_B */ + {OFFSET(gpmc_a11), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (V17) gpmc_a11.gpio1[27] */ /* USB_PWR_EN */ + {OFFSET(gpmc_a9), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (U16) gpmc_a9.gpio1[25] */ /* RST_GSM */ + {OFFSET(gpmc_csn3), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (U17) gpmc_csn3.gpio0[31] */ /* GSM_SUPP_EN */ + {OFFSET(gpmc_a5), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (V15) gpmc_a5.gpio1[21] */ /* GSM_PWR_EN */ + /* Bank 2 */ + {OFFSET(lcd_data3), (MODE(7) | PULLUDEN| PULLUP_EN)}, /* (V5) lcd_pclk.gpio2[9] */ /* SYSBOOT */ + {OFFSET(lcd_data4), (MODE(7) | PULLUDEN| PULLUP_EN)}, /* (V5) lcd_pclk.gpio2[10] */ /* SYSBOOT */ + /* Bank 3 */ + {OFFSET(mii1_rxdv), (MODE(7) | PULLUDDIS)}, /* (J17) gmii1_rxdv.gpio3[4] */ /* BT_EN */ + {OFFSET(mii1_rxdv), (MODE(7) | RXACTIVE)}, /* (K18) gmii1_txclk.gpio3[9] */ /* WLAN_IRQ */ + {OFFSET(mii1_rxclk), (MODE(7) | PULLUDDIS)}, /* (L18) gmii1_rxclk.gpio3[10] */ /* WLAN_EN */ + {OFFSET(mcasp0_ahclkr), (MODE(4) | PULLUDEN | PULLUP_EN)}, /* (C12) mcasp0_ahclkr.ecap2_in_pwm2_out */ /* WLAN_CLK */ + {-1}, +}; + +static struct module_pin_mux usb_netbird_pin_mux[] = { + {OFFSET(usb0_drvvbus), (MODE(0) | PULLUDDIS | PULLDOWN_EN)}, /* (F16) USB0_DRVVBUS.USB0_DRVVBUS */ /* PWM */ + {OFFSET(usb1_drvvbus), (MODE(0) | PULLUDDIS | PULLDOWN_EN)}, /* (F15) USB1_DRVVBUS.USB1_DRVVBUS */ /* RST_PHY~ */ + {-1}, +}; + +static struct module_pin_mux unused_netbird_pin_mux[] = { + {OFFSET(lcd_data6), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, /* SYSBOOT6 is not used bulldown active, receiver disabled */ + {OFFSET(lcd_data7), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, /* SYSBOOT7 is not used bulldown active, receiver disabled */ + {OFFSET(lcd_data10), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, /* SYSBOOT10 is not used bulldown active, receiver disabled */ + {OFFSET(lcd_data11), (MODE(7) | PULLUDEN | PULLDOWN_EN)}, /* SYSBOOT11 is not used bulldown active, receiver disabled */ + {-1}, +}; + +void enable_uart0_pin_mux(void) +{ + configure_module_pin_mux(uart0_netbird_pin_mux); +} + +void enable_uart0_disabled_pin_mux(void) +{ + configure_module_pin_mux(uart0_disabled_netbird_pin_mux); +} + +void enable_uart1_pin_mux(void) +{ + configure_module_pin_mux(uart1_netbird_pin_mux); +} + +void enable_uart2_pin_mux(void) +{ + configure_module_pin_mux(uart2_pin_mux); +} + +void enable_uart3_pin_mux(void) +{ + configure_module_pin_mux(uart3_pin_mux); +} + +void enable_uart4_pin_mux(void) +{ + configure_module_pin_mux(uart4_pin_mux); +} + +void enable_uart5_pin_mux(void) +{ + configure_module_pin_mux(uart5_pin_mux); +} + +void enable_i2c0_pin_mux(void) +{ + configure_module_pin_mux(i2c0_pin_mux); +} + +/* + * The AM335x GP EVM, if daughter card(s) are connected, can have 8 + * different profiles. These profiles determine what peripherals are + * valid and need pinmux to be configured. + */ +#define PROFILE_NONE 0x0 +#define PROFILE_0 (1 << 0) +#define PROFILE_1 (1 << 1) +#define PROFILE_2 (1 << 2) +#define PROFILE_3 (1 << 3) +#define PROFILE_4 (1 << 4) +#define PROFILE_5 (1 << 5) +#define PROFILE_6 (1 << 6) +#define PROFILE_7 (1 << 7) +#define PROFILE_MASK 0x7 +#define PROFILE_ALL 0xFF + +/* CPLD registers */ +#define I2C_CPLD_ADDR 0x35 +#define CFG_REG 0x10 + +void enable_board_pin_mux(void) +{ + /* Netbird board */ + configure_module_pin_mux(gpio_netbird_pin_mux); + configure_module_pin_mux(rmii1_netbird_pin_mux); + configure_module_pin_mux(mmc0_sdio_netbird_pin_mux); + configure_module_pin_mux(mmc1_emmc_netbird_pin_mux); + configure_module_pin_mux(usb_netbird_pin_mux); + configure_module_pin_mux(i2c0_pin_mux); + configure_module_pin_mux(unused_netbird_pin_mux); +} diff --git a/board/nm/nrhw20/shield.c b/board/nm/nrhw20/shield.c new file mode 100644 index 0000000000..97f1394a9d --- /dev/null +++ b/board/nm/nrhw20/shield.c @@ -0,0 +1,73 @@ +#undef DEBUG + +#include +#include +#include + +#include "shield.h" +#include "board.h" + +#define MAX_SHIELDS 16 + +static struct shield_t *shields[MAX_SHIELDS]; +static int shield_count = 0; + +/* Perhaps this function shouldn't leave in shields.c? */ +int shield_gpio_request_as_input(unsigned int gpio, const char *label) +{ + int ret; + + ret = gpio_request(gpio, label); + if ((ret < 0)) { + printf("Could not request shield slot %s gpio\n", label); + return -1; + } + + ret = gpio_direction_input(gpio); + if ((ret < 0)) { + printf("Could not configure shield slot %s gpio as input\n", label); + return -1; + } + + return 0; +} + +void shield_register(struct shield_t *shield) +{ + if (shield_count >= MAX_SHIELDS) { + printf("Max shield count reached (%d), please increment MAX_SHIELDS\n", MAX_SHIELDS); + return; + } + shields[shield_count++] = shield; +} + +int shield_set_mode(const char* shield_type, int argc, char * const argv[]) +{ + int i; + + for (i = 0; i < shield_count; i++) { + if (strcmp(shield_type, shields[i]->name) == 0) { + return shields[i]->setmode(argv, argc); + } + } + printf("## Error: No %s shield installed\n", shield_type); + /* Do not return error, to not show usage (request by rs) */ + return 0; +} + +static int do_shieldmode(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 2) { + return -1; + } + + return shield_set_mode(argv[1], argc - 2, &argv[2]); +} + +U_BOOT_CMD( + shield, 6, 1, do_shieldmode, + "Set the shield mode", + "dualcan termination [on|off] [on|off]\n" + "shield comio mode [rs232|rs485] termination [on|off]\n" +); + diff --git a/board/nm/nrhw20/shield.h b/board/nm/nrhw20/shield.h new file mode 100644 index 0000000000..2ab27a0941 --- /dev/null +++ b/board/nm/nrhw20/shield.h @@ -0,0 +1,21 @@ +/**@file /home/eichenberger/projects/nbhw16/u-boot/board/nm/netbird_v2/shield.h + * @author eichenberger + * @version 704 + * @date + * Created: Wed 31 May 2017 02:56:16 PM CEST \n + * Last Update: Wed 31 May 2017 02:56:16 PM CEST + */ +#ifndef SHIELD_H +#define SHIELD_H + +struct shield_t{ + char name[64]; + int (*setmode)(char * const argv[], int argc); +}; + +int shield_setmode(int mode); +void shield_register(struct shield_t *shield); + +int shield_gpio_request_as_input(unsigned int gpio, const char *label); + +#endif // SHIELD_H diff --git a/board/nm/nrhw20/shield_can.c b/board/nm/nrhw20/shield_can.c new file mode 100644 index 0000000000..99632eee56 --- /dev/null +++ b/board/nm/nrhw20/shield_can.c @@ -0,0 +1,193 @@ +#undef DEBUG + +#include +#include +#include + +#include "shield.h" +#include "board.h" + +#define NETBIRD_GPIO_RST_SHIELD_N GPIO_TO_PIN(0, 27) +#define NETBIRD_GPIO_LATCH GPIO_TO_PIN(0, 7) +#define NETBIRD_GPIO_MODE_0 GPIO_TO_PIN(1, 8) +#define NETBIRD_GPIO_MODE_1 GPIO_TO_PIN(1, 10) + + +static int shield_slot_initialized = 0; + + +static struct module_pin_mux can_shield_netbird_pin_mux_config[] = { + /* Leave UART0 unconfigured because we want to configure it as needed by linux (can/spi/uart/etc) */ + {OFFSET(uart0_ctsn), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* CAN1 tx */ + {OFFSET(uart0_rxd), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* CAN0 tx */ + {OFFSET(ecap0_in_pwm0_out), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* Latch EN */ + {-1}, +}; + +static struct module_pin_mux can_shield_netbird_pin_mux_final[] = { + /* Leave UART0 unconfigured because we want to configure it as needed by linux (can/spi/uart/etc) */ + {OFFSET(uart0_ctsn), (MODE(2) | PULLUDEN | PULLUP_EN)}, /* CAN1 tx */ + {OFFSET(uart0_rtsn), (MODE(2) | PULLUDDIS | RXACTIVE)}, /* CAN1 rx */ + {OFFSET(uart0_txd), (MODE(2) | PULLUDDIS | RXACTIVE)}, /* CAN0 rx */ + {OFFSET(uart0_rxd), (MODE(2) | PULLUDEN | PULLUP_EN)}, /* CAN0 tx */ + {-1}, +}; + +static int request_gpios(void) +{ + int ret; + + debug("Shield configure gpios\n"); + ret = shield_gpio_request_as_input(NETBIRD_GPIO_RST_SHIELD_N, "shield-rst"); + if ((ret < 0)) + return -1; + ret = shield_gpio_request_as_input(NETBIRD_GPIO_LATCH, "shield-load"); + if ((ret < 0)) + return -1; + ret = shield_gpio_request_as_input(NETBIRD_GPIO_MODE_0, "shield-mode0"); + if ((ret < 0)) + return -1; + ret = shield_gpio_request_as_input(NETBIRD_GPIO_MODE_1, "shield-mode1"); + if ((ret < 0)) + return -1; + + shield_slot_initialized = 1; + return 0; +} + +static int configure_shieldmode(int mode) +{ + int ret; + + if (mode < 0 || mode > 3) { + debug("Invalid shield mode %d\n", mode); + return -1; + } + + debug("Shield type dualcan\n"); + debug ("Set shield mode to %d\n", mode); + + if (!shield_slot_initialized) { + if (request_gpios()) { + puts("Failed to request gpios\n"); + return -1; + } + } + + debug("Configure shield pin muxing for configuration\n"); + configure_module_pin_mux(can_shield_netbird_pin_mux_config); + + debug("Make sure shield module is in reset\n"); + ret = gpio_direction_output(NETBIRD_GPIO_RST_SHIELD_N, 0); + if (ret < 0) { + puts("Can not set shield-rst as output\n"); + return -1; + } + udelay(10); + + debug("Set latch to high\n"); + ret = gpio_direction_output(NETBIRD_GPIO_LATCH, 1); + if (ret < 0) { + puts("Can not set shield-load as output\n"); + return -1; + } + udelay(10); + + debug("Write mode to GPIOs\n"); + ret = gpio_direction_output(NETBIRD_GPIO_MODE_0, mode & 0x01); + if (ret < 0) { + puts("Can not set shield-mode0 as output\n"); + return -1; + } + ret = gpio_direction_output(NETBIRD_GPIO_MODE_1, mode & 0x02); + if (ret < 0) { + puts("Can not set shield-mode1 as output\n"); + return -1; + } + udelay(10); + + debug("Set latch to low\n"); + gpio_set_value(NETBIRD_GPIO_LATCH, 0); + udelay(10); + + debug("Set mode0 and mode1 to highz again\n"); + ret = gpio_direction_input(NETBIRD_GPIO_MODE_0); + if ((ret < 0)) { + puts("Could not configure shield slot mode0 gpio as input\n"); + return -1; + } + + ret = gpio_direction_input(NETBIRD_GPIO_MODE_1); + if ((ret < 0)) { + puts("Could not configure shield slot mode1 gpio as input\n"); + return -1; + } + udelay(10); + + debug("Take shield out of reset\n"); + gpio_set_value(NETBIRD_GPIO_RST_SHIELD_N, 1); + udelay(10); + + debug("Set final can shield muxing\n"); + configure_module_pin_mux(can_shield_netbird_pin_mux_final); + + return 0; + +} + +static int get_termination(const char* termination) +{ + if (strcmp("on", termination) == 0) { + return 1; + } + else if (strcmp("off", termination) == 0) { + return 0; + } + + debug ("Invalid termination mode %s (falling back to off)", termination); + return -1; +} + +static int get_mode_from_args(char * const argv[], int argc) +{ +#define CAN_PORTS 2 + int terminations[CAN_PORTS]; + int i; + + assert(argc == (CAN_PORTS + 1)); + + if (strcmp ("termination", argv[0])) { + debug("The only option for dualcan is terminations\n"); + return -1; + } + + for (i = 0; i < CAN_PORTS; i ++) { + terminations[i] = get_termination(argv[i + 1]); + if (terminations[i] < 0) { + return -1; + } + } + + /* Termination is inverse */ + return (!terminations[0] << 0) | (!terminations[1] << 1); +} + +static int set_shieldmode(char * const argv[], int argc) +{ + if (argc != 3) { + debug("Too few arguments for dualcan\n"); + return -1; + } + + return configure_shieldmode(get_mode_from_args(argv, argc)); +} + +struct shield_t can_shield = { + "dualcan", set_shieldmode +}; + +void can_shield_init(void) +{ + shield_register(&can_shield); +} + diff --git a/board/nm/nrhw20/shield_can.h b/board/nm/nrhw20/shield_can.h new file mode 100644 index 0000000000..21684cd4f7 --- /dev/null +++ b/board/nm/nrhw20/shield_can.h @@ -0,0 +1,9 @@ +#ifndef SHIELD_CAN_H +#define SHIELD_CAN_H + +int shield_can_init(void); +int shield_can_setmode(int mode); + +void can_shield_init(void); + +#endif // SHIELD_CAN_H diff --git a/board/nm/nrhw20/shield_comio.c b/board/nm/nrhw20/shield_comio.c new file mode 100644 index 0000000000..2efac38db2 --- /dev/null +++ b/board/nm/nrhw20/shield_comio.c @@ -0,0 +1,251 @@ +#undef DEBUG + +#include +#include +#include + +#include "shield.h" +#include "board.h" + +#define NETBIRD_GPIO_RST_SHIELD_N GPIO_TO_PIN(0, 27) +#define NETBIRD_GPIO_LOAD GPIO_TO_PIN(1, 9) +#define NETBIRD_GPIO_MODE_0 GPIO_TO_PIN(1, 11) +#define NETBIRD_GPIO_MODE_1 GPIO_TO_PIN(1, 10) + + +static int shield_slot_initialized = 0; + + +/* V2OK */ +static struct module_pin_mux shield_gpio_safe_netbird_pin_mux[] = { + /* Leave UART0 unconfigured because we want to configure it as needed by linux (can/spi/uart/etc) */ + {OFFSET(uart0_rxd), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E15) UART0_RXD */ + {OFFSET(uart0_txd), (MODE(7) | PULLUDDIS | RXACTIVE)}, /* (E16) UART0_TXD */ + {-1}, +}; + +static struct module_pin_mux shield_gpio_netbird_pin_mux[] = { + /* Leave UART0 unconfigured because we want to configure it as needed by linux (can/spi/uart/etc) */ + {OFFSET(uart0_rxd), (MODE(7) | PULLUDDIS)}, /* (E15) UART0_RXD */ + {OFFSET(uart0_txd), (MODE(7) | PULLUDEN | PULLUP_EN)}, /* (E16) UART0_TXD */ + {-1}, +}; + +static int request_gpios(void) +{ + int ret; + + debug("Extension slot init\n"); + ret = shield_gpio_request_as_input(NETBIRD_GPIO_RST_SHIELD_N, "shield-rst"); + if ((ret < 0)) + return -1; + ret = shield_gpio_request_as_input(NETBIRD_GPIO_LOAD, "shield-load"); + if ((ret < 0)) + return -1; + ret = shield_gpio_request_as_input(NETBIRD_GPIO_MODE_0, "shield-mode0"); + if ((ret < 0)) + return -1; + ret = shield_gpio_request_as_input(NETBIRD_GPIO_MODE_1, "shield-mode1"); + if ((ret < 0)) + return -1; + + shield_slot_initialized = 1; + return 0; +} + +static int configure_shieldmode(int mode) +{ + int ret; + + if (mode < 0 || mode > 3) { + debug ("Invalid shield mode %d\n", mode); + return -1; + } + + debug("Shield type comio\n"); + debug ("Set shield mode to %d\n", mode); + + if (!shield_slot_initialized) { + if (request_gpios()) { + puts("Failed to request gpios\n"); + return -1; + } + } + + debug("Make sure shield module is in reset\n"); + ret = gpio_direction_output(NETBIRD_GPIO_RST_SHIELD_N, 0); + if (ret < 0) { + puts("Can not set shield-rst as output\n"); + return -1; + } + udelay(10); + + debug("Enable gpio pull-ups\n"); + configure_module_pin_mux(shield_gpio_netbird_pin_mux); + + debug("Set load to low\n"); + ret = gpio_direction_output(NETBIRD_GPIO_LOAD, 0); + if (ret < 0) { + puts("Can not set shield-load as output\n"); + return -1; + } + udelay(10); + + debug("Write mode to GPIOs\n"); + ret = gpio_direction_output(NETBIRD_GPIO_MODE_0, mode & 0x01); + if (ret < 0) { + puts("Can not set shield-mode0 as output\n"); + return -1; + } + ret = gpio_direction_output(NETBIRD_GPIO_MODE_1, mode & 0x02); + if (ret < 0) { + puts("Can not set shield-mode1 as output\n"); + return -1; + } + udelay(10); + + debug("Set load to high\n"); + gpio_set_value(NETBIRD_GPIO_LOAD, 1); + udelay(10); + + debug("Set mode0 and mode1 to highz again\n"); + ret = gpio_direction_input(NETBIRD_GPIO_MODE_0); + if ((ret < 0)) { + puts("Could not configure shield slot mode0 gpio as input\n"); + return -1; + } + + ret = gpio_direction_input(NETBIRD_GPIO_MODE_1); + if ((ret < 0)) { + puts("Could not configure shield slot mode1 gpio as input\n"); + return -1; + } + udelay(10); + + debug("Disable pullups on shield gpios\n"); + configure_module_pin_mux(shield_gpio_safe_netbird_pin_mux); + udelay(10); + + debug("Take shield out of reset\n"); + gpio_set_value(NETBIRD_GPIO_RST_SHIELD_N, 1); + udelay(10); + + debug("Set gpio load as input again\n"); + ret = gpio_direction_input(NETBIRD_GPIO_LOAD); + if (ret < 0) { + puts("Can not configure shield slot load as input"); + return -1; + } + + return 0; +} + +enum mode_nr { + RS232, + RS485, + UNKNOWN +}; + +struct mode { + enum mode_nr nr; + const char* name; + int argc; +}; + +struct mode modes[] = { + {RS232, "rs232", 0}, + {RS485, "rs485", 2} +}; + +static const struct mode *get_mode(const char *mode) +{ + int i; + for (i = 0; i < ARRAY_SIZE(modes); i++) { + if (strcmp(modes[i].name, mode) == 0) { + return &modes[i]; + } + } + return NULL; +} + +static int get_termination(const char* termination) +{ + if (strcmp("on", termination) == 0) { + return 1; + } + else if (strcmp("off", termination) == 0) { + return 0; + } + + debug ("Invalid termination mode %s (falling back to off)", termination); + return -1; +} + +static int get_mode_from_args(char * const argv[], int argc) +{ + int termination = 0; + int rs232 = 0; + const struct mode *selected_mode; + + assert(argc >= 2); + + if (strcmp ("mode", argv[0])) { + debug("Invalid arguments (see help)\n"); + return -1; + } + + selected_mode = get_mode(argv[1]); + if (selected_mode == NULL) { + debug("Mode %s not supported\n", argv[1]); + return -1; + } + + debug ("Mode %s, index %d, argc %d\n", selected_mode->name, + selected_mode->nr, selected_mode->argc); + + if (selected_mode->argc != argc - 2) { + debug("Invalid argument count for mode %s (should %d is %d)\n", + argv[1], selected_mode->argc, argc - 2); + return -1; + } + + if (selected_mode->nr == RS485) { + if (strcmp("termination", argv[2])) { + debug("Invalid arguments, do not configure termination\n"); + return -1; + } + + termination = get_termination(argv[3]); + if (termination < 0) { + debug("Invalid termination %s\n", argv[3]); + return -1; + } + } + else { + rs232 = 1; + } + + /* Termination is inverse */ + return (rs232 << 0) | ((!termination) << 1); +} + +int set_shieldmode(char * const argv[], int argc) +{ + if (argc < 2) { + debug("Too few arguments for comio\n"); + return -1; + } + + /* -1 will make configure_shieldmode to faile and is okay therefore */ + return configure_shieldmode(get_mode_from_args(argv, argc)); +} + +struct shield_t comio_shield = { + "comio", set_shieldmode +}; + +void comio_shield_init(void) +{ + shield_register(&comio_shield); +} + diff --git a/board/nm/nrhw20/shield_comio.h b/board/nm/nrhw20/shield_comio.h new file mode 100644 index 0000000000..2b2602e917 --- /dev/null +++ b/board/nm/nrhw20/shield_comio.h @@ -0,0 +1,6 @@ +#ifndef SHIELD_COMIO_H +#define SHIELD_COMIO_H + +void comio_shield_init(void); + +#endif // SHIELD_COMIO_H diff --git a/board/nm/nrhw20/u-boot.lds b/board/nm/nrhw20/u-boot.lds new file mode 100644 index 0000000000..d1f951e170 --- /dev/null +++ b/board/nm/nrhw20/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/nrhw20/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_nrhw20_defconfig b/configs/am335x_nrhw20_defconfig new file mode 100644 index 0000000000..1030ac6772 --- /dev/null +++ b/configs/am335x_nrhw20_defconfig @@ -0,0 +1,49 @@ +CONFIG_ARM=y +CONFIG_TARGET_AM335X_NRHW20=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_nrhw20.h b/include/configs/am335x_nrhw20.h new file mode 100644 index 0000000000..d12e869817 --- /dev/null +++ b/include/configs/am335x_nrhw20.h @@ -0,0 +1,247 @@ +/* + * am335x_evm.h + * + * 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_NRHW20_H +#define __CONFIG_AM335X_NRHW20_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 + +#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 +#define KERNEL_ADDR "0x80000000" +#define LOAD_ADDR "0x83000000" +#define FDT_ADDR "0x82000000" +#define PXE_ADDR "0x82800000" +#define CONFIG_EXTRA_ENV_SETTINGS \ + "kernel_image=kernel.bin\0" \ + "fdt_image=openwrt-nbhw16-nb800.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, overwritte in board file */ \ + "defaultconsole=ttyS1\0" /* Default output console */ \ + "add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 console=$defaultconsole,115200 rootwait loglevel=4\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; run modifyfdtcmd; " \ + "bootz $kernel_addr - $fdt_addr; fi\0" \ + "bootcmd=run sdboot\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" \ + "kernel_addr_r=" KERNEL_ADDR "\0" \ + "ramdisk_addr_r=" LOAD_ADDR "\0" \ + "bootpretryperiod=1000\0" \ + "tftptimeout=2000\0" \ + "tftptimeoutcountmax=5\0" \ + "bootpretryperiod=2000\0" \ + "autoload=false\0" \ + "shieldcmd=\0" \ + "fdtshieldcmd=\0" \ + "modifyfdtcmd=fdt addr $fdt_addr; run fdtshieldcmd;\0" \ + "tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; setenv bootargs rdinit=/etc/preinit console=$defaultconsole,115200 debug; run shieldcmd; run modifyfdtcmd; 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 + +/* NS16550 Configuration */ +#define CONFIG_SYS_NS16550_COM1 0x44e09000 /* Base EVM has UART0 */ +#define CONFIG_SYS_NS16550_COM2 0x48022000 /* UART1 */ +#define CONFIG_SYS_NS16550_COM3 0x48024000 /* UART2 */ +#define CONFIG_SYS_NS16550_COM4 0x481a6000 /* UART3 */ +#define CONFIG_SYS_NS16550_COM5 0x481a8000 /* UART4 */ +#define CONFIG_SYS_NS16550_COM6 0x481aa000 /* UART5 */ +#define CONFIG_BAUDRATE 115200 +#define CONFIG_CONS_INDEX 2 /* Use UART1 as standard UART (1 = UART0) */ + +#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 + +#define CONFIG_ENV_IS_IN_EEPROM +#define CONFIG_ENV_OFFSET 0x1000 /* The Environment is located at 4k */ +#define CONFIG_ENV_SIZE 0x800 /* The maximum size is 2k */ +#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_POWER_SUPPORT +#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 + +/* Fastboot */ +#define CONFIG_USB_FUNCTION_FASTBOOT +#define CONFIG_CMD_FASTBOOT +#define CONFIG_ANDROID_BOOT_IMAGE +#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR +#define CONFIG_FASTBOOT_BUF_SIZE 0x07000000 + +/* 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 + +/* USB Device Firmware Update support */ +#ifndef CONFIG_SPL_BUILD +#define CONFIG_USB_FUNCTION_DFU +#define CONFIG_DFU_MMC +#define DFU_ALT_INFO_MMC \ + "dfu_alt_info_mmc=" \ + "boot part 0 1;" \ + "rootfs part 0 2;" \ + "MLO fat 0 1;" \ + "MLO.raw raw 0x100 0x100;" \ + "u-boot.img.raw raw 0x300 0x400;" \ + "spl-os-args.raw raw 0x80 0x80;" \ + "spl-os-image.raw raw 0x900 0x2000;" \ + "spl-os-args fat 0 1;" \ + "spl-os-image fat 0 1;" \ + "u-boot.img fat 0 1;" \ + "uEnv.txt fat 0 1\0" +#define DFU_ALT_INFO_NAND "" +#define CONFIG_DFU_RAM +#define DFU_ALT_INFO_RAM \ + "dfu_alt_info_ram=" \ + "kernel ram 0x80200000 0xD80000;" \ + "fdt ram 0x80F80000 0x80000;" \ + "ramdisk ram 0x81000000 0x4000000\0" +#define DFUARGS \ + "dfu_alt_info_emmc=rawemmc raw 0 3751936\0" \ + DFU_ALT_INFO_MMC \ + DFU_ALT_INFO_RAM \ + DFU_ALT_INFO_NAND +#endif + +/* Network. */ +#define CONFIG_PHY_GIGE +#define CONFIG_PHYLIB +#define CONFIG_PHY_SMSC + +#ifdef CONFIG_DRIVER_TI_CPSW +#define CONFIG_CLOCK_SYNTHESIZER +#define CLK_SYNTHESIZER_I2C_ADDR 0x65 +#endif + +#define CONFIG_SYS_MEMTEST_START 0x80000000 +#define CONFIG_SYS_MEMTEST_END 0x87900000 + +/* TODO: Check/remove */ + +/* Enable support for TPS 65218 */ +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#define CONFIG_POWER_TPS65218 +/* For compatibility reasons (BeagleBone) */ +#define CONFIG_POWER_TPS65217 +#define CONFIG_POWER_TPS62362 + +#define CONFIG_CMD_PXE + +/* Never enable ISO it is broaken and can lead to a crash */ +#undef CONFIG_ISO_PARTITION + +#endif /* ! __CONFIG_AM335X_NRHW20_H */