From 1ffa09d30f5da879cb355e9828b7395daa687a4c Mon Sep 17 00:00:00 2001 From: Marcel Reichmuth Date: Mon, 22 Mar 2021 13:11:06 +0100 Subject: [PATCH] ADD: [hw14] added hw14 platform to support new mc board BugzId: 66150 --- Makefile | 3 - arch/arm/dts/Makefile | 1 + arch/arm/dts/armada-385-hw14-common.dtsi | 240 ++++++ arch/arm/dts/armada-385-hw14-spl.dts | 40 + arch/arm/dts/armada-385-hw14.dts | 20 + arch/arm/dts/armada-385-nbhw17-common.dtsi | 65 +- arch/arm/dts/armada-385-nbhw17-v1-spl.dts | 40 + arch/arm/dts/armada-385-nbhw17-v1.dts | 3 + arch/arm/dts/armada-385-nbhw18-v2.dts | 0 arch/arm/mach-mvebu/Kconfig | 9 +- arch/arm/mach-mvebu/cpu.c | 5 +- board/nm/common/nbhw_bd.c | 6 +- board/nm/common/nbhw_env.c | 24 +- board/nm/common/nbhw_fpga_gpio.c | 124 +-- board/nm/common/nbhw_fpga_prog.h | 8 +- board/nm/common/nbhw_gpio_ext.c | 130 ++++ board/nm/common/nbhw_init.c | 25 +- board/nm/common/nbhw_init.h | 2 +- board/nm/common/nbhw_pcie_fixup.c | 14 +- board/nm/hw14/MAINTAINERS | 6 + board/nm/hw14/Makefile | 30 + board/nm/hw14/README | 18 + board/nm/hw14/board.c | 839 +++++++++++++++++++++ board/nm/hw14/kwbimage.cfg | 12 + board/nm/hw14/mvswitch.c | 178 +++++ board/nm/hw14/mvswitch.h | 14 + board/nm/hw14/nbhw_fpga_config.c | 234 ++++++ board/nm/hw14/nbhw_gpio.c | 97 +++ board/nm/hw14/nbhw_gpio.h | 42 ++ board/nm/hw14/nbhw_sim.c | 77 ++ board/nm/nbhw17_v1/Makefile | 11 +- board/nm/nbhw17_v1/board.c | 733 ++++++++++++++++-- board/nm/nbhw17_v1/nbhw_fpga_config.c | 269 +++---- board/nm/nbhw17_v1/nbhw_fpga_prog.c | 144 ---- board/nm/nbhw17_v1/nbhw_fpga_regs.h | 773 ------------------- board/nm/nbhw17_v1/nbhw_gpio.c | 110 ++- board/nm/nbhw17_v1/nbhw_gpio.h | 34 +- board/nm/nbhw17_v1/nbhw_pcie_fixup.c | 228 ------ board/nm/nbhw18_v2/Makefile | 3 +- board/nm/nbhw18_v2/board.c | 43 +- board/nm/nbhw18_v2/nbhw_fpga_config.c | 3 + board/nm/nbhw18_v2/nbhw_sim.c | 7 +- common/board_f.c | 2 + configs/armada-385-hw14_defconfig | 75 ++ configs/armada-385-nbhw17-v1_defconfig | 29 +- drivers/gpio/pca953x_gpio.c | 20 + drivers/net/mvneta.c | 2 + include/configs/armada-385-hw14.h | 223 ++++++ include/configs/armada-385-nbhw17-v1.h | 64 +- include/configs/armada-385-nbhw18-v2.h | 3 +- include/libfdt_env.h | 5 +- include/linux/log2.h | 58 +- lib/crypt.c | 219 +++--- scripts/kconfig/confdata.c | 2 +- 54 files changed, 3613 insertions(+), 1753 deletions(-) create mode 100644 arch/arm/dts/armada-385-hw14-common.dtsi create mode 100644 arch/arm/dts/armada-385-hw14-spl.dts create mode 100644 arch/arm/dts/armada-385-hw14.dts create mode 100644 arch/arm/dts/armada-385-nbhw17-v1-spl.dts mode change 100755 => 100644 arch/arm/dts/armada-385-nbhw18-v2.dts create mode 100644 board/nm/common/nbhw_gpio_ext.c create mode 100644 board/nm/hw14/MAINTAINERS create mode 100644 board/nm/hw14/Makefile create mode 100644 board/nm/hw14/README create mode 100644 board/nm/hw14/board.c create mode 100644 board/nm/hw14/kwbimage.cfg create mode 100644 board/nm/hw14/mvswitch.c create mode 100644 board/nm/hw14/mvswitch.h create mode 100644 board/nm/hw14/nbhw_fpga_config.c create mode 100644 board/nm/hw14/nbhw_gpio.c create mode 100644 board/nm/hw14/nbhw_gpio.h create mode 100644 board/nm/hw14/nbhw_sim.c delete mode 100644 board/nm/nbhw17_v1/nbhw_fpga_prog.c delete mode 100644 board/nm/nbhw17_v1/nbhw_fpga_regs.h delete mode 100644 board/nm/nbhw17_v1/nbhw_pcie_fixup.c create mode 100644 configs/armada-385-hw14_defconfig create mode 100644 include/configs/armada-385-hw14.h mode change 100755 => 100644 include/configs/armada-385-nbhw18-v2.h diff --git a/Makefile b/Makefile index 11d1965811..a14664dfc6 100644 --- a/Makefile +++ b/Makefile @@ -617,9 +617,6 @@ KBUILD_AFLAGS += -Wa,-gstabs,-S endif endif -# Prohibit date/time macros, which would make the build non-deterministic -KBUILD_CFLAGS += $(call cc-option,-Werror=date-time) - include scripts/Makefile.extrawarn # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 43f7f23be8..089eeb0f63 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -83,6 +83,7 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \ tegra210-p2571.dtb dtb-$(CONFIG_ARCH_MVEBU) += \ + armada-385-hw14.dtb \ armada-385-nbhw18-v2.dtb \ armada-385-nbhw17-v1.dtb \ armada-3720-db.dtb \ diff --git a/arch/arm/dts/armada-385-hw14-common.dtsi b/arch/arm/dts/armada-385-hw14-common.dtsi new file mode 100644 index 0000000000..89e52578fe --- /dev/null +++ b/arch/arm/dts/armada-385-hw14-common.dtsi @@ -0,0 +1,240 @@ +/* + * Device Tree file for the NetModule HW14 (NB3800) + * + * Copyright (C) 2021 NetModule + * + * Stefan Eichenberger + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include "armada-385.dtsi" +#include + +/ { + model = "NetModule Router NBHW14 with Armada A385"; + compatible = "marvell,aramda385-hw14", "marvell,armada385", "marvell,armada380"; + + aliases { + /* So that mvebu u-boot can update the MAC addresses */ + ethernet0 = ð0; + ethernet1 = ð1; + ethernet2 = ð2; + /delete-property/ gpio0; /* Causes warnings when requesting gpios */ + /delete-property/ gpio1; /* Causes warnings when requesting gpios */ + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; /* 1 GB */ + }; + + soc { + ranges = ; /* GPIO Ext (CS1) */ + + gpioext: gpio@f40000000 { + compatible = "nm,nbhw-gpio-ext"; + reg = ; /* This translates to 0xf4000000 */ + ngpios = <8>; + gpio-controller; + gpio-bank-name = "Ext"; + #gpio-cells = <2>; + }; + + /* Following node cannot be put into corresponding + I2C bus, because I2C does not use DM and therefore + it would not get probed. */ + gpioi2c: gpio@76 { + compatible = "nxp,pca9539"; + reg = <0x76 0x00 0x00>; + gpio-controller; + #gpio-cells = <2>; + status = "okay"; + }; + + gpio_pins { + compatible = "nm,gpios"; + wd_enable = <&gpioext 4 GPIO_ACTIVE_LOW 0>; + rst_i2c_exp = <&gpioext 5 GPIO_ACTIVE_LOW 1>; + led_dbg = <&gpioext 7 GPIO_ACTIVE_HIGH 0>; + en_sata_pwr = <&gpioi2c 0 GPIO_ACTIVE_HIGH 0>; + usb1_vbus_in = <&gpioi2c 1 GPIO_ACTIVE_HIGH 0>; + usb1_drive_vbus = <&gpioi2c 2 GPIO_ACTIVE_HIGH 0>; + usb1_pwr_fault = <&gpioi2c 3 GPIO_ACTIVE_HIGH 0>; + ext_rst_en = <&gpioi2c 4 GPIO_ACTIVE_LOW 1>; + rst_fpga = <&gpioi2c 5 GPIO_ACTIVE_LOW 1>; + rst_usb_hub = <&gpioi2c 6 GPIO_ACTIVE_LOW 1>; + rst_pse_eth = <&gpioi2c 7 GPIO_ACTIVE_LOW 1>; + reset_button = <&gpio1 24 GPIO_ACTIVE_LOW 1>; + ext_oe = <&gpio0 21 GPIO_ACTIVE_LOW 0>; + serdes4_mux_en = <&gpiofpga 535 GPIO_ACTIVE_LOW 0>; + serdes4_mux_sel = <&gpiofpga 534 GPIO_ACTIVE_HIGH 1>; // 0=usb3, 1=pci + pex2_clk_1_4_mux_en = <&gpiofpga 533 GPIO_ACTIVE_LOW 0>; + pex2_clk_1_4_mux_sel = <&gpiofpga 532 GPIO_ACTIVE_HIGH 1>; // 0=pex2_clk on slot4, 1= pex2_clk on slot1 + }; + + gpiofpga: gpio@fd0000000 { + compatible = "nm,nbhw-fpga"; + reg = ; /* This translates to 0xfd000000 */ + ngpios = <8500>; + gpio-controller; + gpio-bank-name = "FPGA"; + #gpio-cells = <2>; + spi-sck = <&gpioext 0 GPIO_ACTIVE_HIGH 0>; /* SCK */ + spi-sdi = <&gpioext 1 GPIO_ACTIVE_HIGH 0>; /* SDI slave data in */ + spi-ss = <&gpioext 2 GPIO_ACTIVE_LOW 0>; /* SS */ + fpga-reset-logic = <&gpioi2c 5 GPIO_ACTIVE_HIGH 0>; /* FPGA logic reset */ + fpga-cdone = <&gpioi2c 8 GPIO_ACTIVE_HIGH 0>; /* FPGA cdone */ + fpga-cinit = <&gpioi2c 9 GPIO_ACTIVE_LOW 0>; /* FPGA cinit */ + }; + + fpga_conf: fpgaconf@0 { + compatible = "nm,hw14-fpga-config"; + leds = <&gpiofpga 256 0>, <&gpiofpga 257 0>, <&gpiofpga 258 0>, + <&gpiofpga 259 0>, <&gpiofpga 260 0>, <&gpiofpga 261 0>, + <&gpiofpga 262 0>, <&gpiofpga 263 0>, <&gpiofpga 264 0>, + <&gpiofpga 265 0>, <&gpiofpga 266 0>, <&gpiofpga 267 0>, + <&gpiofpga 268 0>, <&gpiofpga 269 0>, <&gpiofpga 270 0>, + <&gpiofpga 271 0>; + + // pcie slot 0 + pcieslot@0 { + reset = <&gpiofpga 384 GPIO_ACTIVE_LOW 1>; + power = <&gpiofpga 400 GPIO_ACTIVE_HIGH 0>; + wdis-out = <&gpiofpga 2053 GPIO_ACTIVE_HIGH 1>; + wdis = <&gpiofpga 2069 GPIO_ACTIVE_LOW 1>; + }; + + // pcie slot 1 + pcieslot@1 { + reset = <&gpiofpga 385 GPIO_ACTIVE_LOW 1>; + power = <&gpiofpga 401 GPIO_ACTIVE_HIGH 0>; + wdis-out = <&gpiofpga 4101 GPIO_ACTIVE_HIGH 1>; + wdis = <&gpiofpga 4117 GPIO_ACTIVE_LOW 1>; + }; + + // pcie slot 2 + pcieslot@2 { + reset = <&gpiofpga 386 GPIO_ACTIVE_LOW 1>; + power = <&gpiofpga 402 GPIO_ACTIVE_HIGH 0>; + wdis-out = <&gpiofpga 6149 GPIO_ACTIVE_HIGH 1>; + wdis = <&gpiofpga 6165 GPIO_ACTIVE_LOW 1>; + }; + + // pcie slot 3 + pcieslot@3 { + reset = <&gpiofpga 387 GPIO_ACTIVE_LOW 1>; + power = <&gpiofpga 403 GPIO_ACTIVE_HIGH 0>; + wdis-out = <&gpiofpga 8197 GPIO_ACTIVE_HIGH 1>; + wdis = <&gpiofpga 8213 GPIO_ACTIVE_LOW 1>; + }; + + // pcie slot 4 + pcieslot@4 { + reset = <&gpiofpga 388 GPIO_ACTIVE_LOW 1>; + power = <&gpiofpga 404 GPIO_ACTIVE_HIGH 0>; + wdis-out = <&gpiofpga 10245 GPIO_ACTIVE_HIGH 1>; + wdis = <&gpiofpga 10261 GPIO_ACTIVE_LOW 1>; + }; + + // pcie slot 5 + pcieslot@5 { + reset = <&gpiofpga 389 GPIO_ACTIVE_LOW 1>; + power = <&gpiofpga 405 GPIO_ACTIVE_HIGH 0>; + wdis-out = <&gpiofpga 12293 GPIO_ACTIVE_HIGH 1>; + wdis = <&gpiofpga 12309 GPIO_ACTIVE_LOW 1>; + }; + }; + + internal-regs { + + i2c0: i2c@11000 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2c1: i2c@11100 { + status = "disabled"; + }; + + sata@a8000 { + status = "disabled"; + }; + + // Never ever enable this SATA controller on A385/A380 ! + sata@e0000 { + status = "disabled"; + }; + + serial@12000 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + status = "okay"; + }; + + serial@12100 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "okay"; + }; + + usb@58000 { + status = "okay"; + }; + }; + + pcie-controller { + status = "okay"; + /* + * The two PCIe units are accessible through + * standard PCIe slots on the board. + */ + pcie@3,0 { + /* Port 2, Lane 0 */ + status = "okay"; + }; + pcie@4,0 { + /* Port 3, Lane 0 */ + status = "okay"; + }; + }; + }; + +}; + +// MAC0 is used for RGMII/MII (100 MBit/s switches on NB3701/NB3711) +ð0 { /* ethernet@70000 */ + status = "okay"; + phy-mode = "mii"; + fixed-link { + speed = <100>; + full-duplex; + }; +}; + +// MAC1 is used for SGMII (1 GBit/s switches on NB3800) +ð1 { /* ethernet@30000 */ + status = "okay"; + phy-mode = "sgmii"; + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mdio { + #address-cells = <1>; + #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins>; +}; + + diff --git a/arch/arm/dts/armada-385-hw14-spl.dts b/arch/arm/dts/armada-385-hw14-spl.dts new file mode 100644 index 0000000000..a20cecd6f2 --- /dev/null +++ b/arch/arm/dts/armada-385-hw14-spl.dts @@ -0,0 +1,40 @@ +/* + * Device Tree file for the NetModule HW14 (NB3800) base variant + * + * Copyright (C) 2020 NetModule + * + * Stefan Eichenberger + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/dts-v1/; +#include "armada-385-hw14-common.dtsi" + +/ { + model = "NetModule Router HW14 with Armada A385 (NB3800)"; + chosen { + stdout-path = "serial0:115200n8"; + }; + + + soc { + internal-regs { + serial@12000 { + u-boot,dm-spl; + }; + }; + }; +}; + +ð0 { + status = "okay"; +}; + +ð1 { + status = "okay"; +}; + + diff --git a/arch/arm/dts/armada-385-hw14.dts b/arch/arm/dts/armada-385-hw14.dts new file mode 100644 index 0000000000..a49198de8f --- /dev/null +++ b/arch/arm/dts/armada-385-hw14.dts @@ -0,0 +1,20 @@ +/* + * Device Tree file for the NetModule NBHW18-V2 (NB1800) base variant + * + * Copyright (C) 2016 NetModule + * + * Stefan Eichenberger + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/dts-v1/; +#include "armada-385-hw14-common.dtsi" + +/ { + model = "NetModule Router HW14 with Armada A385 (NB3800)"; +}; + + diff --git a/arch/arm/dts/armada-385-nbhw17-common.dtsi b/arch/arm/dts/armada-385-nbhw17-common.dtsi index fd777d0ebf..005d7ce8d2 100644 --- a/arch/arm/dts/armada-385-nbhw17-common.dtsi +++ b/arch/arm/dts/armada-385-nbhw17-common.dtsi @@ -1,7 +1,7 @@ /* * Device Tree file for the NetModule NBHW17 (NB2800) * - * Copyright (C) 2016 NetModule + * Copyright (C) 2021 NetModule * * Stefan Eichenberger * @@ -21,10 +21,8 @@ /* So that mvebu u-boot can update the MAC addresses */ ethernet1 = ð1; ethernet2 = ð2; - }; - - chosen { - stdout-path = "serial1:115200n8"; + /delete-property/ gpio0; /* Causes warnings when requesting gpios */ + /delete-property/ gpio1; /* Causes warnings when requesting gpios */ }; memory { @@ -37,7 +35,16 @@ MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000 MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000 /* CESA 0 SRAM */ MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 /* CESA 1 SRAM */ - MBUS_ID(0x01, 0x3e) 0 0xfd000000 0x20000>; /* FPGA */ + MBUS_ID(0x01, 0x3e) 0 0xfd000000 0x20000>; /* FPGA (CS0) */ + + gpio_pins { + compatible = "nm,gpios"; + wd_enable = <&gpio0 27 GPIO_ACTIVE_LOW 0>; + rst_usb_hub = <&gpio1 9 GPIO_ACTIVE_LOW 1>; + rst_fpga = <&gpio1 12 GPIO_ACTIVE_LOW 1>; + rst_eth_phy = <&gpio0 21 GPIO_ACTIVE_LOW 1>; + reset_button = <&gpio1 24 GPIO_ACTIVE_LOW 1>; + }; gpiofpga: gpio@fd0000000 { compatible = "nm,nbhw-fpga"; @@ -46,13 +53,12 @@ gpio-controller; gpio-bank-name = "FPGA"; #gpio-cells = <2>; - spi-ss = <&gpio1 5 0>; /* SS */ - spi-sdo = <&gpio1 6 0>; /* SDO slave data out */ - spi-sck = <&gpio1 7 0>; /* SCK */ - spi-sdi = <&gpio1 8 0>; /* SDI slave data in */ - fpga-reset = <&gpio0 26 0>; /* FPGA reset */ - fpga-cdone = <&gpio0 29 0>; /* FPGA cdone */ - fpga-reset-logic = <&gpio1 12 0>; /* FPGA reset logic (after load)*/ + spi-sck = <&gpio1 7 GPIO_ACTIVE_HIGH 0>; /* SCK (MPP39) */ + spi-sdi = <&gpio1 8 GPIO_ACTIVE_HIGH 0>; /* SDI slave data in (MPP40) */ + spi-ss = <&gpio1 5 GPIO_ACTIVE_HIGH 0>; /* SS (MPP37) */ + fpga-reset = <&gpio0 26 GPIO_ACTIVE_HIGH 0>; /* FPGA config reset */ + fpga-cdone = <&gpio0 29 GPIO_ACTIVE_HIGH 0>; /* FPGA cdone */ + fpga-reset-logic = <&gpio1 12 GPIO_ACTIVE_HIGH 0>; /* FPGA logic reset */ }; fpga_conf: fpgaconf@0 { @@ -64,28 +70,15 @@ <&gpiofpga 268 0>, <&gpiofpga 269 0>, <&gpiofpga 270 0>, <&gpiofpga 271 0>; - misc@0 { - #gpio-cells = <4>; - // gpio controller, gpio number, low/high_active, default value - hold-pwr-on = <&gpiofpga 64 0 1>; - en-gps-ant = <&gpiofpga 65 0 0>; - en-mdio-phy = <&gpiofpga 66 GPIO_ACTIVE_LOW 1>; - en-mdio-ext = <&gpiofpga 67 GPIO_ACTIVE_LOW 0>; - en-sata-pwr = <&gpiofpga 68 GPIO_ACTIVE_HIGH 1>; - serdes-sel = <&gpiofpga 69 GPIO_ACTIVE_HIGH 1>; - serdes-en = <&gpiofpga 70 GPIO_ACTIVE_LOW 0>; - rst-ext = <&gpiofpga 71 GPIO_ACTIVE_LOW 1>; - rst-ext-eth = <&gpiofpga 72 GPIO_ACTIVE_LOW 1>; - rst-ext-en = <&gpiofpga 73 GPIO_ACTIVE_HIGH 0>; - }; - + // pcie slot 0 pcieslot@0 { reset = <&gpiofpga 384 GPIO_ACTIVE_LOW 1>; power = <&gpiofpga 400 GPIO_ACTIVE_HIGH 0>; wdis-out = <&gpiofpga 2053 GPIO_ACTIVE_HIGH 1>; - wdis = <&gpiofpga 2068 GPIO_ACTIVE_LOW 1>; + wdis = <&gpiofpga 2069 GPIO_ACTIVE_LOW 1>; }; + // pcie slot 1 pcieslot@1 { reset = <&gpiofpga 385 GPIO_ACTIVE_LOW 1>; power = <&gpiofpga 401 GPIO_ACTIVE_HIGH 0>; @@ -93,6 +86,7 @@ wdis = <&gpiofpga 4117 GPIO_ACTIVE_LOW 1>; }; + // pcie slot 2 pcieslot@2 { reset = <&gpiofpga 386 GPIO_ACTIVE_LOW 1>; power = <&gpiofpga 402 GPIO_ACTIVE_HIGH 0>; @@ -100,6 +94,7 @@ wdis = <&gpiofpga 6165 GPIO_ACTIVE_LOW 1>; }; + // pcie slot 3 pcieslot@3 { reset = <&gpiofpga 387 GPIO_ACTIVE_LOW 1>; power = <&gpiofpga 403 GPIO_ACTIVE_HIGH 0>; @@ -128,14 +123,6 @@ status = "disabled"; }; - sdhci@d8000 { - broken-cd; - wp-inverted; - no-1-8-v; - bus-width = <8>; - status = "okay"; - }; - serial@12000 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins>; @@ -146,8 +133,12 @@ pinctrl-names = "default"; pinctrl-0 = <&uart1_pins>; u-boot,dm-pre-reloc; + status = "okay"; }; + usb@58000 { + status = "okay"; + }; }; pcie-controller { diff --git a/arch/arm/dts/armada-385-nbhw17-v1-spl.dts b/arch/arm/dts/armada-385-nbhw17-v1-spl.dts new file mode 100644 index 0000000000..3925862059 --- /dev/null +++ b/arch/arm/dts/armada-385-nbhw17-v1-spl.dts @@ -0,0 +1,40 @@ +/* + * Device Tree file for the NetModule NBHW17 (NB2800) base variant + * + * Copyright (C) 2021 NetModule + * + * Stefan Eichenberger + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/dts-v1/; +#include "armada-385-nbhw17-common.dtsi" + +/ { + model = "NetModule Router NBHW17 with Armada A385 (NB2800)"; + chosen { + stdout-path = "serial1:115200n8"; + }; + + + soc { + internal-regs { + serial@12100 { + u-boot,dm-spl; + }; + }; + }; +}; + +ð1 { + status = "okay"; +}; + +ð2 { + status = "okay"; +}; + + diff --git a/arch/arm/dts/armada-385-nbhw17-v1.dts b/arch/arm/dts/armada-385-nbhw17-v1.dts index a78aee6bed..0771eaa3cc 100644 --- a/arch/arm/dts/armada-385-nbhw17-v1.dts +++ b/arch/arm/dts/armada-385-nbhw17-v1.dts @@ -15,6 +15,9 @@ / { model = "NetModule Router NBHW17 with Armada A385 (NB2800)"; +// chosen { +// stdout-path = "serial1:115200n8"; +// }; }; ð1 { diff --git a/arch/arm/dts/armada-385-nbhw18-v2.dts b/arch/arm/dts/armada-385-nbhw18-v2.dts old mode 100755 new mode 100644 diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 9a6fafc145..508ea20c61 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -88,9 +88,9 @@ config TARGET_DB_88F6820_GP bool "Support DB-88F6820-GP" select 88F6820 -config TARGET_NM_NBHW18_V1 - bool "Support NBHW18 V1" - select 88F6820 +config TARGET_NM_HW14 + bool "Support HW14" + select 88F6820 config TARGET_NM_NBHW18_V2 bool "Support NBHW18 V2" @@ -154,6 +154,7 @@ config SYS_BOARD default "ds414" if TARGET_DS414 default "maxbcm" if TARGET_MAXBCM default "theadorable" if TARGET_THEADORABLE + default "hw14" if TARGET_NM_HW14 default "nbhw18_v1" if TARGET_NM_NBHW18_V1 default "nbhw18_v2" if TARGET_NM_NBHW18_V2 default "nbhw17_v1" if TARGET_NM_NBHW17_V1 @@ -170,6 +171,7 @@ config SYS_CONFIG_NAME default "maxbcm" if TARGET_MAXBCM default "theadorable" if TARGET_THEADORABLE default "turris_omnia" if TARGET_TURRIS_OMNIA + default "armada-385-hw14" if TARGET_NM_HW14 default "armada-385-nbhw18-v2" if TARGET_NM_NBHW18_V2 default "armada-385-nbhw17-v1" if TARGET_NM_NBHW17_V1 @@ -183,6 +185,7 @@ config SYS_VENDOR default "solidrun" if TARGET_CLEARFOG default "Synology" if TARGET_DS414 default "CZ.NIC" if TARGET_TURRIS_OMNIA + default "nm" if TARGET_NM_HW14 default "nm" if TARGET_NM_NBHW18_V1 default "nm" if TARGET_NM_NBHW18_V2 default "nm" if TARGET_NM_NBHW17_V1 diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c index d6a7692a40..7302598bed 100644 --- a/arch/arm/mach-mvebu/cpu.c +++ b/arch/arm/mach-mvebu/cpu.c @@ -18,8 +18,9 @@ static struct mbus_win windows[] = { /* SPI */ - { MBUS_SPI_BASE, MBUS_SPI_SIZE, - CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH }, + /* @@NM@@MR@@ Conflicts with the windows for the HW14 gpio extension */ + /*{ MBUS_SPI_BASE, MBUS_SPI_SIZE, + CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH }, */ /* NOR */ { MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE, diff --git a/board/nm/common/nbhw_bd.c b/board/nm/common/nbhw_bd.c index 9069858591..62431837dd 100644 --- a/board/nm/common/nbhw_bd.c +++ b/board/nm/common/nbhw_bd.c @@ -27,7 +27,7 @@ #include "nbhw_bd.h" static const BD_Context *bdctx_list; /* The board descriptor context */ -static size_t bdctx_count = 0; +static size_t bdctx_count = 0; void bd_register_context_list(const BD_Context *list, size_t count) { bdctx_list = list; @@ -37,8 +37,8 @@ void bd_register_context_list(const BD_Context *list, size_t count) { int bd_get_context(BD_Context *bdctx, uint32_t i2caddress, uint32_t offset) { bd_bool_t rc; - uint8_t bdHeader[8]; - void* pBdData = NULL; + uint8_t bdHeader[8]; + void* pBdData = NULL; /* Read header bytes from beginning of EEPROM */ if (i2c_read( i2caddress, offset, 2, bdHeader, BD_HEADER_LENGTH )) { printf("%s() Can't read BD header from EEPROM\n", __func__); diff --git a/board/nm/common/nbhw_env.c b/board/nm/common/nbhw_env.c index 86c990af84..58b2c41ad1 100644 --- a/board/nm/common/nbhw_env.c +++ b/board/nm/common/nbhw_env.c @@ -21,6 +21,7 @@ void set_console(void) char buf[6]; char consolefile[] = "/root/boot/consoledev"; char *defaultconsole = env_get("defaultconsole"); + int use_default_console = 0; #if defined(CONFIG_PRE_CONSOLE_BUFFER) int len = 0; @@ -28,17 +29,28 @@ void set_console(void) read_file_set_blk_dev("mmc", "0:3", FS_TYPE_EXT); len = get_file_size(consolefile); - if (len>=5) { - read_file(consolefile, buf, sizeof(buf)); - buf[sizeof(buf)-1] = 0; - if ((strstr(buf, "tty")!=buf) || ((buf[4]<'0') && (buf[4]>'1'))) { + if (len>=4) { + memset(buf, 0x00, sizeof(buf)); + read_file(consolefile, buf, sizeof(buf)-1); + if (strstr(buf, "ttyS")==buf) { + if ((buf[4]<'0') && (buf[4]>'1')) { + /* invalid tty specified */ + use_default_console = 1; + } else { + /* Use retrieved ttySx */ + } + } else if (strstr(buf, "none")==buf) { + /* disable console */ buf[0] = 0; + } else { + /* invalid device specified */ + use_default_console = 1; } } else { - buf[0] = 0; + use_default_console = 1; } - if (buf[0] == 0) { + if (use_default_console) { strncpy(buf, defaultconsole, sizeof(buf)); } printf("consoledev: %s\n", buf); diff --git a/board/nm/common/nbhw_fpga_gpio.c b/board/nm/common/nbhw_fpga_gpio.c index b02f8cdba6..4b5eb4146a 100644 --- a/board/nm/common/nbhw_fpga_gpio.c +++ b/board/nm/common/nbhw_fpga_gpio.c @@ -51,7 +51,9 @@ struct nbhw_fpga_priv { struct gpio_desc ss; struct gpio_desc sck; struct gpio_desc sdi; +#ifdef CONFIG_FPGA_LATTICE_SSPI struct gpio_desc sdo; +#endif struct gpio_desc reset; struct gpio_desc reset_logic; struct gpio_desc cdone; @@ -72,6 +74,8 @@ void tickdelay(void) while (get_ticks() < curtick+1); /* loop till event */ } +#ifdef CONFIG_FPGA_LATTICE_SSPI + static inline u8 spi_read_sspi(const struct nbhw_fpga_priv *priv) { int i; @@ -119,6 +123,8 @@ static inline void spi_write_sspi(const struct nbhw_fpga_priv *priv, u8 data) } } +#endif + static inline void spi_write(const struct nbhw_fpga_priv *priv, u8 data) { int i; @@ -130,13 +136,13 @@ static inline void spi_write(const struct nbhw_fpga_priv *priv, u8 data) { data_write = (data & 0x80) ? 1 : 0; /* Clear clk bit and put data on the line */ - dm_gpio_set_value(&priv->sck, 0); - dm_gpio_set_value(&priv->sdi, data_write); - udelay(1); + dm_gpio_set_value(&priv->sck, 0); + dm_gpio_set_value(&priv->sdi, data_write); + tickdelay(); /* Read data on rising edge */ - dm_gpio_set_value(&priv->sck, 1); + dm_gpio_set_value(&priv->sck, 1); data = data << 1; - udelay(1); + tickdelay(); } } @@ -153,19 +159,19 @@ static int fpga_verify(struct nbhw_fpga_priv *priv) if (signature == 0xa501) { - strcpy(fpga_type, "XC3S50A-4VQ100I top layer"); + strcpy(fpga_type, "XC3S50A-4VQ100I top layer HW14"); } else if (signature == 0xa502) { - strcpy(fpga_type, "XC3S200A-4VQ100I top layer"); + strcpy(fpga_type, "XC3S200A-4VQ100I top layer HW14"); } else if (signature == 0xa511) { - strcpy(fpga_type, "XC3S50A-4FTG256I bottom layer"); + strcpy(fpga_type, "XC3S50A-4FTG256I bottom layer HW14"); } else if (signature == 0xa512) { - strcpy(fpga_type, "XC3S200A-4FTG256I bottom layer"); + strcpy(fpga_type, "XC3S200A-4FTG256I bottom layer HW14"); } else if (signature == 0x4004) { - strcpy(fpga_type, "ICE40HX4K-CB132 NBHW17"); + strcpy(fpga_type, "ICE40HX4K-CB132 HW17"); } else if (signature == 0x4184) { - strcpy(fpga_type, "ICE40HX4K-CB132 NBHW18 V1"); + strcpy(fpga_type, "ICE40HX4K-CB132 HW18 V1"); } else if (signature == 0x012f) { - strcpy(fpga_type, "LFE5U-12F-6BG381I NBHW18 V2"); + strcpy(fpga_type, "LFE5U-12F-6BG381I HW18 V2"); } else { priv->signature = signature; goto abort; @@ -183,6 +189,8 @@ abort: return 0; } +#ifdef CONFIG_FPGA_LATTICE_SSPI + #define print_out_string printf extern unsigned int a_uiRowCount; void printError(int code){ @@ -246,6 +254,8 @@ void printError(int code){ } } +#endif + static void put_in_prog_mode(const struct nbhw_fpga_priv *priv) { /* Change the muxing to GPIO */ @@ -255,6 +265,7 @@ static void put_in_prog_mode(const struct nbhw_fpga_priv *priv) printf("Put FPGA in programming mode\n"); dm_gpio_set_value(&priv->ss, 1); udelay(10); + dm_gpio_set_value(&priv->ss, 0); dm_gpio_set_value(&priv->sck, 1); dm_gpio_set_value(&priv->reset, 1); @@ -268,6 +279,8 @@ static void put_in_prog_mode(const struct nbhw_fpga_priv *priv) udelay(800); } +#ifdef CONFIG_FPGA_LATTICE_SSPI + static void put_in_prog_mode_lattice_sspi(const struct nbhw_fpga_priv *priv) { /* Change the muxing to GPIO */ @@ -297,13 +310,15 @@ static void put_in_prog_mode_lattice_sspi(const struct nbhw_fpga_priv *priv) debug("Initialised Reset with pulling PROGRAM~\n"); } +#endif + static void clean_up_after_programming(const struct nbhw_fpga_priv *priv) { /* Change the muxing back to Devbus */ writel(0x55555555, MVEBU_MPP_BASE + 0x10); writel(0x06605505, MVEBU_MPP_BASE + 0x14); - //dm_gpio_set_value(&priv->reset_logic, 0); //TODO : that seems wrong (AO) + dm_gpio_set_value(&priv->reset_logic, 0); //TODO : that seems wrong (AO) udelay(100); dm_gpio_set_value(&priv->reset_logic, 1); udelay(100); @@ -326,13 +341,6 @@ static int fpga_load_bitstream (const struct nbhw_fpga_priv *priv, const u8* dat debug("Configuration sent\n"); - if (dm_gpio_get_value(&priv->cdone)) { - printf("Error: Fpga does not signal done\n"); - return 0; - } - - debug("FPGA signals done\n"); - /* Send some extra clocks for startup */ for ( i=0; i<100; i++) { @@ -344,25 +352,6 @@ static int fpga_load_bitstream (const struct nbhw_fpga_priv *priv, const u8* dat return 1; } -#ifdef CONFIG_FPGA_LATTICE_SSPI - -static int fpga_load_bitstream_lattice_sspi (const struct nbhw_fpga_priv *priv, - const u8* pBitstreamAddr, int pBitstreamSize, - const u8* pAlgoAddr, int pAlgoSize) -{ - int siRetCode; - siRetCode = SSPIEm_preset(pAlgoAddr, pAlgoSize, pBitstreamAddr, pBitstreamSize); - siRetCode = SSPIEm(0xFFFFFFFF); - if ( siRetCode != 2 ) { - printError(siRetCode); - return 0; - } - - return 1; -} - -#endif - static int fpga_check_bitstream_lattice(const struct nbhw_fpga_priv *priv, const u8* fpgadata, int dataNumBytes, const u8** pBitstreamAddr, int* pBitstreamSize) @@ -384,6 +373,23 @@ static int fpga_check_bitstream_lattice(const struct nbhw_fpga_priv *priv, return 0; } +#ifdef CONFIG_FPGA_LATTICE_SSPI + +static int fpga_load_bitstream_lattice_sspi (const struct nbhw_fpga_priv *priv, + const u8* pBitstreamAddr, int pBitstreamSize, + const u8* pAlgoAddr, int pAlgoSize) +{ + int siRetCode; + siRetCode = SSPIEm_preset(pAlgoAddr, pAlgoSize, pBitstreamAddr, pBitstreamSize); + siRetCode = SSPIEm(0xFFFFFFFF); + if ( siRetCode != 2 ) { + printError(siRetCode); + return 0; + } + + return 1; +} + #define CHECKMARKER(index, a, b, c, d) ((fpgadata[index]==a) && (fpgadata[index+1]==b) \ && (fpgadata[index+2]==c) && (fpgadata[index+3]==d)) @@ -432,6 +438,8 @@ abort: return -1; } +#endif + /* Legacy Xilinx check ported from PPC, seems to work */ static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv, const u8* fpgadata, int dataNumBytes, @@ -474,10 +482,6 @@ static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv, printf(" design filename = \"%s\"\n", buffer); - /* verify fpga identifier */ - if (priv->fpga_id == 0xFFFFFFFF) { - return 0; - } p = strstr(buffer, "UserID=0x"); if (p) { p += 9; @@ -496,10 +500,13 @@ static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv, return -1; } } - if (fpgaid != priv->fpga_id) { - printf("%s: User identifier not matched in bitstream\n", - __FUNCTION__ ); - return -1; + /* verify fpga identifier */ + if (priv->fpga_id != 0xFFFFFFFF) { + if (fpgaid != priv->fpga_id) { + printf("%s: User identifier not matched in bitstream\n", + __FUNCTION__ ); + return -1; + } } } else { printf("%s: User identifier not found in bitstream\n", @@ -580,21 +587,24 @@ static int fpga_check_bitstream(const struct nbhw_fpga_priv *priv, debug("check bitstream %d, %0x, %0x\n", *pBitstreamSize, fpgadata[0], fpgadata[1]); + /* Lattice header starts with 0xFF00 followed by comment */ if (fpgadata[0] == 0xFF && fpgadata[1] == 0x00) { return fpga_check_bitstream_lattice(priv, fpgadata, dataNumBytes, pBitstreamAddr, pBitstreamSize); } +#ifdef CONFIG_FPGA_LATTICE_SSPI /* Lattice SSPI header starts with 0xae 0x00 0x00 0x01 (SEA tag) */ else if(fpgadata[0] == 0xae && fpgadata[1] == 0x00) { return fpga_check_bitstream_lattice_sspi(priv, fpgadata, dataNumBytes, pBitstreamAddr, pBitstreamSize, pAlgoAddr, pAlgoSize); } +#else /* Xilinx header starts with 0x00 0x09 which means header with 0x09 length */ - else if(fpgadata[0] == 0x00 && fpgadata[1] == 0x09) { + if(fpgadata[0] == 0x00 && fpgadata[1] == 0x09) { return fpga_check_bitstream_xilinx(priv, fpgadata, dataNumBytes, pBitstreamAddr, pBitstreamSize); } - +#endif printf("Unknown bitstream file format (not Xilinx nor Lattice)\n"); return -1; } @@ -675,7 +685,7 @@ static void setup_device_bus(void) /* Device Bus Control Interface Register */ val = readl(MV_DEV_BUS_REGS_OFFSET + 0xC0); - debug("Device Bus Control Interface Regiseter (0x104C0): 0x%08X\n", val); + debug("Device Bus Control Interface Register (0x104C0): 0x%08X\n", val); writel(0x5FFFF, MV_DEV_BUS_REGS_OFFSET + 0xC0); /* Device Bus Synchronous Control Register */ val = readl(MV_DEV_BUS_REGS_OFFSET + 0xC8); @@ -727,15 +737,15 @@ static int request_gpios(struct udevice *dev) printf("Could not request spi-gpio sdi\n"); return -1; } - +#ifdef CONFIG_FPGA_LATTICE_SSPI if (gpio_request_by_name(dev, "spi-sdo", 0, &priv->sdo, GPIOD_IS_IN) != 0) { printf("Could not request spi-gpio sdo\n"); return -1; } +#endif if (gpio_request_by_name(dev, "fpga-reset", 0, &priv->reset, GPIOD_IS_OUT) != 0) { - printf("Could not request fpga-reset\n"); - return -1; + debug("Could not request fpga-reset\n"); } if (gpio_request_by_name(dev, "fpga-cdone", 0, &priv->cdone, GPIOD_IS_IN) != 0) { @@ -777,15 +787,15 @@ static int fpga_program(struct udevice *dev, unsigned long load_addr, } } + /* Make sure device bus works, because HW14 uses its gpios to do SPI */ + setup_device_bus(); + /* NBHW_BASE_ADDRESS_FPGA points to base of FPGA registers */ if (!fpga_boot_buffer(priv, (const u8*)load_addr, filesize)) { printf ("Loading FPGA over SPI failed.\n"); return -3; } - /* Make sure device bus works, becaus NBHW14 uses its gpios to do SPI */ - setup_device_bus(); - /* Verify, if FPGA is loaded successfully */ i = 0; do { @@ -1032,6 +1042,7 @@ U_BOOT_DRIVER(gpio_nbhw_fpga) = { .ops = &nbhw_fpga_ops, }; +#ifdef CONFIG_FPGA_LATTICE_SSPI /* Lattice SSPI programming tool wrappers */ void FPGA_START(void) { @@ -1060,3 +1071,4 @@ void FPGA_CS_HIGH(void) dm_gpio_set_value(&FPGA_PRIV->ss, 1); } +#endif diff --git a/board/nm/common/nbhw_fpga_prog.h b/board/nm/common/nbhw_fpga_prog.h index 2767754bc6..f9ecaea2b1 100644 --- a/board/nm/common/nbhw_fpga_prog.h +++ b/board/nm/common/nbhw_fpga_prog.h @@ -6,16 +6,16 @@ #define FPGA_REG(x) *((volatile unsigned short*)( NBHW_BASE_ADDRESS_FPGA + ((unsigned int)x))) typedef enum _fpga_type { - FPGA_TYPE_NONE, - FPGA_TYPE_XILINX, - FPGA_TYPE_LATTICE, + FPGA_TYPE_NONE, + FPGA_TYPE_XILINX, + FPGA_TYPE_LATTICE, }fpga_type; typedef struct _fpga_prog_operation { void (*pre_programming)(void); void (*post_programming)(void); void (*spi_write)(u8); - int (*check_bitstream_compatibility)(fpga_type, u32); + int (*check_bitstream_compatibility)(fpga_type, u32); } fpga_prog_operation; int nbhw_fpga_program(void); diff --git a/board/nm/common/nbhw_gpio_ext.c b/board/nm/common/nbhw_gpio_ext.c new file mode 100644 index 0000000000..7f1458cf18 --- /dev/null +++ b/board/nm/common/nbhw_gpio_ext.c @@ -0,0 +1,130 @@ +/****************************************************************************** + * (c) COPYRIGHT 2020 by NetModule AG, Switzerland. All rights reserved. + * + * 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. + * + *****************************************************************************/ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include + +struct nbhw_gpio_ext_priv { + volatile u8* base_addr; + u8 value; +}; + +static int nbhw_gpio_ext_bind(struct udevice *dev) +{ + struct nbhw_gpio_ext_priv *priv = malloc(sizeof(struct nbhw_gpio_ext_priv)); + + if (priv == NULL) { + puts("Can't allocate memory for nbhw gpio ext driver\n"); + return -1; + } + + dev->priv = priv; + + /* Get memory address for gpio ext */ + priv->base_addr = (u8*)devfdt_get_addr(dev); + debug("GPIO Ext address: %p\n", priv->base_addr); + + priv->value = 0; + + return 0; +} + +static int nbhw_gpio_ext_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), + "gpio-bank-name", NULL); + uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "ngpios", 1024); + + debug("%s done\n", __func__); + + return 0; +} + +static int nbhw_gpio_ext_get_value (struct udevice *dev, unsigned offset) +{ + struct nbhw_gpio_ext_priv *priv = dev_get_priv(dev); + + if (offset > 7) return -1; + + return ((priv->value) >> offset) & 0x01; +} + +static int nbhw_gpio_ext_set_value (struct udevice *dev, unsigned offset, int value) +{ + struct nbhw_gpio_ext_priv *priv = dev_get_priv(dev); + + debug("%s\n", __func__); + + if (offset > 7) return -1; + + priv->value &= ~(1 << offset); + priv->value |= ((value ? 1 : 0) << offset); + + debug("Write 0x%x to addr 0x%x (offset:0x%x, value:0x%x)\n", priv->value, (int)priv->base_addr, offset, value); + + return writeb(priv->value, priv->base_addr); +} + +static int nbhw_gpio_ext_direction_input(struct udevice *dev, unsigned offset) +{ + debug("%s offset:0x%x\n", __func__, offset); + + return 0; +} + +static int nbhw_gpio_ext_direction_output (struct udevice *dev, unsigned offset, int value) +{ + debug("%s offset:%d, value:%d\n", __func__, offset, value); + + nbhw_gpio_ext_set_value(dev, offset, value); + + return 0; +} + +static int nbhw_gpio_ext_get_function(struct udevice *dev, unsigned offset) +{ + return GPIOF_OUTPUT; +} + +static const struct dm_gpio_ops nbhw_gpio_ext_ops = { + .direction_input = nbhw_gpio_ext_direction_input, + .direction_output = nbhw_gpio_ext_direction_output, + .get_value = nbhw_gpio_ext_get_value, + .set_value = nbhw_gpio_ext_set_value, + .get_function = nbhw_gpio_ext_get_function, +}; + +static const struct udevice_id nbhw_gpio_ext_ids[] = { + { .compatible = "nm,nbhw-gpio-ext" }, + { } +}; + +U_BOOT_DRIVER(gpio_nbhw_gpio_ext) = { + .name = "gpio_nbhw_gpio_ext", + .id = UCLASS_GPIO, + .of_match = nbhw_gpio_ext_ids, + .probe = nbhw_gpio_ext_probe, + .bind = nbhw_gpio_ext_bind, + .ops = &nbhw_gpio_ext_ops, +}; diff --git a/board/nm/common/nbhw_init.c b/board/nm/common/nbhw_init.c index e044622da6..c49ba096a2 100644 --- a/board/nm/common/nbhw_init.c +++ b/board/nm/common/nbhw_init.c @@ -34,7 +34,7 @@ static void set_mac(int interface, uint8_t macaddress[], size_t size) /* Serial number consists of 1st MAC address */ env_set("ethaddr", macstring); } - /* Always set eth%daddr because newer u-boots expect it */ + /* Always set eth%daddr because newer u-boots expect it */ { char ethaddr[32]; @@ -45,23 +45,20 @@ static void set_mac(int interface, uint8_t macaddress[], size_t size) } } -void set_mac_addresses(int interfaces) { +void set_mac_address(int interface, int mac) { uint8_t macaddress[6]; - int i; - /* If the compiler does inlining direct initialization of macaddress - * fails, this is the safer way */ + /* If the compiler does inlining direct initialization of macaddress + * fails, this is the safer way */ memset(macaddress, 0x11, sizeof(macaddress)); - for (i = 0; i < interfaces; i++) { - if(bd_get_mac(i, macaddress, 6) == 0) - set_mac(i, macaddress, 6); - else { - /* make temporary address */ - macaddress[0] = 0; - macaddress[5] += 1; - set_mac(i, macaddress, 6); - } + if (bd_get_mac(mac, macaddress, 6) == 0) + set_mac(interface, macaddress, 6); + else { + /* make temporary address */ + macaddress[0] = 0; + macaddress[5] += 1; + set_mac(interface, macaddress, 6); } } diff --git a/board/nm/common/nbhw_init.h b/board/nm/common/nbhw_init.h index 7e837941b3..f8c1228b6e 100644 --- a/board/nm/common/nbhw_init.h +++ b/board/nm/common/nbhw_init.h @@ -8,6 +8,6 @@ #ifndef _NBHW_INIT_H #define _NBHW_INIT_H -void set_mac_addresses(int interfaces); +void set_mac_address(int interface, int mac); #endif // _NBHW_INIT_H diff --git a/board/nm/common/nbhw_pcie_fixup.c b/board/nm/common/nbhw_pcie_fixup.c index da5c51f439..d3a89d596e 100644 --- a/board/nm/common/nbhw_pcie_fixup.c +++ b/board/nm/common/nbhw_pcie_fixup.c @@ -81,7 +81,7 @@ static int has_slot_wlan(int slot) char pdValue[200]; sprintf(slotDescr, "slot=%d", slot); - for (module=0; module<4; module++) { + for (module=0; module<6; module++) { strcpy(pdValue, "" ); /*init with an empty string*/ if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) { /* Wifi module needs PCIe */ @@ -127,7 +127,6 @@ static int has_pcie_link_on_slot(int slot) default: printf("Slot %d does not support PCIE\n", slot); } - return 1; } @@ -227,7 +226,7 @@ static void wait_for_reset(int reset_counter) * boot */ static int do_wlan_fixup(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int i; + int i, j; #define MAX_RESET_COUNT 6 int reset_counter = get_reset_counter(); int ret; @@ -244,11 +243,10 @@ static int do_wlan_fixup(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv /* Try it for at least one second */ for (i = 0; i < 100; i++) { - ret = 3; - if (check_pcie_slot_status(0)) ret &= ~1; - - if (check_pcie_slot_status(1)) ret &= ~2; - + ret = 0x3f; + for (j = 0; j < 6; j++) { + if (check_pcie_slot_status(j)) ret &= ~(1 << j); + } if (is_module_check_abort()) { puts("Abort WLAN module check\n"); ret = 0; diff --git a/board/nm/hw14/MAINTAINERS b/board/nm/hw14/MAINTAINERS new file mode 100644 index 0000000000..f5649400ec --- /dev/null +++ b/board/nm/hw14/MAINTAINERS @@ -0,0 +1,6 @@ +DB_88F6820_GP BOARD +M: Stefan Roese +S: Maintained +F: board/Marvell/db-88f6820-gp/ +F: include/configs/db-88f6820-gp.h +F: configs/db-88f6820-gp_defconfig diff --git a/board/nm/hw14/Makefile b/board/nm/hw14/Makefile new file mode 100644 index 0000000000..f6a0a0089a --- /dev/null +++ b/board/nm/hw14/Makefile @@ -0,0 +1,30 @@ +# +# Copyright (C) 2015 Stefan Roese +# +# SPDX-License-Identifier: GPL-2.0+ +# + +commonobj = ../common/bdparser.o \ + ../common/nbhw_bd.o \ + ../common/nbhw_env.o \ + ../common/nbhw_init.o \ + ../common/nbhw_fileaccess.o \ + ../common/nbhw_fpga_gpio.o \ + ../common/nbhw_gpio_ext.o \ + ../common/nbhw_partitions.o \ + ../common/nbhw_pcie_fixup.o + +ccflags-y := -I../common + +ifndef CONFIG_SPL_BUILD +obj-y := board.o nbhw_gpio.o nbhw_fpga_config.o mvswitch.o \ + ../common/nbhw_sim.o nbhw_sim.o \ + $(commonobj) +else +obj-y := board.o \ + ../common/nbhw_bd.o \ + ../common/nbhw_partitions.o \ + ../common/bdparser.o \ + ../common/nbhw_bd.o +endif + diff --git a/board/nm/hw14/README b/board/nm/hw14/README new file mode 100644 index 0000000000..9bea5b35cb --- /dev/null +++ b/board/nm/hw14/README @@ -0,0 +1,18 @@ +Update from original Marvell U-Boot to mainline U-Boot: +------------------------------------------------------- + +The resulting image including the SPL binary with the +full DDR setup is "u-boot-spl.kwb". + +To update the SPI NOR flash, please use the following +command: + +=> sf probe;tftpboot 2000000 db-88f6820-gp/u-boot-spl.kwb;\ +sf update 2000000 0 60000 + +Note that the original Marvell U-Boot seems to have +problems with the "sf update" command. This does not +work reliable. So here this command should be used: + +=> sf probe;tftpboot 2000000 db-88f6820-gp/u-boot-spl.kwb;\ +sf erase 0 60000;sf write 2000000 0 60000 diff --git a/board/nm/hw14/board.c b/board/nm/hw14/board.c new file mode 100644 index 0000000000..c0f1c02deb --- /dev/null +++ b/board/nm/hw14/board.c @@ -0,0 +1,839 @@ +/* + * Copyright (C) 2015 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#undef DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* ctrlc */ + +#include + +#include "nbhw_gpio.h" +#include "mvswitch.h" + +#include "../common/nbhw_init.h" +#include "../common/nbhw_env.h" +#include "../common/nbhw_bd.h" + +#include "../drivers/ddr/marvell/a38x/ddr3_init.h" +#include <../serdes/a38x/high_speed_env_spec.h> + +//#define EARLY_CONSOLE_OUTPUT + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Those values and defines are taken from the Marvell U-Boot version + * "u-boot-2013.01-2014_T3.0" + */ +#define GPP_OUT_ENA_LOW (~(BIT(21))) /* 1=Input, default input */ +#define GPP_OUT_ENA_MID (~(BIT(16))) + +#define GPP_OUT_VAL_LOW (BIT(21)) +#define GPP_OUT_VAL_MID (0x00) + +#define GPP_POL_LOW 0x0 +#define GPP_POL_MID 0x0 + +#define CP_BD_EEPROM_ADDR (0x50) /* CPU BD EEPROM (8kByte) is at 50 (A0) */ +#define MC_BD_EEPROM_ADDR (0x51) /* MC BD EEPROM (8kByte) is at 51 (A0) */ +#define PSE_BD_EEPROM_ADDR (0x52) /* PSE BD EEPROM (8kByte) is at 52 (A0) */ +#define BD_ADDRESS (0x0000) /* Board descriptor at beginning of EEPROM */ +#define PD_ADDRESS (0x0200) /* Product descriptor */ +#define PARTITION_ADDRESS (0x0600) /* Partition Table */ +#define SERDES_CONFIG_ADDRESS (0x0800) /* SERDES config address */ + +#define DEV_CS0_BASE 0xfd000000 +#define DEV_CS1_BASE 0xf4000000 + +/* Default serdes configuration */ +static struct serdes_map board_serdes_map[] = { + { SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, + { SGMII1, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, + { SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, + { PEX3, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 }, + { USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, + { PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 } +}; + +enum serdes_type get_serdes_type(int index) +{ + if ((index>=0) && (index =sizeof(eeprom_serdes_config.serdes_cfg))) return 0xff; + return eeprom_serdes_config.serdes_cfg[serdes_index]; +} + + +static inline int __maybe_unused read_eeprom(void) +{ + int res = _bd_init(); + + read_eeprom_serdes_config(); + + return res; +} + +#define RESET_REASON_SHM_LOCATION (0x3ffff000) + +extern int console_init_f(void); + +#if !defined(CONFIG_SPL_BUILD) + +static int init_console(void) +{ + int ret; + struct udevice *dev; + char *consoledev; + char buf[16] = "serial@12100"; + + debug("init console\n"); + + /* Make sure all devices are probed, it seems + * that this stuff is buggy in U-Boot */ + ret = uclass_first_device(UCLASS_SERIAL, &dev); + if (ret) { + printf("Could not find any serial device\n"); + return ret; + } + + while (list_is_last(&dev->uclass_node, &dev->uclass->dev_head) == 0) { + uclass_next_device(&dev); + } + + set_console(); + + consoledev = env_get("consoledev"); + if (strncmp(consoledev, "ttyS0", 5) == 0) { + strncpy(buf, "serial@12000", sizeof(buf)); + } + + env_set("stdin", buf); + env_set("stdout", buf); + env_set("stderr", buf); + + return 0; +} + +#endif + +int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) +{ + int i; + + if (read_eeprom() < 0){ + /* If we do not have a board descriptor use the default + serdes configuration defined in board_serdes_map */ + puts("Could not read board descriptor using default serdes config.\n"); + } else { + for (i = 0; i < ARRAY_SIZE(board_serdes_map); i++) { + enum serdes_type type; + uint8_t user_config = get_eeprom_serdes_config(i); + + if (user_config != 0xff) { + /* if we have a user config we use that one */ + type = (enum serdes_type)user_config; + } else { + /* otherwise we use the config from the bd */ + type = bd_get_serdes_type(i); + } + + if (type < LAST_SERDES_TYPE) { + if ((type >= SGMII0) && (type <= SGMII2)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS; + board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; + } + else if ((type >= PEX0) && (type <= PEX3)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1; + } + else if ((type >= USB3_HOST0) && (type <= USB3_HOST1)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1; + } + else if ((type >= SATA0) && (type <= SATA3)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_3_GBPS; + board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; + } + else if ((type == DEFAULT_SERDES)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS; + board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; + } else { + printf("SERDES Type %d not supported\n", type); + /* Keep default serdes configuration */ + type = board_serdes_map[i].serdes_type; + } + + debug("Configure SERDES %d to %d\n", i, type); + + board_serdes_map[i].serdes_type = type; + } + } + } + + *serdes_map_array = board_serdes_map; + *count = ARRAY_SIZE(board_serdes_map); + return 0; +} + +/* + * Define the DDR layout / topology here in the board file. This will + * be used by the DDR3 init code in the SPL U-Boot version to configure + * the DDR3 controller. + */ +static struct mv_ddr_topology_map board_topology_map = { + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */ + { { { {0x1, 0, 0, 0}, + {0x1, 0, 0, 0}, + {0x1, 0, 0, 0}, + {0x1, 0, 0, 0}, + {0x1, 0, 0, 0} }, + SPEED_BIN_DDR_1600K, /* speed_bin */ + MV_DDR_DEV_WIDTH_16BIT, /* sdram device width */ + MV_DDR_DIE_CAP_4GBIT, /* die capacity */ + MV_DDR_FREQ_667, /* frequency */ + 0, 0, /* cas_l cas_wl */ + MV_DDR_TEMP_HIGH} }, /* temperature */ + BUS_MASK_32BIT, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + { {0} }, /* raw spd data */ + {0} /* timing parameters */ +}; + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ + /* Return the board topology as defined in the board code */ + return &board_topology_map; +} + +#if defined(CONFIG_WATCHDOG) + +void watchdog_init(void) +{ + /* NOTE: Global watchdog counter register is at 0xf1020334 + Could not find this in the manual. */ + if (uclass_get_device(UCLASS_WDT, 0, (struct udevice **)&(gd->watchdog))) { + puts("Cannot enable watchdog!\n"); + } else { + puts("Enabling watchdog\n"); + wdt_start(gd->watchdog, (u32) 25000000 * 150, 0); /* Timer runs at 25 MHz */ + } +} + +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + static ulong next_reset = 0; + ulong now; + + if (!(gd->watchdog)) return; + + now = timer_get_us(); + + /* Do not reset the watchdog too often */ + if (now > next_reset) { + wdt_reset(gd->watchdog); + next_reset = now + 1000000; + } +} +#endif + +int board_early_init_f(void) +{ + /* Configure MPP */ + writel(0x11111111, MVEBU_MPP_BASE + 0x00); + writel(0x11111111, MVEBU_MPP_BASE + 0x04); + writel(0x55011111, MVEBU_MPP_BASE + 0x08); + writel(0x55550550, MVEBU_MPP_BASE + 0x0c); + writel(0x55555555, MVEBU_MPP_BASE + 0x10); + writel(0x06605505, MVEBU_MPP_BASE + 0x14); + writel(0x55550555, MVEBU_MPP_BASE + 0x18); + writel(0x00005550, MVEBU_MPP_BASE + 0x1c); + + /* Set GPP Out value */ + writel(GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00); + writel(GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00); + + /* Set GPP Polarity */ + writel(GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c); + writel(GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c); + + /* Set GPP Out Enable */ + writel(GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04); + writel(GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04); + + return 0; +} + +u32 spl_boot_mode(const u32 boot_device) +{ + return MMCSD_MODE_EMMCBOOT; +} + +void spl_board_init(void) +{ + int err; + struct mmc *mmcp; + + err = mmc_initialize(0); + if (err) + return; + + debug("SPL: select partition\n"); + mmcp = find_mmc_device(0); + mmc_init(mmcp); + printf("Partition found: %p\n", mmcp); + /* select boot0 as first boot partition */ + mmcp->part_config &= ~(PART_ACCESS_MASK << 3); + mmcp->part_config |= (1 << 3); + debug("Boot partition set to boot0\n"); +} + +#if !defined(CONFIG_SPL_BUILD) + +static void get_hw14_hw_version(BD_Context* bdctx, int *ver, int *rev) +{ + static uint8_t hwver = 0; + static uint8_t hwrev = 0; + + if ( !BD_GetUInt8( bdctx, BD_Hw_Ver, 0, &hwver) ) + debug("%s() no Hw Version found\n", __func__); + + if ( !BD_GetUInt8( bdctx, BD_Hw_Rel, 0, &hwrev) ) + debug("%s() no Hw Release found\n", __func__); + + *ver = hwver; + *rev = hwrev; +} + +static void pass_hw_rev(void) +{ + int cm_hw_ver = 0, cm_hw_rev = 0; + int mc_hw_ver = 0, mc_hw_rev = 0; + int pse_hw_ver = 0, pse_hw_rev = 0; + char *old_env; + char hw_versions[128]; + char new_env[256]; + + get_hw14_hw_version(&bdctx[0], &cm_hw_ver, &cm_hw_rev); + + get_hw14_hw_version(&bdctx[3], &mc_hw_ver, &mc_hw_rev); + + get_hw14_hw_version(&bdctx[4], &pse_hw_ver, &pse_hw_rev); + + snprintf(hw_versions, sizeof(hw_versions), "CP=%d.%d MC=%d.%d PSE=%d.%d", + cm_hw_ver, cm_hw_rev, mc_hw_ver, mc_hw_rev, pse_hw_ver, pse_hw_rev); + + old_env = env_get("add_version_bootargs"); + + /* Normaly add_version_bootargs should already be set (see board include file) */ + if (old_env != NULL) { + snprintf(new_env, sizeof(new_env), "%s %s", old_env, hw_versions); + } + else { + snprintf(new_env, sizeof(new_env), "setenv bootargs $bootargs %s", hw_versions); + } + + env_set("add_version_bootargs", new_env); +} + +#endif + +int board_init(void) +{ +#if defined(CONFIG_WATCHDOG) + watchdog_init(); +#endif + + /* address of boot parameters */ + gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100; + + /* Setup the MBUS mapping for Devicebus CS0 (FPGA) */ + mbus_dt_setup_win(&mbus_state, DEV_CS0_BASE, 16 << 20, + CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS0 /* 0x3e */); + + /* Setup the MBUS mapping for Devicebus CS1 (GPIO Ext) */ + /* Warning: Conflicts with the default definition for MBUS_SPI_BASE in arch/arm/mach-mvebu/cpu.c */ + mbus_dt_setup_win(&mbus_state, DEV_CS1_BASE, 16 << 20, + CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS1 /* 0x3d */ ); + + if (read_eeprom() < 0) + puts("Could not get board ID.\n"); + + /* @@se: With this call we disable a debug feature, that allows one to read out the memory + * over i2c at slave address 0x64. This feature is for some undocumented reasons enabled by default + * the default value is 0x00370010, according to the documentation it should be 0x00330010. If we set + * it back to this value address 0x64 is unused again. This is necessary because atsha204 uses 0x64 as + * slave address. + */ + writel(0x00330010, SOC_REGS_PHY_BASE + 0x0001108c); + + return 0; +} + +int board_early_init_r(void) +{ + /* We need to force mmc_initialization here, so that + * we have mmc available for read of /boot/consoledev */ + mmc_initialize(gd->bd); + /* We need to force the env relocation so that it won't overwritte the + * serial devices that we set in init_console */ + env_relocate(); + gd->env_valid = ENV_VALID; + + return 0; +} + +#if !defined(CONFIG_SPL_BUILD) + +static bool get_button_state(void) +{ + return (get_gpio(GPIO_RESET_BUTTON) == 0); +} + +static int 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 */ + + /* let all green LEDs blink up */ + set_led(LED0_GREEN, 1); + set_led(LED1_GREEN, 1); + set_led(LED2_GREEN, 1); + set_led(LED3_GREEN, 1); + set_led(LED4_GREEN, 1); + set_led(LED5_GREEN, 1); + udelay(400000); /* 400ms */ + set_led(LED1_GREEN, 0); + set_led(LED2_GREEN, 0); + set_led(LED3_GREEN, 0); + set_led(LED4_GREEN, 0); + set_led(LED5_GREEN, 0); + } else if (counter == 12000) { + /* Indicate recovery boot threshold */ + + /* let all red LEDs blink up */ + set_led(LED0_GREEN, 0); + set_led(LED0_RED, 1); + set_led(LED1_RED, 1); + set_led(LED2_RED, 1); + set_led(LED3_RED, 1); + set_led(LED4_RED, 1); + set_led(LED5_RED, 1); + udelay(400000); /* 400ms */ + set_led(LED0_RED, 0); + set_led(LED1_RED, 0); + set_led(LED2_RED, 0); + set_led(LED3_RED, 0); + set_led(LED4_RED, 0); + set_led(LED5_RED, 0); + set_led(LED0_GREEN, 1); + } + } 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 = env_get("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)); + + env_set("bootargs", new_bootargs); + return 1; + } + else + { + /* Boot into recovery for duration > 12s */ + + printf("Booting recovery image...\n"); + + /* Set bootcmd to run recovery */ + env_set("bootcmd", "run recovery"); + + return 0; + } + + return 0; +} + +#ifdef CONFIG_CMD_NB_TEST +/* + * Perform a hardware reset test. The complete test loops until + * interrupted by ctrl-c or by pressed the RESET button. + */ +int do_hwreset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int gpio_cpu_value = 0; + + printf(" Press RESET button for testing or ctrl-c to abort\n"); + + while (gpio_cpu_value == 0) { + gpio_cpu_value = get_button_state() ? 1 : 0; + + printf("RESET_BTN = %d\n",gpio_cpu_value); + if (ctrlc()) { + putc ('\n'); + return 1; + } + udelay(20*1000); + } + + return 1; +} +#endif /* CONFIG_CMD_NB_TEST */ + +static void init_rtc(void) +{ + /* Enable trickle charger for rtc backup capacitor */ + uchar charge_mode = 0xa5; /* No diode, 250 Ohm resistor */ + if (0 != i2c_write(0x68, 0x10, 1, &charge_mode, 1)) + { + puts("No RTC found\n"); + } +} + +#endif /* !defined(CONFIG_SPL_BUILD) */ + +int misc_init_r(void) +{ + struct serdes_map* sm; + u8 sm_count; + +#ifdef EARLY_CONSOLE_OUTPUT + init_console(); + console_init_f(); +#endif + + /* Initialize output extension */ + debug("Power on WD and other stuff\n"); + set_gpio(GPIO_WD_ENABLE, 0); + set_gpio(GPIO_RST_I2C_EXP, 0); + set_gpio(GPIO_LED_DBG, 1); + + /* Drive CS1 output extension pins */ + debug("Enable DevBus IO Expander\n"); + set_gpio(GPIO_EXT_OE, 1); + mdelay(20); + + /* Enable SATA power */ + debug("Enable SATA\n"); + set_gpio(GPIO_EN_SATA_PWR, 1); + mdelay(10); + + /* Deassert USB hub reset */ + debug("Enable USB Hub\n"); + set_gpio(GPIO_RST_USB_HUB, 0); + mdelay(10); + + /* Enable USB bus power */ + debug("Enable USB\n"); + set_gpio(GPIO_USB1_DRIVE_VBUS, 1); + mdelay(10); + + /* Deassert ethernet switch reset */ + debug("Enable ethernet switch\n"); + set_gpio(GPIO_RST_PSE_ETH, 0); + mdelay(10); + + /* Determine SERDES configuration */ + hws_board_topology_load(&sm, &sm_count); + +#if !defined(CONFIG_SPL_BUILD) + /* Enable PMIC RTC backup charger (charge with 6mA to 3.1V) */ + init_rtc(); +#endif + + return 0; +} + +#if !defined(CONFIG_SPL_BUILD) + +static void set_devicetree_name(void) +{ + char devicetreename[64]; + + if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) { + printf("Devicetree name not found in BD\n"); + strncpy(devicetreename, "openwrt-nbhw14.dtb", sizeof(devicetreename)); + if (get_mvswitch_type() != MVS_88E6060) { + strncpy(devicetreename, "openwrt-nbhw14-sgmii.dtb", sizeof(devicetreename)); + } + printf ("Selected %s devicetree file based on ethernet configuration\n", devicetreename); + } + + env_set("fdt_image", devicetreename); +} + +#endif + +int board_late_init(void) +{ +#if !defined(CONFIG_SPL_BUILD) + find_and_set_active_partition(); + pass_hw_rev(); + + run_command("run load_fpga", CMD_FLAG_ENV); + +#ifndef EARLY_CONSOLE_OUTPUT + init_console(); + console_init_f(); +#endif + + check_reset_button(); + + /* Set address on both MACs as RGMII and SGMII use different MACs */ + set_mac_address(0, 0); + set_mac_address(1, 0); +#endif + + return 0; +} + +#if !defined(CONFIG_SPL_BUILD) +int board_network_enable(struct mii_dev *bus) +{ + static int NETWORK_ENABLED = 0; + + if (!NETWORK_ENABLED) { + configure_mvswitch(); + set_devicetree_name(); + NETWORK_ENABLED = 1; + } + + return 0; +} +#endif + +int checkboard(void) +{ + debug("Board: NetModule HW14\n"); + + return 0; +} + +int board_fit_config_name_match(const char *name) +{ +#ifdef CONFIG_SPL_BUILD + /* SPL has enabled serial0 per default and will output everything + * independend of /boot/consoledev */ +#define DEFAULT_DTB_NAME "armada-385-hw14-spl" +#else + /* U-Boot will read /boot/consoledev and based on that it + * enables its own serial console */ +#define DEFAULT_DTB_NAME "armada-385-hw14" +#endif + + /* Check if name fits our dts */ + return strcmp(DEFAULT_DTB_NAME, name); +} + +#ifdef CONFIG_OF_BOARD_FIXUP + + +int fdt_enable_by_ofname(void *rw_fdt_blob, char *ofname) +{ + int offset = fdt_path_offset(rw_fdt_blob, ofname); + + return fdt_status_okay(rw_fdt_blob, offset); +} + +int board_fix_fdt(void *fdt_blob) +{ + return 0; +} + +#endif + +int pcie_lane_by_slot(int slot) +{ + int serdes; + switch (slot) { + case 0 : + serdes = 3; + break; + case 1 : + if ((board_serdes_map[4].serdes_type >= PEX0) && + (board_serdes_map[4].serdes_type <= PEX3)) + { + serdes = 4; + } else { + serdes = -1; + } + break; + case 4 : + if ((board_serdes_map[5].serdes_type >= PEX0) && + (board_serdes_map[5].serdes_type <= PEX3)) + { + serdes = 5; + } else { + serdes = -1; + } + break; + default : + serdes = -1; + break; + } + + if ((serdes<0) || serdes>=ARRAY_SIZE(board_serdes_map)) + return -1; + + switch (board_serdes_map[serdes].serdes_type) + { + case PEX0 : + return 0; + case PEX1 : + return 1; + case PEX2 : + return 2; + case PEX3 : + return 3; + default : + return -1; + } + +} + +/******************************************************************************* + Enable additional nodes in DTS depending on board descriptor +*******************************************************************************/ + +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"); + } +} + +int ft_board_setup(void *blob, bd_t *bd) +{ + char pdValue[200]; + + /* Enabled all components in dts depending on + current serdes configuration */ + + /* Enable DIOs on PSE board (NB37xx only) */ + memset(pdValue, 0x00, sizeof(pdValue)); + if (bd_get_prodname(pdValue, sizeof(pdValue))==0) { + if (strstr(pdValue, "37")) { + /* if it is an NB3700 series device enable + the on board DIOs on the PSE */ + printf("FT: enable netbox_dio_pse\n"); + ft_enable_node(blob, "/fpga_dio"); + } + } + + return 0; +} diff --git a/board/nm/hw14/kwbimage.cfg b/board/nm/hw14/kwbimage.cfg new file mode 100644 index 0000000000..a705a795c0 --- /dev/null +++ b/board/nm/hw14/kwbimage.cfg @@ -0,0 +1,12 @@ +# +# Copyright (C) 2014 Stefan Roese +# + +# Armada XP uses version 1 image format +VERSION 1 + +# Boot Media configurations +BOOT_FROM sdio + +# Binary Header (bin_hdr) with DDR3 training code +BINARY spl/u-boot-spl-dtb.bin 0000005b 00000068 diff --git a/board/nm/hw14/mvswitch.c b/board/nm/hw14/mvswitch.c new file mode 100644 index 0000000000..5b92e113f6 --- /dev/null +++ b/board/nm/hw14/mvswitch.c @@ -0,0 +1,178 @@ +#undef DEBUG +#include +#include +#include "mvswitch.h" + +static enum MvSwitchType mvSwType = MVS_UNKNOWN; + +static int check_mvswitch(void) +{ + const char* miidev = miiphy_get_current_dev(); + unsigned short switchPortProductId; + int res; + + debug ("miidev: %s\n", miidev); + + res = miiphy_read(miidev, 0x10, 0x03, &switchPortProductId); + if (res) goto abort; + + if ((switchPortProductId & 0xfff0) == 0x0990) { + unsigned short statusRegister; + + res = miiphy_read(miidev, 0x1A, 0x00, &statusRegister); + if (res) goto abort; + + /* If status register says phy is in SGMII mode */ + if ((statusRegister & 0x07) == 0x6) { + printf("Detected MV88E6097 switch in SGMII mode (0x%4.4x)\n", switchPortProductId); + } + else { + printf("Detected MV88E6097 switch in RGMII mode (0x%4.4x)\n", switchPortProductId); + } + mvSwType = MVS_88E6097; + } else { + res = miiphy_read(miidev, 0x08, 0x03, &switchPortProductId); + if (res) goto abort; + + if ((switchPortProductId & 0xfff0) == 0x0600) { + printf("Detected MV88E6060 switch in MII mode (0x%4.4x)\n", switchPortProductId); + mvSwType = MVS_88E6060; + } + } + + return 0; + +abort: + printf("Could not identify ethernet switch!"); + return 1; +} + +static int init_mvswitch(void) +{ + const char* miidev = miiphy_get_current_dev(); + unsigned short value; + unsigned short page; + int i; + + debug ("miidev: %s\n", miidev); + + switch (mvSwType) + { + case MVS_88E6097 : + /* Disable PPU */ + miiphy_write(miidev, 0x1b, 0x0004, 0x0080); + + /* Reset switch */ + miiphy_write(miidev, 0x1b, 0x0004, 0x8080); + + for (i = 0x10; i <= 0x1a; i++) { + /* Isolate external ports from each other */ + if (i==0x1a) + { + miiphy_write(miidev, i, 0x06, 0x03ff); + } else { + miiphy_write(miidev, i, 0x06, 0x0400); + } + + /* Enable forwarding & flooding of unknown addresses on all ethernet ports */ + value = 0x000f; + miiphy_write(miidev, i, 0x04, value); + } + + /* Power-up all ethernet phys except 10 (mii no phy) */ + for (i = 0x00; i <= 0x0A; i++) { + if (i == 0x0A) continue; + miiphy_read(miidev, i, 0x00, &value); + value &= ~0x0800; + miiphy_write(miidev, i, 0x00, value); + } + + /* Configure mii port 10 */ + miiphy_write(miidev, 0x1a, 0x01, 0x203E); + + /* Correct Clk Signal */ + /* comment se: This is somehow strange, we have + * to write to switch port timing control register 0x16 + * but it effects Port 0x0a (so register 0x1a would be normal). In the documentation they write + * "RGMII Timing Control (Device Offset 0x16 only)" with that + * they mean the only valid register to modify is 0x16. Below they write: + * "These RGMII timing bits affect Port 10’s timing only and only if Port 10 is + * configured in RGMII mode" so it seems this is the way to go... + */ + miiphy_read(miidev, 0x16, 0x1a, &value); + value |= 0x0600; + miiphy_write(miidev, 0x16, 0x1a, value); + + /* Configure external phy 8 and 9 led */ + for (i = 0x08; i <= 0x09; i++) { + miiphy_read(miidev, i, 0x16, &page); + miiphy_write(miidev, i, 0x16, 0x0003); + miiphy_read(miidev, i, 0x10, &value); + value &= ~0x0F0F; + value |= 0x0E01; + miiphy_write(miidev, i, 0x10, value); + miiphy_write(miidev, i, 0x16, page); + } + + /*Enable PPU*/ + miiphy_write(miidev, 0x1b, 0x0004, 0x4080); + + /* select eth1 */ + env_set("ethact", "ethernet@30000"); + + break; + + case MVS_88E6060 : + /* Disable bridging between external ethernet ports */ + miiphy_write(miidev, 0x08, 0x06, 0x0020); + miiphy_write(miidev, 0x09, 0x06, 0x0020); + miiphy_write(miidev, 0x0a, 0x06, 0x0020); + miiphy_write(miidev, 0x0b, 0x06, 0x0020); + miiphy_write(miidev, 0x0c, 0x06, 0x0020); + miiphy_write(miidev, 0x0d, 0x06, 0x001f); + + /* Enable all ethernet ports */ + miiphy_write(miidev, 0x08, 0x04, 0x0003); + miiphy_write(miidev, 0x09, 0x04, 0x0003); + miiphy_write(miidev, 0x0a, 0x04, 0x0003); + miiphy_write(miidev, 0x0b, 0x04, 0x0003); + miiphy_write(miidev, 0x0c, 0x04, 0x0003); + miiphy_write(miidev, 0x0d, 0x04, 0x0003); + + /* select eth0 */ + env_set("ethact", "ethernet@70000"); + + break; + + case MVS_UNKNOWN : + default : + printf("No or unknown ethernet switch detected!"); + goto abort; + break; + } + return 0; + +abort: + return 1; +} + +int configure_mvswitch(void) +{ + int res; + + res = check_mvswitch(); + if (res) goto abort; + + res = init_mvswitch(); + if (res) goto abort; + + return 0; + +abort: + return 1; +} + +enum MvSwitchType get_mvswitch_type(void) +{ + return mvSwType; +} diff --git a/board/nm/hw14/mvswitch.h b/board/nm/hw14/mvswitch.h new file mode 100644 index 0000000000..68fb039a20 --- /dev/null +++ b/board/nm/hw14/mvswitch.h @@ -0,0 +1,14 @@ +#ifndef MVSWITCH_H +#define MVSWITCH_H + +enum MvSwitchType { + MVS_UNKNOWN, + MVS_88E6060, + MVS_88E6097 +}; + +int configure_mvswitch(void); + +enum MvSwitchType get_mvswitch_type(void); + +#endif diff --git a/board/nm/hw14/nbhw_fpga_config.c b/board/nm/hw14/nbhw_fpga_config.c new file mode 100644 index 0000000000..65baf4c9ba --- /dev/null +++ b/board/nm/hw14/nbhw_fpga_config.c @@ -0,0 +1,234 @@ +#undef DEBUG +#include +#include +#include +#include +#include +#include +#include +#include "../common/nbhw_bd.h" +#include "../common/nbhw_sim.h" +#include "nbhw_gpio.h" + +DECLARE_GLOBAL_DATA_PTR; + +struct gpio_desc leds[16]; +struct udevice *driver_dev; + +struct config_priv { + u32 led_count; +} priv; + +typedef enum { + TYPE_USB, + TYPE_USB3, + TYPE_PCIE, +} slot_type_t; + +struct pcie_slot_gpios { + struct gpio_desc reset; + struct gpio_desc power; + struct gpio_desc wdis_out; + struct gpio_desc wdis; +}; + +#define PCIE_SLOT_COUNT 8 +static struct pcie_slot_gpios pcie_slots[PCIE_SLOT_COUNT]; + +static int pcie_slot_count = 0; + +int pcie_lane_by_slot(int slot); + +static int request_and_set_gpio_by_name(ofnode fdt, + const char *name, struct gpio_desc *desc) +{ + int default_value = 0; + u32 gpio_array[4]; + debug("%s\n", __func__); + + /* Request the gpio described by the property */ + if (gpio_request_by_name_nodev(fdt, name, 0, desc, + GPIOD_IS_OUT)) + { + debug("Could not request gpio %s\n", name); + return -1; + } + + /* Get the gpio array, to find out its default value (4 index) */ + if (ofnode_read_u32_array(fdt, name, gpio_array, 4)) { + printf("Could not request gpio array %s\n", name); + return -1; + + } + + default_value = gpio_array[3]; + debug("Set GPIO %s to %d\n", name, default_value); + dm_gpio_set_value(desc, default_value); + return 0; +} + +static int add_pcie_slot(ofnode fdt) +{ + debug("%s\n", __func__); + + request_and_set_gpio_by_name(fdt, "power", + &pcie_slots[pcie_slot_count].power); + + request_and_set_gpio_by_name(fdt, "reset", + &pcie_slots[pcie_slot_count].reset); + + request_and_set_gpio_by_name(fdt, "wdis-out", + &pcie_slots[pcie_slot_count].wdis_out); + + request_and_set_gpio_by_name(fdt, "wdis", + &pcie_slots[pcie_slot_count].wdis); + + pcie_slot_count++; + return 0; +} + +static void configure_pcie_muxes(void) +{ + /* Disable PCI clock and serdes4 routing unless + explicitly requested later. */ + set_gpio(GPIO_SERDES4_MUX_EN, 0); + set_gpio(GPIO_PEX2_CLK_1_4_MUX_EN, 0); + + /* Check for PCIe on slot 1 */ + if (pcie_lane_by_slot(1) >= 0) { + // PEX2 is on slot 1 + + // mux serdes4 to slot 1 pci pins + set_gpio(GPIO_SERDES4_MUX_SEL, 1); + set_gpio(GPIO_SERDES4_MUX_EN, 1); + // route PEX2 clock to slot 1 + set_gpio(GPIO_PEX2_CLK_1_4_MUX_SEL, 1); + set_gpio(GPIO_PEX2_CLK_1_4_MUX_EN, 1); + } else { + // mux serdes4 to slot 1 usb 3.0 pins + set_gpio(GPIO_SERDES4_MUX_SEL, 0); + set_gpio(GPIO_SERDES4_MUX_EN, 1); + } + + /* Check for PCIe on slot 4 */ + if (pcie_lane_by_slot(4) >= 0) { + // PEX2 is on slot 4 + + // route PEX2 clock to slot 4 + set_gpio(GPIO_PEX2_CLK_1_4_MUX_SEL, 0); + set_gpio(GPIO_PEX2_CLK_1_4_MUX_EN, 1); + } +} + +static int configure_pcie_slots(void) +{ + int i; + + configure_pcie_muxes(); + configure_sim_slots(6); + + udelay(1200000); /* 1.2 s */ + + /* Apply power to all PCIe slots */ + for (i = 0; i < pcie_slot_count; i++) { + dm_gpio_set_value(&pcie_slots[i].power, 1); + udelay(200000); /* 200 ms */ + } + + /* Assert reset after power is enabled */ + for (i = 0; i < pcie_slot_count; i++) { + dm_gpio_set_value(&pcie_slots[i].reset, 1); + } + + /* Deactivate WDIS */ + for (i = 0; i < pcie_slot_count; i++) { + dm_gpio_set_value(&pcie_slots[i].wdis_out, 1); + dm_gpio_set_value(&pcie_slots[i].wdis, 0); + udelay(2000); /* 2 ms needed by Reyax module as regulator is enabled by WDIS~*/ + } + + udelay(12000); /* 12 ms */ + + /* Deassert reset */ + for (i = 0; i < pcie_slot_count; i++) { + dm_gpio_set_value(&pcie_slots[i].reset, 0); + } + + pci_init_board(); + + return 0; +} + +static int configure_leds(void) +{ + int i; + int led_count; + + led_count = gpio_request_list_by_name(driver_dev, "leds", leds, + ARRAY_SIZE(leds), GPIOD_IS_OUT); + + dm_gpio_set_value(&leds[0], 1); + for (i = 1; i < ARRAY_SIZE(leds); i++) { + dm_gpio_set_value(&leds[i], 0); + } + + priv.led_count = led_count; + + return 0; +} + +void set_led(int index, int value) +{ + if ((index<0) || (index>=priv.led_count)) return; + + dm_gpio_set_value(&leds[index], value); +} + +int nbhw_fpga_configure(void) +{ + ofnode subnode; + ofnode node = driver_dev->node; + debug("%s\n", __func__); + + ofnode_for_each_subnode(subnode, node) { + const char *name; + + name = ofnode_get_name(subnode); + + debug("Try to configure %s\n", name); + + if (!strncmp("pcieslot", name, 8)) { + add_pcie_slot(subnode); + } + } + + if (configure_leds()) + return -1; + + if (configure_pcie_slots()) { + return -1; + } + + return 0; +} + +static int nbhw_fpga_config_bind(struct udevice *dev) +{ + debug("%s\n", __func__); + + driver_dev = dev; + return 0; +} + +static const struct udevice_id nbhw_fpga_config_ids[] = { + { .compatible = "nm,hw14-fpga-config" }, + { } +}; + +U_BOOT_DRIVER(gpio_nbhw_fpga_config) = { + .name = "hw14_fpga_config", + .id = UCLASS_ROOT, + .of_match = nbhw_fpga_config_ids, + .bind = nbhw_fpga_config_bind, +}; + diff --git a/board/nm/hw14/nbhw_gpio.c b/board/nm/hw14/nbhw_gpio.c new file mode 100644 index 0000000000..3289499a4e --- /dev/null +++ b/board/nm/hw14/nbhw_gpio.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include "nbhw_gpio.h" + +struct gpio_node { + struct gpio_node* next; + struct gpio_desc desc; + const char* name; + int is_output; +}; + +static struct gpio_node* gl = NULL; + +static struct gpio_desc* lookup_gpio(const char* gpio_name, int is_output) { + struct gpio_node* cur = gl; + + while (cur) { + if ((strcmp(gpio_name, cur->name)==0) && + (is_output == cur->is_output)) { + return &(cur->desc); + } + cur = cur->next; + } + return NULL; +} + +static struct gpio_desc* acquire_gpio(const char* gpio_name, int is_output) { + struct gpio_node* gn = 0; + int node; + + /* Check, if we already requested this gpio */ + struct gpio_desc* desc = lookup_gpio(gpio_name, is_output); + + if (desc) return desc; + + /* If we do not have it try to request it now. */ + node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "nm,gpios"); + if (node < 0) { + goto abort; + } + + gn = (struct gpio_node*)malloc(sizeof(struct gpio_node)); + if (!gn) goto abort; + + if (gpio_request_by_name_nodev(offset_to_ofnode(node), gpio_name, 0, &(gn->desc), is_output ? GPIOD_IS_OUT : GPIOD_IS_IN) < 0) { + goto abort; + } + + gn->name = gpio_name; + gn->is_output = is_output; + gn->next = gl; + gl = gn; + + desc = &(gn->desc); + + return desc; + +abort: + if (gn) free(gn); + printk("Could not acquire gpio %s as %s!\n", gpio_name, is_output ? "output" : "input"); + return 0; +} + +int get_gpio(const char* gpio_name) +{ + struct gpio_desc* d; + int res; + + d = acquire_gpio(gpio_name, 0); + if (!d) goto abort; + + res = dm_gpio_get_value(d); + + return res; + +abort: + printf("Could not set gpio %s!\n", gpio_name); + return -1; +} + +int set_gpio(const char* gpio_name, int value) +{ + struct gpio_desc* d; + + d = acquire_gpio(gpio_name, 1); + if (!d) goto abort; + + dm_gpio_set_value(d, value); + + return 0; + +abort: + printf("Could not set gpio %s!\n", gpio_name); + return -1; +} + diff --git a/board/nm/hw14/nbhw_gpio.h b/board/nm/hw14/nbhw_gpio.h new file mode 100644 index 0000000000..a2c5deb2e6 --- /dev/null +++ b/board/nm/hw14/nbhw_gpio.h @@ -0,0 +1,42 @@ +#ifndef HW14_GPIO_H +#define HW14_GPIO_H + +/* GPIO definitions */ +#define GPIO_WD_ENABLE "wd_enable" +#define GPIO_RST_I2C_EXP "rst_i2c_exp" +#define GPIO_LED_DBG "led_dbg" +#define GPIO_EN_SATA_PWR "en_sata_pwr" +#define GPIO_USB1_VBUS_IN "usb1_vbus_in" +#define GPIO_USB1_DRIVE_VBUS "usb1_drive_vbus" +#define GPIO_USB1_PWR_FAULT "usb1_pwr_fault" +#define GPIO_EXT_RST_EN "ext_rst_en" +#define GPIO_RST_FPGA "rst_fpga" +#define GPIO_RST_USB_HUB "rst_usb_hub" +#define GPIO_RST_PSE_ETH "rst_pse_eth" +#define GPIO_RESET_BUTTON "reset_button" +#define GPIO_EXT_OE "ext_oe" +#define GPIO_SERDES4_MUX_EN "serdes4_mux_en" +#define GPIO_SERDES4_MUX_SEL "serdes4_mux_sel" +#define GPIO_PEX2_CLK_1_4_MUX_EN "pex2_clk_1_4_mux_en" +#define GPIO_PEX2_CLK_1_4_MUX_SEL "pex2_clk_1_4_mux_sel" + +int get_gpio(const char* gpio_name); +int set_gpio(const char* gpio_name, int value); + +/* LED definitions */ +#define LED0_GREEN 0 +#define LED0_RED 1 +#define LED1_GREEN 2 +#define LED1_RED 3 +#define LED2_GREEN 4 +#define LED2_RED 5 +#define LED3_GREEN 6 +#define LED3_RED 7 +#define LED4_GREEN 8 +#define LED4_RED 9 +#define LED5_GREEN 10 +#define LED5_RED 11 + +void set_led(int index, int value); + +#endif diff --git a/board/nm/hw14/nbhw_sim.c b/board/nm/hw14/nbhw_sim.c new file mode 100644 index 0000000000..7541c18f47 --- /dev/null +++ b/board/nm/hw14/nbhw_sim.c @@ -0,0 +1,77 @@ +#include +#include + +#include "../common/nbhw_fpga_prog.h" + +struct simcfg_t{ + uint16_t simctrl; + uint16_t simctrlmask; + uint16_t simbusctrl; + uint16_t simbusctrlmask; +}; + +static struct simcfg_t get_simcfg(int sim, int simbus, int slotsel) +{ + struct simcfg_t simcfg; + + memset(&simcfg, 0, sizeof(simcfg)); + + if (sim > 4) { + printf("SIM carrier not supported for NB3800\n"); + return simcfg; + } + + if (simbus == -1) { + /* Clear the SIM enable flag only */ + simcfg.simctrlmask = 0x1 << (sim * 2); + return simcfg; + } + + if (sim < 4 && sim >= 0) { + simcfg.simctrl = (1 << (sim * 2)) | ((simbus & 1) << (1 + sim * 2)) | ((simbus & 2) << (7 + sim)); + simcfg.simctrlmask = (0x1 << (sim + 8)) | (0x3 << (sim * 2)); + } + + switch (slotsel) { + case 0: simcfg.simbusctrl = 0x01, simcfg.simbusctrlmask = 0x3; break; + case 1: simcfg.simbusctrl = 0x03, simcfg.simbusctrlmask = 0x3; break; + case 2: simcfg.simbusctrl = 0x04, simcfg.simbusctrlmask = 0xC; break; + case 3: simcfg.simbusctrl = 0x0C, simcfg.simbusctrlmask = 0xC; break; + default: simcfg.simbusctrlmask = 0; + } + + return simcfg; +} + +void connect_sim_to_slot(int sim, int slot) { + struct simcfg_t simcfg; + uint16_t simctrl; + uint16_t simbusctrl; + + if (sim > 4 || sim < 0) { + printf("Invalid sim %d selected, can't connect slot %d\n", sim, slot); + return; + } + + /* Parser to broken FPGA register structure */ + switch(slot) { + case 0: simcfg = get_simcfg(sim, 0, 0); break; + case 1: simcfg = get_simcfg(sim, 1, -1); break; + case 2: simcfg = get_simcfg(sim, 0, 1); break; + case 3: simcfg = get_simcfg(sim, 2, -1); break; + case 4: simcfg = get_simcfg(sim, 3, 2); break; + case 5: simcfg = get_simcfg(sim, 3, 3); break; + default: simcfg = get_simcfg(sim, -1, -1); break; + } + + simctrl = FPGA_REG(0x0040); + simctrl &= ~simcfg.simctrlmask; + simctrl |= simcfg.simctrl; + FPGA_REG(0x0040) = simctrl; + + simbusctrl = FPGA_REG(0x0042); + simbusctrl &= ~simcfg.simbusctrlmask; + simbusctrl |= simcfg.simbusctrl; + FPGA_REG(0x0042) = simbusctrl; +} + diff --git a/board/nm/nbhw17_v1/Makefile b/board/nm/nbhw17_v1/Makefile index 4726bebfbd..df444753ab 100644 --- a/board/nm/nbhw17_v1/Makefile +++ b/board/nm/nbhw17_v1/Makefile @@ -11,14 +11,19 @@ commonobj = ../common/bdparser.o \ ../common/nbhw_fileaccess.o \ ../common/nbhw_fpga_gpio.o \ ../common/nbhw_partitions.o \ - ../common/nbhw_pcie_fixup.o + ../common/nbhw_pcie_fixup.o ccflags-y := -I../common ifndef CONFIG_SPL_BUILD -obj-y := board.o nbhw_gpio.o nbhw_fpga_config.o $(commonobj) +obj-y := board.o nbhw_gpio.o nbhw_fpga_config.o \ + $(commonobj) else -obj-y := board.o nbhw_gpio.o ../common/nbhw_bd.o ../common/nbhw_partitions.o +obj-y := board.o \ + ../common/nbhw_bd.o \ + ../common/nbhw_partitions.o \ + ../common/bdparser.o \ + ../common/nbhw_bd.o endif diff --git a/board/nm/nbhw17_v1/board.c b/board/nm/nbhw17_v1/board.c index e6b311544a..10cba1b5d5 100644 --- a/board/nm/nbhw17_v1/board.c +++ b/board/nm/nbhw17_v1/board.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: GPL-2.0+ */ -#define DEBUG +#undef DEBUG #include #include #include @@ -15,6 +15,10 @@ #include #include #include +#include +#include +#include +#include /* ctrlc */ #include @@ -24,38 +28,60 @@ #include "../common/nbhw_env.h" #include "../common/nbhw_bd.h" -#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h" +#include "../drivers/ddr/marvell/a38x/ddr3_init.h" #include <../serdes/a38x/high_speed_env_spec.h> +//#define EARLY_CONSOLE_OUTPUT + DECLARE_GLOBAL_DATA_PTR; /* * Those values and defines are taken from the Marvell U-Boot version * "u-boot-2013.01-2014_T3.0" */ -#define GPP_OUT_ENA_LOW (~(BIT(7) | BIT(19) | BIT(21))) /* 1=Input, default input */ +/* 21: RST_ETH_PHYS~, 26: FPGA_CFG_RESET, 27: WD_ENABLE~ */ +#define GPP_OUT_ENA_LOW (~(BIT(21) | BIT(26) /*| BIT(27) */)) /* 1=Input, default input */ +/* 41/9: RST_USB_HUB~, 44/12: RST_FPGA~, 47/15: WD_TRIG */ +#define GPP_OUT_ENA_MID (~(BIT(9) | BIT(12) | BIT(15))) -#define GPP_OUT_ENA_MID (~(BIT(9) | BIT(12))) +#define GPP_OUT_VAL_LOW (BIT(21)) /* 1=pin on */ +#define GPP_OUT_VAL_MID (0x0) +#define GPP_POL_LOW (0x0) /* 0=no inversion */ +#define GPP_POL_MID (0x0) -#define GPP_OUT_VAL_LOW (~(BIT(21) | BIT(26) | BIT(27))) -#define GPP_OUT_VAL_MID (~(BIT(9) | BIT(12) | BIT(15))) -#define GPP_POL_LOW (BIT(21)) /* 1=pin on */ -#define GPP_POL_MID 0x0 - -#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 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 SERDES_CONFIG_ADDRESS (0x0800) /* SERDES config address */ #define DEV_CS0_BASE 0xfd000000 +/* Chip select base addresses */ +#define NBHW_BASE_ADDRESS_FPGA DEV_CS0_BASE + +/* Compute FPGA register addresses */ +#define FPGA_REG(x) *((volatile unsigned short*)( NBHW_BASE_ADDRESS_FPGA + ((unsigned int)x))) + +#define PCIE_4_PCM_GPIO_EN (0x0430) +#define PCIE_4_PCM_GPIO_DIR (0x0432) +#define PCIE_4_PCM_GPIO_DAT (0x0434) + +/* TODO: These platform specific SERDES default definitions are + currently defined twice here and in by hws_board_topology_load(). + Actually these platform specific defaults should only be set + in hws_board_topology_load(). + The defaults should there be set also for the case where we have + a valid BD but that BD does not contain SERDES configuration + info to support old HW14 boards. +*/ static struct serdes_map board_serdes_map[] = { { PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 }, { SGMII1, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, { SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, { SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, { PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 }, - { USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0 } + { USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0 } }; enum serdes_type get_serdes_type(int index) @@ -68,8 +94,223 @@ enum serdes_type get_serdes_type(int index) } } +typedef struct __attribute__ ((packed)) EthPhyRegs { + int page; + int reg; + int reserved; + int data; +} EthPhyRegs; + +const EthPhyRegs NB2800_ETH_PHY_REGS[] = { + { 0x0003, 0x0010, 0, 0x1032 }, /* LED function control register */ + { 0x0003, 0x0011, 0, 0x4405 }, /* LED polarity control register */ + { 0x0003, 0x0012, 0, 0x4a08 }, /* LED timer control register */ + { -1, -1, -1, -1 } +}; + +const EthPhyRegs NB2810_ETH_PHY_REGS[] = { + { 0x0003, 0x0010, 0, 0x1418 }, /* LED function control register */ + { 0x0003, 0x0011, 0, 0x442a }, /* LED polarity control register */ + { 0x0003, 0x0012, 0, 0x4a08 }, /* LED timer control register */ + { -1, -1, -1, -1 } +}; + +const EthPhyRegs* sSelectedPhyRegs = 0; + +static BD_Context bdctx[3]; /* The descriptor context */ + +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) { + /* Ignore that, legacy boxes don't have a pd */ + } + + 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; +} + +typedef struct EEPROM_SERDES_CONFIG { + uint8_t magic[2]; + uint8_t version; + uint8_t spare_0; + uint8_t serdes_cfg[6]; + uint8_t spare1[2]; + uint32_t crc32; +} EEPROM_SERDES_CONFIG; + +static struct EEPROM_SERDES_CONFIG eeprom_serdes_config; + +static void read_eeprom_serdes_config(void) +{ + uint32_t crc; + if (i2c_read(BD_EEPROM_ADDR, SERDES_CONFIG_ADDRESS, 2, (uint8_t *)&eeprom_serdes_config, sizeof(eeprom_serdes_config))) { + goto fail; + } + + crc = crc32(0, (uint8_t *)&eeprom_serdes_config, sizeof(eeprom_serdes_config)-4); + + if ((eeprom_serdes_config.magic[0] != 0x83) || + (eeprom_serdes_config.magic[1] != 0xfb) || + (eeprom_serdes_config.version != 0x01) || + (eeprom_serdes_config.crc32 != crc)) + { + goto fail; + } + + printf("Using user defined serdes config override\n"); + return; + +fail: + memset(&eeprom_serdes_config, 0xff, sizeof(eeprom_serdes_config)); + printf("Using default serdes config (No user defined override)\n"); + return; +} + +static uint8_t get_eeprom_serdes_config(int serdes_index) +{ + if ((serdes_index<0) || (serdes_index>=sizeof(eeprom_serdes_config.serdes_cfg))) return 0xff; + return eeprom_serdes_config.serdes_cfg[serdes_index]; +} + + +static inline int __maybe_unused read_eeprom(void) +{ + int res = _bd_init(); + + read_eeprom_serdes_config(); + + return res; +} + +#define RESET_REASON_SHM_LOCATION (0x3ffff000) + +extern int console_init_f(void); + +#if !defined(CONFIG_SPL_BUILD) + +static int init_console(void) +{ + int ret; + struct udevice *dev; + char *consoledev; + char buf[16] = "serial@12100"; + + debug("init console\n"); + + /* Make sure all devices are probed, it seems + * that this stuff is buggy in U-Boot */ + ret = uclass_first_device(UCLASS_SERIAL, &dev); + if (ret) { + printf("Could not find any serial device\n"); + return ret; + } + + while (list_is_last(&dev->uclass_node, &dev->uclass->dev_head) == 0) { + uclass_next_device(&dev); + } + + set_console(); + + consoledev = env_get("consoledev"); + if (strncmp(consoledev, "ttyS0", 5) == 0) { + strncpy(buf, "serial@12000", sizeof(buf)); + } + + env_set("stdin", buf); + env_set("stdout", buf); + env_set("stderr", buf); + + return 0; +} + +#endif + int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) { + int i; + + if (read_eeprom() < 0){ + puts("Could not read board descriptor using default serdes config.\n"); + + board_serdes_map[0].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[0].serdes_mode = PEX_ROOT_COMPLEX_X1; + board_serdes_map[0].serdes_type = PEX0; + + board_serdes_map[1].serdes_speed = SERDES_SPEED_1_25_GBPS; + board_serdes_map[1].serdes_mode = SERDES_DEFAULT_MODE; + board_serdes_map[1].serdes_type = SGMII1; + + board_serdes_map[2].serdes_speed = SERDES_SPEED_3_GBPS; + board_serdes_map[2].serdes_mode = SERDES_DEFAULT_MODE; + board_serdes_map[2].serdes_type = SATA1; + + board_serdes_map[3].serdes_speed = SERDES_SPEED_1_25_GBPS; + board_serdes_map[3].serdes_mode = SERDES_DEFAULT_MODE; + board_serdes_map[3].serdes_type = SGMII2; + + board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[4].serdes_mode = PEX_ROOT_COMPLEX_X1; + board_serdes_map[4].serdes_type = PEX2; + + board_serdes_map[5].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[5].serdes_mode = SERDES_DEFAULT_MODE; + board_serdes_map[5].serdes_type = USB3_HOST1; + } else { + for (i = 0; i < ARRAY_SIZE(board_serdes_map); i++) { + enum serdes_type type; + uint8_t user_config = get_eeprom_serdes_config(i); + + if (user_config != 0xff) { + /* if we have a user config we use that one */ + type = (enum serdes_type)user_config; + } else { + /* otherwise we use the config from the bd */ + type = bd_get_serdes_type(i); + } + + if (type < LAST_SERDES_TYPE) { + if ((type >= SGMII0) && (type <= SGMII2)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS; + board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; + } + else if ((type >= PEX0) && (type <= PEX3)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1; + } + else if ((type >= USB3_HOST0) && (type <= USB3_HOST1)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1; + } + else if ((type >= SATA0) && (type <= SATA3)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_3_GBPS; + board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; + } + else if ((type == DEFAULT_SERDES)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS; + board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; + } else { + printf("SERDES Type %d not supported\n", type); + /* Keep default serdes configuration */ + type = board_serdes_map[i].serdes_type; + } + + debug("Configure SERDES %d to %d\n", i, type); + + board_serdes_map[i].serdes_type = type; + } + } + } + *serdes_map_array = board_serdes_map; *count = ARRAY_SIZE(board_serdes_map); return 0; @@ -80,30 +321,65 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) * be used by the DDR3 init code in the SPL U-Boot version to configure * the DDR3 controller. */ -static struct hws_topology_map board_topology_map = { +static struct mv_ddr_topology_map board_topology_map = { + DEBUG_LEVEL_ERROR, 0x1, /* active interfaces */ /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */ { { { {0x1, 0, 0, 0}, - {0x1, 0, 0, 0}, - {0x1, 0, 0, 0}, - {0x1, 0, 0, 0}, - {0x1, 0, 0, 0} }, - SPEED_BIN_DDR_1600K, /* speed_bin */ - BUS_WIDTH_16, /* memory_width */ - MEM_4G, /* mem_size */ - DDR_FREQ_667, /* frequency */ - 7, 9, /* cas_l cas_wl */ - HWS_TEMP_HIGH} }, /* temperature */ - 5, /* Num Of Bus Per Interface*/ - BUS_MASK_32BIT /* Busses mask */ + {0x1, 0, 0, 0}, + {0x1, 0, 0, 0}, + {0x1, 0, 0, 0}, + {0x1, 0, 0, 0} }, + SPEED_BIN_DDR_1600K, /* speed_bin */ + MV_DDR_DEV_WIDTH_16BIT, /* sdram device width */ + MV_DDR_DIE_CAP_4GBIT, /* die capacity */ + MV_DDR_FREQ_667, /* frequency */ + 0, 0, /* cas_l cas_wl */ + MV_DDR_TEMP_HIGH} }, /* temperature */ + BUS_MASK_32BIT, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + { {0} }, /* raw spd data */ + {0} /* timing parameters */ }; -struct hws_topology_map *ddr3_get_topology_map(void) +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) { /* Return the board topology as defined in the board code */ return &board_topology_map; } +#if defined(CONFIG_WATCHDOG) + +void watchdog_init(void) +{ + /* NOTE: Global watchdog counter register is at 0xf1020334 + Could not find this in the manual. */ + if (uclass_get_device(UCLASS_WDT, 0, (struct udevice **)&(gd->watchdog))) { + puts("Cannot enable watchdog!\n"); + } else { + puts("Enabling watchdog\n"); + wdt_start(gd->watchdog, (u32) 25000000 * 150, 0); /* Timer runs at 25 MHz */ + } +} + +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + static ulong next_reset = 0; + ulong now; + + if (!(gd->watchdog)) return; + + now = timer_get_us(); + + /* Do not reset the watchdog too often */ + if (now > next_reset) { + wdt_reset(gd->watchdog); + next_reset = now + 1000000; + } +} +#endif + int board_early_init_f(void) { /* Configure MPP */ @@ -141,50 +417,22 @@ void spl_board_init(void) int err; struct mmc *mmcp; - err = mmc_initialize(NULL); + err = mmc_initialize(0); if (err) return; - puts("SPL: select partition\n"); + debug("SPL: select partition\n"); mmcp = find_mmc_device(0); mmc_init(mmcp); printf("Partition found: %p\n", mmcp); - /* select boot0 as bootpart */ + /* select boot0 as first boot partition */ + mmcp->part_config &= ~(PART_ACCESS_MASK << 3); mmcp->part_config |= (1 << 3); - puts("Partition switched to boot0\n"); + debug("Boot partition set to boot0\n"); } -static BD_Context bdctx[3]; /* The descriptor context */ +#if !defined(CONFIG_SPL_BUILD) -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) { - /* Ignore that, legacy boxes don't have a pd */ - } - - 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; -} - -static inline int __maybe_unused read_eeprom(void) -{ - return _bd_init(); -} - -static void set_gpios(void) -{ - init_gpios(); -} static void pass_hw_rev(void) { @@ -205,39 +453,201 @@ static void pass_hw_rev(void) snprintf(new_env, sizeof(new_env), "%s %s", old_env, hw_versions); } else { - snprintf(new_env, sizeof(new_env), "env_set bootargs $bootargs %s\n", hw_versions); + snprintf(new_env, sizeof(new_env), "setenv bootargs $bootargs %s", hw_versions); } env_set("add_version_bootargs", new_env); } +#endif + int board_init(void) { - /* adress of boot parameters */ +#if defined(CONFIG_WATCHDOG) + watchdog_init(); +#endif + + /* address of boot parameters */ gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100; - /* Setup the MBUS mapping for Devicebus CS0 */ + /* Setup the MBUS mapping for Devicebus CS0 (FPGA) */ mbus_dt_setup_win(&mbus_state, DEV_CS0_BASE, 16 << 20, - CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS0); + CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS0 /* 0x3e */); if (read_eeprom() < 0) puts("Could not get board ID.\n"); - set_console(); - - set_gpios(); - /* @@se: With this call we disable a debug feature, that allows one to read out the memory * over i2c at slave address 0x64. This feature is for some undocumented reasons enabled by default * the default value is 0x00370010, according to the documentation it should be 0x00330010. If we set * it back to this value address 0x64 is unused again. This is necessary because atsha204 uses 0x64 as * slave address. */ - writel(0x00330010, INTER_REGS_BASE + 0x1108C); + writel(0x00330010, SOC_REGS_PHY_BASE + 0x0001108c); return 0; } +int board_early_init_r(void) +{ + /* We need to force mmc_initialization here, so that + * we have mmc available for read of /boot/consoledev */ + mmc_initialize(gd->bd); + /* We need to force the env relocation so that it won't overwritte the + * serial devices that we set in init_console */ + env_relocate(); + gd->env_valid = ENV_VALID; + + return 0; +} + +#if !defined(CONFIG_SPL_BUILD) + +static bool get_button_state(void) +{ + return (get_gpio(GPIO_RESET_BUTTON) == 0); +} + +static int 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 */ + + /* let all green LEDs blink up */ + set_led(LED0_GREEN, 1); + set_led(LED1_GREEN, 1); + set_led(LED2_GREEN, 1); + set_led(LED3_GREEN, 1); + set_led(LED4_GREEN, 1); + set_led(LED5_GREEN, 1); + udelay(400000); /* 400ms */ + set_led(LED1_GREEN, 0); + set_led(LED2_GREEN, 0); + set_led(LED3_GREEN, 0); + set_led(LED4_GREEN, 0); + set_led(LED5_GREEN, 0); + } else if (counter == 12000) { + /* Indicate recovery boot threshold */ + + /* let all red LEDs blink up */ + set_led(LED0_GREEN, 0); + set_led(LED0_RED, 1); + set_led(LED1_RED, 1); + set_led(LED2_RED, 1); + set_led(LED3_RED, 1); + set_led(LED4_RED, 1); + set_led(LED5_RED, 1); + udelay(400000); /* 400ms */ + set_led(LED0_RED, 0); + set_led(LED1_RED, 0); + set_led(LED2_RED, 0); + set_led(LED3_RED, 0); + set_led(LED4_RED, 0); + set_led(LED5_RED, 0); + set_led(LED0_GREEN, 1); + } + } 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 = env_get("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)); + + env_set("bootargs", new_bootargs); + return 1; + } + else + { + /* Boot into recovery for duration > 12s */ + + printf("Booting recovery image...\n"); + + /* Set bootcmd to run recovery */ + env_set("bootcmd", "run recovery"); + + return 0; + } + + return 0; +} + +#ifdef CONFIG_CMD_NB_TEST +/* + * Perform a hardware reset test. The complete test loops until + * interrupted by ctrl-c or by pressed the RESET button. + */ +int do_hwreset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int gpio_cpu_value = 0; + + printf(" Press RESET button for testing or ctrl-c to abort\n"); + + while (gpio_cpu_value == 0) { + gpio_cpu_value = get_button_state() ? 1 : 0; + + printf("RESET_BTN = %d\n",gpio_cpu_value); + if (ctrlc()) { + putc ('\n'); + return 1; + } + udelay(20*1000); + } + + return 1; +} +#endif /* CONFIG_CMD_NB_TEST */ + + +#endif /* !defined(CONFIG_SPL_BUILD) */ + +int misc_init_r(void) +{ + struct serdes_map* sm; + u8 sm_count; + +#ifdef EARLY_CONSOLE_OUTPUT + init_console(); + console_init_f(); +#endif + + /* Disable watchdog */ + debug("Disable watchdog\n"); +// set_gpio(GPIO_WD_ENABLE, 0); + + /* Enable USB hub */ + debug("Enable USB Hub\n"); + set_gpio(GPIO_RST_USB_HUB, 0); + udelay(10000); + + /* Determine SERDES configuration */ + hws_board_topology_load(&sm, &sm_count); + + return 0; +} + +#if !defined(CONFIG_SPL_BUILD) + static void set_phy_page(const char *miidev, int phy_addr, int page) { miiphy_write(miidev, phy_addr, 22, page); @@ -246,20 +656,38 @@ static void set_phy_page(const char *miidev, int phy_addr, int page) static void set_phy_fast_blink_mode(int phy_addr) { const char *miidev = miiphy_get_current_dev(); + int numRegs = 0; + debug ("miidev: %s\n", miidev); - set_phy_page(miidev, phy_addr, 3); - miiphy_write(miidev, phy_addr, 16, 0x1032); - miiphy_write(miidev, phy_addr, 17, 0x4405); - miiphy_write(miidev, phy_addr, 18, 0x4A08); + while (sSelectedPhyRegs[numRegs].reserved != -1) { + set_phy_page(miidev, phy_addr, sSelectedPhyRegs[numRegs].page); + miiphy_write(miidev, phy_addr, sSelectedPhyRegs[numRegs].reg, sSelectedPhyRegs[numRegs].data); + numRegs++; + } set_phy_page(miidev, phy_addr, 0); } +static void set_devicetree_name(void) +{ + char devicetreename[64]; + + if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) { + printf("Devicetree name not found in BD\n"); + strncpy(devicetreename, "openwrt-nbhw17.dtb", sizeof(devicetreename)); + printf ("Selected default devicetree file\n"); + } + + env_set("fdt_image", devicetreename); +} + +#endif + int board_late_init(void) { - - gpio_request(21, "RST_ETH_PHY_N"); - gpio_direction_output(21, 0); +#if !defined(CONFIG_SPL_BUILD) + set_devicetree_name(); + set_gpio(GPIO_RST_ETH_PHY, 1); find_and_set_active_partition(); pass_hw_rev(); @@ -267,29 +695,86 @@ int board_late_init(void) /* Todo: It seems that something with the network is wrong */ run_command("run load_fpga", CMD_FLAG_ENV); +#ifndef EARLY_CONSOLE_OUTPUT + init_console(); + console_init_f(); +#endif + + check_reset_button(); + set_mac_addresses(2); +#endif /* Take phy out of reset after FPGA was loaded */ - gpio_set_value(21, 1); + set_gpio(GPIO_RST_ETH_PHY, 0); return 0; } +#if !defined(CONFIG_SPL_BUILD) int board_network_enable(struct mii_dev *bus) { + char prodName[20]; + + if (bd_get_prodname(prodName, sizeof(prodName)) != 0) { + prodName[0] = 0; + } + + if (strcmp(prodName, "2810") == 0) { + /* NB2810 */ + sSelectedPhyRegs = NB2810_ETH_PHY_REGS; + } else { + /* NB2800 or unknown */ + sSelectedPhyRegs = NB2800_ETH_PHY_REGS; + } + set_phy_fast_blink_mode(0); set_phy_fast_blink_mode(1); return 0; } +#endif int checkboard(void) { - puts("Board: NetModule NBHW17\n"); + debug("Board: NetModule NBHW17\n"); return 0; } +int board_fit_config_name_match(const char *name) +{ +#ifdef CONFIG_SPL_BUILD + /* SPL has enabled serial1 per default and will output everything + * independend of /boot/consoledev */ +#define DEFAULT_DTB_NAME "armada-385-nbhw17-v1-spl" +#else + /* U-Boot will read /boot/consoledev and based on that it + * enables its own serial console */ +#define DEFAULT_DTB_NAME "armada-385-nbhw17-v1" +#endif + + /* Check if name fits our dts */ + return strcmp(DEFAULT_DTB_NAME, name); +} + +#ifdef CONFIG_OF_BOARD_FIXUP + + +int fdt_enable_by_ofname(void *rw_fdt_blob, char *ofname) +{ + int offset = fdt_path_offset(rw_fdt_blob, ofname); + + return fdt_status_okay(rw_fdt_blob, offset); +} + +int board_fix_fdt(void *fdt_blob) +{ + return 0; +} + +#endif + int pcie_lane_by_slot(int slot) { int serdes; @@ -322,3 +807,91 @@ int pcie_lane_by_slot(int slot) return -1; } } + +/******************************************************************************* + Enable additional nodes in DTS depending on board descriptor +*******************************************************************************/ + +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_netbox_dio_ptt_4(void *blob) +{ + printf("FT: enable netbox_dio_ptt_4\n"); + + ft_enable_node(blob, "/netbox_dio_ptt_4"); + + // also reconfigure PCM lines in FPGA as GPIOs + FPGA_REG(PCIE_4_PCM_GPIO_EN) = 0x0001; /* Enable GPIO functionality for slot 4 */ + FPGA_REG(PCIE_4_PCM_GPIO_DIR) = 0x0004; /* Set GPIO directions */ + FPGA_REG(PCIE_4_PCM_GPIO_DAT) = 0; /* Set output to 0 */ +} + +void ft_set_eth_led_config(void *blob) +{ + int node_ofs; + int numRegs = 0; + int i; + int phy; + EthPhyRegs* pBigEndianPhyRegs = 0; + + if (!sSelectedPhyRegs) goto abort; + + while (sSelectedPhyRegs[numRegs].reserved != -1) numRegs++; + + /* DTS needs big endian so swap everything */ + + pBigEndianPhyRegs = malloc(numRegs * sizeof(NB2800_ETH_PHY_REGS)); + if (!pBigEndianPhyRegs) goto abort; + + memcpy(pBigEndianPhyRegs, sSelectedPhyRegs, numRegs * sizeof(EthPhyRegs)); + + for (i=0; i= 0) { + fdt_setprop(blob, node_ofs, "marvell,reg-init", + pBigEndianPhyRegs, numRegs * sizeof(EthPhyRegs)); + } + } + +abort: + if (pBigEndianPhyRegs) free(pBigEndianPhyRegs); + return; +} + +int ft_board_setup(void *blob, bd_t *bd) +{ + int module; + char* slotDescr = "slot=3"; + char pdValue[200]; + + for (module=0; module<4; module++) { + pdValue[0] = 0; /*init with an empty string*/ + if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) { + /* We have a PTT module with gpios in slot 4, so enable it */ + if ((strstr(pdValue, slotDescr)) && (strstr(pdValue, "dio-x1"))) + ft_netbox_dio_ptt_4(blob); + } + } + + ft_set_eth_led_config(blob); + + return 0; +} diff --git a/board/nm/nbhw17_v1/nbhw_fpga_config.c b/board/nm/nbhw17_v1/nbhw_fpga_config.c index 87fd52a667..041edbd52c 100644 --- a/board/nm/nbhw17_v1/nbhw_fpga_config.c +++ b/board/nm/nbhw17_v1/nbhw_fpga_config.c @@ -31,53 +31,53 @@ typedef enum { TYPE_PCIE, } slot_type_t; -static slot_type_t get_pcie_slot_type(const int slot) -{ - int module; - char pdValue[200]; - char slotDescr[20]; - - sprintf(slotDescr, "slot=%d", slot); - - for (module=0; module<4; module++) { - strcpy(pdValue, "" ); /*init with an empty string*/ - if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) { - - if ((strstr(pdValue, slotDescr)) && (strstr(pdValue, "wlan-"))) { - /* Wifi module needs PCIe */ - return TYPE_PCIE; - } - } - } - - return TYPE_USB; -} - -static int serdes_en_hack(struct gpio_desc *gpio) -{ - slot_type_t slot_type = get_pcie_slot_type(0); - - /* Lucky for us pcie slot1 has some muxes, to workaround buggy Sierra Wireless Modules */ - if (slot_type == TYPE_USB) { - /* Buggy Sierra Wireless Modules don't like to have USB3 enabled - * because the TX of the USB3 Lane is attached to it's system - * reset which is the default (see dts) */ - printf("Slot1: wwan\n"); - } - else if (slot_type == TYPE_PCIE) { - dm_gpio_set_value(gpio, 1); - printf("Slot1: wlan\n"); - } - else { - /* If once we would use other buggy Sierra Wireless modules, where they have - * decided to use USB3 too, then we have to enable the SERDES, the reset signal - * was moved away from this pins again (bravo!!!) */ - printf("Slot1: wwan (usb3)\n"); - } - - return 0; - -} +//static slot_type_t get_pcie_slot_type(const int slot) +//{ +// int module; +// char pdValue[200]; +// char slotDescr[20]; +// +// sprintf(slotDescr, "slot=%d", slot); +// +// for (module=0; module<4; module++) { +// strcpy(pdValue, "" ); /*init with an empty string*/ +// if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) { +// +// if ((strstr(pdValue, slotDescr)) && (strstr(pdValue, "wlan-"))) { +// /* Wifi module needs PCIe */ +// return TYPE_PCIE; +// } +// } +// } +// +// return TYPE_USB; +//} +// +//static int serdes_en_hack(struct gpio_desc *gpio) +//{ +// slot_type_t slot_type = get_pcie_slot_type(0); +// +// /* Lucky for us pcie slot1 has some muxes, to workaround buggy Sierra Wireless Modules */ +// if (slot_type == TYPE_USB) { +// /* Buggy Sierra Wireless Modules don't like to have USB3 enabled +// * because the TX of the USB3 Lane is attached to it's system +// * reset which is the default (see dts) */ +// printf("Slot1: wwan\n"); +// } +// else if (slot_type == TYPE_PCIE) { +// dm_gpio_set_value(gpio, 1); +// printf("Slot1: wlan\n"); +// } +// else { +// /* If once we would use other buggy Sierra Wireless modules, where they have +// * decided to use USB3 too, then we have to enable the SERDES, the reset signal +// * was moved away from this pins again (bravo!!!) */ +// printf("Slot1: wwan (usb3)\n"); +// } +// +// return 0; +// +//} struct pcie_slot_gpios { struct gpio_desc reset; @@ -102,7 +102,7 @@ static int request_and_set_gpio_by_name(ofnode fdt, if (gpio_request_by_name_nodev(fdt, name, 0, desc, GPIOD_IS_OUT)) { - printf("Could not request gpio %s\n", name); + debug("Could not request gpio %s\n", name); return -1; } @@ -122,17 +122,19 @@ static int request_and_set_gpio_by_name(ofnode fdt, static int add_pcie_slot(ofnode fdt) { debug("%s\n", __func__); - request_and_set_gpio_by_name(fdt, "reset", - &pcie_slots[pcie_slot_count].reset); request_and_set_gpio_by_name(fdt, "power", &pcie_slots[pcie_slot_count].power); + request_and_set_gpio_by_name(fdt, "reset", + &pcie_slots[pcie_slot_count].reset); + request_and_set_gpio_by_name(fdt, "wdis-out", &pcie_slots[pcie_slot_count].wdis_out); request_and_set_gpio_by_name(fdt, "wdis", &pcie_slots[pcie_slot_count].wdis); + pcie_slot_count++; return 0; } @@ -140,35 +142,36 @@ static int add_pcie_slot(ofnode fdt) static int configure_pcie_slots(void) { int i; + udelay(1200000); /* 1.2 s */ - for (i = 0; i < pcie_slot_count;i ++) { - dm_gpio_set_value(&pcie_slots[i].reset, 1); - } - - for (i = 0; i < pcie_slot_count;i ++) { - dm_gpio_set_value(&pcie_slots[i].wdis_out, 1); - dm_gpio_set_value(&pcie_slots[i].wdis, 0); - udelay(1000); /* 1 ms */ - } - /* Apply power to all PCIe slots */ - for (i = 0; i < pcie_slot_count;i ++) { + for (i = 0; i < pcie_slot_count; i++) { dm_gpio_set_value(&pcie_slots[i].power, 1); udelay(200000); /* 200 ms */ } - for (i = 0; i < pcie_slot_count;i ++) { + /* Assert reset after power is enabled */ + for (i = 0; i < pcie_slot_count; i++) { + dm_gpio_set_value(&pcie_slots[i].reset, 1); + } + + /* Deactivate WDIS */ + for (i = 0; i < pcie_slot_count; i++) { dm_gpio_set_value(&pcie_slots[i].wdis_out, 1); dm_gpio_set_value(&pcie_slots[i].wdis, 0); - udelay(1000); /* 1 ms */ + udelay(2000); /* 2 ms needed by Reyax module as regulator is enabled by WDIS~*/ } udelay(12000); /* 12 ms */ - for (i = 0; i < pcie_slot_count;i ++) { + + /* Deassert reset */ + for (i = 0; i < pcie_slot_count; i++) { dm_gpio_set_value(&pcie_slots[i].reset, 0); } + pci_init_board(); + return 0; } @@ -189,112 +192,38 @@ static int configure_leds(void) return 0; } - -struct hack_list_entry { - const char* name; - int (*fn)(struct gpio_desc *gpio); -}; - -struct hack_list_entry hack_list[] = { - {"serdes-en", serdes_en_hack} -}; - -static int exec_hack_list_fn(const char *name, struct gpio_desc *gpio) +// TODO: Check, if needed +//struct hack_list_entry { +// const char* name; +// int (*fn)(struct gpio_desc *gpio); +//}; +// +//struct hack_list_entry hack_list[] = { +// {"serdes-en", serdes_en_hack} +//}; +// +//static int exec_hack_list_fn(const char *name, struct gpio_desc *gpio) +//{ +// int i; +// for (i = 0; i < ARRAY_SIZE(hack_list); i++) { +// if (strcmp(hack_list[i]. name, name) == 0) { +// if (hack_list[i].fn(gpio)) { +// printf("Hack for %s failed\n", name); +// return -1; +// } +// return 0; +// } +// } +// +// /* Not part of hacklist */ +// return 0; +//} +// +void set_led(int index, int value) { - int i; - for (i = 0; i < ARRAY_SIZE(hack_list); i++) { - if (strcmp(hack_list[i]. name, name) == 0) { - if (hack_list[i].fn(gpio)) { - printf("Hack for %s failed\n", name); - return -1; - } - return 0; - } - } + if ((index<0) || (index>=priv.led_count)) return; - /* Not part of hacklist */ - return 0; -} - -static int request_and_set_gpios(ofnode fdt, - struct gpio_desc *gpios, u32 max_gpios) -{ - int i = 0; - int default_value = 0; - int offset = 0; - - - for (offset = fdt_first_property_offset(gd->fdt_blob, ofnode_to_offset(fdt)); - offset >= 0; - offset = fdt_next_property_offset(gd->fdt_blob, offset)) { - u32 gpio_array[4]; - const char *name; - const struct fdt_property *prop; - - - if (i >= max_gpios) { - printf("Too many gpio entries (max %d)\n", max_gpios); - break; - } - - prop = fdt_get_property_by_offset(gd->fdt_blob, offset, NULL); - - name = fdt_string(gd->fdt_blob, fdt32_to_cpu(prop->nameoff)); - debug("Name: %s\n", name); - if (name[0] == '#') { - continue; - } - - /* Request the gpio descriped by the property */ - if (gpio_request_by_name_nodev(fdt, name, 0, &gpios[i], - GPIOD_IS_OUT)) - { - printf("Could not request gpio %s\n", name); - return -1; - } - - /* Get the gpio array, to find out its default value (4 index) */ - if (ofnode_read_u32_array(fdt, name, - gpio_array, 4)) { - printf("Could not request gpio array %s\n", name); - return -1; - - } - default_value = gpio_array[3]; - debug("Set GPIO %s to %d\n", name, default_value); - dm_gpio_set_value(&gpios[i], default_value); - - if (exec_hack_list_fn(name, &gpios[i])) { - printf("Execution of hack for %s failed\n", name); - continue; - } - - i++; - } - - debug("leave %s with %d gpios\n", __func__, i); - return i; -} - - -static int configure_misc(ofnode fdt) -{ - struct gpio_desc misc_gpios[16]; - int gpio_count; - debug("%s\n", __func__); - - gpio_count = request_and_set_gpios(fdt, - misc_gpios, ARRAY_SIZE(misc_gpios)); - if (gpio_count < 1) { - return -1; - } - - debug("Free gpios\n"); - /* Free gpios so that we could use them via gpio subsystem */ - gpio_free_list_nodev(misc_gpios, gpio_count); - debug("return %s\n", __func__); - - return 0; + dm_gpio_set_value(&leds[index], value); } int nbhw_fpga_configure(void) @@ -309,14 +238,10 @@ int nbhw_fpga_configure(void) name = ofnode_get_name(subnode); debug("Try to configure %s\n", name); - if (!strncmp("misc", name, 4)) { - configure_misc(subnode); - } if (!strncmp("pcieslot", name, 4)) { add_pcie_slot(subnode); } - } if (configure_leds()) diff --git a/board/nm/nbhw17_v1/nbhw_fpga_prog.c b/board/nm/nbhw17_v1/nbhw_fpga_prog.c deleted file mode 100644 index 112b727796..0000000000 --- a/board/nm/nbhw17_v1/nbhw_fpga_prog.c +++ /dev/null @@ -1,144 +0,0 @@ -/* #define DEBUG */ -#include - -#include "board/mv_ebu/common/common/mvCommon.h" -#include "board/mv_ebu/common/mv_hal/gpp/mvGpp.h" -#include "board/mv_ebu/common/uboot_oss/mvOs.h" -#include "../armada_38x_family/ctrlEnv/mvCtrlEnvLib.h" -#include "fs.h" -#include "../nbhw_fpga_prog.h" -#include "nbhw18_gpio.h" - -#define SS_MPP BIT5 -#define SDO_MPP BIT6 /* SDO means slave data out */ -#define SCK_MPP BIT7 -#define SDI_MPP BIT8 /* SDI means slave data in */ -#define FPGA_RESET BIT19 - -#define FPGA_RESET_GROUP 0 -#define SPI_GROUP 1 - -#define MPP_MASK_4 0xFFF00000 -#define MPP_MASK_5 0x0000000F - -extern int fpga_program(fpga_prog_operation *operation); - -static MV_U32 mpp_group_4_init_value; -static MV_U32 mpp_group_5_init_value; - -static void set_cs(int active) -{ - if (active) { - mvGppValueSet(SPI_GROUP, SS_MPP, SS_MPP); - } - else { - mvGppValueSet(SPI_GROUP, SS_MPP, 0); - } -} - -static void write_spi_data(MV_U8 data) -{ - int i; - MV_U32 data_write = 0; - - for (i=0; i<8; i++) - { - data_write = (data & 0x80) ? SDI_MPP : 0; - /* Clear clk bit and put data on the line */ - mvGppValueSet(SPI_GROUP, SDI_MPP | SCK_MPP, data_write); - /* Read data on rising edge */ - mvGppValueSet(SPI_GROUP, SCK_MPP, SCK_MPP); - data = data << 1; - } -} - -static void put_in_prog_mode(void) -{ - /* Set CS firt to 1 */ - mvGppValueSet(SPI_GROUP, SS_MPP , SS_MPP); - udelay(10); - - /* Set SS to 0 and SCK to 1 */ - mvGppValueSet(SPI_GROUP, SS_MPP | SCK_MPP, SCK_MPP); - /* Put FPGA in reset */ - mvGppValueSet(FPGA_RESET_GROUP, FPGA_RESET, 1); - - /* Sleep at least 200ns according to lattice manual */ - udelay(1); - - /* Take FPGA out of reset */ - mvGppValueSet(FPGA_RESET_GROUP, FPGA_RESET, 0); - /* Wait for at least 800 us according to lattice manual */ - udelay(800); -} - -static void pre_programming(void) -{ - debug("NBHW18 pre programming\n"); - MV_U32 reg_data; - mpp_group_4_init_value = readl(mvCtrlMppRegGet(4)); - mpp_group_5_init_value = readl(mvCtrlMppRegGet(5)); - - /* Set MPP37, 38 and 39 to GPIO */ - reg_data = (mpp_group_4_init_value & ~(MPP_MASK_4)); - writel(reg_data, mvCtrlMppRegGet(4)); - - /* Set MPP40 to GPIO */ - reg_data = (mpp_group_5_init_value & ~(MPP_MASK_5)); - writel(reg_data, mvCtrlMppRegGet(5)); - - /* Configure outputs (default input) 0=> output */ - mvGppTypeSet(SPI_GROUP, (SS_MPP | SCK_MPP | SDI_MPP), 0); - - debug("NBHW18 put in progmode\n"); - put_in_prog_mode(); -} - -static void post_programming(void) -{ - int i; - - if (in_fpga_cdone()) { - printf("Error: Fpga does not signalize done\n"); - } - - debug ("NBHW18 post programming\n"); - /* At least 49 SPI_SCK Cycles rising edge to rising edge */ - for (i = 0; i < 100; i++) { - write_spi_data(0); - } - - set_cs(1); - - /* Set MPP37, 38, 39 and 40 to inital value again */ - writel(mpp_group_4_init_value, mvCtrlMppRegGet(4)); - writel(mpp_group_5_init_value, mvCtrlMppRegGet(5)); - - /* Do a logic reset */ - out_fpga_logic_reset(0); - udelay(100); - out_fpga_logic_reset(1); - udelay(100); - -} - -static int check_bitstream_compatibility(fpga_type type, u32 id) -{ - if (type != FPGA_TYPE_LATTICE) { - return -1; - } - - return 0; -} - -static fpga_prog_operation operation = { - pre_programming, - post_programming, - write_spi_data, - check_bitstream_compatibility, -}; - -int nbhw_fpga_program(void) -{ - return fpga_program(&operation); -} diff --git a/board/nm/nbhw17_v1/nbhw_fpga_regs.h b/board/nm/nbhw17_v1/nbhw_fpga_regs.h deleted file mode 100644 index dc5f64f8e6..0000000000 --- a/board/nm/nbhw17_v1/nbhw_fpga_regs.h +++ /dev/null @@ -1,773 +0,0 @@ -/******************************************************************************* - * - * Register Description - * - * Automatically generated, do not edit manually - * Source: ./dd_fw_NBHW_18_Mainboard_FPGA.docx - * Date: 2017-03-22 13:44:10.255175 - * - ******************************************************************************/ - -#ifndef NBHW18_FPGA_REGS_H -#define NBHW18_FPGA_REGS_H - -/*** Identification for NBHW18 ***/ -#define IDENTIFICATION_REGISTER (0x0000) -/* Identification register */ -#define IDENTIFICATION_REGISTER_SIGNATURE_SHIFT (0UL) -#define IDENTIFICATION_REGISTER_SIGNATURE_MASK (0xffffUL) -#define IDENTIFICATION_REGISTER_SIGNATURE_ACCESS (READ_ONLY) - - -/*** FPGA firmware version register ***/ -#define VERSION (0x0002) -/* Minor firmware version */ -#define VERSION_MINOR_VERSION_SHIFT (0UL) -#define VERSION_MINOR_VERSION_MASK (0xffUL) -#define VERSION_MINOR_VERSION_ACCESS (READ_ONLY) -/* Major firmware version */ -#define VERSION_MAJOR_VERSION_SHIFT (8UL) -#define VERSION_MAJOR_VERSION_MASK (0xff00UL) -#define VERSION_MAJOR_VERSION_ACCESS (READ_ONLY) - - -/*** User scratch register ***/ -#define SCRATCH (0x0004) -/* Scratch register */ -#define SCRATCH_SCRATCH_SHIFT (0UL) -#define SCRATCH_SCRATCH_MASK (0xffffUL) -#define SCRATCH_SCRATCH_ACCESS (READ_WRITE) - - -/*** Main Board Inputs ***/ -#define STATUS1 (0x0006) -/* 0: No SIM Card inserted in Slot 1 -1: SIM Card inserted in Slot 1 */ -#define STATUS1_SIM_CD1_SHIFT (10UL) -#define STATUS1_SIM_CD1_MASK (0x400UL) -#define STATUS1_SIM_CD1_ACCESS (READ_ONLY) -/* 0: No SIM Card inserted in Slot 2 -1: SIM Card inserted in Slot 2 */ -#define STATUS1_SIM_CD2_SHIFT (11UL) -#define STATUS1_SIM_CD2_MASK (0x800UL) -#define STATUS1_SIM_CD2_ACCESS (READ_ONLY) -/* RTC Interrupt */ -#define STATUS1_RTC_N_SHIFT (12UL) -#define STATUS1_RTC_N_MASK (0x1000UL) -#define STATUS1_RTC_N_ACCESS (READ_ONLY) -/* LM75 interrupt */ -#define STATUS1_LM75_N_SHIFT (13UL) -#define STATUS1_LM75_N_MASK (0x2000UL) -#define STATUS1_LM75_N_ACCESS (READ_ONLY) -/* Ethernet PHY 1 Interrupt */ -#define STATUS1_IRQ_PHY1_N_SHIFT (14UL) -#define STATUS1_IRQ_PHY1_N_MASK (0x4000UL) -#define STATUS1_IRQ_PHY1_N_ACCESS (READ_ONLY) -/* Ethernet PHY 2 Interrupt */ -#define STATUS1_IRQ_PHY2_N_SHIFT (15UL) -#define STATUS1_IRQ_PHY2_N_MASK (0x8000UL) -#define STATUS1_IRQ_PHY2_N_ACCESS (READ_ONLY) - - -/*** Main Board Inputs ***/ -#define OUTPUT1 (0x0008) -/* Active I2C ext -0: disabled -1: enabled */ -#define OUTPUT1_EN_I2C_EXT_N_SHIFT (0UL) -#define OUTPUT1_EN_I2C_EXT_N_MASK (0x1UL) -#define OUTPUT1_EN_I2C_EXT_N_ACCESS (READ_WRITE) -/* Active GPS Antenna Supply -0: disabled -1: enabled */ -#define OUTPUT1_EN_GPS_ANT_SHIFT (1UL) -#define OUTPUT1_EN_GPS_ANT_MASK (0x2UL) -#define OUTPUT1_EN_GPS_ANT_ACCESS (READ_WRITE) -/* Reset WLAN mod -0: active -1: not active */ -#define OUTPUT1_RST_WLAN_MOD_N_SHIFT (2UL) -#define OUTPUT1_RST_WLAN_MOD_N_MASK (0x4UL) -#define OUTPUT1_RST_WLAN_MOD_N_ACCESS (READ_WRITE) -/* Active 5V ext -0: disabled -1: enabled */ -#define OUTPUT1_EN_5V0_EXT_SHIFT (3UL) -#define OUTPUT1_EN_5V0_EXT_MASK (0x8UL) -#define OUTPUT1_EN_5V0_EXT_ACCESS (READ_WRITE) -/* Active 1V5 ext -0: disabled -1: enabled */ -#define OUTPUT1_EN_1V5_SHIFT (4UL) -#define OUTPUT1_EN_1V5_MASK (0x10UL) -#define OUTPUT1_EN_1V5_ACCESS (READ_WRITE) - - -/*** Interrupt Mask Register 1 ***/ -#define INTMASK1 (0x0010) -/* PCM RX irq of PCM controller 1 */ -#define INTMASK1_PCM1_RX_SHIFT (0UL) -#define INTMASK1_PCM1_RX_MASK (0x1UL) -#define INTMASK1_PCM1_RX_ACCESS (READ_WRITE) -/* PCM TX irq of PCM controller 1 */ -#define INTMASK1_PCM1_TX_SHIFT (1UL) -#define INTMASK1_PCM1_TX_MASK (0x2UL) -#define INTMASK1_PCM1_TX_ACCESS (READ_WRITE) -/* PCM RX irq of PCM controller 2 */ -#define INTMASK1_PCM2_RX_SHIFT (2UL) -#define INTMASK1_PCM2_RX_MASK (0x4UL) -#define INTMASK1_PCM2_RX_ACCESS (READ_ONLY) -/* PCM TX irq of PCM controller 2 */ -#define INTMASK1_PCM2_TX_SHIFT (3UL) -#define INTMASK1_PCM2_TX_MASK (0x8UL) -#define INTMASK1_PCM2_TX_ACCESS (READ_WRITE) -/* RTC Interrupt */ -#define INTMASK1_RTC_N_SHIFT (8UL) -#define INTMASK1_RTC_N_MASK (0x100UL) -#define INTMASK1_RTC_N_ACCESS (READ_WRITE) -/* LM75 interrupt */ -#define INTMASK1_LM75_N_SHIFT (9UL) -#define INTMASK1_LM75_N_MASK (0x200UL) -#define INTMASK1_LM75_N_ACCESS (READ_WRITE) -/* SIM Card 1 Detect signal change interrupt */ -#define INTMASK1_SIMCARD1_SHIFT (12UL) -#define INTMASK1_SIMCARD1_MASK (0x1000UL) -#define INTMASK1_SIMCARD1_ACCESS (READ_WRITE) -/* SIM Card 2 Detect signal change interrupt */ -#define INTMASK1_SIMCARD2_SHIFT (13UL) -#define INTMASK1_SIMCARD2_MASK (0x2000UL) -#define INTMASK1_SIMCARD2_ACCESS (READ_WRITE) -/* Ethernet PHY 1 Interrupt */ -#define INTMASK1_PHY1_N_SHIFT (14UL) -#define INTMASK1_PHY1_N_MASK (0x4000UL) -#define INTMASK1_PHY1_N_ACCESS (READ_WRITE) -/* Ethernet PHY 2 Interrupt */ -#define INTMASK1_PHY2_N_SHIFT (15UL) -#define INTMASK1_PHY2_N_MASK (0x8000UL) -#define INTMASK1_PHY2_N_ACCESS (READ_WRITE) - - -/*** Interrupt Mask Register 2 ***/ -#define INTMASK2 (0x0012) - - -/*** Interrupt Pending Register 1 ***/ -#define INTPENDING1 (0x0014) -/* PCM RX irq of PCM controller 1 -0: no interrupt -1: interrupt flag set */ -#define INTPENDING1_PCM1_RX_SHIFT (0UL) -#define INTPENDING1_PCM1_RX_MASK (0x1UL) -#define INTPENDING1_PCM1_RX_ACCESS (READ_ONLY) -/* PCM TX irq of PCM controller 1 */ -#define INTPENDING1_PCM1_TX_SHIFT (1UL) -#define INTPENDING1_PCM1_TX_MASK (0x2UL) -#define INTPENDING1_PCM1_TX_ACCESS (READ_WRITE) -/* PCM RX irq of PCM controller 2 */ -#define INTPENDING1_PCM2_RX_SHIFT (2UL) -#define INTPENDING1_PCM2_RX_MASK (0x4UL) -#define INTPENDING1_PCM2_RX_ACCESS (READ_ONLY) -/* PCM TX irq of PCM controller 2 */ -#define INTPENDING1_PCM2_TX_SHIFT (3UL) -#define INTPENDING1_PCM2_TX_MASK (0x8UL) -#define INTPENDING1_PCM2_TX_ACCESS (READ_WRITE) -/* RTC Interrupt */ -#define INTPENDING1_RTC_N_SHIFT (8UL) -#define INTPENDING1_RTC_N_MASK (0x100UL) -#define INTPENDING1_RTC_N_ACCESS (READ_WRITE) -/* LM75 interrupt */ -#define INTPENDING1_LM75_N_SHIFT (9UL) -#define INTPENDING1_LM75_N_MASK (0x200UL) -#define INTPENDING1_LM75_N_ACCESS (READ_WRITE) -/* SIM Card 1 Detect signal change interrupt */ -#define INTPENDING1_SIMCARD1_SHIFT (12UL) -#define INTPENDING1_SIMCARD1_MASK (0x1000UL) -#define INTPENDING1_SIMCARD1_ACCESS (READ_WRITE) -/* SIM Card 2 Detect signal change interrupt */ -#define INTPENDING1_SIMCARD2_SHIFT (13UL) -#define INTPENDING1_SIMCARD2_MASK (0x2000UL) -#define INTPENDING1_SIMCARD2_ACCESS (READ_WRITE) -/* Ethernet PHY 1 Interrupt */ -#define INTPENDING1_PHY1_N_SHIFT (14UL) -#define INTPENDING1_PHY1_N_MASK (0x4000UL) -#define INTPENDING1_PHY1_N_ACCESS (READ_WRITE) -/* Ethernet PHY 2 Interrupt */ -#define INTPENDING1_PHY2_N_SHIFT (15UL) -#define INTPENDING1_PHY2_N_MASK (0x8000UL) -#define INTPENDING1_PHY2_N_ACCESS (READ_WRITE) - - -/*** Interrupt Pending Register 2 ***/ -#define INTPENDING2 (0x0016) - - -/*** Interrupt Status Register 1 ***/ -#define INTSTATUS1 (0x0018) -/* PCM RX irq of PCM controller 1 -0: no interrupt -1: interrupt flag set */ -#define INTSTATUS1_PCM1_RX_SHIFT (0UL) -#define INTSTATUS1_PCM1_RX_MASK (0x1UL) -#define INTSTATUS1_PCM1_RX_ACCESS (READ_ONLY) -/* PCM TX irq of PCM controller 1 */ -#define INTSTATUS1_PCM1_TX_SHIFT (1UL) -#define INTSTATUS1_PCM1_TX_MASK (0x2UL) -#define INTSTATUS1_PCM1_TX_ACCESS (READ_WRITE) -/* PCM RX irq of PCM controller 2 */ -#define INTSTATUS1_PCM2_RX_SHIFT (2UL) -#define INTSTATUS1_PCM2_RX_MASK (0x4UL) -#define INTSTATUS1_PCM2_RX_ACCESS (READ_ONLY) -/* PCM TX irq of PCM controller 2 */ -#define INTSTATUS1_PCM2_TX_SHIFT (3UL) -#define INTSTATUS1_PCM2_TX_MASK (0x8UL) -#define INTSTATUS1_PCM2_TX_ACCESS (READ_WRITE) -/* RTC Interrupt */ -#define INTSTATUS1_RTC_N_SHIFT (8UL) -#define INTSTATUS1_RTC_N_MASK (0x100UL) -#define INTSTATUS1_RTC_N_ACCESS (READ_WRITE) -/* LM75 interrupt */ -#define INTSTATUS1_LM75_N_SHIFT (9UL) -#define INTSTATUS1_LM75_N_MASK (0x200UL) -#define INTSTATUS1_LM75_N_ACCESS (READ_WRITE) -/* SIM Card 1 Detect signal change interrupt */ -#define INTSTATUS1_SIMCARD1_SHIFT (12UL) -#define INTSTATUS1_SIMCARD1_MASK (0x1000UL) -#define INTSTATUS1_SIMCARD1_ACCESS (READ_WRITE) -/* SIM Card 2 Detect signal change interrupt */ -#define INTSTATUS1_SIMCARD2_SHIFT (13UL) -#define INTSTATUS1_SIMCARD2_MASK (0x2000UL) -#define INTSTATUS1_SIMCARD2_ACCESS (READ_WRITE) -/* Ethernet PHY 1 Interrupt */ -#define INTSTATUS1_PHY1_N_SHIFT (14UL) -#define INTSTATUS1_PHY1_N_MASK (0x4000UL) -#define INTSTATUS1_PHY1_N_ACCESS (READ_WRITE) -/* Ethernet PHY 2 Interrupt */ -#define INTSTATUS1_PHY2_N_SHIFT (15UL) -#define INTSTATUS1_PHY2_N_MASK (0x8000UL) -#define INTSTATUS1_PHY2_N_ACCESS (READ_WRITE) - - -/*** Interrupt Status Register 2 ***/ -#define INTSTATUS2 (0x001A) - - -/*** Interrupt Acknowledge Register 1 ***/ -#define INTACK1 (0x0018) -/* PCM RX irq of PCM controller 1 -0: no interrupt -1: interrupt flag set */ -#define INTACK1_PCM1_RX_SHIFT (0UL) -#define INTACK1_PCM1_RX_MASK (0x1UL) -#define INTACK1_PCM1_RX_ACCESS (READ_ONLY) -/* PCM TX irq of PCM controller 1 */ -#define INTACK1_PCM1_TX_SHIFT (1UL) -#define INTACK1_PCM1_TX_MASK (0x2UL) -#define INTACK1_PCM1_TX_ACCESS (READ_WRITE) -/* PCM RX irq of PCM controller 2 */ -#define INTACK1_PCM2_RX_SHIFT (2UL) -#define INTACK1_PCM2_RX_MASK (0x4UL) -#define INTACK1_PCM2_RX_ACCESS (READ_ONLY) -/* PCM TX irq of PCM controller 2 */ -#define INTACK1_PCM2_TX_SHIFT (3UL) -#define INTACK1_PCM2_TX_MASK (0x8UL) -#define INTACK1_PCM2_TX_ACCESS (READ_WRITE) -/* RTC Interrupt */ -#define INTACK1_RTC_N_SHIFT (8UL) -#define INTACK1_RTC_N_MASK (0x100UL) -#define INTACK1_RTC_N_ACCESS (READ_WRITE) -/* LM75 interrupt */ -#define INTACK1_LM75_N_SHIFT (9UL) -#define INTACK1_LM75_N_MASK (0x200UL) -#define INTACK1_LM75_N_ACCESS (READ_WRITE) -/* SIM Card 1 Detect signal change interrupt */ -#define INTACK1_SIMCARD1_SHIFT (12UL) -#define INTACK1_SIMCARD1_MASK (0x1000UL) -#define INTACK1_SIMCARD1_ACCESS (READ_WRITE) -/* SIM Card 2 Detect signal change interrupt */ -#define INTACK1_SIMCARD2_SHIFT (13UL) -#define INTACK1_SIMCARD2_MASK (0x2000UL) -#define INTACK1_SIMCARD2_ACCESS (READ_WRITE) -/* Ethernet PHY 1 Interrupt */ -#define INTACK1_PHY1_N_SHIFT (14UL) -#define INTACK1_PHY1_N_MASK (0x4000UL) -#define INTACK1_PHY1_N_ACCESS (READ_WRITE) -/* Ethernet PHY 2 Interrupt */ -#define INTACK1_PHY2_N_SHIFT (15UL) -#define INTACK1_PHY2_N_MASK (0x8000UL) -#define INTACK1_PHY2_N_ACCESS (READ_WRITE) - - -/*** Interrupt Acknowledge Register 2 ***/ -#define INTACK2 (0x001A) - - -/*** LED Control Register ***/ -#define LED (0x0020) -/* Enable LED 0 (green) */ -#define LED_LED0_GREEN_SHIFT (0UL) -#define LED_LED0_GREEN_MASK (0x1UL) -#define LED_LED0_GREEN_ACCESS (READ_WRITE) -/* Enable LED 0 (red) */ -#define LED_LED0_RED_SHIFT (1UL) -#define LED_LED0_RED_MASK (0x2UL) -#define LED_LED0_RED_ACCESS (READ_WRITE) -/* Enable LED 1 (green) */ -#define LED_LED1_GREEN_SHIFT (2UL) -#define LED_LED1_GREEN_MASK (0x4UL) -#define LED_LED1_GREEN_ACCESS (READ_WRITE) -/* Enable LED 1 (red) */ -#define LED_LED1_RED_SHIFT (3UL) -#define LED_LED1_RED_MASK (0x8UL) -#define LED_LED1_RED_ACCESS (READ_WRITE) -/* Enable LED 2 (green) */ -#define LED_LED2_GREEN_SHIFT (4UL) -#define LED_LED2_GREEN_MASK (0x10UL) -#define LED_LED2_GREEN_ACCESS (READ_WRITE) -/* Enable LED 2 (red) */ -#define LED_LED2_RED_SHIFT (5UL) -#define LED_LED2_RED_MASK (0x20UL) -#define LED_LED2_RED_ACCESS (READ_WRITE) -/* Enable LED 3 (green) */ -#define LED_LED3_GREEN_SHIFT (6UL) -#define LED_LED3_GREEN_MASK (0x40UL) -#define LED_LED3_GREEN_ACCESS (READ_WRITE) -/* Enable LED 3 (red) */ -#define LED_LED3_RED_SHIFT (7UL) -#define LED_LED3_RED_MASK (0x80UL) -#define LED_LED3_RED_ACCESS (READ_WRITE) -/* Enable LED 4 (green) */ -#define LED_LED4_GREEN_SHIFT (8UL) -#define LED_LED4_GREEN_MASK (0x100UL) -#define LED_LED4_GREEN_ACCESS (READ_WRITE) -/* Enable LED 4 (red) */ -#define LED_LED4_RED_SHIFT (9UL) -#define LED_LED4_RED_MASK (0x200UL) -#define LED_LED4_RED_ACCESS (READ_WRITE) -/* Enable LED 5 (green) */ -#define LED_LED5_GREEN_SHIFT (10UL) -#define LED_LED5_GREEN_MASK (0x400UL) -#define LED_LED5_GREEN_ACCESS (READ_WRITE) -/* Enable LED 5 (red) */ -#define LED_LED5_RED_SHIFT (11UL) -#define LED_LED5_RED_MASK (0x800UL) -#define LED_LED5_RED_ACCESS (READ_WRITE) - - -/*** SIM Slot Control Register ***/ -#define SIM_CTRL (0x0040) -/* 000: disconnect analog switch 1 -001: Connect PCie Slot 1 to SIM Chip 1 -010: Connect PCie Slot 1 to SIM Chip 2 -Note: If no SIM Card is inserted, the power is disable of the corresponding slot. */ -#define SIM_CTRL_PCIE1_SIM_SEL_SHIFT (0UL) -#define SIM_CTRL_PCIE1_SIM_SEL_MASK (0x7UL) -#define SIM_CTRL_PCIE1_SIM_SEL_ACCESS (READ_WRITE) -/* 000: disconnect analog switch 1 -001: Connect PCie Slot 2 to SIM Chip 1 -010: Connect PCie Slot 2 to SIM Chip 2 -Note: If no SIM Card is inserted, the power is disable of the corresponding slot. */ -#define SIM_CTRL_PCIE3_SIM_SEL_SHIFT (4UL) -#define SIM_CTRL_PCIE3_SIM_SEL_MASK (0x70UL) -#define SIM_CTRL_PCIE3_SIM_SEL_ACCESS (READ_WRITE) - -/*** PCIe Slot Reset ***/ -#define PCIE_RESET (0x0030) -/* PCIe Slot 1 Reset -0: reset asserted */ -#define PCIE_RESET_PCIE1_RST_N_SHIFT (0UL) -#define PCIE_RESET_PCIE1_RST_N_MASK (0x1UL) -#define PCIE_RESET_PCIE1_RST_N_ACCESS (READ_WRITE) -/* PCIe Slot 2 Reset -0: reset asserted */ -#define PCIE_RESET_PCIE2_RST_N_SHIFT (1UL) -#define PCIE_RESET_PCIE2_RST_N_MASK (0x2UL) -#define PCIE_RESET_PCIE2_RST_N_ACCESS (READ_WRITE) -/* PCIe Slot 3 Reset -0: reset asserted */ -#define PCIE_RESET_PCIE3_RST_N_SHIFT (2UL) -#define PCIE_RESET_PCIE3_RST_N_MASK (0x4UL) -#define PCIE_RESET_PCIE3_RST_N_ACCESS (READ_WRITE) - - -/*** PCIe Slot Power Control ***/ -#define PCIE_POWER (0x0032) -/* PCIe Slot 1 Power -0: disabled */ -#define PCIE_POWER_PCIE1_PWR_SHIFT (0UL) -#define PCIE_POWER_PCIE1_PWR_MASK (0x1UL) -#define PCIE_POWER_PCIE1_PWR_ACCESS (READ_WRITE) -/* PCIe Slot 2 Power -0: disabled */ -#define PCIE_POWER_PCIE2_PWR_SHIFT (1UL) -#define PCIE_POWER_PCIE2_PWR_MASK (0x2UL) -#define PCIE_POWER_PCIE2_PWR_ACCESS (READ_WRITE) -/* PCIe Slot 3 Power -0: disabled */ -#define PCIE_POWER_PCIE3_PWR_SHIFT (2UL) -#define PCIE_POWER_PCIE3_PWR_MASK (0x4UL) -#define PCIE_POWER_PCIE3_PWR_ACCESS (READ_WRITE) - - -/*** PCIe Slot SIM Clk Redriver Control ***/ -#define PCIE_SIM_CLOCK (0x0034) -/* 0: Enable SIM Clock Driver of PCIe Slot 1 */ -#define PCIE_SIM_CLOCK_SIM_CLK_EN1_N_SHIFT (0UL) -#define PCIE_SIM_CLOCK_SIM_CLK_EN1_N_MASK (0x1UL) -#define PCIE_SIM_CLOCK_SIM_CLK_EN1_N_ACCESS (READ_WRITE) -/* 0: Enable SIM Clock Driver of PCIe Slot 2 */ -#define PCIE_SIM_CLOCK_SIM_CLK_EN2_N_SHIFT (1UL) -#define PCIE_SIM_CLOCK_SIM_CLK_EN2_N_MASK (0x2UL) -#define PCIE_SIM_CLOCK_SIM_CLK_EN2_N_ACCESS (READ_WRITE) -/* 0: Enable SIM Clock Driver of PCIe Slot 3 */ -#define PCIE_SIM_CLOCK_SIM_CLK_EN3_N_SHIFT (2UL) -#define PCIE_SIM_CLOCK_SIM_CLK_EN3_N_MASK (0x4UL) -#define PCIE_SIM_CLOCK_SIM_CLK_EN3_N_ACCESS (READ_WRITE) - - -/*** I/O read/write ***/ -#define GPIO_REGISTER (0x0070) -/* */ -#define GPIO_REGISTER_IO_OUT1_SHIFT (0UL) -#define GPIO_REGISTER_IO_OUT1_MASK (0x1UL) -#define GPIO_REGISTER_IO_OUT1_ACCESS (READ_ONLY) -/* */ -#define GPIO_REGISTER_IO_OUT2_SHIFT (1UL) -#define GPIO_REGISTER_IO_OUT2_MASK (0x2UL) -#define GPIO_REGISTER_IO_OUT2_ACCESS (READ_ONLY) -/* */ -#define GPIO_REGISTER_IO_IN1_SHIFT (5UL) -#define GPIO_REGISTER_IO_IN1_MASK (0x20UL) -#define GPIO_REGISTER_IO_IN1_ACCESS () -/* */ -#define GPIO_REGISTER_IO_IN2_SHIFT (6UL) -#define GPIO_REGISTER_IO_IN2_MASK (0x40UL) -#define GPIO_REGISTER_IO_IN2_ACCESS () - - -/*** SFP Control ***/ -#define SFP_CONTROL (0x0072) -/* */ -#define SFP_CONTROL_SFP_IO_TX_DIS_SHIFT (0UL) -#define SFP_CONTROL_SFP_IO_TX_DIS_MASK (0x1UL) -#define SFP_CONTROL_SFP_IO_TX_DIS_ACCESS (READ_WRITE) - - -/*** SFP Monitor ***/ -#define SFP_MONITOR (0x0074) -/* */ -#define SFP_MONITOR_SFP_IO_LOS_SHIFT (0UL) -#define SFP_MONITOR_SFP_IO_LOS_MASK (0x1UL) -#define SFP_MONITOR_SFP_IO_LOS_ACCESS (READ_ONLY) -/* */ -#define SFP_MONITOR_SFP_IO_PRSNT_SHIFT (1UL) -#define SFP_MONITOR_SFP_IO_PRSNT_MASK (0x2UL) -#define SFP_MONITOR_SFP_IO_PRSNT_ACCESS (READ_ONLY) -/* */ -#define SFP_MONITOR_SFP_IO_TX_FAULT_SHIFT (2UL) -#define SFP_MONITOR_SFP_IO_TX_FAULT_MASK (0x4UL) -#define SFP_MONITOR_SFP_IO_TX_FAULT_ACCESS () - - -/*** I/O direction register 1 ***/ -#define PCIE_1_SLOT_DIR1 (0x0100) -/* Direction of I/O Signal (FPGA Pin) -0: Input (default) */ -#define PCIE_1_SLOT_DIR1_COEX1_DIR_SHIFT (0UL) -#define PCIE_1_SLOT_DIR1_COEX1_DIR_MASK (0x1UL) -#define PCIE_1_SLOT_DIR1_COEX1_DIR_ACCESS (READ_WRITE) -/* Direction of I/O Signal (FPGA Pin) -0: Input (default) */ -#define PCIE_1_SLOT_DIR1_COEX2_DIR_SHIFT (1UL) -#define PCIE_1_SLOT_DIR1_COEX2_DIR_MASK (0x2UL) -#define PCIE_1_SLOT_DIR1_COEX2_DIR_ACCESS (READ_WRITE) -/* Direction of I/O Signal (FPGA Pin) -0: Input (default) */ -#define PCIE_1_SLOT_DIR1_LED_WLAN_DIR_SHIFT (2UL) -#define PCIE_1_SLOT_DIR1_LED_WLAN_DIR_MASK (0x4UL) -#define PCIE_1_SLOT_DIR1_LED_WLAN_DIR_ACCESS (READ_WRITE) -/* Direction of I/O Signal (FPGA Pin) -0: Input (default) */ -#define PCIE_1_SLOT_DIR1_LED_WWAN_DIR_SHIFT (3UL) -#define PCIE_1_SLOT_DIR1_LED_WWAN_DIR_MASK (0x8UL) -#define PCIE_1_SLOT_DIR1_LED_WWAN_DIR_ACCESS (READ_WRITE) -/* Direction of I/O Signal (FPGA Pin) -0: Input (default) */ -#define PCIE_1_SLOT_DIR1_WAKE_N_DIR_SHIFT (4UL) -#define PCIE_1_SLOT_DIR1_WAKE_N_DIR_MASK (0x10UL) -#define PCIE_1_SLOT_DIR1_WAKE_N_DIR_ACCESS (READ_WRITE) -/* Direction of I/O Signal (FPGA Pin) -0: Input (default) */ -#define PCIE_1_SLOT_DIR1_WDISABLE_N_DIR_SHIFT (5UL) -#define PCIE_1_SLOT_DIR1_WDISABLE_N_DIR_MASK (0x20UL) -#define PCIE_1_SLOT_DIR1_WDISABLE_N_DIR_ACCESS (READ_WRITE) - - -/*** I/O direction register 1 with all signals on FPGA I/O ***/ -#define PCIE_2_SLOT_DIR1 (0x0200) - - -/*** I/O direction register 1 with all signals on FPGA I/O ***/ -#define PCIE_3_SLOT_DIR1 (0x0300) - - -/*** I/O control register 1 ***/ -#define PCIE_1_SLOT_CTRL1 (0x0102) -/* When X DIR = 0 (Input): Value of input pin -0: Low -1: High -When X DIR = 1 (Output): Value written to output */ -#define PCIE_1_SLOT_CTRL1_COEX1_SHIFT (0UL) -#define PCIE_1_SLOT_CTRL1_COEX1_MASK (0x1UL) -#define PCIE_1_SLOT_CTRL1_COEX1_ACCESS (READ_WRITE) -/* see COEX1 */ -#define PCIE_1_SLOT_CTRL1_COEX2_SHIFT (1UL) -#define PCIE_1_SLOT_CTRL1_COEX2_MASK (0x2UL) -#define PCIE_1_SLOT_CTRL1_COEX2_ACCESS (READ_WRITE) -/* see COEX1 */ -#define PCIE_1_SLOT_CTRL1_LED_WLAN_SHIFT (2UL) -#define PCIE_1_SLOT_CTRL1_LED_WLAN_MASK (0x4UL) -#define PCIE_1_SLOT_CTRL1_LED_WLAN_ACCESS (READ_WRITE) -/* see COEX1 */ -#define PCIE_1_SLOT_CTRL1_LED_WWAN_SHIFT (3UL) -#define PCIE_1_SLOT_CTRL1_LED_WWAN_MASK (0x8UL) -#define PCIE_1_SLOT_CTRL1_LED_WWAN_ACCESS (READ_WRITE) -/* see COEX1 */ -#define PCIE_1_SLOT_CTRL1_WAKE_N_SHIFT (4UL) -#define PCIE_1_SLOT_CTRL1_WAKE_N_MASK (0x10UL) -#define PCIE_1_SLOT_CTRL1_WAKE_N_ACCESS (READ_WRITE) -/* see COEX1 */ -#define PCIE_1_SLOT_CTRL1_WDISABLE_N_SHIFT (5UL) -#define PCIE_1_SLOT_CTRL1_WDISABLE_N_MASK (0x20UL) -#define PCIE_1_SLOT_CTRL1_WDISABLE_N_ACCESS (READ_WRITE) -/* PCIe Power Good */ -#define PCIE_1_SLOT_CTRL1_PGOOD_N_SHIFT (6UL) -#define PCIE_1_SLOT_CTRL1_PGOOD_N_MASK (0x40UL) -#define PCIE_1_SLOT_CTRL1_PGOOD_N_ACCESS (READ_ONLY) - - -/*** I/O control register 1 ***/ -#define PCIE_2_SLOT_CTRL1 (0x0202) - - -/*** I/O control register 1 ***/ -#define PCIE_3_SLOT_CTRL1 (0x0302) - - -/*** PCM I/O assignment register -PCM Slot mux control ***/ -#define PCIE_PCM_IO_MUX_CONTROLLER_1 (0x0104) -/* See Table 12 */ -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN45_SHIFT (0UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN45_MASK (0x3UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN45_ACCESS (READ_WRITE) -/* See Table 12 */ -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN47_SHIFT (2UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN47_MASK (0xcUL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN47_ACCESS (READ_WRITE) -/* See Table 12 */ -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN49_SHIFT (4UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN49_MASK (0x30UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN49_ACCESS (READ_WRITE) -/* See Table 12 */ -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN51_SHIFT (6UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN51_MASK (0xc0UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PIN51_ACCESS (READ_WRITE) -/* See Table 13. */ -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PCM_SLOT_CTRL_SHIFT (8UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PCM_SLOT_CTRL_MASK (0x700UL) -#define PCIE_PCM_IO_MUX_CONTROLLER_1_PCM_SLOT_CTRL_ACCESS (READ_WRITE) - - -/*** PCM Module ID register ***/ -#define PCM_MODULE_IDENTIFIER_REGISTER (0x0106) -/* 0: default -1: Triorail TRM-5 Module -others: reserved */ -#define PCM_MODULE_IDENTIFIER_REGISTER_ID_SHIFT (0UL) -#define PCM_MODULE_IDENTIFIER_REGISTER_ID_MASK (0xffffUL) -#define PCM_MODULE_IDENTIFIER_REGISTER_ID_ACCESS (READ_WRITE) - - -/*** PCM control register ***/ -#define VCTL (0x0110) -/* Enable PCM data transmission transfer for this PCIe Slot. -0: disabled -1: transfer enabled */ -#define VCTL_PCM_EN_SHIFT (0UL) -#define VCTL_PCM_EN_MASK (0x1UL) -#define VCTL_PCM_EN_ACCESS (READ_WRITE) -/* Enables PCB Data Loopback -PCM data from PCIe slot is written to TX buffer and PCM data from CPU is written to RX buffer. */ -#define VCTL_LOOP_SHIFT (1UL) -#define VCTL_LOOP_MASK (0x2UL) -#define VCTL_LOOP_ACCESS (READ_WRITE) -/* Writing 1 clears RX buffer */ -#define VCTL_VBCRX_SHIFT (2UL) -#define VCTL_VBCRX_MASK (0x4UL) -#define VCTL_VBCRX_ACCESS (WRITE_ONLY) -/* Writing 1 clears TX buffer */ -#define VCTL_VBCTX_SHIFT (3UL) -#define VCTL_VBCTX_MASK (0x8UL) -#define VCTL_VBCTX_ACCESS (WRITE_ONLY) -/* 0: PCM stream has 8kHz samples -1: PCM stream has 16kHz samples */ -#define VCTL_PCM_16KHZ_SHIFT (4UL) -#define VCTL_PCM_16KHZ_MASK (0x10UL) -#define VCTL_PCM_16KHZ_ACCESS (READ_ONLY) - - -/*** Voice Receive Buffer Data Register ***/ -#define VRDB (0x0112) -/* Received voice data sample */ -#define VRDB_RXDATA_SHIFT (0UL) -#define VRDB_RXDATA_MASK (0xffffUL) -#define VRDB_RXDATA_ACCESS (READ_ONLY) - - -/*** Voice Receive Buffer Fill Level Register ***/ -#define VRBFL (0x0114) -/* Number of available 16-bit voice samples available to be read in the receive buffer. */ -#define VRBFL_RXLEVEL_SHIFT (0UL) -#define VRBFL_RXLEVEL_MASK (0xffffUL) -#define VRBFL_RXLEVEL_ACCESS (READ_ONLY) - - -/*** Voice Receive Buffer Watermark Register ***/ -#define VRBW (0x0116) -/* Watermark in number of 16-bit voice samples. (0xffff disables receive buffer watermark interrupts.) */ -#define VRBW_RXWM_SHIFT (0UL) -#define VRBW_RXWM_MASK (0xffffUL) -#define VRBW_RXWM_ACCESS (READ_WRITE) - - -/*** Voice Idle Sample Transmit Register ***/ -#define VRIS (0x0118) -/* 16-Bit voice sample */ -#define VRIS_IDLE_SHIFT (0UL) -#define VRIS_IDLE_MASK (0xffffUL) -#define VRIS_IDLE_ACCESS (READ_WRITE) - - -/*** Voice Transmit Buffer Data Register ***/ -#define VTDB (0x011A) -/* Received voice data sample */ -#define VTDB_TXDATA_SHIFT (0UL) -#define VTDB_TXDATA_MASK (0xffffUL) -#define VTDB_TXDATA_ACCESS (WRITE_ONLY) - - -/*** Voice Transmit Buffer Fill Level Register ***/ -#define VTBFL (0x011C) -/* Number of available 16-bit voice samples available to be read in the receive buffer. */ -#define VTBFL_TXLEVEL_SHIFT (0UL) -#define VTBFL_TXLEVEL_MASK (0xffffUL) -#define VTBFL_TXLEVEL_ACCESS (READ_ONLY) - - -/*** Voice Transmit Buffer Watermark Register ***/ -#define VTBW (0x011E) -/* Watermark in number of 16-bit voice samples. (0xffff disables transmit buffer watermark interrupts.) */ -#define VTBW_TXWM_SHIFT (0UL) -#define VTBW_TXWM_MASK (0xffffUL) -#define VTBW_TXWM_ACCESS (READ_WRITE) - - -/*** Voice Idle Sample Transmit Register ***/ -#define VTIS (0x0120) -/* 16-Bit voice sample */ -#define VTIS_IDLE_SHIFT (0UL) -#define VTIS_IDLE_MASK (0xffffUL) -#define VTIS_IDLE_ACCESS (READ_WRITE) - - -/*** ***/ -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1 (0x0130) -/* 1: use PCIe slot 1 pin 45 as GPIO -0: use PCIe slot 1 pin 45 as PCM */ -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__45_ENB_SHIFT (0UL) -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__45_ENB_MASK (0x1UL) -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__45_ENB_ACCESS (READ_WRITE) -/* 1: use PCIe slot 1 pin 47 as GPIO -0: use PCIe slot 1 pin 47 as PCM */ -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__47_ENB_SHIFT (1UL) -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__47_ENB_MASK (0x2UL) -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__47_ENB_ACCESS (READ_WRITE) -/* 1: use PCIe slot 1 pin 49 as GPIO -0: use PCIe slot 1 pin 49 as PCM */ -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__49_ENB_SHIFT (2UL) -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__49_ENB_MASK (0x4UL) -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__49_ENB_ACCESS (READ_WRITE) -/* 1: use PCIe slot 1 pin 51 as GPIO -0: use PCIe slot 1 pin 51 as PCM */ -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__51_ENB_SHIFT (3UL) -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__51_ENB_MASK (0x8UL) -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_1_PCIE_PIN__51_ENB_ACCESS (READ_WRITE) - - -/*** Enable / disable the GPIO functionality on the PCM pins connected to PCM controller 2 -For further details see "PCIe slot PCM pin GPIO EN register 1" ***/ -#define PCIE_SLOT_PCM_PIN_GPIO_EN_REGISTER_2 (0x0230) - - -/*** Sets the direction of GPIO on the PCM pins connected to PCM controller 1 -Note: only applicable if GPIO is enabled ***/ -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1 (0x0132) -/* 0: PCIe slot 1 pin 45 is Input (default) -1: PCIe slot 1 pin 45 is Output */ -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__45_DIR_SHIFT (0UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__45_DIR_MASK (0x1UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__45_DIR_ACCESS (READ_WRITE) -/* 0: PCIe slot 1 pin 47 is Input (default) -1: PCIe slot 1 pin 47 is Output */ -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__47_DIR_SHIFT (1UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__47_DIR_MASK (0x2UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__47_DIR_ACCESS (READ_WRITE) -/* 0: PCIe slot 1 pin 49 is Input (default) -1: PCIe slot 1 pin 49 is Output */ -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__49_DIR_SHIFT (2UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__49_DIR_MASK (0x4UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__49_DIR_ACCESS (READ_WRITE) -/* 0: PCIe slot 1 pin 51 is Input (default) -1: PCIe slot 1 pin 51 is Output */ -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__51_DIR_SHIFT (3UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__51_DIR_MASK (0x8UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_1_PCIE_PIN__51_DIR_ACCESS (READ_WRITE) - - -/*** Sets the direction of GPIO on the PCM pins connected to PCM controller 2 -Note: only applicable if GPIO is enabled -For further details see "PCIe slot PCM pin GPIO DIR register 1" ***/ -#define PCIE_SLOT_PCM_PIN_GPIO_DIR_REGISTER_2 (0x0232) - - -/*** Access to the data register of GPIOs on the PCM pins connected to PCM controller 1 -Note: only applicable if GPIO is enable ***/ -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1 (0x0134) -/* PCIe slot 1 pin 45: -Signal level applied to the pin, when configured as input / or signal level driven on the pin, when configured as output. -0: Low -1: High */ -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__45_RW_SHIFT (0UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__45_RW_MASK (0x1UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__45_RW_ACCESS (READ_WRITE) -/* See PCIE_PIN _45_RW */ -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__47_RW_SHIFT (1UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__47_RW_MASK (0x2UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__47_RW_ACCESS (READ_WRITE) -/* See PCIE_PIN _45_RW */ -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__49_RW_SHIFT (2UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__49_RW_MASK (0x4UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__49_RW_ACCESS (READ_WRITE) -/* See PCIE_PIN _45_RW */ -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__51_RW_SHIFT (3UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__51_RW_MASK (0x8UL) -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_1_PCIE_PIN__51_RW_ACCESS (READ_WRITE) - - -/*** Access to the data register of GPIOs on the PCM pins connected to PCM controller 2 -Note: only applicable if GPIO is enable -For further details see "PCIe slot PCM pin GPIO DATA register 1" ***/ -#define PCIE_SLOT_PCM_PIN_GPIO_DATA_REGISTER_2 (0x0234) - - -#endif /* NBHW18_FPGA_REGS_H */ diff --git a/board/nm/nbhw17_v1/nbhw_gpio.c b/board/nm/nbhw17_v1/nbhw_gpio.c index d06c10855d..3289499a4e 100644 --- a/board/nm/nbhw17_v1/nbhw_gpio.c +++ b/board/nm/nbhw17_v1/nbhw_gpio.c @@ -1,43 +1,97 @@ #include #include +#include +#include "nbhw_gpio.h" -#define SET_LOGIC(enable,group,bit) \ -if (enable) \ - mvGppValueSet(group, bit, bit); \ -else \ - mvGppValueSet(group, bit, 0); +struct gpio_node { + struct gpio_node* next; + struct gpio_desc desc; + const char* name; + int is_output; +}; -#define GPIO_RESET_BUTTON (14) +static struct gpio_node* gl = NULL; -void init_gpios(void) -{ - gpio_request(GPIO_RESET_BUTTON, "GPIO_RESET_BUTTON"); - gpio_direction_input(GPIO_RESET_BUTTON); +static struct gpio_desc* lookup_gpio(const char* gpio_name, int is_output) { + struct gpio_node* cur = gl; + + while (cur) { + if ((strcmp(gpio_name, cur->name)==0) && + (is_output == cur->is_output)) { + return &(cur->desc); + } + cur = cur->next; + } + return NULL; } -void out_usb_power(int enable) -{ -// SET_LOGIC(enable, 1, BIT9); +static struct gpio_desc* acquire_gpio(const char* gpio_name, int is_output) { + struct gpio_node* gn = 0; + int node; + + /* Check, if we already requested this gpio */ + struct gpio_desc* desc = lookup_gpio(gpio_name, is_output); + + if (desc) return desc; + + /* If we do not have it try to request it now. */ + node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "nm,gpios"); + if (node < 0) { + goto abort; + } + + gn = (struct gpio_node*)malloc(sizeof(struct gpio_node)); + if (!gn) goto abort; + + if (gpio_request_by_name_nodev(offset_to_ofnode(node), gpio_name, 0, &(gn->desc), is_output ? GPIOD_IS_OUT : GPIOD_IS_IN) < 0) { + goto abort; + } + + gn->name = gpio_name; + gn->is_output = is_output; + gn->next = gl; + gl = gn; + + desc = &(gn->desc); + + return desc; + +abort: + if (gn) free(gn); + printk("Could not acquire gpio %s as %s!\n", gpio_name, is_output ? "output" : "input"); + return 0; } -void out_watchdog(int enable) +int get_gpio(const char* gpio_name) { -// SET_LOGIC(enable, 0, BIT19); + struct gpio_desc* d; + int res; + + d = acquire_gpio(gpio_name, 0); + if (!d) goto abort; + + res = dm_gpio_get_value(d); + + return res; + +abort: + printf("Could not set gpio %s!\n", gpio_name); + return -1; } -void out_fpga_logic_reset(int enable) +int set_gpio(const char* gpio_name, int value) { -// SET_LOGIC(enable, 1, BIT12); + struct gpio_desc* d; + + d = acquire_gpio(gpio_name, 1); + if (!d) goto abort; + + dm_gpio_set_value(d, value); + + return 0; + +abort: + printf("Could not set gpio %s!\n", gpio_name); + return -1; } -void out_ext_reset_en(int enable) -{ -// SET_LOGIC(enable, 0, BIT7); -} - -int in_reset_button(void) -{ - return gpio_get_value(GPIO_RESET_BUTTON); -} - - diff --git a/board/nm/nbhw17_v1/nbhw_gpio.h b/board/nm/nbhw17_v1/nbhw_gpio.h index b56ae91902..0eb0a21d91 100644 --- a/board/nm/nbhw17_v1/nbhw_gpio.h +++ b/board/nm/nbhw17_v1/nbhw_gpio.h @@ -1,14 +1,30 @@ -#ifndef NBHW18_GPIO_H -#define NBHW18_GPIO_H -#include "../common/nbhw_gpio.h" +#ifndef HW17_GPIO_H +#define HW17_GPIO_H -void init_gpios(void); +/* GPIO definitions */ +#define GPIO_WD_ENABLE "wd_enable" +#define GPIO_RST_USB_HUB "rst_usb_hub" +#define GPIO_RST_FPGA "rst_fpga" +#define GPIO_RST_ETH_PHY "rst_eth_phy" +#define GPIO_RESET_BUTTON "reset_button" -void out_usb_power(int enable); -void out_watchdog(int enable); -void out_fpga_logic_reset(int enable); +int get_gpio(const char* gpio_name); +int set_gpio(const char* gpio_name, int value); -int in_reset_button(void); -int in_fpga_cdone(void); +/* LED definitions */ +#define LED0_GREEN 0 +#define LED0_RED 1 +#define LED1_GREEN 2 +#define LED1_RED 3 +#define LED2_GREEN 4 +#define LED2_RED 5 +#define LED3_GREEN 6 +#define LED3_RED 7 +#define LED4_GREEN 8 +#define LED4_RED 9 +#define LED5_GREEN 10 +#define LED5_RED 11 + +void set_led(int index, int value); #endif diff --git a/board/nm/nbhw17_v1/nbhw_pcie_fixup.c b/board/nm/nbhw17_v1/nbhw_pcie_fixup.c deleted file mode 100644 index 3f0a8bba23..0000000000 --- a/board/nm/nbhw17_v1/nbhw_pcie_fixup.c +++ /dev/null @@ -1,228 +0,0 @@ -/****************************************************************************** - * (c) COPYRIGHT 2015 by NetModule AG, Switzerland. All rights reserved. - * - * 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. - * - *****************************************************************************/ -/* #define DEBUG */ -#include -#include -#include -#include - -#include "config.h" -#include "../common/nbhw_bd.h" - -static void pcie_fixup_modify(u32 reg, u32 val, u32 mask) -{ - u32 regval; - regval = readl(reg); - regval &= ~mask; - regval |= (val & mask); - writel(regval, reg); -} - -/* We have a problem with the hardware during the detection phase this hack - * reduces the detection timeout from 4ns to 0ns so a minmal impulse will - * already trigger a detection. This is necessary to work with WLE600 modules. */ -static void pcie_fixup(void) -{ -/* SERDES0 PCIE0 = SLOT1 */ -#define PCIE0_USB3_CONTROL_REG 0xF10A0120 -/* SERDES4 PCIE2 = SLOT0 */ -#define PCIE2_USB3_CONTROL_REG 0xF10A2120 -#define PCIE_USB3_CONTROL_TIMING_MASK 0xC0 -#define PCIE_USB3_CONTROL_TIMING_VALUE 0x00 - - pcie_fixup_modify(PCIE0_USB3_CONTROL_REG, PCIE_USB3_CONTROL_TIMING_VALUE, PCIE_USB3_CONTROL_TIMING_MASK); - pcie_fixup_modify(PCIE2_USB3_CONTROL_REG, PCIE_USB3_CONTROL_TIMING_VALUE, PCIE_USB3_CONTROL_TIMING_MASK); -} - -static int has_slot_wlan(int slot) -{ - int module; - char slotDescr[20]; - char pdValue[200]; - - sprintf(slotDescr, "slot=%d", slot); - for (module=0; module<4; module++) { - strcpy(pdValue, "" ); /*init with an empty string*/ - if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) { - /* Wifi module needs PCIe */ - if ((strstr(pdValue, slotDescr)) && (strstr(pdValue, "wlan-"))) - return 1; - } - } - - return 0; -} - - -/* PCIE0 is on slot 1 (sw)*/ -#define PCIE0_STATUS_REG 0xF1081A04 -/* PCIE2 is on slot 0 (sw)*/ -#define PCIE2_STATUS_REG 0xF1045A04 - -#define PCIE_DL_DOWN_MASK 0x01 - -static int has_pcie_link_on_slot(int slot) -{ - /* If there is no module populated we say we have link (because we don't care) */ - switch (slot) { - case 0: - if (readw(PCIE2_STATUS_REG) & PCIE_DL_DOWN_MASK) - return 0; - break; - case 1: - if (readw(PCIE0_STATUS_REG) & PCIE_DL_DOWN_MASK) - return 0; - break; - default: - printf("Slot %d does not support PCIE\n", slot); - } - - return 1; -} - -static int check_pcie_slot_status(int slot){ - int ret = 1; - /* If WLAN on slot we need to check if we have link */ - if (has_slot_wlan(slot)) { - ret = has_pcie_link_on_slot(slot); - } - - return ret; -} - -/* The reset counter is at 256 MB, make sure it is not overlapping the address of the reset-reason mechanim, - * which is located at 1GB - 512kB. The reset reason counter is necessary to not try to reset - * the system more than 3 times */ -#define RESET_COUNTER_ADDRESS ((int *)0x10000000) -#define RESET_COUNTER_MD5 (RESET_COUNTER_ADDRESS + 4) -int get_reset_counter(void) -{ - volatile int *reset_counter = RESET_COUNTER_ADDRESS; - unsigned char reset_counter_checksum[16]; - - debug("reset_counter before inc: %d\n", *reset_counter); - - md5((unsigned char*) reset_counter, 4, reset_counter_checksum); - debug("md5 before inc: 0x%08X\n", *(unsigned int*)reset_counter_checksum); - /* Invalid checksum means it's the first boot. In this case we should see the counter - * as zero */ - if (memcmp(reset_counter_checksum, RESET_COUNTER_MD5, 16) != 0) { - *reset_counter = 0; - } - - return *reset_counter; -} - -int inc_reset_counter(void) -{ - volatile int *reset_counter = RESET_COUNTER_ADDRESS; - unsigned char reset_counter_checksum[16]; - - (*reset_counter)++; - debug("reset_counter after inc: %d\n", *reset_counter); - md5((unsigned char*) reset_counter, 4, reset_counter_checksum); - debug("md5 after inc: 0x%08X\n", *(unsigned int*)reset_counter_checksum); - memcpy(RESET_COUNTER_MD5, reset_counter_checksum, 16); - - return *reset_counter; - -} - -int reset_reset_counter(void) -{ - volatile int *reset_counter = RESET_COUNTER_ADDRESS; - - /* We don't need to do anything with the checksum, because invalid checksum = 0 */ - (*reset_counter) = 0; - - return *reset_counter; - -} - -static int is_module_check_abort(void) { - char c; - /* Check for abort */ - if (tstc()) { - c = getc(); - if (c == 'a') { - return 1; - } - } - - return 0; -} - -/* Check if pcie link is detected for wlan modules, some WLE600 modules have - * even with the pcie_fixup patch a problem that they don't appear during the first - * boot */ -static int do_wlan_fixup(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - int i; -#define MAX_RESET_COUNT 6 - int reset_counter = get_reset_counter(); - int ret; - - pcie_fixup(); - - /* If we do a reboot it can happen that reset_counter is still 3, in this case - * we need to restart the counter */ - if (reset_counter >= MAX_RESET_COUNT) { - reset_counter = reset_reset_counter(); - } - - puts("Checking PCIe WLAN modules (abort with a)\n"); - - /* Try it for at least one second */ - for (i = 0; i < 100; i++) { - ret = 3; - if (check_pcie_slot_status(0)) ret &= ~1; - - if (check_pcie_slot_status(1)) ret &= ~2; - - if (is_module_check_abort()) { - puts("Abort WLAN module check\n"); - ret = 0; - } - - if (ret == 0) break; - - udelay(10000); - } - - /* One module that should have link does not have link */ - if (ret) { - reset_counter = inc_reset_counter(); - if (reset_counter >= MAX_RESET_COUNT) { - printf("WLAN Modules missing but reset counter reached %d, continue\n", reset_counter); - return 0; - } - printf ("Not all WLAN Modules from the bd came up (ret=0x%08X), reset (try %d of %d)\n", ret, reset_counter, MAX_RESET_COUNT); - printf ("Wait with reset for %ds\n", reset_counter * 10); - udelay(10000000 * reset_counter); - do_reset(NULL, 0, 0, NULL); - } - - /* Reset the counter in case of success */ - reset_reset_counter(); - - return 0; -} - -U_BOOT_CMD( - nbhw_wlan_fixup, 1, 1, do_wlan_fixup, - "NBHW WLAN fixup for some Wifi modules", - "Checks if WLAN modules have been detected correctly, or resets\n" -); - diff --git a/board/nm/nbhw18_v2/Makefile b/board/nm/nbhw18_v2/Makefile index 10ffdece18..8bd91073fb 100644 --- a/board/nm/nbhw18_v2/Makefile +++ b/board/nm/nbhw18_v2/Makefile @@ -11,12 +11,13 @@ commonobj = ../common/bdparser.o \ ../common/nbhw_fileaccess.o \ ../common/nbhw_fpga_gpio.o \ ../common/nbhw_partitions.o \ - ../common/nbhw_pcie_fixup.o + ../common/nbhw_pcie_fixup.o ccflags-y := -I../common ifndef CONFIG_SPL_BUILD obj-y := board.o nbhw_gpio.o nbhw_fpga_config.o nbhw_mvswitch.o \ + ../common/nbhw_sim.o nbhw_sim.o \ ../common/da9063.o \ ../common/lattice/core.o \ ../common/lattice/hardware.o \ diff --git a/board/nm/nbhw18_v2/board.c b/board/nm/nbhw18_v2/board.c index d3306be943..04c2bcf49b 100644 --- a/board/nm/nbhw18_v2/board.c +++ b/board/nm/nbhw18_v2/board.c @@ -55,6 +55,7 @@ DECLARE_GLOBAL_DATA_PTR; #define DEV_CS0_BASE 0xfd000000 +/* Default serdes configuration */ static struct serdes_map board_serdes_map[] = { { SGMII0, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, { USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, @@ -205,31 +206,9 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) int i; if (read_eeprom() < 0){ + /* If we do not have a board descriptor use the default + serdes configuration defined in board_serdes_map */ puts("Could not read board descriptor using default serdes config.\n"); - - board_serdes_map[0].serdes_speed = SERDES_SPEED_1_25_GBPS; - board_serdes_map[0].serdes_mode = SERDES_DEFAULT_MODE; - board_serdes_map[0].serdes_type = SGMII0; - - board_serdes_map[1].serdes_speed = SERDES_SPEED_5_GBPS; - board_serdes_map[1].serdes_mode = PEX_ROOT_COMPLEX_X1; - board_serdes_map[1].serdes_type = USB3_HOST0; - - board_serdes_map[2].serdes_speed = SERDES_SPEED_1_25_GBPS; - board_serdes_map[2].serdes_mode = SERDES_DEFAULT_MODE; - board_serdes_map[2].serdes_type = SGMII1; - - board_serdes_map[3].serdes_speed = SERDES_SPEED_5_GBPS; - board_serdes_map[3].serdes_mode = PEX_ROOT_COMPLEX_X1; - board_serdes_map[3].serdes_type = PEX3; - - board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS; - board_serdes_map[4].serdes_mode = PEX_ROOT_COMPLEX_X1; - board_serdes_map[4].serdes_type = PEX2; - - board_serdes_map[5].serdes_speed = SERDES_SPEED_1_25_GBPS; - board_serdes_map[5].serdes_mode = SERDES_DEFAULT_MODE; - board_serdes_map[5].serdes_type = SGMII2; } else { for (i = 0; i < ARRAY_SIZE(board_serdes_map); i++) { enum serdes_type type; @@ -243,7 +222,6 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) type = bd_get_serdes_type(i); } - /* Do not touch serdes */ if (type < LAST_SERDES_TYPE) { if ((type >= SGMII0) && (type <= SGMII2)) { board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS; @@ -256,7 +234,12 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) else if ((type >= USB3_HOST0) && (type <= USB3_HOST1)) { board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS; board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1; - } else if ((type == DEFAULT_SERDES)) { + } + else if ((type >= SATA0) && (type <= SATA3)) { + board_serdes_map[i].serdes_speed = SERDES_SPEED_3_GBPS; + board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; + } + else if ((type == DEFAULT_SERDES)) { board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS; board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; } else { @@ -653,7 +636,7 @@ static void set_phy_fast_blink_mode(int phy_addr) 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, "armada-385-nbhw18-prod1.dtb"); @@ -673,9 +656,7 @@ int board_late_init(void) find_and_set_active_partition(); pass_hw_rev(); - /* Todo: It seems that something with the network is wrong */ run_command("run load_fpga", CMD_FLAG_ENV); - #endif /* TODO: Move the following two lines up to misc_init_r when ttyS1 works without FPGA again */ @@ -688,7 +669,9 @@ int board_late_init(void) set_devicetree_name(); - set_mac_addresses(3); + set_mac_address(0, 0); + set_mac_address(1, 1); + set_mac_address(2, 2); /* Take phy out of reset after FPGA was loaded */ gpio_set_value(29, 1); diff --git a/board/nm/nbhw18_v2/nbhw_fpga_config.c b/board/nm/nbhw18_v2/nbhw_fpga_config.c index e95b934f68..26ce9b8d9a 100644 --- a/board/nm/nbhw18_v2/nbhw_fpga_config.c +++ b/board/nm/nbhw18_v2/nbhw_fpga_config.c @@ -7,6 +7,7 @@ #include #include #include "../common/nbhw_bd.h" +#include "../common/nbhw_sim.h" DECLARE_GLOBAL_DATA_PTR; @@ -150,6 +151,8 @@ static int configure_pcie_slots(void) int i, res; char volt[10]; + configure_sim_slots(4); + udelay(1200000); /* 1.2 s */ for (i = 0; i < 5; i++) { diff --git a/board/nm/nbhw18_v2/nbhw_sim.c b/board/nm/nbhw18_v2/nbhw_sim.c index 9a7d4258d2..be143ffd64 100644 --- a/board/nm/nbhw18_v2/nbhw_sim.c +++ b/board/nm/nbhw18_v2/nbhw_sim.c @@ -1,14 +1,14 @@ #include -#include +#include "../common/nbhw_fpga_prog.h" -#include "nbhw18_fpga_regs.h" +#define SIM_CTRL (0x0040) void connect_sim_to_slot(int sim, int slot) { uint16_t sim_ctrl; uint16_t sim_shift; uint16_t slot_sel; - if (sim > 3) { + if (sim > 1) { printf("Invalid sim %d selected, can't connect slot %d\n", sim, slot); return; } @@ -32,4 +32,3 @@ void connect_sim_to_slot(int sim, int slot) { FPGA_REG(SIM_CTRL) = sim_ctrl; } - diff --git a/common/board_f.c b/common/board_f.c index 9220815441..ffa887441f 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -791,7 +791,9 @@ static const init_fnc_t init_sequence_f[] = { env_init, /* initialize environment */ init_baud_rate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ +#if !defined(CONFIG_PRE_CONSOLE_BUFFER) console_init_f, /* stage 1 init of console */ +#endif display_options, /* say that we are here */ display_text_info, /* show debugging info if required */ #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SH) || \ diff --git a/configs/armada-385-hw14_defconfig b/configs/armada-385-hw14_defconfig new file mode 100644 index 0000000000..478c977100 --- /dev/null +++ b/configs/armada-385-hw14_defconfig @@ -0,0 +1,75 @@ +CONFIG_ARM=y +CONFIG_ARCH_MVEBU=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TARGET_NM_HW14=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_DEFAULT_DEVICE_TREE="armada-385-hw14-spl" +CONFIG_SMBIOS_PRODUCT_NAME="hw14" +CONFIG_FIT=y +CONFIG_FIT_ENABLE_SHA256_SUPPORT=y +CONFIG_BOOTDELAY=3 +CONFIG_BOOTSTAGE_STASH_SIZE=4096 +CONFIG_PRE_CONSOLE_BUFFER=y +CONFIG_SYS_CONSOLE_IS_IN_ENV=y +CONFIG_PRE_CON_BUF_SZ=4096 +CONFIG_PRE_CON_BUF_ADDR=0x04000000 +# CONFIG_CONSOLE_MUX is not set +CONFIG_DEFAULT_FDT_FILE="armada-385-hw14-spl" +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_SPL=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x190 +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_NB_TEST=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_EFI_PARTITION=y +# CONFIG_PARTITION_UUIDS is not set +# CONFIG_SPL_PARTITION_UUIDS is not set +CONFIG_OF_BOARD_FIXUP=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_OF_LIST="armada-385-hw14-spl armada-385-hw14" +CONFIG_MULTI_DTB_FIT=y +CONFIG_DM_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_SDMA=y +CONFIG_MMC_SDHCI_MV=y +CONFIG_SPI_FLASH=y +CONFIG_MVNETA=y +CONFIG_PCI=y +# CONFIG_DEBUG_UART is not set +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set +CONFIG_SYS_NS16550=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MARVELL=y +CONFIG_USB_STORAGE=y +CONFIG_MVEBU_GPIO=y +CONFIG_CMD_EEPROM=y +CONFIG_ENV_IS_IN_EEPROM=y +CONFIG_WDT=y +CONFIG_WDT_ORION=y diff --git a/configs/armada-385-nbhw17-v1_defconfig b/configs/armada-385-nbhw17-v1_defconfig index 70ef23086b..1f9dbcfed8 100644 --- a/configs/armada-385-nbhw17-v1_defconfig +++ b/configs/armada-385-nbhw17-v1_defconfig @@ -7,11 +7,18 @@ CONFIG_TARGET_NM_NBHW17_V1=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_LIBDISK_SUPPORT=y -CONFIG_DEFAULT_DEVICE_TREE="armada-385-nbhw17-v1" -CONFIG_DEFAULT_FDT_FILE="armada-385-nbhw17-v1" +CONFIG_DEFAULT_DEVICE_TREE="armada-385-nbhw17-v1-spl" +CONFIG_SMBIOS_PRODUCT_NAME="hw17" +CONFIG_FIT=y +CONFIG_FIT_ENABLE_SHA256_SUPPORT=y CONFIG_BOOTDELAY=3 CONFIG_BOOTSTAGE_STASH_SIZE=4096 -CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_PRE_CONSOLE_BUFFER=y +CONFIG_SYS_CONSOLE_IS_IN_ENV=y +CONFIG_PRE_CON_BUF_SZ=4096 +CONFIG_PRE_CON_BUF_ADDR=0x04000000 +# CONFIG_CONSOLE_MUX is not set +CONFIG_DEFAULT_FDT_FILE="armada-385-nbhw17-v1-spl" # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_SPL=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x190 @@ -19,6 +26,7 @@ CONFIG_SPL_I2C_SUPPORT=y CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y # CONFIG_CMD_IMLS is not set +CONFIG_CMD_NB_TEST=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_MMC=y CONFIG_CMD_SF=y @@ -40,17 +48,19 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_EFI_PARTITION=y # CONFIG_PARTITION_UUIDS is not set # CONFIG_SPL_PARTITION_UUIDS is not set +CONFIG_OF_BOARD_FIXUP=y CONFIG_SPL_OF_TRANSLATE=y +CONFIG_OF_LIST="armada-385-nbhw17-v1-spl armada-385-nbhw17-v1" +CONFIG_MULTI_DTB_FIT=y +CONFIG_DM_GPIO=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_MV=y CONFIG_SPI_FLASH=y CONFIG_MVNETA=y CONFIG_PCI=y -CONFIG_DEBUG_UART=y -CONFIG_DEBUG_UART_BASE=0xd0012000 -CONFIG_DEBUG_UART_CLOCK=250000000 -CONFIG_DEBUG_UART_SHIFT=2 +# CONFIG_DEBUG_UART is not set +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set CONFIG_SYS_NS16550=y CONFIG_USB=y CONFIG_DM_USB=y @@ -58,4 +68,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MARVELL=y CONFIG_USB_STORAGE=y CONFIG_MVEBU_GPIO=y -CONFIG_DM_GPIO=y +CONFIG_CMD_EEPROM=y +CONFIG_ENV_IS_IN_EEPROM=y +CONFIG_WDT=y +CONFIG_WDT_ORION=y diff --git a/drivers/gpio/pca953x_gpio.c b/drivers/gpio/pca953x_gpio.c index 791d1d1516..4d599db4f7 100644 --- a/drivers/gpio/pca953x_gpio.c +++ b/drivers/gpio/pca953x_gpio.c @@ -83,7 +83,11 @@ static int pca953x_write_single(struct udevice *dev, int reg, u8 val, int off = offset / BANK_SZ; int ret = 0; +#ifdef CONFIG_DM_I2C ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1); +#else + ret = i2c_write(info->addr, (reg << bank_shift) + off, 1, &val, 1); +#endif if (ret) { dev_err(dev, "%s error\n", __func__); return ret; @@ -101,7 +105,11 @@ static int pca953x_read_single(struct udevice *dev, int reg, u8 *val, int ret; u8 byte; +#ifdef CONFIG_DM_I2C ret = dm_i2c_read(dev, (reg << bank_shift) + off, &byte, 1); +#else + ret = i2c_read(info->addr, (reg << bank_shift) + off, 1, &byte, 1); +#endif if (ret) { dev_err(dev, "%s error\n", __func__); return ret; @@ -118,12 +126,24 @@ static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val) int ret = 0; if (info->gpio_count <= 8) { +#ifdef CONFIG_DM_I2C ret = dm_i2c_read(dev, reg, val, 1); +#else + ret = i2c_read(info->addr, reg, 1, val, 1); +#endif } else if (info->gpio_count <= 16) { +#ifdef CONFIG_DM_I2C ret = dm_i2c_read(dev, reg << 1, val, info->bank_count); +#else + ret = i2c_read(info->addr, reg << 1, 1, val, info->bank_count); +#endif } else if (info->gpio_count == 40) { /* Auto increment */ +#ifdef CONFIG_DM_I2C ret = dm_i2c_read(dev, (reg << 3) | 0x80, val, info->bank_count); +#else + ret = i2c_read(info->addr, (reg << 3) | 0x80, 1, val, info->bank_count); +#endif } else { dev_err(dev, "Unsupported now\n"); return -EINVAL; diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index 3144120788..5dba3dbadd 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -1372,6 +1372,8 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) case PHY_INTERFACE_MODE_RGMII_ID: ctrl |= MVNETA_GMAC2_PORT_RGMII; break; + case PHY_INTERFACE_MODE_MII: + break; default: return -EINVAL; } diff --git a/include/configs/armada-385-hw14.h b/include/configs/armada-385-hw14.h new file mode 100644 index 0000000000..e7bad115f6 --- /dev/null +++ b/include/configs/armada-385-hw14.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2014 Stefan Roese + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CONFIG_DB_88F6820_GP_H +#define _CONFIG_DB_88F6820_GP_H + +/* + * High Level Configuration Options (easy to change) + */ + +#define CONFIG_DISPLAY_BOARDINFO_LATE + +/* + * TEXT_BASE needs to be below 16MiB, since this area is scrubbed + * for DDR ECC byte filling in the SPL before loading the main + * U-Boot into it. + */ +#define CONFIG_SYS_TEXT_BASE 0x00800000 +#define CONFIG_SYS_TCLK 250000000 /* 250MHz */ + +/* + * Commands configuration + */ +#define CONFIG_CMD_PCI + +/* I2C */ +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MVTWSI +#define CONFIG_I2C_MVTWSI_BASE0 MVEBU_TWSI_BASE +#define CONFIG_SYS_I2C_SLAVE 0x0 +#define CONFIG_SYS_I2C_SPEED 100000 + +/* + * SDIO/MMC Card Configuration + */ +#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE + +/* Partition support */ + +/* USB/EHCI configuration */ +#define CONFIG_EHCI_IS_TDI + +/* Environment in I2C EEPROM */ +/** + * Layout on the NBHW08 Board: + * Offset Size Description + * 0x0000 0x200 The NetModule Boarddescriptor + * 0x0200 0x200 The NetModule Productdescriptor + * 0x0400 0x200 The NetModule License Descriptor + * 0x0600 0x400 The NetModule Parition table + * 0x0A00 0x600 reserved + * 0x1000 0xA00 The U-Boot environment + * 0x1A00 0x600 reserved + */ +#define CONFIG_ENV_OFFSET (0x1000) /* The Environment is located at 4k */ +#define CONFIG_ENV_SIZE (0xA00) /* 64KiB */ +#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */ + +#define CONFIG_ENV_EEPROM_IS_ON_I2C +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* Main EEPROM */ +#define CONFIG_SYS_DEF_EEPROM_ADDR 0x50 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN (2) +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 5 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 70 + +#define CONFIG_PHY_MARVELL /* there is a marvell phy */ +#define PHY_ANEG_TIMEOUT 8000 /* PHY needs a longer aneg time */ + +/* PCIe support */ +#ifndef CONFIG_SPL_BUILD +#define CONFIG_PCI_MVEBU +#define CONFIG_PCI_SCAN_SHOW +#endif + +#if !defined(UBOOT_USER_BUILD) && !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT_ORION) +#define CONFIG_WATCHDOG +#endif + +#define CONFIG_OF_BOARD_SETUP + +#define CONFIG_SYS_ALT_MEMTEST + +#ifndef CONFIG_SPL_BUILD + +#define CONFIG_NM_LOGIN +#define CONFIG_CRYPT +#define CONFIG_SUPPORT_EMMC_RPMB + +#define KERNEL_ADDR "0x01000000" +#define LOAD_ADDR "0x03000000" +#define FDT_ADDR "0x02000000" +#define PXE_ADDR "0x02800000" +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_high=0x12000000\0" \ + "initrd_high=0x13000000\0" \ + "kernel_image=kernel.bin\0" \ + "fdt_image=openwrt-nbhw14-sgmii.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 */ \ + "eth1addr=00:11:22:33:44:55\0" \ + "eth2addr=00:11:22:33:44:56\0" \ + "eth3addr=00:11:22:33:44:57\0" \ + "ethact=ethernet@34000\0" \ + "add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 rootwait; run set_console_dev\0" \ + "add_version_bootargs=setenv bootargs $bootargs\0" \ + "fdt_skip_update=yes\0" \ + "sdbringup=echo Try bringup boot && ext4load mmc 0:$root_part $kernel_addr /boot/zImage && " \ + "ext4load mmc 0:$root_part $fdt_addr /boot/$fdt_image && setenv bootargs $bootargs rw;\0" \ + "sdprod=ext4load mmc 0:$root_part $kernel_addr /boot/$kernel_image && " \ + "ext4load mmc 0:$root_part $fdt_addr /boot/$fdt_image && setenv bootargs $bootargs ro;\0" \ + "sdboot=if mmc dev 0; then nbhw_wlan_fixup &&" \ + "echo Copying Linux from SD to RAM...; "\ + "if test -e mmc 0:$root_part /boot/$kernel_image; then run sdprod; " \ + "else run sdbringup; fi; " \ + "run add_sd_bootargs; run add_version_bootargs; " \ + "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" \ + "defaultconsole=ttyS0\0" \ + "set_console_dev=if test -n ${consoledev}; then setenv bootargs $bootargs console=$consoledev,115200; fi; true\0" \ + "tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; setenv bootargs rdinit=/etc/preinit console=$defaultconsole,115200 debug; run add_version_bootargs; bootz $kernel_addr - $fdt_addr\0" \ + "pxe_recovery=sleep 3 && dhcp && pxe get && pxe boot\0" \ + "load_fpga=ext4load mmc 0:$root_part $kernel_addr /logic/LG00000000 && nbhw_fpga program xilinx 0xffffffff $kernel_addr $filesize && nbhw_fpga configure\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 + + +/* SPL */ +/* + * Select the boot device here + * + * Currently supported are: + * SPL_BOOT_SPI_NOR_FLASH - Booting via SPI NOR flash + * SPL_BOOT_SDIO_MMC_CARD - Booting via SDIO/MMC card (partition 1) + */ +#define SPL_BOOT_SPI_NOR_FLASH 1 +#define SPL_BOOT_SDIO_MMC_CARD 2 +#define CONFIG_SPL_BOOT_DEVICE SPL_BOOT_SDIO_MMC_CARD + +/* Defines for SPL */ +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_SIZE (180 << 10) +#define CONFIG_SPL_TEXT_BASE 0x40000030 +#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x0030) + +#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE) +#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10) + +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_MALLOC_SIMPLE +#define CONFIG_OF_STDOUT_VIA_ALIAS +#endif + +#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10)) +#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4) + +#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SPI_NOR_FLASH +/* SPL related SPI defines */ +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x24000 +#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS +#endif + +#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SDIO_MMC_CARD +/* SPL related MMC defines */ +#define CONFIG_SYS_MMC_U_BOOT_OFFS (200 << 10) +#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_MMC_U_BOOT_OFFS +#ifdef CONFIG_SPL_BUILD +#define CONFIG_FIXED_SDHCI_ALIGNED_BUFFER 0x00180000 /* in SDRAM */ +#endif +#define CONFIG_SPL_BOARD_INIT +#endif + +/* + * mv-common.h should be defined after CMD configs since it used them + * to enable certain macros + */ +#include "mv-common.h" + +/* + * NBHW needs md5 support + */ +#ifndef CONFIG_MD5 +#define CONFIG_MD5 +#endif + +/* + * We need some functions to be called after environment setup + */ +#define CONFIG_BOARD_LATE_INIT + +#define CONFIG_AUTOBOOT_KEYED 1 +#define CONFIG_AUTOBOOT_PROMPT \ + "Press s to abort autoboot in %d seconds\n" +#undef CONFIG_AUTOBOOT_DELAY_STR +#define CONFIG_AUTOBOOT_STOP_STR "s" + +#ifndef CONFIG_SPL_BUILD +#undef CONFIG_REQUIRE_SERIAL_CONSOLE +/* Wee need early init r to actually print the pre console buffer + * because u-boot is buggy */ +#define CONFIG_BOARD_EARLY_INIT_R +#define CONFIG_MISC_INIT_R +#endif + +#endif /* _CONFIG_DB_88F6820_GP_H */ diff --git a/include/configs/armada-385-nbhw17-v1.h b/include/configs/armada-385-nbhw17-v1.h index 6f86cb41ef..50b8117f32 100644 --- a/include/configs/armada-385-nbhw17-v1.h +++ b/include/configs/armada-385-nbhw17-v1.h @@ -43,11 +43,28 @@ /* USB/EHCI configuration */ #define CONFIG_EHCI_IS_TDI -/* Environment in SPI NOR flash */ -#define CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */ -#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ -#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */ +/* Environment in I2C EEPROM */ +/** + * Layout on the NBHW08 Board: + * Offset Size Description + * 0x0000 0x200 The NetModule Boarddescriptor + * 0x0200 0x200 The NetModule Productdescriptor + * 0x0400 0x200 The NetModule License Descriptor + * 0x0600 0x400 The NetModule Parition table + * 0x0A00 0x600 reserved + * 0x1000 0xA00 The U-Boot environment + * 0x1A00 0x600 reserved + */ +#define CONFIG_ENV_OFFSET (0x1000) /* The Environment is located at 4k */ +#define CONFIG_ENV_SIZE (0xA00) /* 64KiB */ +#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */ + +#define CONFIG_ENV_EEPROM_IS_ON_I2C +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* Main EEPROM */ +#define CONFIG_SYS_DEF_EEPROM_ADDR 0x50 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN (2) +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 5 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 70 #define CONFIG_PHY_MARVELL /* there is a marvell phy */ #define PHY_ANEG_TIMEOUT 8000 /* PHY needs a longer aneg time */ @@ -58,9 +75,20 @@ #define CONFIG_PCI_SCAN_SHOW #endif +#if !defined(UBOOT_USER_BUILD) && !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT_ORION) +#define CONFIG_WATCHDOG +#endif + +#define CONFIG_OF_BOARD_SETUP + #define CONFIG_SYS_ALT_MEMTEST #ifndef CONFIG_SPL_BUILD + +#define CONFIG_NM_LOGIN +#define CONFIG_CRYPT +#define CONFIG_SUPPORT_EMMC_RPMB + #define KERNEL_ADDR "0x01000000" #define LOAD_ADDR "0x03000000" #define FDT_ADDR "0x02000000" @@ -78,14 +106,14 @@ "eth1addr=00:11:22:33:44:55\0" \ "eth2addr=00:11:22:33:44:56\0" \ "ethact=ethernet@30000\0" \ - "add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 console=ttyS1,115200 rootwait\0" \ + "add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 rootwait; run set_console_dev\0" \ "add_version_bootargs=setenv bootargs $bootargs\0" \ "fdt_skip_update=yes\0" \ "sdbringup=echo Try bringup boot && ext4load mmc 0:$root_part $kernel_addr /boot/zImage && " \ "ext4load mmc 0:$root_part $fdt_addr /boot/$fdt_image && setenv bootargs $bootargs rw;\0" \ "sdprod=ext4load mmc 0:$root_part $kernel_addr /boot/$kernel_image && " \ "ext4load mmc 0:$root_part $fdt_addr /boot/$fdt_image && setenv bootargs $bootargs ro;\0" \ - "sdboot=if mmc dev 0; then echo Load FPGA...; nbhw_wlan_fixup &&" \ + "sdboot=if mmc dev 0; then nbhw_wlan_fixup &&" \ "echo Copying Linux from SD to RAM...; "\ "if test -e mmc 0:$root_part /boot/$kernel_image; then run sdprod; " \ "else run sdbringup; fi; " \ @@ -103,14 +131,15 @@ "tftptimeoutcountmax=5\0" \ "bootpretryperiod=2000\0" \ "autoload=false\0" \ - "tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; setenv bootargs rdinit=/etc/preinit console=ttyO1,115200 debug; bootz $kernel_addr - $fdt_addr\0" \ + "defaultconsole=ttyS1\0" \ + "set_console_dev=if test -n ${consoledev}; then setenv bootargs $bootargs console=$consoledev,115200; fi; true\0" \ + "tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; setenv bootargs rdinit=/etc/preinit console=$defaultconsole,115200 debug; run add_version_bootargs; bootz $kernel_addr - $fdt_addr\0" \ "pxe_recovery=sleep 3 && dhcp && pxe get && pxe boot\0" \ "load_fpga=ext4load mmc 0:$root_part $kernel_addr /logic/LG00000000 && nbhw_fpga program lattice 0xffffffff $kernel_addr $filesize && nbhw_fpga configure\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 - /* SPL */ /* * Select the boot device here @@ -134,6 +163,7 @@ #ifdef CONFIG_SPL_BUILD #define CONFIG_SYS_MALLOC_SIMPLE +#define CONFIG_OF_STDOUT_VIA_ALIAS #endif #define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10)) @@ -165,11 +195,27 @@ /* * NBHW needs md5 support */ +#ifndef CONFIG_MD5 #define CONFIG_MD5 +#endif /* * We need some functions to be called after environment setup */ #define CONFIG_BOARD_LATE_INIT +#define CONFIG_AUTOBOOT_KEYED 1 +#define CONFIG_AUTOBOOT_PROMPT \ + "Press s to abort autoboot in %d seconds\n" +#undef CONFIG_AUTOBOOT_DELAY_STR +#define CONFIG_AUTOBOOT_STOP_STR "s" + +#ifndef CONFIG_SPL_BUILD +#undef CONFIG_REQUIRE_SERIAL_CONSOLE +/* Wee need early init r to actually print the pre console buffer + * because u-boot is buggy */ +#define CONFIG_BOARD_EARLY_INIT_R +#define CONFIG_MISC_INIT_R +#endif + #endif /* _CONFIG_DB_88F6820_GP_H */ diff --git a/include/configs/armada-385-nbhw18-v2.h b/include/configs/armada-385-nbhw18-v2.h old mode 100755 new mode 100644 index fd59a022be..04c990c78d --- a/include/configs/armada-385-nbhw18-v2.h +++ b/include/configs/armada-385-nbhw18-v2.h @@ -112,7 +112,7 @@ "eth2addr=00:11:22:33:44:56\0" \ "eth3addr=00:11:22:33:44:57\0" \ "ethact=ethernet@34000\0" \ - "add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 console=$consoledev,115200 rootwait loglevel=4\0" \ + "add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 rootwait loglevel=4; run set_console_dev\0" \ "add_version_bootargs=setenv bootargs $bootargs\0" \ "fdt_skip_update=yes\0" \ "sdbringup=echo Try bringup boot && ext4load mmc 0:$root_part $kernel_addr /boot/zImage && " \ @@ -138,6 +138,7 @@ "bootpretryperiod=2000\0" \ "autoload=false\0" \ "defaultconsole=ttyS1\0" \ + "set_console_dev=if test -n ${consoledev}; then setenv bootargs $bootargs console=$consoledev,115200; fi; true\0" \ "tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; setenv bootargs rdinit=/etc/preinit console=$defaultconsole,115200 debug; bootz $kernel_addr - $fdt_addr\0" \ "pxe_recovery=sleep 3 && dhcp && pxe get && pxe boot\0" \ "load_fpga=ext4load mmc 0:$root_part $kernel_addr /logic/LG00000000 && nbhw_fpga program lattice-sspi 0xffffffff $kernel_addr $filesize && nbhw_fpga configure\0" \ diff --git a/include/libfdt_env.h b/include/libfdt_env.h index 6c6845f76c..dc50aafcf7 100644 --- a/include/libfdt_env.h +++ b/include/libfdt_env.h @@ -6,7 +6,8 @@ * SPDX-License-Identifier: LGPL-2.1+ */ -#ifndef _LIBFDT_ENV_H +#ifndef LIBFDT_ENV_H +#define LIBFDT_ENV_H #define _LIBFDT_ENV_H #include "compiler.h" @@ -32,4 +33,4 @@ typedef __be64 fdt64_t; /* adding a ramdisk needs 0x44 bytes in version 2008.10 */ #define FDT_RAMDISK_OVERHEAD 0x80 -#endif /* _LIBFDT_ENV_H */ +#endif /* LIBFDT_ENV_H */ diff --git a/include/linux/log2.h b/include/linux/log2.h index aa1de63090..8b01d234dd 100644 --- a/include/linux/log2.h +++ b/include/linux/log2.h @@ -12,12 +12,6 @@ #include #include -/* - * deal with unrepresentable constant logarithms - */ -extern __attribute__((const, noreturn)) -int ____ilog2_NaN(void); - /* * non-constant log of base 2 calculators * - the arch may override these in asm/bitops.h if they can be implemented @@ -40,19 +34,23 @@ int __ilog2_u64(u64 n) } #endif -/* - * Determine whether some value is a power of two, where zero is +/** + * is_power_of_2() - check if a value is a power of two + * @n: the value to check + * + * Determine whether some value is a power of two, where zero is * *not* considered a power of two. + * Return: true if @n is a power of 2, otherwise false. */ - static inline __attribute__((const)) bool is_power_of_2(unsigned long n) { return (n != 0 && ((n & (n - 1)) == 0)); } -/* - * round up to nearest power of two +/** + * __roundup_pow_of_two() - round up to nearest power of two + * @n: value to round up */ static inline __attribute__((const)) unsigned long __roundup_pow_of_two(unsigned long n) @@ -60,8 +58,9 @@ unsigned long __roundup_pow_of_two(unsigned long n) return 1UL << fls_long(n - 1); } -/* - * round down to nearest power of two +/** + * __rounddown_pow_of_two() - round down to nearest power of two + * @n: value to round down */ static inline __attribute__((const)) unsigned long __rounddown_pow_of_two(unsigned long n) @@ -70,19 +69,19 @@ unsigned long __rounddown_pow_of_two(unsigned long n) } /** - * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value - * @n - parameter + * ilog2 - log base 2 of 32-bit or a 64-bit unsigned value + * @n: parameter * * constant-capable log of base 2 calculation * - this can be used to initialise global variables from constant data, hence - * the massive ternary operator construction + * the massive ternary operator construction * * selects the appropriately-sized optimised version depending on sizeof(n) */ #define ilog2(n) \ ( \ __builtin_constant_p(n) ? ( \ - (n) < 1 ? ____ilog2_NaN() : \ + (n) < 2 ? 0 : \ (n) & (1ULL << 63) ? 63 : \ (n) & (1ULL << 62) ? 62 : \ (n) & (1ULL << 61) ? 61 : \ @@ -145,10 +144,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) (n) & (1ULL << 4) ? 4 : \ (n) & (1ULL << 3) ? 3 : \ (n) & (1ULL << 2) ? 2 : \ - (n) & (1ULL << 1) ? 1 : \ - (n) & (1ULL << 0) ? 0 : \ - ____ilog2_NaN() \ - ) : \ + 1) : \ (sizeof(n) <= 4) ? \ __ilog2_u32(n) : \ __ilog2_u64(n) \ @@ -156,7 +152,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) /** * roundup_pow_of_two - round the given value up to nearest power of two - * @n - parameter + * @n: parameter * * round the given value up to the nearest power of two * - the result is undefined when n == 0 @@ -173,7 +169,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n) /** * rounddown_pow_of_two - round the given value down to nearest power of two - * @n - parameter + * @n: parameter * * round the given value down to the nearest power of two * - the result is undefined when n == 0 @@ -186,6 +182,12 @@ unsigned long __rounddown_pow_of_two(unsigned long n) __rounddown_pow_of_two(n) \ ) +static inline __attribute_const__ +int __order_base_2(unsigned long n) +{ + return n > 1 ? ilog2(n - 1) + 1 : 0; +} + /** * order_base_2 - calculate the (rounded up) base 2 order of the argument * @n: parameter @@ -199,7 +201,11 @@ unsigned long __rounddown_pow_of_two(unsigned long n) * ob2(5) = 3 * ... and so on. */ - -#define order_base_2(n) ilog2(roundup_pow_of_two(n)) - +#define order_base_2(n) \ +( \ + __builtin_constant_p(n) ? ( \ + ((n) == 0 || (n) == 1) ? 0 : \ + ilog2((n) - 1) + 1) : \ + __order_base_2(n) \ +) #endif /* _LINUX_LOG2_H */ diff --git a/lib/crypt.c b/lib/crypt.c index 1bc19b4183..3c7e28507f 100755 --- a/lib/crypt.c +++ b/lib/crypt.c @@ -1,26 +1,19 @@ -#include -#include -#include -#include - -/* The crypt source code was ported from busybox sources pw_crypt */ - -/* Used by pw_encrypt_XXX.c */ -static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -static char* -to64(char *s, unsigned v, int n) -{ - while (--n >= 0) { - *s++ = ascii64[v & 0x3f]; - v >>= 6; - } - return s; -} +/* + * The crypt source code was ported from busybox sources pw_crypt, file + * libbb/pw_encrypt_sha.c + * + * 20191108rs: Update to Busybox commit 49ecee0 (Jan 24, 2017) + * Major cleanup, provide missing functions + */ /* SHA256 and SHA512-based Unix crypt implementation. * Released into the Public Domain by Ulrich Drepper . */ +#include +#include +#include +#include /* Prefix for optional rounds specification. */ static const char str_rounds[] = "rounds=%u$"; @@ -33,50 +26,98 @@ static const char str_rounds[] = "rounds=%u$"; /* Maximum number of rounds. */ #define ROUNDS_MAX 999999999 -char *sha_crypt(const char *key_data, const char *salt_data) +/* Missing busybox functions */ + +static char* to64(char *s, unsigned v, int n) +{ + static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + while (--n >= 0) { + *s++ = ascii64[v & 0x3f]; + v >>= 6; + } + return s; +} + +void* xzalloc(size_t size) +{ + void *ptr = malloc(size); + /* note: error check left out */ + + memset(ptr, 0, size); + return ptr; +} + +static char *xstrdup(const char *s) +{ + size_t len = strlen (s) + 1; + char *ret = malloc (len); + /* note: error check left out */ + + memcpy (ret, s, len); + return ret; +} + +#if 0 /* currently not required, see note below */ +static char *xstrndup(const char *s, size_t n) +{ + char *result; + size_t len = strlen (s); + if (n < len) + len = n; + printf("allocating %d bytes\n", len+1); + result = malloc (len + 1); + /* note: error check left out */ + result[len] = '\0'; + memcpy (result, s, len); + return (char *)result; +} +#endif + +char *sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) { void (*sha_begin)(void *ctx); void (*sha_hash)(void *ctx, const void *buffer, size_t len); - void* (*sha_end)( void *ctx, void *resbuf); + void (*sha_end)(void *ctx, void *resbuf); int _32or64; char *result, *resptr; /* btw, sha256 needs [32] and uint32_t only */ - unsigned char alt_result[64] __attribute__((__aligned__(__alignof__(uint64_t)))); - unsigned char temp_result[64] __attribute__((__aligned__(__alignof__(uint64_t)))); - union { - sha256_context x; - #if 0 - sha512_ctx_t y; - #endif - } ctx; - union { - sha256_context x; - #if 0 - sha512_ctx_t y; - #endif - } alt_ctx; + struct { + unsigned char alt_result[64]; + unsigned char temp_result[64]; + union { + sha256_context x; +/* sha512_ctx_t y; */ + } ctx; + union { + sha256_context x; +/* sha512_ctx_t y; */ + } alt_ctx; + } L; +#define alt_result (L.alt_result ) +#define temp_result (L.temp_result) +#define ctx (L.ctx ) +#define alt_ctx (L.alt_ctx ) unsigned salt_len; unsigned key_len; unsigned cnt; unsigned rounds; char *cp; - char is_sha512; - char *tmp; /* Analyze salt, construct already known part of result */ cnt = strlen(salt_data) + 1 + 43 + 1; - is_sha512 = salt_data[1]; - if (is_sha512 == '6') { - printf("SHA-512 is not supported yet"); - return 0; - /* cnt += 43; */ - } - result = resptr = malloc(cnt); /* will provide NUL terminator */ - memset(result, 0, cnt); + _32or64 = 32; + if (salt_data[1] == '6') { /* sha512 */ + _32or64 *= 2; /*64*/ + cnt += 43; + puts("SHA-512 is not supported"); + return 0; + } + result = resptr = xzalloc(cnt); /* will provide NUL terminator */ *resptr++ = '$'; - *resptr++ = is_sha512; + *resptr++ = salt_data[1]; *resptr++ = '$'; rounds = ROUNDS_DEFAULT; salt_data += 3; @@ -95,50 +136,41 @@ char *sha_crypt(const char *key_data, const char *salt_data) resptr += sprintf(resptr, str_rounds, rounds); } } - { - char *salt_end = strchr(salt_data, '$'); - if (salt_end != 0) { - salt_len = salt_end - salt_data; - } - else { - salt_len = strnlen(salt_data, SALT_LEN_MAX); - } - } - // salt_len = (int)strchrnul(salt_data, '$') - (int)salt_data; + + salt_len = (int)strchrnul(salt_data, '$') - (int)salt_data; if (salt_len > SALT_LEN_MAX) salt_len = SALT_LEN_MAX; /* xstrdup assures suitable alignment; also we will use it as a scratch space later. */ - tmp = malloc(strnlen(salt_data, 128)); - memcpy(tmp, salt_data, strnlen(salt_data, 128)); - salt_data = tmp; - //salt_data = xstrndup(salt_data, salt_len); + + /* NOTE: Something is wrong here. + * when bytes are reserved there is a problem later in + * the code and computations are incorrect. + * So far it is not clear what the root problem is. + * By not truncating the buffer the code works fine + */ +/* salt_data = xstrndup(salt_data, salt_len); */ + salt_data = xstrdup(salt_data); /* add "salt$" to result */ strcpy(resptr, salt_data); resptr += salt_len; *resptr++ = '$'; /* key data doesn't need much processing */ key_len = strlen(key_data); - tmp = malloc(strnlen(key_data, 256)); - memcpy(tmp, key_data, strnlen(key_data, 256)); - key_data = tmp; - // key_data = xstrdup(key_data); + key_data = xstrdup(key_data); /* Which flavor of SHAnnn ops to use? */ sha_begin = (void*)sha256_starts; sha_hash = (void*)sha256_update; sha_end = (void*)sha256_finish; - _32or64 = 32; - /* Not supported */ #if 0 - if (is_sha512 == '6') { + /* SHA512 not supported */ + if (_32or64 != 32) { sha_begin = (void*)sha512_begin; sha_hash = (void*)sha512_hash; sha_end = (void*)sha512_end; - _32or64 = 64; } #endif - /* Add KEY, SALT. */ sha_begin(&ctx); sha_hash(&ctx, key_data, key_len); @@ -230,35 +262,30 @@ char *sha_crypt(const char *key_data, const char *salt_data) sha_end(&ctx, alt_result); } - /* Append encrypted password to result buffer */ //TODO: replace with something like // bb_uuencode(cp, src, length, bb_uuenc_tbl_XXXbase64); #define b64_from_24bit(B2, B1, B0, N) \ -do { \ - unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \ - resptr = to64(resptr, w, N); \ +do { \ + unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \ + resptr = to64(resptr, w, N); \ } while (0) - if (is_sha512 == '5') { + if (_32or64 == 32) { /* sha256 */ unsigned i = 0; - unsigned j = 10; - unsigned k = 20; - /* strange swap of one byte (see below why) */ - unsigned char alt_result_31 = alt_result[31]; - alt_result[31] = alt_result[1]; while (1) { + unsigned j = i + 10; + unsigned k = i + 20; + if (j >= 30) j -= 30; + if (k >= 30) k -= 30; b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4); - if (i == 9) + if (k == 29) break; - i += 21; i = (((i >> 4) & 2) + i) & 0x1f; - j += 21; j = (((j >> 4) & 2) + j) & 0x1f; - k += 21; k = (((k >> 4) & 2) + k) & 0x1f; + i = k + 1; } - b64_from_24bit(0, alt_result_31, alt_result[30], 3); + b64_from_24bit(0, alt_result[31], alt_result[30], 3); /* was: b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4); b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4); - ...............................^^^^^^^^^^^^^ why [1] and not [31]? b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4); b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4); b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4); @@ -271,15 +298,15 @@ do { \ */ } else { unsigned i = 0; - unsigned j = 21; - unsigned k = 42; while (1) { + unsigned j = i + 21; + unsigned k = i + 42; + if (j >= 63) j -= 63; + if (k >= 63) k -= 63; b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4); - if (i == 62) + if (j == 20) break; - i += 22; i = ((i >> 6) + i) & 0x3f; - j += 22; j = ((j >> 6) + j) & 0x3f; - k += 22; k = ((k >> 6) + k) & 0x3f; + i = j + 1; } b64_from_24bit(0, 0, alt_result[63], 2); /* was: @@ -309,21 +336,19 @@ do { \ } /* *resptr = '\0'; - xzalloc did it */ #undef b64_from_24bit - /* Clear the buffer for the intermediate result so that people attaching to processes or reading core dumps cannot get any information. */ - memset(temp_result, 0, sizeof(temp_result)); - memset(alt_result, 0, sizeof(alt_result)); - memset(&ctx, 0, sizeof(ctx)); - memset(&alt_ctx, 0, sizeof(alt_ctx)); + memset(&L, 0, sizeof(L)); /* [alt]_ctx and XXX_result buffers */ memset(key_data, 0, key_len); /* also p_bytes */ memset(salt_data, 0, salt_len); /* also s_bytes */ free(key_data); free(salt_data); #undef p_bytes #undef s_bytes - return result; +#undef alt_result +#undef temp_result +#undef ctx +#undef alt_ctx } - diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 745cb93050..c1e69792fd 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -743,7 +743,7 @@ int conf_write(const char *name) struct menu *menu; const char *basename; const char *str; - char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; + char dirname[PATH_MAX+1], tmpname[PATH_MAX+14], newname[PATH_MAX+8]; char *env; dirname[0] = 0;