ADD: [hw14] added hw14 platform to support new mc board

BugzId: 66150
This commit is contained in:
Marcel Reichmuth 2021-03-22 13:11:06 +01:00
parent 21fb3f581f
commit 1ffa09d30f
54 changed files with 3613 additions and 1753 deletions

View File

@ -617,9 +617,6 @@ KBUILD_AFLAGS += -Wa,-gstabs,-S
endif endif
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 include scripts/Makefile.extrawarn
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments

View File

@ -83,6 +83,7 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
tegra210-p2571.dtb tegra210-p2571.dtb
dtb-$(CONFIG_ARCH_MVEBU) += \ dtb-$(CONFIG_ARCH_MVEBU) += \
armada-385-hw14.dtb \
armada-385-nbhw18-v2.dtb \ armada-385-nbhw18-v2.dtb \
armada-385-nbhw17-v1.dtb \ armada-385-nbhw17-v1.dtb \
armada-3720-db.dtb \ armada-3720-db.dtb \

View File

@ -0,0 +1,240 @@
/*
* Device Tree file for the NetModule HW14 (NB3800)
*
* Copyright (C) 2021 NetModule
*
* Stefan Eichenberger <stefan.eichenberger@netmodule.com>
*
* 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 <dt-bindings/gpio/gpio.h>
/ {
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 = &eth0;
ethernet1 = &eth1;
ethernet2 = &eth2;
/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 = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
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 (CS0) */
MBUS_ID(0x01, 0x3d) 0 0xf4000000 0x20000>; /* GPIO Ext (CS1) */
gpioext: gpio@f40000000 {
compatible = "nm,nbhw-gpio-ext";
reg = <MBUS_ID(0x01, 0x3d) 0 0x20000>; /* 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 = <MBUS_ID(0x01, 0x3e) 0 0x20000>; /* 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)
&eth0 { /* ethernet@70000 */
status = "okay";
phy-mode = "mii";
fixed-link {
speed = <100>;
full-duplex;
};
};
// MAC1 is used for SGMII (1 GBit/s switches on NB3800)
&eth1 { /* 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>;
};

View File

@ -0,0 +1,40 @@
/*
* Device Tree file for the NetModule HW14 (NB3800) base variant
*
* Copyright (C) 2020 NetModule
*
* Stefan Eichenberger <stefan.eichenberger@netmodule.com>
*
* 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;
};
};
};
};
&eth0 {
status = "okay";
};
&eth1 {
status = "okay";
};

View File

@ -0,0 +1,20 @@
/*
* Device Tree file for the NetModule NBHW18-V2 (NB1800) base variant
*
* Copyright (C) 2016 NetModule
*
* Stefan Eichenberger <stefan.eichenberger@netmodule.com>
*
* 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)";
};

View File

@ -1,7 +1,7 @@
/* /*
* Device Tree file for the NetModule NBHW17 (NB2800) * Device Tree file for the NetModule NBHW17 (NB2800)
* *
* Copyright (C) 2016 NetModule * Copyright (C) 2021 NetModule
* *
* Stefan Eichenberger <stefan.eichenberger@netmodule.com> * Stefan Eichenberger <stefan.eichenberger@netmodule.com>
* *
@ -21,10 +21,8 @@
/* So that mvebu u-boot can update the MAC addresses */ /* So that mvebu u-boot can update the MAC addresses */
ethernet1 = &eth1; ethernet1 = &eth1;
ethernet2 = &eth2; ethernet2 = &eth2;
}; /delete-property/ gpio0; /* Causes warnings when requesting gpios */
/delete-property/ gpio1; /* Causes warnings when requesting gpios */
chosen {
stdout-path = "serial1:115200n8";
}; };
memory { memory {
@ -37,7 +35,16 @@
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000 MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000 /* CESA 0 SRAM */ MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000 /* CESA 0 SRAM */
MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 /* CESA 1 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 { gpiofpga: gpio@fd0000000 {
compatible = "nm,nbhw-fpga"; compatible = "nm,nbhw-fpga";
@ -46,13 +53,12 @@
gpio-controller; gpio-controller;
gpio-bank-name = "FPGA"; gpio-bank-name = "FPGA";
#gpio-cells = <2>; #gpio-cells = <2>;
spi-ss = <&gpio1 5 0>; /* SS */ spi-sck = <&gpio1 7 GPIO_ACTIVE_HIGH 0>; /* SCK (MPP39) */
spi-sdo = <&gpio1 6 0>; /* SDO slave data out */ spi-sdi = <&gpio1 8 GPIO_ACTIVE_HIGH 0>; /* SDI slave data in (MPP40) */
spi-sck = <&gpio1 7 0>; /* SCK */ spi-ss = <&gpio1 5 GPIO_ACTIVE_HIGH 0>; /* SS (MPP37) */
spi-sdi = <&gpio1 8 0>; /* SDI slave data in */ fpga-reset = <&gpio0 26 GPIO_ACTIVE_HIGH 0>; /* FPGA config reset */
fpga-reset = <&gpio0 26 0>; /* FPGA reset */ fpga-cdone = <&gpio0 29 GPIO_ACTIVE_HIGH 0>; /* FPGA cdone */
fpga-cdone = <&gpio0 29 0>; /* FPGA cdone */ fpga-reset-logic = <&gpio1 12 GPIO_ACTIVE_HIGH 0>; /* FPGA logic reset */
fpga-reset-logic = <&gpio1 12 0>; /* FPGA reset logic (after load)*/
}; };
fpga_conf: fpgaconf@0 { fpga_conf: fpgaconf@0 {
@ -64,28 +70,15 @@
<&gpiofpga 268 0>, <&gpiofpga 269 0>, <&gpiofpga 270 0>, <&gpiofpga 268 0>, <&gpiofpga 269 0>, <&gpiofpga 270 0>,
<&gpiofpga 271 0>; <&gpiofpga 271 0>;
misc@0 { // pcie slot 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>;
};
pcieslot@0 { pcieslot@0 {
reset = <&gpiofpga 384 GPIO_ACTIVE_LOW 1>; reset = <&gpiofpga 384 GPIO_ACTIVE_LOW 1>;
power = <&gpiofpga 400 GPIO_ACTIVE_HIGH 0>; power = <&gpiofpga 400 GPIO_ACTIVE_HIGH 0>;
wdis-out = <&gpiofpga 2053 GPIO_ACTIVE_HIGH 1>; 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 { pcieslot@1 {
reset = <&gpiofpga 385 GPIO_ACTIVE_LOW 1>; reset = <&gpiofpga 385 GPIO_ACTIVE_LOW 1>;
power = <&gpiofpga 401 GPIO_ACTIVE_HIGH 0>; power = <&gpiofpga 401 GPIO_ACTIVE_HIGH 0>;
@ -93,6 +86,7 @@
wdis = <&gpiofpga 4117 GPIO_ACTIVE_LOW 1>; wdis = <&gpiofpga 4117 GPIO_ACTIVE_LOW 1>;
}; };
// pcie slot 2
pcieslot@2 { pcieslot@2 {
reset = <&gpiofpga 386 GPIO_ACTIVE_LOW 1>; reset = <&gpiofpga 386 GPIO_ACTIVE_LOW 1>;
power = <&gpiofpga 402 GPIO_ACTIVE_HIGH 0>; power = <&gpiofpga 402 GPIO_ACTIVE_HIGH 0>;
@ -100,6 +94,7 @@
wdis = <&gpiofpga 6165 GPIO_ACTIVE_LOW 1>; wdis = <&gpiofpga 6165 GPIO_ACTIVE_LOW 1>;
}; };
// pcie slot 3
pcieslot@3 { pcieslot@3 {
reset = <&gpiofpga 387 GPIO_ACTIVE_LOW 1>; reset = <&gpiofpga 387 GPIO_ACTIVE_LOW 1>;
power = <&gpiofpga 403 GPIO_ACTIVE_HIGH 0>; power = <&gpiofpga 403 GPIO_ACTIVE_HIGH 0>;
@ -128,14 +123,6 @@
status = "disabled"; status = "disabled";
}; };
sdhci@d8000 {
broken-cd;
wp-inverted;
no-1-8-v;
bus-width = <8>;
status = "okay";
};
serial@12000 { serial@12000 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>; pinctrl-0 = <&uart0_pins>;
@ -146,8 +133,12 @@
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart1_pins>; pinctrl-0 = <&uart1_pins>;
u-boot,dm-pre-reloc; u-boot,dm-pre-reloc;
status = "okay";
}; };
usb@58000 {
status = "okay";
};
}; };
pcie-controller { pcie-controller {

View File

@ -0,0 +1,40 @@
/*
* Device Tree file for the NetModule NBHW17 (NB2800) base variant
*
* Copyright (C) 2021 NetModule
*
* Stefan Eichenberger <stefan.eichenberger@netmodule.com>
*
* 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;
};
};
};
};
&eth1 {
status = "okay";
};
&eth2 {
status = "okay";
};

View File

@ -15,6 +15,9 @@
/ { / {
model = "NetModule Router NBHW17 with Armada A385 (NB2800)"; model = "NetModule Router NBHW17 with Armada A385 (NB2800)";
// chosen {
// stdout-path = "serial1:115200n8";
// };
}; };
&eth1 { &eth1 {

0
arch/arm/dts/armada-385-nbhw18-v2.dts Executable file → Normal file
View File

View File

@ -88,9 +88,9 @@ config TARGET_DB_88F6820_GP
bool "Support DB-88F6820-GP" bool "Support DB-88F6820-GP"
select 88F6820 select 88F6820
config TARGET_NM_NBHW18_V1 config TARGET_NM_HW14
bool "Support NBHW18 V1" bool "Support HW14"
select 88F6820 select 88F6820
config TARGET_NM_NBHW18_V2 config TARGET_NM_NBHW18_V2
bool "Support NBHW18 V2" bool "Support NBHW18 V2"
@ -154,6 +154,7 @@ config SYS_BOARD
default "ds414" if TARGET_DS414 default "ds414" if TARGET_DS414
default "maxbcm" if TARGET_MAXBCM default "maxbcm" if TARGET_MAXBCM
default "theadorable" if TARGET_THEADORABLE default "theadorable" if TARGET_THEADORABLE
default "hw14" if TARGET_NM_HW14
default "nbhw18_v1" if TARGET_NM_NBHW18_V1 default "nbhw18_v1" if TARGET_NM_NBHW18_V1
default "nbhw18_v2" if TARGET_NM_NBHW18_V2 default "nbhw18_v2" if TARGET_NM_NBHW18_V2
default "nbhw17_v1" if TARGET_NM_NBHW17_V1 default "nbhw17_v1" if TARGET_NM_NBHW17_V1
@ -170,6 +171,7 @@ config SYS_CONFIG_NAME
default "maxbcm" if TARGET_MAXBCM default "maxbcm" if TARGET_MAXBCM
default "theadorable" if TARGET_THEADORABLE default "theadorable" if TARGET_THEADORABLE
default "turris_omnia" if TARGET_TURRIS_OMNIA 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-nbhw18-v2" if TARGET_NM_NBHW18_V2
default "armada-385-nbhw17-v1" if TARGET_NM_NBHW17_V1 default "armada-385-nbhw17-v1" if TARGET_NM_NBHW17_V1
@ -183,6 +185,7 @@ config SYS_VENDOR
default "solidrun" if TARGET_CLEARFOG default "solidrun" if TARGET_CLEARFOG
default "Synology" if TARGET_DS414 default "Synology" if TARGET_DS414
default "CZ.NIC" if TARGET_TURRIS_OMNIA 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_V1
default "nm" if TARGET_NM_NBHW18_V2 default "nm" if TARGET_NM_NBHW18_V2
default "nm" if TARGET_NM_NBHW17_V1 default "nm" if TARGET_NM_NBHW17_V1

View File

@ -18,8 +18,9 @@
static struct mbus_win windows[] = { static struct mbus_win windows[] = {
/* SPI */ /* SPI */
{ MBUS_SPI_BASE, MBUS_SPI_SIZE, /* @@NM@@MR@@ Conflicts with the windows for the HW14 gpio extension */
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH }, /*{ MBUS_SPI_BASE, MBUS_SPI_SIZE,
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH }, */
/* NOR */ /* NOR */
{ MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE, { MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE,

View File

@ -27,7 +27,7 @@
#include "nbhw_bd.h" #include "nbhw_bd.h"
static const BD_Context *bdctx_list; /* The board descriptor context */ 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) { void bd_register_context_list(const BD_Context *list, size_t count) {
bdctx_list = list; 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) int bd_get_context(BD_Context *bdctx, uint32_t i2caddress, uint32_t offset)
{ {
bd_bool_t rc; bd_bool_t rc;
uint8_t bdHeader[8]; uint8_t bdHeader[8];
void* pBdData = NULL; void* pBdData = NULL;
/* Read header bytes from beginning of EEPROM */ /* Read header bytes from beginning of EEPROM */
if (i2c_read( i2caddress, offset, 2, bdHeader, BD_HEADER_LENGTH )) { if (i2c_read( i2caddress, offset, 2, bdHeader, BD_HEADER_LENGTH )) {
printf("%s() Can't read BD header from EEPROM\n", __func__); printf("%s() Can't read BD header from EEPROM\n", __func__);

View File

@ -21,6 +21,7 @@ void set_console(void)
char buf[6]; char buf[6];
char consolefile[] = "/root/boot/consoledev"; char consolefile[] = "/root/boot/consoledev";
char *defaultconsole = env_get("defaultconsole"); char *defaultconsole = env_get("defaultconsole");
int use_default_console = 0;
#if defined(CONFIG_PRE_CONSOLE_BUFFER) #if defined(CONFIG_PRE_CONSOLE_BUFFER)
int len = 0; int len = 0;
@ -28,17 +29,28 @@ void set_console(void)
read_file_set_blk_dev("mmc", "0:3", FS_TYPE_EXT); read_file_set_blk_dev("mmc", "0:3", FS_TYPE_EXT);
len = get_file_size(consolefile); len = get_file_size(consolefile);
if (len>=5) { if (len>=4) {
read_file(consolefile, buf, sizeof(buf)); memset(buf, 0x00, sizeof(buf));
buf[sizeof(buf)-1] = 0; read_file(consolefile, buf, sizeof(buf)-1);
if ((strstr(buf, "tty")!=buf) || ((buf[4]<'0') && (buf[4]>'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; buf[0] = 0;
} else {
/* invalid device specified */
use_default_console = 1;
} }
} else { } else {
buf[0] = 0; use_default_console = 1;
} }
if (buf[0] == 0) { if (use_default_console) {
strncpy(buf, defaultconsole, sizeof(buf)); strncpy(buf, defaultconsole, sizeof(buf));
} }
printf("consoledev: %s\n", buf); printf("consoledev: %s\n", buf);

View File

@ -51,7 +51,9 @@ struct nbhw_fpga_priv {
struct gpio_desc ss; struct gpio_desc ss;
struct gpio_desc sck; struct gpio_desc sck;
struct gpio_desc sdi; struct gpio_desc sdi;
#ifdef CONFIG_FPGA_LATTICE_SSPI
struct gpio_desc sdo; struct gpio_desc sdo;
#endif
struct gpio_desc reset; struct gpio_desc reset;
struct gpio_desc reset_logic; struct gpio_desc reset_logic;
struct gpio_desc cdone; struct gpio_desc cdone;
@ -72,6 +74,8 @@ void tickdelay(void)
while (get_ticks() < curtick+1); /* loop till event */ 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) static inline u8 spi_read_sspi(const struct nbhw_fpga_priv *priv)
{ {
int i; 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) static inline void spi_write(const struct nbhw_fpga_priv *priv, u8 data)
{ {
int i; 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; data_write = (data & 0x80) ? 1 : 0;
/* Clear clk bit and put data on the line */ /* Clear clk bit and put data on the line */
dm_gpio_set_value(&priv->sck, 0); dm_gpio_set_value(&priv->sck, 0);
dm_gpio_set_value(&priv->sdi, data_write); dm_gpio_set_value(&priv->sdi, data_write);
udelay(1); tickdelay();
/* Read data on rising edge */ /* Read data on rising edge */
dm_gpio_set_value(&priv->sck, 1); dm_gpio_set_value(&priv->sck, 1);
data = data << 1; data = data << 1;
udelay(1); tickdelay();
} }
} }
@ -153,19 +159,19 @@ static int fpga_verify(struct nbhw_fpga_priv *priv)
if (signature == 0xa501) if (signature == 0xa501)
{ {
strcpy(fpga_type, "XC3S50A-4VQ100I top layer"); strcpy(fpga_type, "XC3S50A-4VQ100I top layer HW14");
} else if (signature == 0xa502) { } else if (signature == 0xa502) {
strcpy(fpga_type, "XC3S200A-4VQ100I top layer"); strcpy(fpga_type, "XC3S200A-4VQ100I top layer HW14");
} else if (signature == 0xa511) { } else if (signature == 0xa511) {
strcpy(fpga_type, "XC3S50A-4FTG256I bottom layer"); strcpy(fpga_type, "XC3S50A-4FTG256I bottom layer HW14");
} else if (signature == 0xa512) { } else if (signature == 0xa512) {
strcpy(fpga_type, "XC3S200A-4FTG256I bottom layer"); strcpy(fpga_type, "XC3S200A-4FTG256I bottom layer HW14");
} else if (signature == 0x4004) { } else if (signature == 0x4004) {
strcpy(fpga_type, "ICE40HX4K-CB132 NBHW17"); strcpy(fpga_type, "ICE40HX4K-CB132 HW17");
} else if (signature == 0x4184) { } else if (signature == 0x4184) {
strcpy(fpga_type, "ICE40HX4K-CB132 NBHW18 V1"); strcpy(fpga_type, "ICE40HX4K-CB132 HW18 V1");
} else if (signature == 0x012f) { } else if (signature == 0x012f) {
strcpy(fpga_type, "LFE5U-12F-6BG381I NBHW18 V2"); strcpy(fpga_type, "LFE5U-12F-6BG381I HW18 V2");
} else { } else {
priv->signature = signature; priv->signature = signature;
goto abort; goto abort;
@ -183,6 +189,8 @@ abort:
return 0; return 0;
} }
#ifdef CONFIG_FPGA_LATTICE_SSPI
#define print_out_string printf #define print_out_string printf
extern unsigned int a_uiRowCount; extern unsigned int a_uiRowCount;
void printError(int code){ 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) static void put_in_prog_mode(const struct nbhw_fpga_priv *priv)
{ {
/* Change the muxing to GPIO */ /* 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"); printf("Put FPGA in programming mode\n");
dm_gpio_set_value(&priv->ss, 1); dm_gpio_set_value(&priv->ss, 1);
udelay(10); udelay(10);
dm_gpio_set_value(&priv->ss, 0); dm_gpio_set_value(&priv->ss, 0);
dm_gpio_set_value(&priv->sck, 1); dm_gpio_set_value(&priv->sck, 1);
dm_gpio_set_value(&priv->reset, 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); udelay(800);
} }
#ifdef CONFIG_FPGA_LATTICE_SSPI
static void put_in_prog_mode_lattice_sspi(const struct nbhw_fpga_priv *priv) static void put_in_prog_mode_lattice_sspi(const struct nbhw_fpga_priv *priv)
{ {
/* Change the muxing to GPIO */ /* 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"); debug("Initialised Reset with pulling PROGRAM~\n");
} }
#endif
static void clean_up_after_programming(const struct nbhw_fpga_priv *priv) static void clean_up_after_programming(const struct nbhw_fpga_priv *priv)
{ {
/* Change the muxing back to Devbus */ /* Change the muxing back to Devbus */
writel(0x55555555, MVEBU_MPP_BASE + 0x10); writel(0x55555555, MVEBU_MPP_BASE + 0x10);
writel(0x06605505, MVEBU_MPP_BASE + 0x14); 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); udelay(100);
dm_gpio_set_value(&priv->reset_logic, 1); dm_gpio_set_value(&priv->reset_logic, 1);
udelay(100); udelay(100);
@ -326,13 +341,6 @@ static int fpga_load_bitstream (const struct nbhw_fpga_priv *priv, const u8* dat
debug("Configuration sent\n"); 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 */ /* Send some extra clocks for startup */
for ( i=0; i<100; i++) 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; 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, static int fpga_check_bitstream_lattice(const struct nbhw_fpga_priv *priv,
const u8* fpgadata, int dataNumBytes, const u8* fpgadata, int dataNumBytes,
const u8** pBitstreamAddr, int* pBitstreamSize) const u8** pBitstreamAddr, int* pBitstreamSize)
@ -384,6 +373,23 @@ static int fpga_check_bitstream_lattice(const struct nbhw_fpga_priv *priv,
return 0; 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) \ #define CHECKMARKER(index, a, b, c, d) ((fpgadata[index]==a) && (fpgadata[index+1]==b) \
&& (fpgadata[index+2]==c) && (fpgadata[index+3]==d)) && (fpgadata[index+2]==c) && (fpgadata[index+3]==d))
@ -432,6 +438,8 @@ abort:
return -1; return -1;
} }
#endif
/* Legacy Xilinx check ported from PPC, seems to work */ /* Legacy Xilinx check ported from PPC, seems to work */
static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv, static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv,
const u8* fpgadata, int dataNumBytes, 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); printf(" design filename = \"%s\"\n", buffer);
/* verify fpga identifier */
if (priv->fpga_id == 0xFFFFFFFF) {
return 0;
}
p = strstr(buffer, "UserID=0x"); p = strstr(buffer, "UserID=0x");
if (p) { if (p) {
p += 9; p += 9;
@ -496,10 +500,13 @@ static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv,
return -1; return -1;
} }
} }
if (fpgaid != priv->fpga_id) { /* verify fpga identifier */
printf("%s: User identifier not matched in bitstream\n", if (priv->fpga_id != 0xFFFFFFFF) {
__FUNCTION__ ); if (fpgaid != priv->fpga_id) {
return -1; printf("%s: User identifier not matched in bitstream\n",
__FUNCTION__ );
return -1;
}
} }
} else { } else {
printf("%s: User identifier not found in bitstream\n", 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], debug("check bitstream %d, %0x, %0x\n", *pBitstreamSize, fpgadata[0],
fpgadata[1]); fpgadata[1]);
/* Lattice header starts with 0xFF00 followed by comment */ /* Lattice header starts with 0xFF00 followed by comment */
if (fpgadata[0] == 0xFF && fpgadata[1] == 0x00) { if (fpgadata[0] == 0xFF && fpgadata[1] == 0x00) {
return fpga_check_bitstream_lattice(priv, fpgadata, dataNumBytes, pBitstreamAddr, pBitstreamSize); 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) */ /* Lattice SSPI header starts with 0xae 0x00 0x00 0x01 (SEA tag) */
else if(fpgadata[0] == 0xae && fpgadata[1] == 0x00) { else if(fpgadata[0] == 0xae && fpgadata[1] == 0x00) {
return fpga_check_bitstream_lattice_sspi(priv, fpgadata, dataNumBytes, return fpga_check_bitstream_lattice_sspi(priv, fpgadata, dataNumBytes,
pBitstreamAddr, pBitstreamSize, pBitstreamAddr, pBitstreamSize,
pAlgoAddr, pAlgoSize); pAlgoAddr, pAlgoSize);
} }
#else
/* Xilinx header starts with 0x00 0x09 which means header with 0x09 length */ /* 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); return fpga_check_bitstream_xilinx(priv, fpgadata, dataNumBytes, pBitstreamAddr, pBitstreamSize);
} }
#endif
printf("Unknown bitstream file format (not Xilinx nor Lattice)\n"); printf("Unknown bitstream file format (not Xilinx nor Lattice)\n");
return -1; return -1;
} }
@ -675,7 +685,7 @@ static void setup_device_bus(void)
/* Device Bus Control Interface Register */ /* Device Bus Control Interface Register */
val = readl(MV_DEV_BUS_REGS_OFFSET + 0xC0); 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); writel(0x5FFFF, MV_DEV_BUS_REGS_OFFSET + 0xC0);
/* Device Bus Synchronous Control Register */ /* Device Bus Synchronous Control Register */
val = readl(MV_DEV_BUS_REGS_OFFSET + 0xC8); 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"); printf("Could not request spi-gpio sdi\n");
return -1; return -1;
} }
#ifdef CONFIG_FPGA_LATTICE_SSPI
if (gpio_request_by_name(dev, "spi-sdo", 0, &priv->sdo, GPIOD_IS_IN) != 0) { if (gpio_request_by_name(dev, "spi-sdo", 0, &priv->sdo, GPIOD_IS_IN) != 0) {
printf("Could not request spi-gpio sdo\n"); printf("Could not request spi-gpio sdo\n");
return -1; return -1;
} }
#endif
if (gpio_request_by_name(dev, "fpga-reset", 0, &priv->reset, GPIOD_IS_OUT) != 0) { if (gpio_request_by_name(dev, "fpga-reset", 0, &priv->reset, GPIOD_IS_OUT) != 0) {
printf("Could not request fpga-reset\n"); debug("Could not request fpga-reset\n");
return -1;
} }
if (gpio_request_by_name(dev, "fpga-cdone", 0, &priv->cdone, GPIOD_IS_IN) != 0) { 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 */ /* NBHW_BASE_ADDRESS_FPGA points to base of FPGA registers */
if (!fpga_boot_buffer(priv, (const u8*)load_addr, filesize)) { if (!fpga_boot_buffer(priv, (const u8*)load_addr, filesize)) {
printf ("Loading FPGA over SPI failed.\n"); printf ("Loading FPGA over SPI failed.\n");
return -3; return -3;
} }
/* Make sure device bus works, becaus NBHW14 uses its gpios to do SPI */
setup_device_bus();
/* Verify, if FPGA is loaded successfully */ /* Verify, if FPGA is loaded successfully */
i = 0; i = 0;
do { do {
@ -1032,6 +1042,7 @@ U_BOOT_DRIVER(gpio_nbhw_fpga) = {
.ops = &nbhw_fpga_ops, .ops = &nbhw_fpga_ops,
}; };
#ifdef CONFIG_FPGA_LATTICE_SSPI
/* Lattice SSPI programming tool wrappers */ /* Lattice SSPI programming tool wrappers */
void FPGA_START(void) { void FPGA_START(void) {
@ -1060,3 +1071,4 @@ void FPGA_CS_HIGH(void)
dm_gpio_set_value(&FPGA_PRIV->ss, 1); dm_gpio_set_value(&FPGA_PRIV->ss, 1);
} }
#endif

View File

@ -6,16 +6,16 @@
#define FPGA_REG(x) *((volatile unsigned short*)( NBHW_BASE_ADDRESS_FPGA + ((unsigned int)x))) #define FPGA_REG(x) *((volatile unsigned short*)( NBHW_BASE_ADDRESS_FPGA + ((unsigned int)x)))
typedef enum _fpga_type { typedef enum _fpga_type {
FPGA_TYPE_NONE, FPGA_TYPE_NONE,
FPGA_TYPE_XILINX, FPGA_TYPE_XILINX,
FPGA_TYPE_LATTICE, FPGA_TYPE_LATTICE,
}fpga_type; }fpga_type;
typedef struct _fpga_prog_operation { typedef struct _fpga_prog_operation {
void (*pre_programming)(void); void (*pre_programming)(void);
void (*post_programming)(void); void (*post_programming)(void);
void (*spi_write)(u8); void (*spi_write)(u8);
int (*check_bitstream_compatibility)(fpga_type, u32); int (*check_bitstream_compatibility)(fpga_type, u32);
} fpga_prog_operation; } fpga_prog_operation;
int nbhw_fpga_program(void); int nbhw_fpga_program(void);

View File

@ -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 <common.h>
#include <dm.h>
#include <dm/device.h>
#include <asm/types.h>
#include <asm/gpio.h>
#include <asm/io.h>
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,
};

View File

@ -34,7 +34,7 @@ static void set_mac(int interface, uint8_t macaddress[], size_t size)
/* Serial number consists of 1st MAC address */ /* Serial number consists of 1st MAC address */
env_set("ethaddr", macstring); 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]; 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]; uint8_t macaddress[6];
int i;
/* If the compiler does inlining direct initialization of macaddress /* If the compiler does inlining direct initialization of macaddress
* fails, this is the safer way */ * fails, this is the safer way */
memset(macaddress, 0x11, sizeof(macaddress)); memset(macaddress, 0x11, sizeof(macaddress));
for (i = 0; i < interfaces; i++) { if (bd_get_mac(mac, macaddress, 6) == 0)
if(bd_get_mac(i, macaddress, 6) == 0) set_mac(interface, macaddress, 6);
set_mac(i, macaddress, 6); else {
else { /* make temporary address */
/* make temporary address */ macaddress[0] = 0;
macaddress[0] = 0; macaddress[5] += 1;
macaddress[5] += 1; set_mac(interface, macaddress, 6);
set_mac(i, macaddress, 6);
}
} }
} }

View File

@ -8,6 +8,6 @@
#ifndef _NBHW_INIT_H #ifndef _NBHW_INIT_H
#define _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 #endif // _NBHW_INIT_H

View File

@ -81,7 +81,7 @@ static int has_slot_wlan(int slot)
char pdValue[200]; char pdValue[200];
sprintf(slotDescr, "slot=%d", slot); sprintf(slotDescr, "slot=%d", slot);
for (module=0; module<4; module++) { for (module=0; module<6; module++) {
strcpy(pdValue, "" ); /*init with an empty string*/ strcpy(pdValue, "" ); /*init with an empty string*/
if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) { if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) {
/* Wifi module needs PCIe */ /* Wifi module needs PCIe */
@ -127,7 +127,6 @@ static int has_pcie_link_on_slot(int slot)
default: default:
printf("Slot %d does not support PCIE\n", slot); printf("Slot %d does not support PCIE\n", slot);
} }
return 1; return 1;
} }
@ -227,7 +226,7 @@ static void wait_for_reset(int reset_counter)
* boot */ * boot */
static int do_wlan_fixup(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 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 #define MAX_RESET_COUNT 6
int reset_counter = get_reset_counter(); int reset_counter = get_reset_counter();
int ret; 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 */ /* Try it for at least one second */
for (i = 0; i < 100; i++) { for (i = 0; i < 100; i++) {
ret = 3; ret = 0x3f;
if (check_pcie_slot_status(0)) ret &= ~1; for (j = 0; j < 6; j++) {
if (check_pcie_slot_status(j)) ret &= ~(1 << j);
if (check_pcie_slot_status(1)) ret &= ~2; }
if (is_module_check_abort()) { if (is_module_check_abort()) {
puts("Abort WLAN module check\n"); puts("Abort WLAN module check\n");
ret = 0; ret = 0;

View File

@ -0,0 +1,6 @@
DB_88F6820_GP BOARD
M: Stefan Roese <sr@denx.de>
S: Maintained
F: board/Marvell/db-88f6820-gp/
F: include/configs/db-88f6820-gp.h
F: configs/db-88f6820-gp_defconfig

30
board/nm/hw14/Makefile Normal file
View File

@ -0,0 +1,30 @@
#
# Copyright (C) 2015 Stefan Roese <sr@denx.de>
#
# 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

18
board/nm/hw14/README Normal file
View File

@ -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

839
board/nm/hw14/board.c Normal file
View File

@ -0,0 +1,839 @@
/*
* Copyright (C) 2015 Stefan Roese <sr@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#undef DEBUG
#include <common.h>
#include <i2c.h>
#include <miiphy.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
#include <mmc.h>
#include <spl.h>
#include <linux/mbus.h>
#include <environment.h>
#include <fdt_support.h>
#include <dm.h>
#include <wdt.h>
#include <console.h> /* ctrlc */
#include <asm/gpio.h>
#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 <ARRAY_SIZE(board_serdes_map)))
{
return board_serdes_map[index].serdes_type;
} else {
return LAST_SERDES_TYPE;
}
}
static BD_Context bdctx[5]; /* The descriptor context */
static int _bd_init(void)
{
if (bd_get_context(&bdctx[0], CP_BD_EEPROM_ADDR, BD_ADDRESS) != 0) {
printf("%s() no valid cp bd found\n", __func__);
return -1;
}
if (bd_get_context(&bdctx[1], CP_BD_EEPROM_ADDR, PD_ADDRESS) != 0) {
/* Ignore that, legacy boxes don't have a pd */
}
if (bd_get_context(&bdctx[2], CP_BD_EEPROM_ADDR, PARTITION_ADDRESS) != 0) {
printf("%s() no valid partition table found\n", __func__);
}
if (bd_get_context(&bdctx[3], MC_BD_EEPROM_ADDR, BD_ADDRESS) != 0) {
printf("%s() no valid mc bd found\n", __func__);
}
if (bd_get_context(&bdctx[4], PSE_BD_EEPROM_ADDR, BD_ADDRESS) != 0) {
printf("%s() no valid pse bd 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(CP_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){
/* 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;
}

View File

@ -0,0 +1,12 @@
#
# Copyright (C) 2014 Stefan Roese <sr@denx.de>
#
# 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

178
board/nm/hw14/mvswitch.c Normal file
View File

@ -0,0 +1,178 @@
#undef DEBUG
#include <common.h>
#include <miiphy.h>
#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 10s 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;
}

14
board/nm/hw14/mvswitch.h Normal file
View File

@ -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

View File

@ -0,0 +1,234 @@
#undef DEBUG
#include <common.h>
#include <dm.h>
#include <dm/device.h>
#include <dm/ofnode.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <errno.h>
#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,
};

97
board/nm/hw14/nbhw_gpio.c Normal file
View File

@ -0,0 +1,97 @@
#include <common.h>
#include <asm/gpio.h>
#include <stdlib.h>
#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;
}

42
board/nm/hw14/nbhw_gpio.h Normal file
View File

@ -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

77
board/nm/hw14/nbhw_sim.c Normal file
View File

@ -0,0 +1,77 @@
#include <common.h>
#include <malloc.h>
#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;
}

View File

@ -16,9 +16,14 @@ commonobj = ../common/bdparser.o \
ccflags-y := -I../common ccflags-y := -I../common
ifndef CONFIG_SPL_BUILD 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 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 endif

View File

@ -3,7 +3,7 @@
* *
* SPDX-License-Identifier: GPL-2.0+ * SPDX-License-Identifier: GPL-2.0+
*/ */
#define DEBUG #undef DEBUG
#include <common.h> #include <common.h>
#include <i2c.h> #include <i2c.h>
#include <miiphy.h> #include <miiphy.h>
@ -15,6 +15,10 @@
#include <spl.h> #include <spl.h>
#include <linux/mbus.h> #include <linux/mbus.h>
#include <environment.h> #include <environment.h>
#include <fdt_support.h>
#include <dm.h>
#include <wdt.h>
#include <console.h> /* ctrlc */
#include <asm/gpio.h> #include <asm/gpio.h>
@ -24,38 +28,60 @@
#include "../common/nbhw_env.h" #include "../common/nbhw_env.h"
#include "../common/nbhw_bd.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> #include <../serdes/a38x/high_speed_env_spec.h>
//#define EARLY_CONSOLE_OUTPUT
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
/* /*
* Those values and defines are taken from the Marvell U-Boot version * Those values and defines are taken from the Marvell U-Boot version
* "u-boot-2013.01-2014_T3.0" * "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 BD_EEPROM_ADDR (0x50) /* CPU BD EEPROM (8kByte) is at 50 (A0) */
#define GPP_OUT_VAL_MID (~(BIT(9) | BIT(12) | BIT(15))) #define BD_ADDRESS (0x0000) /* Board descriptor at beginning of EEPROM */
#define GPP_POL_LOW (BIT(21)) /* 1=pin on */ #define PD_ADDRESS (0x0200) /* Product descriptor */
#define GPP_POL_MID 0x0 #define PARTITION_ADDRESS (0x0600) /* Partition Table */
#define SERDES_CONFIG_ADDRESS (0x0800) /* SERDES config address */
#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 DEV_CS0_BASE 0xfd000000 #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[] = { static struct serdes_map board_serdes_map[] = {
{ PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 }, { PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 },
{ SGMII1, SERDES_SPEED_1_25_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 }, { SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0 },
{ SGMII2, SERDES_SPEED_1_25_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 }, { 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) 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 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; *serdes_map_array = board_serdes_map;
*count = ARRAY_SIZE(board_serdes_map); *count = ARRAY_SIZE(board_serdes_map);
return 0; 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 * be used by the DDR3 init code in the SPL U-Boot version to configure
* the DDR3 controller. * 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 */ 0x1, /* active interfaces */
/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */ /* 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}, {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 */ SPEED_BIN_DDR_1600K, /* speed_bin */
BUS_WIDTH_16, /* memory_width */ MV_DDR_DEV_WIDTH_16BIT, /* sdram device width */
MEM_4G, /* mem_size */ MV_DDR_DIE_CAP_4GBIT, /* die capacity */
DDR_FREQ_667, /* frequency */ MV_DDR_FREQ_667, /* frequency */
7, 9, /* cas_l cas_wl */ 0, 0, /* cas_l cas_wl */
HWS_TEMP_HIGH} }, /* temperature */ MV_DDR_TEMP_HIGH} }, /* temperature */
5, /* Num Of Bus Per Interface*/ BUS_MASK_32BIT, /* subphys mask */
BUS_MASK_32BIT /* Busses 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 the board topology as defined in the board code */
return &board_topology_map; 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) int board_early_init_f(void)
{ {
/* Configure MPP */ /* Configure MPP */
@ -141,50 +417,22 @@ void spl_board_init(void)
int err; int err;
struct mmc *mmcp; struct mmc *mmcp;
err = mmc_initialize(NULL); err = mmc_initialize(0);
if (err) if (err)
return; return;
puts("SPL: select partition\n"); debug("SPL: select partition\n");
mmcp = find_mmc_device(0); mmcp = find_mmc_device(0);
mmc_init(mmcp); mmc_init(mmcp);
printf("Partition found: %p\n", 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); 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) 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); snprintf(new_env, sizeof(new_env), "%s %s", old_env, hw_versions);
} }
else { 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); env_set("add_version_bootargs", new_env);
} }
#endif
int board_init(void) 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; 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, 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) if (read_eeprom() < 0)
puts("Could not get board ID.\n"); 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 /* @@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 * 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 * 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 * it back to this value address 0x64 is unused again. This is necessary because atsha204 uses 0x64 as
* slave address. * slave address.
*/ */
writel(0x00330010, INTER_REGS_BASE + 0x1108C); writel(0x00330010, SOC_REGS_PHY_BASE + 0x0001108c);
return 0; 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) static void set_phy_page(const char *miidev, int phy_addr, int page)
{ {
miiphy_write(miidev, phy_addr, 22, 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) static void set_phy_fast_blink_mode(int phy_addr)
{ {
const char *miidev = miiphy_get_current_dev(); const char *miidev = miiphy_get_current_dev();
int numRegs = 0;
debug ("miidev: %s\n", miidev); debug ("miidev: %s\n", miidev);
set_phy_page(miidev, phy_addr, 3); while (sSelectedPhyRegs[numRegs].reserved != -1) {
miiphy_write(miidev, phy_addr, 16, 0x1032); set_phy_page(miidev, phy_addr, sSelectedPhyRegs[numRegs].page);
miiphy_write(miidev, phy_addr, 17, 0x4405); miiphy_write(miidev, phy_addr, sSelectedPhyRegs[numRegs].reg, sSelectedPhyRegs[numRegs].data);
miiphy_write(miidev, phy_addr, 18, 0x4A08); numRegs++;
}
set_phy_page(miidev, phy_addr, 0); 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) int board_late_init(void)
{ {
#if !defined(CONFIG_SPL_BUILD)
gpio_request(21, "RST_ETH_PHY_N"); set_devicetree_name();
gpio_direction_output(21, 0); set_gpio(GPIO_RST_ETH_PHY, 1);
find_and_set_active_partition(); find_and_set_active_partition();
pass_hw_rev(); pass_hw_rev();
@ -267,29 +695,86 @@ int board_late_init(void)
/* Todo: It seems that something with the network is wrong */ /* Todo: It seems that something with the network is wrong */
run_command("run load_fpga", CMD_FLAG_ENV); 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); set_mac_addresses(2);
#endif
/* Take phy out of reset after FPGA was loaded */ /* Take phy out of reset after FPGA was loaded */
gpio_set_value(21, 1); set_gpio(GPIO_RST_ETH_PHY, 0);
return 0; return 0;
} }
#if !defined(CONFIG_SPL_BUILD)
int board_network_enable(struct mii_dev *bus) 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(0);
set_phy_fast_blink_mode(1); set_phy_fast_blink_mode(1);
return 0; return 0;
} }
#endif
int checkboard(void) int checkboard(void)
{ {
puts("Board: NetModule NBHW17\n"); debug("Board: NetModule NBHW17\n");
return 0; 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 pcie_lane_by_slot(int slot)
{ {
int serdes; int serdes;
@ -322,3 +807,91 @@ int pcie_lane_by_slot(int slot)
return -1; 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<numRegs; i++) {
pBigEndianPhyRegs[i].page = cpu_to_be32(pBigEndianPhyRegs[i].page);
pBigEndianPhyRegs[i].reg = cpu_to_be32(pBigEndianPhyRegs[i].reg);
pBigEndianPhyRegs[i].reserved = cpu_to_be32(pBigEndianPhyRegs[i].reserved);
pBigEndianPhyRegs[i].data = cpu_to_be32(pBigEndianPhyRegs[i].data);
}
for (phy=0; phy<2; phy++) {
char phyPath[60];
snprintf(phyPath, sizeof(phyPath), "/soc/internal-regs/mdio/ethernet-phy@%d", phy);
phyPath[sizeof(phyPath)-1] = 0;
node_ofs = fdt_path_offset(blob, phyPath);
if (node_ofs >= 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;
}

View File

@ -31,53 +31,53 @@ typedef enum {
TYPE_PCIE, TYPE_PCIE,
} slot_type_t; } slot_type_t;
static slot_type_t get_pcie_slot_type(const int slot) //static slot_type_t get_pcie_slot_type(const int slot)
{ //{
int module; // int module;
char pdValue[200]; // char pdValue[200];
char slotDescr[20]; // char slotDescr[20];
//
sprintf(slotDescr, "slot=%d", slot); // sprintf(slotDescr, "slot=%d", slot);
//
for (module=0; module<4; module++) { // for (module=0; module<4; module++) {
strcpy(pdValue, "" ); /*init with an empty string*/ // strcpy(pdValue, "" ); /*init with an empty string*/
if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) { // if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) {
//
if ((strstr(pdValue, slotDescr)) && (strstr(pdValue, "wlan-"))) { // if ((strstr(pdValue, slotDescr)) && (strstr(pdValue, "wlan-"))) {
/* Wifi module needs PCIe */ // /* Wifi module needs PCIe */
return TYPE_PCIE; // return TYPE_PCIE;
} // }
} // }
} // }
//
return TYPE_USB; // return TYPE_USB;
} //}
//
static int serdes_en_hack(struct gpio_desc *gpio) //static int serdes_en_hack(struct gpio_desc *gpio)
{ //{
slot_type_t slot_type = get_pcie_slot_type(0); // slot_type_t slot_type = get_pcie_slot_type(0);
//
/* Lucky for us pcie slot1 has some muxes, to workaround buggy Sierra Wireless Modules */ // /* Lucky for us pcie slot1 has some muxes, to workaround buggy Sierra Wireless Modules */
if (slot_type == TYPE_USB) { // if (slot_type == TYPE_USB) {
/* Buggy Sierra Wireless Modules don't like to have USB3 enabled // /* Buggy Sierra Wireless Modules don't like to have USB3 enabled
* because the TX of the USB3 Lane is attached to it's system // * because the TX of the USB3 Lane is attached to it's system
* reset which is the default (see dts) */ // * reset which is the default (see dts) */
printf("Slot1: wwan\n"); // printf("Slot1: wwan\n");
} // }
else if (slot_type == TYPE_PCIE) { // else if (slot_type == TYPE_PCIE) {
dm_gpio_set_value(gpio, 1); // dm_gpio_set_value(gpio, 1);
printf("Slot1: wlan\n"); // printf("Slot1: wlan\n");
} // }
else { // else {
/* If once we would use other buggy Sierra Wireless modules, where they have // /* 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 // * decided to use USB3 too, then we have to enable the SERDES, the reset signal
* was moved away from this pins again (bravo!!!) */ // * was moved away from this pins again (bravo!!!) */
printf("Slot1: wwan (usb3)\n"); // printf("Slot1: wwan (usb3)\n");
} // }
//
return 0; // return 0;
//
} //}
struct pcie_slot_gpios { struct pcie_slot_gpios {
struct gpio_desc reset; 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, if (gpio_request_by_name_nodev(fdt, name, 0, desc,
GPIOD_IS_OUT)) GPIOD_IS_OUT))
{ {
printf("Could not request gpio %s\n", name); debug("Could not request gpio %s\n", name);
return -1; return -1;
} }
@ -122,17 +122,19 @@ static int request_and_set_gpio_by_name(ofnode fdt,
static int add_pcie_slot(ofnode fdt) static int add_pcie_slot(ofnode fdt)
{ {
debug("%s\n", __func__); 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", request_and_set_gpio_by_name(fdt, "power",
&pcie_slots[pcie_slot_count].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", request_and_set_gpio_by_name(fdt, "wdis-out",
&pcie_slots[pcie_slot_count].wdis_out); &pcie_slots[pcie_slot_count].wdis_out);
request_and_set_gpio_by_name(fdt, "wdis", request_and_set_gpio_by_name(fdt, "wdis",
&pcie_slots[pcie_slot_count].wdis); &pcie_slots[pcie_slot_count].wdis);
pcie_slot_count++; pcie_slot_count++;
return 0; return 0;
} }
@ -140,35 +142,36 @@ static int add_pcie_slot(ofnode fdt)
static int configure_pcie_slots(void) static int configure_pcie_slots(void)
{ {
int i; int i;
udelay(1200000); /* 1.2 s */ 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 */ /* 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); dm_gpio_set_value(&pcie_slots[i].power, 1);
udelay(200000); /* 200 ms */ 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_out, 1);
dm_gpio_set_value(&pcie_slots[i].wdis, 0); 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 */ 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); dm_gpio_set_value(&pcie_slots[i].reset, 0);
} }
pci_init_board();
return 0; return 0;
} }
@ -189,112 +192,38 @@ static int configure_leds(void)
return 0; return 0;
} }
// TODO: Check, if needed
struct hack_list_entry { //struct hack_list_entry {
const char* name; // const char* name;
int (*fn)(struct gpio_desc *gpio); // int (*fn)(struct gpio_desc *gpio);
}; //};
//
struct hack_list_entry hack_list[] = { //struct hack_list_entry hack_list[] = {
{"serdes-en", serdes_en_hack} // {"serdes-en", serdes_en_hack}
}; //};
//
static int exec_hack_list_fn(const char *name, struct gpio_desc *gpio) //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; if ((index<0) || (index>=priv.led_count)) return;
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 */ dm_gpio_set_value(&leds[index], value);
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;
} }
int nbhw_fpga_configure(void) int nbhw_fpga_configure(void)
@ -309,14 +238,10 @@ int nbhw_fpga_configure(void)
name = ofnode_get_name(subnode); name = ofnode_get_name(subnode);
debug("Try to configure %s\n", name); debug("Try to configure %s\n", name);
if (!strncmp("misc", name, 4)) {
configure_misc(subnode);
}
if (!strncmp("pcieslot", name, 4)) { if (!strncmp("pcieslot", name, 4)) {
add_pcie_slot(subnode); add_pcie_slot(subnode);
} }
} }
if (configure_leds()) if (configure_leds())

View File

@ -1,144 +0,0 @@
/* #define DEBUG */
#include <nbhw.h>
#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);
}

View File

@ -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 */

View File

@ -1,43 +1,97 @@
#include <common.h> #include <common.h>
#include <asm/gpio.h> #include <asm/gpio.h>
#include <stdlib.h>
#include "nbhw_gpio.h"
#define SET_LOGIC(enable,group,bit) \ struct gpio_node {
if (enable) \ struct gpio_node* next;
mvGppValueSet(group, bit, bit); \ struct gpio_desc desc;
else \ const char* name;
mvGppValueSet(group, bit, 0); int is_output;
};
#define GPIO_RESET_BUTTON (14) static struct gpio_node* gl = NULL;
void init_gpios(void) static struct gpio_desc* lookup_gpio(const char* gpio_name, int is_output) {
{ struct gpio_node* cur = gl;
gpio_request(GPIO_RESET_BUTTON, "GPIO_RESET_BUTTON");
gpio_direction_input(GPIO_RESET_BUTTON); 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) static struct gpio_desc* acquire_gpio(const char* gpio_name, int is_output) {
{ struct gpio_node* gn = 0;
// SET_LOGIC(enable, 1, BIT9); 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);
}

View File

@ -1,14 +1,30 @@
#ifndef NBHW18_GPIO_H #ifndef HW17_GPIO_H
#define NBHW18_GPIO_H #define HW17_GPIO_H
#include "../common/nbhw_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); int get_gpio(const char* gpio_name);
void out_watchdog(int enable); int set_gpio(const char* gpio_name, int value);
void out_fpga_logic_reset(int enable);
int in_reset_button(void); /* LED definitions */
int in_fpga_cdone(void); #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 #endif

View File

@ -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 <common.h>
#include <environment.h>
#include <asm/io.h>
#include <u-boot/md5.h>
#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"
);

View File

@ -17,6 +17,7 @@ ccflags-y := -I../common
ifndef CONFIG_SPL_BUILD ifndef CONFIG_SPL_BUILD
obj-y := board.o nbhw_gpio.o nbhw_fpga_config.o nbhw_mvswitch.o \ 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/da9063.o \
../common/lattice/core.o \ ../common/lattice/core.o \
../common/lattice/hardware.o \ ../common/lattice/hardware.o \

View File

@ -55,6 +55,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define DEV_CS0_BASE 0xfd000000 #define DEV_CS0_BASE 0xfd000000
/* Default serdes configuration */
static struct serdes_map board_serdes_map[] = { static struct serdes_map board_serdes_map[] = {
{ SGMII0, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, { SGMII0, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 },
{ USB3_HOST0, SERDES_SPEED_5_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; int i;
if (read_eeprom() < 0){ 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"); 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 { } else {
for (i = 0; i < ARRAY_SIZE(board_serdes_map); i++) { for (i = 0; i < ARRAY_SIZE(board_serdes_map); i++) {
enum serdes_type type; 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); type = bd_get_serdes_type(i);
} }
/* Do not touch serdes */
if (type < LAST_SERDES_TYPE) { if (type < LAST_SERDES_TYPE) {
if ((type >= SGMII0) && (type <= SGMII2)) { if ((type >= SGMII0) && (type <= SGMII2)) {
board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS; 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)) { else if ((type >= USB3_HOST0) && (type <= USB3_HOST1)) {
board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS; board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS;
board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1; 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_speed = SERDES_SPEED_1_25_GBPS;
board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE; board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE;
} else { } else {
@ -653,7 +636,7 @@ static void set_phy_fast_blink_mode(int phy_addr)
static void set_devicetree_name(void) static void set_devicetree_name(void)
{ {
char devicetreename[64]; char devicetreename[64];
/* add hardware versions to environment */
if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) { if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) {
printf("Devicetree name not found, use legacy name\n"); printf("Devicetree name not found, use legacy name\n");
strcpy(devicetreename, "armada-385-nbhw18-prod1.dtb"); strcpy(devicetreename, "armada-385-nbhw18-prod1.dtb");
@ -673,9 +656,7 @@ int board_late_init(void)
find_and_set_active_partition(); find_and_set_active_partition();
pass_hw_rev(); pass_hw_rev();
/* Todo: It seems that something with the network is wrong */
run_command("run load_fpga", CMD_FLAG_ENV); run_command("run load_fpga", CMD_FLAG_ENV);
#endif #endif
/* TODO: Move the following two lines up to misc_init_r when ttyS1 works without FPGA again */ /* 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_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 */ /* Take phy out of reset after FPGA was loaded */
gpio_set_value(29, 1); gpio_set_value(29, 1);

View File

@ -7,6 +7,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <errno.h> #include <errno.h>
#include "../common/nbhw_bd.h" #include "../common/nbhw_bd.h"
#include "../common/nbhw_sim.h"
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -150,6 +151,8 @@ static int configure_pcie_slots(void)
int i, res; int i, res;
char volt[10]; char volt[10];
configure_sim_slots(4);
udelay(1200000); /* 1.2 s */ udelay(1200000); /* 1.2 s */
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {

View File

@ -1,14 +1,14 @@
#include <common.h> #include <common.h>
#include <nbhw.h> #include "../common/nbhw_fpga_prog.h"
#include "nbhw18_fpga_regs.h" #define SIM_CTRL (0x0040)
void connect_sim_to_slot(int sim, int slot) { void connect_sim_to_slot(int sim, int slot) {
uint16_t sim_ctrl; uint16_t sim_ctrl;
uint16_t sim_shift; uint16_t sim_shift;
uint16_t slot_sel; uint16_t slot_sel;
if (sim > 3) { if (sim > 1) {
printf("Invalid sim %d selected, can't connect slot %d\n", sim, slot); printf("Invalid sim %d selected, can't connect slot %d\n", sim, slot);
return; return;
} }
@ -32,4 +32,3 @@ void connect_sim_to_slot(int sim, int slot) {
FPGA_REG(SIM_CTRL) = sim_ctrl; FPGA_REG(SIM_CTRL) = sim_ctrl;
} }

View File

@ -791,7 +791,9 @@ static const init_fnc_t init_sequence_f[] = {
env_init, /* initialize environment */ env_init, /* initialize environment */
init_baud_rate, /* initialze baudrate settings */ init_baud_rate, /* initialze baudrate settings */
serial_init, /* serial communications setup */ serial_init, /* serial communications setup */
#if !defined(CONFIG_PRE_CONSOLE_BUFFER)
console_init_f, /* stage 1 init of console */ console_init_f, /* stage 1 init of console */
#endif
display_options, /* say that we are here */ display_options, /* say that we are here */
display_text_info, /* show debugging info if required */ display_text_info, /* show debugging info if required */
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SH) || \ #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SH) || \

View File

@ -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

View File

@ -7,11 +7,18 @@ CONFIG_TARGET_NM_NBHW17_V1=y
CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_LIBDISK_SUPPORT=y CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_DEFAULT_DEVICE_TREE="armada-385-nbhw17-v1" CONFIG_DEFAULT_DEVICE_TREE="armada-385-nbhw17-v1-spl"
CONFIG_DEFAULT_FDT_FILE="armada-385-nbhw17-v1" CONFIG_SMBIOS_PRODUCT_NAME="hw17"
CONFIG_FIT=y
CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
CONFIG_BOOTDELAY=3 CONFIG_BOOTDELAY=3
CONFIG_BOOTSTAGE_STASH_SIZE=4096 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_DISPLAY_BOARDINFO is not set
CONFIG_SPL=y CONFIG_SPL=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x190 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x190
@ -19,6 +26,7 @@ CONFIG_SPL_I2C_SUPPORT=y
CONFIG_HUSH_PARSER=y CONFIG_HUSH_PARSER=y
CONFIG_CMD_BOOTZ=y CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set # CONFIG_CMD_IMLS is not set
CONFIG_CMD_NB_TEST=y
# CONFIG_CMD_FLASH is not set # CONFIG_CMD_FLASH is not set
CONFIG_CMD_MMC=y CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y CONFIG_CMD_SF=y
@ -40,17 +48,19 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_EFI_PARTITION=y CONFIG_EFI_PARTITION=y
# CONFIG_PARTITION_UUIDS is not set # CONFIG_PARTITION_UUIDS is not set
# CONFIG_SPL_PARTITION_UUIDS is not set # CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_OF_BOARD_FIXUP=y
CONFIG_SPL_OF_TRANSLATE=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=y
CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_SDMA=y
CONFIG_MMC_SDHCI_MV=y CONFIG_MMC_SDHCI_MV=y
CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH=y
CONFIG_MVNETA=y CONFIG_MVNETA=y
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_DEBUG_UART=y # CONFIG_DEBUG_UART is not set
CONFIG_DEBUG_UART_BASE=0xd0012000 # CONFIG_REQUIRE_SERIAL_CONSOLE is not set
CONFIG_DEBUG_UART_CLOCK=250000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y CONFIG_SYS_NS16550=y
CONFIG_USB=y CONFIG_USB=y
CONFIG_DM_USB=y CONFIG_DM_USB=y
@ -58,4 +68,7 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MARVELL=y CONFIG_USB_EHCI_MARVELL=y
CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE=y
CONFIG_MVEBU_GPIO=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

View File

@ -83,7 +83,11 @@ static int pca953x_write_single(struct udevice *dev, int reg, u8 val,
int off = offset / BANK_SZ; int off = offset / BANK_SZ;
int ret = 0; int ret = 0;
#ifdef CONFIG_DM_I2C
ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1); 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) { if (ret) {
dev_err(dev, "%s error\n", __func__); dev_err(dev, "%s error\n", __func__);
return ret; return ret;
@ -101,7 +105,11 @@ static int pca953x_read_single(struct udevice *dev, int reg, u8 *val,
int ret; int ret;
u8 byte; u8 byte;
#ifdef CONFIG_DM_I2C
ret = dm_i2c_read(dev, (reg << bank_shift) + off, &byte, 1); 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) { if (ret) {
dev_err(dev, "%s error\n", __func__); dev_err(dev, "%s error\n", __func__);
return ret; return ret;
@ -118,12 +126,24 @@ static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
int ret = 0; int ret = 0;
if (info->gpio_count <= 8) { if (info->gpio_count <= 8) {
#ifdef CONFIG_DM_I2C
ret = dm_i2c_read(dev, reg, val, 1); 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) { } else if (info->gpio_count <= 16) {
#ifdef CONFIG_DM_I2C
ret = dm_i2c_read(dev, reg << 1, val, info->bank_count); 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) { } else if (info->gpio_count == 40) {
/* Auto increment */ /* Auto increment */
#ifdef CONFIG_DM_I2C
ret = dm_i2c_read(dev, (reg << 3) | 0x80, val, info->bank_count); 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 { } else {
dev_err(dev, "Unsupported now\n"); dev_err(dev, "Unsupported now\n");
return -EINVAL; return -EINVAL;

View File

@ -1372,6 +1372,8 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_ID:
ctrl |= MVNETA_GMAC2_PORT_RGMII; ctrl |= MVNETA_GMAC2_PORT_RGMII;
break; break;
case PHY_INTERFACE_MODE_MII:
break;
default: default:
return -EINVAL; return -EINVAL;
} }

View File

@ -0,0 +1,223 @@
/*
* Copyright (C) 2014 Stefan Roese <sr@denx.de>
*
* 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 */

View File

@ -43,11 +43,28 @@
/* USB/EHCI configuration */ /* USB/EHCI configuration */
#define CONFIG_EHCI_IS_TDI #define CONFIG_EHCI_IS_TDI
/* Environment in SPI NOR flash */ /* Environment in I2C EEPROM */
#define CONFIG_ENV_IS_IN_SPI_FLASH /**
#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */ * Layout on the NBHW08 Board:
#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ * Offset Size Description
#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */ * 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 CONFIG_PHY_MARVELL /* there is a marvell phy */
#define PHY_ANEG_TIMEOUT 8000 /* PHY needs a longer aneg time */ #define PHY_ANEG_TIMEOUT 8000 /* PHY needs a longer aneg time */
@ -58,9 +75,20 @@
#define CONFIG_PCI_SCAN_SHOW #define CONFIG_PCI_SCAN_SHOW
#endif #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 #define CONFIG_SYS_ALT_MEMTEST
#ifndef CONFIG_SPL_BUILD #ifndef CONFIG_SPL_BUILD
#define CONFIG_NM_LOGIN
#define CONFIG_CRYPT
#define CONFIG_SUPPORT_EMMC_RPMB
#define KERNEL_ADDR "0x01000000" #define KERNEL_ADDR "0x01000000"
#define LOAD_ADDR "0x03000000" #define LOAD_ADDR "0x03000000"
#define FDT_ADDR "0x02000000" #define FDT_ADDR "0x02000000"
@ -78,14 +106,14 @@
"eth1addr=00:11:22:33:44:55\0" \ "eth1addr=00:11:22:33:44:55\0" \
"eth2addr=00:11:22:33:44:56\0" \ "eth2addr=00:11:22:33:44:56\0" \
"ethact=ethernet@30000\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" \ "add_version_bootargs=setenv bootargs $bootargs\0" \
"fdt_skip_update=yes\0" \ "fdt_skip_update=yes\0" \
"sdbringup=echo Try bringup boot && ext4load mmc 0:$root_part $kernel_addr /boot/zImage && " \ "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" \ "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 && " \ "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" \ "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...; "\ "echo Copying Linux from SD to RAM...; "\
"if test -e mmc 0:$root_part /boot/$kernel_image; then run sdprod; " \ "if test -e mmc 0:$root_part /boot/$kernel_image; then run sdprod; " \
"else run sdbringup; fi; " \ "else run sdbringup; fi; " \
@ -103,14 +131,15 @@
"tftptimeoutcountmax=5\0" \ "tftptimeoutcountmax=5\0" \
"bootpretryperiod=2000\0" \ "bootpretryperiod=2000\0" \
"autoload=false\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" \ "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" \ "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 */ "recovery=run pxe_recovery || setenv ipaddr $ipaddr; setenv serverip $serverip; run tftp_recovery\0" /* setenv ipaddr and serverip is necessary, because dhclient can destroy the IPs inernally */
#endif #endif
/* SPL */ /* SPL */
/* /*
* Select the boot device here * Select the boot device here
@ -134,6 +163,7 @@
#ifdef CONFIG_SPL_BUILD #ifdef CONFIG_SPL_BUILD
#define CONFIG_SYS_MALLOC_SIMPLE #define CONFIG_SYS_MALLOC_SIMPLE
#define CONFIG_OF_STDOUT_VIA_ALIAS
#endif #endif
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10)) #define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
@ -165,11 +195,27 @@
/* /*
* NBHW needs md5 support * NBHW needs md5 support
*/ */
#ifndef CONFIG_MD5
#define CONFIG_MD5 #define CONFIG_MD5
#endif
/* /*
* We need some functions to be called after environment setup * We need some functions to be called after environment setup
*/ */
#define CONFIG_BOARD_LATE_INIT #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 */ #endif /* _CONFIG_DB_88F6820_GP_H */

3
include/configs/armada-385-nbhw18-v2.h Executable file → Normal file
View File

@ -112,7 +112,7 @@
"eth2addr=00:11:22:33:44:56\0" \ "eth2addr=00:11:22:33:44:56\0" \
"eth3addr=00:11:22:33:44:57\0" \ "eth3addr=00:11:22:33:44:57\0" \
"ethact=ethernet@34000\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" \ "add_version_bootargs=setenv bootargs $bootargs\0" \
"fdt_skip_update=yes\0" \ "fdt_skip_update=yes\0" \
"sdbringup=echo Try bringup boot && ext4load mmc 0:$root_part $kernel_addr /boot/zImage && " \ "sdbringup=echo Try bringup boot && ext4load mmc 0:$root_part $kernel_addr /boot/zImage && " \
@ -138,6 +138,7 @@
"bootpretryperiod=2000\0" \ "bootpretryperiod=2000\0" \
"autoload=false\0" \ "autoload=false\0" \
"defaultconsole=ttyS1\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" \ "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" \ "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" \ "load_fpga=ext4load mmc 0:$root_part $kernel_addr /logic/LG00000000 && nbhw_fpga program lattice-sspi 0xffffffff $kernel_addr $filesize && nbhw_fpga configure\0" \

View File

@ -6,7 +6,8 @@
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*/ */
#ifndef _LIBFDT_ENV_H #ifndef LIBFDT_ENV_H
#define LIBFDT_ENV_H
#define _LIBFDT_ENV_H #define _LIBFDT_ENV_H
#include "compiler.h" #include "compiler.h"
@ -32,4 +33,4 @@ typedef __be64 fdt64_t;
/* adding a ramdisk needs 0x44 bytes in version 2008.10 */ /* adding a ramdisk needs 0x44 bytes in version 2008.10 */
#define FDT_RAMDISK_OVERHEAD 0x80 #define FDT_RAMDISK_OVERHEAD 0x80
#endif /* _LIBFDT_ENV_H */ #endif /* LIBFDT_ENV_H */

View File

@ -12,12 +12,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/bitops.h> #include <linux/bitops.h>
/*
* deal with unrepresentable constant logarithms
*/
extern __attribute__((const, noreturn))
int ____ilog2_NaN(void);
/* /*
* non-constant log of base 2 calculators * non-constant log of base 2 calculators
* - the arch may override these in asm/bitops.h if they can be implemented * - the arch may override these in asm/bitops.h if they can be implemented
@ -40,19 +34,23 @@ int __ilog2_u64(u64 n)
} }
#endif #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. * *not* considered a power of two.
* Return: true if @n is a power of 2, otherwise false.
*/ */
static inline __attribute__((const)) static inline __attribute__((const))
bool is_power_of_2(unsigned long n) bool is_power_of_2(unsigned long n)
{ {
return (n != 0 && ((n & (n - 1)) == 0)); 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)) static inline __attribute__((const))
unsigned long __roundup_pow_of_two(unsigned long n) 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); 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)) static inline __attribute__((const))
unsigned long __rounddown_pow_of_two(unsigned long n) 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 * ilog2 - log base 2 of 32-bit or a 64-bit unsigned value
* @n - parameter * @n: parameter
* *
* constant-capable log of base 2 calculation * constant-capable log of base 2 calculation
* - this can be used to initialise global variables from constant data, hence * - 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) * selects the appropriately-sized optimised version depending on sizeof(n)
*/ */
#define ilog2(n) \ #define ilog2(n) \
( \ ( \
__builtin_constant_p(n) ? ( \ __builtin_constant_p(n) ? ( \
(n) < 1 ? ____ilog2_NaN() : \ (n) < 2 ? 0 : \
(n) & (1ULL << 63) ? 63 : \ (n) & (1ULL << 63) ? 63 : \
(n) & (1ULL << 62) ? 62 : \ (n) & (1ULL << 62) ? 62 : \
(n) & (1ULL << 61) ? 61 : \ (n) & (1ULL << 61) ? 61 : \
@ -145,10 +144,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
(n) & (1ULL << 4) ? 4 : \ (n) & (1ULL << 4) ? 4 : \
(n) & (1ULL << 3) ? 3 : \ (n) & (1ULL << 3) ? 3 : \
(n) & (1ULL << 2) ? 2 : \ (n) & (1ULL << 2) ? 2 : \
(n) & (1ULL << 1) ? 1 : \ 1) : \
(n) & (1ULL << 0) ? 0 : \
____ilog2_NaN() \
) : \
(sizeof(n) <= 4) ? \ (sizeof(n) <= 4) ? \
__ilog2_u32(n) : \ __ilog2_u32(n) : \
__ilog2_u64(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 * 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 * round the given value up to the nearest power of two
* - the result is undefined when n == 0 * - 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 * 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 * round the given value down to the nearest power of two
* - the result is undefined when n == 0 * - 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) \ __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 * order_base_2 - calculate the (rounded up) base 2 order of the argument
* @n: parameter * @n: parameter
@ -199,7 +201,11 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
* ob2(5) = 3 * ob2(5) = 3
* ... and so on. * ... and so on.
*/ */
#define order_base_2(n) \
#define order_base_2(n) ilog2(roundup_pow_of_two(n)) ( \
__builtin_constant_p(n) ? ( \
((n) == 0 || (n) == 1) ? 0 : \
ilog2((n) - 1) + 1) : \
__order_base_2(n) \
)
#endif /* _LINUX_LOG2_H */ #endif /* _LINUX_LOG2_H */

View File

@ -1,26 +1,19 @@
#include <common.h> /*
#include <u-boot/sha256.h> * The crypt source code was ported from busybox sources pw_crypt, file
#include <malloc.h> * libbb/pw_encrypt_sha.c
#include <linux/types.h> *
* 20191108rs: Update to Busybox commit 49ecee0 (Jan 24, 2017)
/* The crypt source code was ported from busybox sources pw_crypt */ * Major cleanup, provide missing functions
*/
/* 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;
}
/* SHA256 and SHA512-based Unix crypt implementation. /* SHA256 and SHA512-based Unix crypt implementation.
* Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. * Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>.
*/ */
#include <common.h>
#include <u-boot/sha256.h>
#include <malloc.h>
#include <linux/types.h>
/* Prefix for optional rounds specification. */ /* Prefix for optional rounds specification. */
static const char str_rounds[] = "rounds=%u$"; static const char str_rounds[] = "rounds=%u$";
@ -33,50 +26,98 @@ static const char str_rounds[] = "rounds=%u$";
/* Maximum number of rounds. */ /* Maximum number of rounds. */
#define ROUNDS_MAX 999999999 #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_begin)(void *ctx);
void (*sha_hash)(void *ctx, const void *buffer, size_t len); 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; int _32or64;
char *result, *resptr; char *result, *resptr;
/* btw, sha256 needs [32] and uint32_t only */ /* btw, sha256 needs [32] and uint32_t only */
unsigned char alt_result[64] __attribute__((__aligned__(__alignof__(uint64_t)))); struct {
unsigned char temp_result[64] __attribute__((__aligned__(__alignof__(uint64_t)))); unsigned char alt_result[64];
union { unsigned char temp_result[64];
sha256_context x; union {
#if 0 sha256_context x;
sha512_ctx_t y; /* sha512_ctx_t y; */
#endif } ctx;
} ctx; union {
union { sha256_context x;
sha256_context x; /* sha512_ctx_t y; */
#if 0 } alt_ctx;
sha512_ctx_t y; } L;
#endif #define alt_result (L.alt_result )
} alt_ctx; #define temp_result (L.temp_result)
#define ctx (L.ctx )
#define alt_ctx (L.alt_ctx )
unsigned salt_len; unsigned salt_len;
unsigned key_len; unsigned key_len;
unsigned cnt; unsigned cnt;
unsigned rounds; unsigned rounds;
char *cp; char *cp;
char is_sha512;
char *tmp;
/* Analyze salt, construct already known part of result */ /* Analyze salt, construct already known part of result */
cnt = strlen(salt_data) + 1 + 43 + 1; cnt = strlen(salt_data) + 1 + 43 + 1;
is_sha512 = salt_data[1]; _32or64 = 32;
if (is_sha512 == '6') { if (salt_data[1] == '6') { /* sha512 */
printf("SHA-512 is not supported yet"); _32or64 *= 2; /*64*/
return 0; cnt += 43;
/* cnt += 43; */ puts("SHA-512 is not supported");
} return 0;
result = resptr = malloc(cnt); /* will provide NUL terminator */ }
memset(result, 0, cnt); result = resptr = xzalloc(cnt); /* will provide NUL terminator */
*resptr++ = '$'; *resptr++ = '$';
*resptr++ = is_sha512; *resptr++ = salt_data[1];
*resptr++ = '$'; *resptr++ = '$';
rounds = ROUNDS_DEFAULT; rounds = ROUNDS_DEFAULT;
salt_data += 3; salt_data += 3;
@ -95,50 +136,41 @@ char *sha_crypt(const char *key_data, const char *salt_data)
resptr += sprintf(resptr, str_rounds, rounds); resptr += sprintf(resptr, str_rounds, rounds);
} }
} }
{
char *salt_end = strchr(salt_data, '$'); salt_len = (int)strchrnul(salt_data, '$') - (int)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;
if (salt_len > SALT_LEN_MAX) if (salt_len > SALT_LEN_MAX)
salt_len = SALT_LEN_MAX; salt_len = SALT_LEN_MAX;
/* xstrdup assures suitable alignment; also we will use it /* xstrdup assures suitable alignment; also we will use it
as a scratch space later. */ as a scratch space later. */
tmp = malloc(strnlen(salt_data, 128));
memcpy(tmp, salt_data, strnlen(salt_data, 128)); /* NOTE: Something is wrong here.
salt_data = tmp; * when <salt_len> bytes are reserved there is a problem later in
//salt_data = xstrndup(salt_data, salt_len); * 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 */ /* add "salt$" to result */
strcpy(resptr, salt_data); strcpy(resptr, salt_data);
resptr += salt_len; resptr += salt_len;
*resptr++ = '$'; *resptr++ = '$';
/* key data doesn't need much processing */ /* key data doesn't need much processing */
key_len = strlen(key_data); key_len = strlen(key_data);
tmp = malloc(strnlen(key_data, 256)); key_data = xstrdup(key_data);
memcpy(tmp, key_data, strnlen(key_data, 256));
key_data = tmp;
// key_data = xstrdup(key_data);
/* Which flavor of SHAnnn ops to use? */ /* Which flavor of SHAnnn ops to use? */
sha_begin = (void*)sha256_starts; sha_begin = (void*)sha256_starts;
sha_hash = (void*)sha256_update; sha_hash = (void*)sha256_update;
sha_end = (void*)sha256_finish; sha_end = (void*)sha256_finish;
_32or64 = 32;
/* Not supported */
#if 0 #if 0
if (is_sha512 == '6') { /* SHA512 not supported */
if (_32or64 != 32) {
sha_begin = (void*)sha512_begin; sha_begin = (void*)sha512_begin;
sha_hash = (void*)sha512_hash; sha_hash = (void*)sha512_hash;
sha_end = (void*)sha512_end; sha_end = (void*)sha512_end;
_32or64 = 64;
} }
#endif #endif
/* Add KEY, SALT. */ /* Add KEY, SALT. */
sha_begin(&ctx); sha_begin(&ctx);
sha_hash(&ctx, key_data, key_len); 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); sha_end(&ctx, alt_result);
} }
/* Append encrypted password to result buffer */ /* Append encrypted password to result buffer */
//TODO: replace with something like //TODO: replace with something like
// bb_uuencode(cp, src, length, bb_uuenc_tbl_XXXbase64); // bb_uuencode(cp, src, length, bb_uuenc_tbl_XXXbase64);
#define b64_from_24bit(B2, B1, B0, N) \ #define b64_from_24bit(B2, B1, B0, N) \
do { \ do { \
unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \ unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \
resptr = to64(resptr, w, N); \ resptr = to64(resptr, w, N); \
} while (0) } while (0)
if (is_sha512 == '5') { if (_32or64 == 32) { /* sha256 */
unsigned i = 0; 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) { 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); b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4);
if (i == 9) if (k == 29)
break; break;
i += 21; i = (((i >> 4) & 2) + i) & 0x1f; i = k + 1;
j += 21; j = (((j >> 4) & 2) + j) & 0x1f;
k += 21; k = (((k >> 4) & 2) + k) & 0x1f;
} }
b64_from_24bit(0, alt_result_31, alt_result[30], 3); b64_from_24bit(0, alt_result[31], alt_result[30], 3);
/* was: /* was:
b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4); 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); 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[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[3], alt_result[13], alt_result[23], 4);
b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4); b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4);
@ -271,15 +298,15 @@ do { \
*/ */
} else { } else {
unsigned i = 0; unsigned i = 0;
unsigned j = 21;
unsigned k = 42;
while (1) { 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); b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4);
if (i == 62) if (j == 20)
break; break;
i += 22; i = ((i >> 6) + i) & 0x3f; i = j + 1;
j += 22; j = ((j >> 6) + j) & 0x3f;
k += 22; k = ((k >> 6) + k) & 0x3f;
} }
b64_from_24bit(0, 0, alt_result[63], 2); b64_from_24bit(0, 0, alt_result[63], 2);
/* was: /* was:
@ -309,21 +336,19 @@ do { \
} }
/* *resptr = '\0'; - xzalloc did it */ /* *resptr = '\0'; - xzalloc did it */
#undef b64_from_24bit #undef b64_from_24bit
/* Clear the buffer for the intermediate result so that people /* Clear the buffer for the intermediate result so that people
attaching to processes or reading core dumps cannot get any attaching to processes or reading core dumps cannot get any
information. */ information. */
memset(temp_result, 0, sizeof(temp_result)); memset(&L, 0, sizeof(L)); /* [alt]_ctx and XXX_result buffers */
memset(alt_result, 0, sizeof(alt_result));
memset(&ctx, 0, sizeof(ctx));
memset(&alt_ctx, 0, sizeof(alt_ctx));
memset(key_data, 0, key_len); /* also p_bytes */ memset(key_data, 0, key_len); /* also p_bytes */
memset(salt_data, 0, salt_len); /* also s_bytes */ memset(salt_data, 0, salt_len); /* also s_bytes */
free(key_data); free(key_data);
free(salt_data); free(salt_data);
#undef p_bytes #undef p_bytes
#undef s_bytes #undef s_bytes
return result; return result;
#undef alt_result
#undef temp_result
#undef ctx
#undef alt_ctx
} }

View File

@ -743,7 +743,7 @@ int conf_write(const char *name)
struct menu *menu; struct menu *menu;
const char *basename; const char *basename;
const char *str; 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; char *env;
dirname[0] = 0; dirname[0] = 0;