ADD: [hw14] added hw14 platform to support new mc board
BugzId: 66150
This commit is contained in:
parent
21fb3f581f
commit
1ffa09d30f
3
Makefile
3
Makefile
|
|
@ -617,9 +617,6 @@ KBUILD_AFLAGS += -Wa,-gstabs,-S
|
|||
endif
|
||||
endif
|
||||
|
||||
# Prohibit date/time macros, which would make the build non-deterministic
|
||||
KBUILD_CFLAGS += $(call cc-option,-Werror=date-time)
|
||||
|
||||
include scripts/Makefile.extrawarn
|
||||
|
||||
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
|
|||
tegra210-p2571.dtb
|
||||
|
||||
dtb-$(CONFIG_ARCH_MVEBU) += \
|
||||
armada-385-hw14.dtb \
|
||||
armada-385-nbhw18-v2.dtb \
|
||||
armada-385-nbhw17-v1.dtb \
|
||||
armada-3720-db.dtb \
|
||||
|
|
|
|||
|
|
@ -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 = ð0;
|
||||
ethernet1 = ð1;
|
||||
ethernet2 = ð2;
|
||||
/delete-property/ gpio0; /* Causes warnings when requesting gpios */
|
||||
/delete-property/ gpio1; /* Causes warnings when requesting gpios */
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x40000000>; /* 1 GB */
|
||||
};
|
||||
|
||||
soc {
|
||||
ranges = <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)
|
||||
ð0 { /* ethernet@70000 */
|
||||
status = "okay";
|
||||
phy-mode = "mii";
|
||||
fixed-link {
|
||||
speed = <100>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
// MAC1 is used for SGMII (1 GBit/s switches on NB3800)
|
||||
ð1 { /* ethernet@30000 */
|
||||
status = "okay";
|
||||
phy-mode = "sgmii";
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ð0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ð1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -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)";
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Device Tree file for the NetModule NBHW17 (NB2800)
|
||||
*
|
||||
* Copyright (C) 2016 NetModule
|
||||
* Copyright (C) 2021 NetModule
|
||||
*
|
||||
* Stefan Eichenberger <stefan.eichenberger@netmodule.com>
|
||||
*
|
||||
|
|
@ -21,10 +21,8 @@
|
|||
/* So that mvebu u-boot can update the MAC addresses */
|
||||
ethernet1 = ð1;
|
||||
ethernet2 = ð2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial1:115200n8";
|
||||
/delete-property/ gpio0; /* Causes warnings when requesting gpios */
|
||||
/delete-property/ gpio1; /* Causes warnings when requesting gpios */
|
||||
};
|
||||
|
||||
memory {
|
||||
|
|
@ -37,7 +35,16 @@
|
|||
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
|
||||
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000 /* CESA 0 SRAM */
|
||||
MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 /* CESA 1 SRAM */
|
||||
MBUS_ID(0x01, 0x3e) 0 0xfd000000 0x20000>; /* FPGA */
|
||||
MBUS_ID(0x01, 0x3e) 0 0xfd000000 0x20000>; /* FPGA (CS0) */
|
||||
|
||||
gpio_pins {
|
||||
compatible = "nm,gpios";
|
||||
wd_enable = <&gpio0 27 GPIO_ACTIVE_LOW 0>;
|
||||
rst_usb_hub = <&gpio1 9 GPIO_ACTIVE_LOW 1>;
|
||||
rst_fpga = <&gpio1 12 GPIO_ACTIVE_LOW 1>;
|
||||
rst_eth_phy = <&gpio0 21 GPIO_ACTIVE_LOW 1>;
|
||||
reset_button = <&gpio1 24 GPIO_ACTIVE_LOW 1>;
|
||||
};
|
||||
|
||||
gpiofpga: gpio@fd0000000 {
|
||||
compatible = "nm,nbhw-fpga";
|
||||
|
|
@ -46,13 +53,12 @@
|
|||
gpio-controller;
|
||||
gpio-bank-name = "FPGA";
|
||||
#gpio-cells = <2>;
|
||||
spi-ss = <&gpio1 5 0>; /* SS */
|
||||
spi-sdo = <&gpio1 6 0>; /* SDO slave data out */
|
||||
spi-sck = <&gpio1 7 0>; /* SCK */
|
||||
spi-sdi = <&gpio1 8 0>; /* SDI slave data in */
|
||||
fpga-reset = <&gpio0 26 0>; /* FPGA reset */
|
||||
fpga-cdone = <&gpio0 29 0>; /* FPGA cdone */
|
||||
fpga-reset-logic = <&gpio1 12 0>; /* FPGA reset logic (after load)*/
|
||||
spi-sck = <&gpio1 7 GPIO_ACTIVE_HIGH 0>; /* SCK (MPP39) */
|
||||
spi-sdi = <&gpio1 8 GPIO_ACTIVE_HIGH 0>; /* SDI slave data in (MPP40) */
|
||||
spi-ss = <&gpio1 5 GPIO_ACTIVE_HIGH 0>; /* SS (MPP37) */
|
||||
fpga-reset = <&gpio0 26 GPIO_ACTIVE_HIGH 0>; /* FPGA config reset */
|
||||
fpga-cdone = <&gpio0 29 GPIO_ACTIVE_HIGH 0>; /* FPGA cdone */
|
||||
fpga-reset-logic = <&gpio1 12 GPIO_ACTIVE_HIGH 0>; /* FPGA logic reset */
|
||||
};
|
||||
|
||||
fpga_conf: fpgaconf@0 {
|
||||
|
|
@ -64,28 +70,15 @@
|
|||
<&gpiofpga 268 0>, <&gpiofpga 269 0>, <&gpiofpga 270 0>,
|
||||
<&gpiofpga 271 0>;
|
||||
|
||||
misc@0 {
|
||||
#gpio-cells = <4>;
|
||||
// gpio controller, gpio number, low/high_active, default value
|
||||
hold-pwr-on = <&gpiofpga 64 0 1>;
|
||||
en-gps-ant = <&gpiofpga 65 0 0>;
|
||||
en-mdio-phy = <&gpiofpga 66 GPIO_ACTIVE_LOW 1>;
|
||||
en-mdio-ext = <&gpiofpga 67 GPIO_ACTIVE_LOW 0>;
|
||||
en-sata-pwr = <&gpiofpga 68 GPIO_ACTIVE_HIGH 1>;
|
||||
serdes-sel = <&gpiofpga 69 GPIO_ACTIVE_HIGH 1>;
|
||||
serdes-en = <&gpiofpga 70 GPIO_ACTIVE_LOW 0>;
|
||||
rst-ext = <&gpiofpga 71 GPIO_ACTIVE_LOW 1>;
|
||||
rst-ext-eth = <&gpiofpga 72 GPIO_ACTIVE_LOW 1>;
|
||||
rst-ext-en = <&gpiofpga 73 GPIO_ACTIVE_HIGH 0>;
|
||||
};
|
||||
|
||||
// pcie slot 0
|
||||
pcieslot@0 {
|
||||
reset = <&gpiofpga 384 GPIO_ACTIVE_LOW 1>;
|
||||
power = <&gpiofpga 400 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-out = <&gpiofpga 2053 GPIO_ACTIVE_HIGH 1>;
|
||||
wdis = <&gpiofpga 2068 GPIO_ACTIVE_LOW 1>;
|
||||
wdis = <&gpiofpga 2069 GPIO_ACTIVE_LOW 1>;
|
||||
};
|
||||
|
||||
// pcie slot 1
|
||||
pcieslot@1 {
|
||||
reset = <&gpiofpga 385 GPIO_ACTIVE_LOW 1>;
|
||||
power = <&gpiofpga 401 GPIO_ACTIVE_HIGH 0>;
|
||||
|
|
@ -93,6 +86,7 @@
|
|||
wdis = <&gpiofpga 4117 GPIO_ACTIVE_LOW 1>;
|
||||
};
|
||||
|
||||
// pcie slot 2
|
||||
pcieslot@2 {
|
||||
reset = <&gpiofpga 386 GPIO_ACTIVE_LOW 1>;
|
||||
power = <&gpiofpga 402 GPIO_ACTIVE_HIGH 0>;
|
||||
|
|
@ -100,6 +94,7 @@
|
|||
wdis = <&gpiofpga 6165 GPIO_ACTIVE_LOW 1>;
|
||||
};
|
||||
|
||||
// pcie slot 3
|
||||
pcieslot@3 {
|
||||
reset = <&gpiofpga 387 GPIO_ACTIVE_LOW 1>;
|
||||
power = <&gpiofpga 403 GPIO_ACTIVE_HIGH 0>;
|
||||
|
|
@ -128,14 +123,6 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
sdhci@d8000 {
|
||||
broken-cd;
|
||||
wp-inverted;
|
||||
no-1-8-v;
|
||||
bus-width = <8>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
serial@12000 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_pins>;
|
||||
|
|
@ -146,8 +133,12 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart1_pins>;
|
||||
u-boot,dm-pre-reloc;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb@58000 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
pcie-controller {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ð1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ð2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -15,6 +15,9 @@
|
|||
|
||||
/ {
|
||||
model = "NetModule Router NBHW17 with Armada A385 (NB2800)";
|
||||
// chosen {
|
||||
// stdout-path = "serial1:115200n8";
|
||||
// };
|
||||
};
|
||||
|
||||
ð1 {
|
||||
|
|
|
|||
|
|
@ -88,9 +88,9 @@ config TARGET_DB_88F6820_GP
|
|||
bool "Support DB-88F6820-GP"
|
||||
select 88F6820
|
||||
|
||||
config TARGET_NM_NBHW18_V1
|
||||
bool "Support NBHW18 V1"
|
||||
select 88F6820
|
||||
config TARGET_NM_HW14
|
||||
bool "Support HW14"
|
||||
select 88F6820
|
||||
|
||||
config TARGET_NM_NBHW18_V2
|
||||
bool "Support NBHW18 V2"
|
||||
|
|
@ -154,6 +154,7 @@ config SYS_BOARD
|
|||
default "ds414" if TARGET_DS414
|
||||
default "maxbcm" if TARGET_MAXBCM
|
||||
default "theadorable" if TARGET_THEADORABLE
|
||||
default "hw14" if TARGET_NM_HW14
|
||||
default "nbhw18_v1" if TARGET_NM_NBHW18_V1
|
||||
default "nbhw18_v2" if TARGET_NM_NBHW18_V2
|
||||
default "nbhw17_v1" if TARGET_NM_NBHW17_V1
|
||||
|
|
@ -170,6 +171,7 @@ config SYS_CONFIG_NAME
|
|||
default "maxbcm" if TARGET_MAXBCM
|
||||
default "theadorable" if TARGET_THEADORABLE
|
||||
default "turris_omnia" if TARGET_TURRIS_OMNIA
|
||||
default "armada-385-hw14" if TARGET_NM_HW14
|
||||
default "armada-385-nbhw18-v2" if TARGET_NM_NBHW18_V2
|
||||
default "armada-385-nbhw17-v1" if TARGET_NM_NBHW17_V1
|
||||
|
||||
|
|
@ -183,6 +185,7 @@ config SYS_VENDOR
|
|||
default "solidrun" if TARGET_CLEARFOG
|
||||
default "Synology" if TARGET_DS414
|
||||
default "CZ.NIC" if TARGET_TURRIS_OMNIA
|
||||
default "nm" if TARGET_NM_HW14
|
||||
default "nm" if TARGET_NM_NBHW18_V1
|
||||
default "nm" if TARGET_NM_NBHW18_V2
|
||||
default "nm" if TARGET_NM_NBHW17_V1
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@
|
|||
|
||||
static struct mbus_win windows[] = {
|
||||
/* SPI */
|
||||
{ MBUS_SPI_BASE, MBUS_SPI_SIZE,
|
||||
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH },
|
||||
/* @@NM@@MR@@ Conflicts with the windows for the HW14 gpio extension */
|
||||
/*{ MBUS_SPI_BASE, MBUS_SPI_SIZE,
|
||||
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH }, */
|
||||
|
||||
/* NOR */
|
||||
{ MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "nbhw_bd.h"
|
||||
|
||||
static const BD_Context *bdctx_list; /* The board descriptor context */
|
||||
static size_t bdctx_count = 0;
|
||||
static size_t bdctx_count = 0;
|
||||
|
||||
void bd_register_context_list(const BD_Context *list, size_t count) {
|
||||
bdctx_list = list;
|
||||
|
|
@ -37,8 +37,8 @@ void bd_register_context_list(const BD_Context *list, size_t count) {
|
|||
int bd_get_context(BD_Context *bdctx, uint32_t i2caddress, uint32_t offset)
|
||||
{
|
||||
bd_bool_t rc;
|
||||
uint8_t bdHeader[8];
|
||||
void* pBdData = NULL;
|
||||
uint8_t bdHeader[8];
|
||||
void* pBdData = NULL;
|
||||
/* Read header bytes from beginning of EEPROM */
|
||||
if (i2c_read( i2caddress, offset, 2, bdHeader, BD_HEADER_LENGTH )) {
|
||||
printf("%s() Can't read BD header from EEPROM\n", __func__);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ void set_console(void)
|
|||
char buf[6];
|
||||
char consolefile[] = "/root/boot/consoledev";
|
||||
char *defaultconsole = env_get("defaultconsole");
|
||||
int use_default_console = 0;
|
||||
|
||||
#if defined(CONFIG_PRE_CONSOLE_BUFFER)
|
||||
int len = 0;
|
||||
|
|
@ -28,17 +29,28 @@ void set_console(void)
|
|||
read_file_set_blk_dev("mmc", "0:3", FS_TYPE_EXT);
|
||||
|
||||
len = get_file_size(consolefile);
|
||||
if (len>=5) {
|
||||
read_file(consolefile, buf, sizeof(buf));
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
if ((strstr(buf, "tty")!=buf) || ((buf[4]<'0') && (buf[4]>'1'))) {
|
||||
if (len>=4) {
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
read_file(consolefile, buf, sizeof(buf)-1);
|
||||
if (strstr(buf, "ttyS")==buf) {
|
||||
if ((buf[4]<'0') && (buf[4]>'1')) {
|
||||
/* invalid tty specified */
|
||||
use_default_console = 1;
|
||||
} else {
|
||||
/* Use retrieved ttySx */
|
||||
}
|
||||
} else if (strstr(buf, "none")==buf) {
|
||||
/* disable console */
|
||||
buf[0] = 0;
|
||||
} else {
|
||||
/* invalid device specified */
|
||||
use_default_console = 1;
|
||||
}
|
||||
} else {
|
||||
buf[0] = 0;
|
||||
use_default_console = 1;
|
||||
}
|
||||
|
||||
if (buf[0] == 0) {
|
||||
if (use_default_console) {
|
||||
strncpy(buf, defaultconsole, sizeof(buf));
|
||||
}
|
||||
printf("consoledev: %s\n", buf);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ struct nbhw_fpga_priv {
|
|||
struct gpio_desc ss;
|
||||
struct gpio_desc sck;
|
||||
struct gpio_desc sdi;
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
struct gpio_desc sdo;
|
||||
#endif
|
||||
struct gpio_desc reset;
|
||||
struct gpio_desc reset_logic;
|
||||
struct gpio_desc cdone;
|
||||
|
|
@ -72,6 +74,8 @@ void tickdelay(void)
|
|||
while (get_ticks() < curtick+1); /* loop till event */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
|
||||
static inline u8 spi_read_sspi(const struct nbhw_fpga_priv *priv)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -119,6 +123,8 @@ static inline void spi_write_sspi(const struct nbhw_fpga_priv *priv, u8 data)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline void spi_write(const struct nbhw_fpga_priv *priv, u8 data)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -130,13 +136,13 @@ static inline void spi_write(const struct nbhw_fpga_priv *priv, u8 data)
|
|||
{
|
||||
data_write = (data & 0x80) ? 1 : 0;
|
||||
/* Clear clk bit and put data on the line */
|
||||
dm_gpio_set_value(&priv->sck, 0);
|
||||
dm_gpio_set_value(&priv->sdi, data_write);
|
||||
udelay(1);
|
||||
dm_gpio_set_value(&priv->sck, 0);
|
||||
dm_gpio_set_value(&priv->sdi, data_write);
|
||||
tickdelay();
|
||||
/* Read data on rising edge */
|
||||
dm_gpio_set_value(&priv->sck, 1);
|
||||
dm_gpio_set_value(&priv->sck, 1);
|
||||
data = data << 1;
|
||||
udelay(1);
|
||||
tickdelay();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -153,19 +159,19 @@ static int fpga_verify(struct nbhw_fpga_priv *priv)
|
|||
|
||||
if (signature == 0xa501)
|
||||
{
|
||||
strcpy(fpga_type, "XC3S50A-4VQ100I top layer");
|
||||
strcpy(fpga_type, "XC3S50A-4VQ100I top layer HW14");
|
||||
} else if (signature == 0xa502) {
|
||||
strcpy(fpga_type, "XC3S200A-4VQ100I top layer");
|
||||
strcpy(fpga_type, "XC3S200A-4VQ100I top layer HW14");
|
||||
} else if (signature == 0xa511) {
|
||||
strcpy(fpga_type, "XC3S50A-4FTG256I bottom layer");
|
||||
strcpy(fpga_type, "XC3S50A-4FTG256I bottom layer HW14");
|
||||
} else if (signature == 0xa512) {
|
||||
strcpy(fpga_type, "XC3S200A-4FTG256I bottom layer");
|
||||
strcpy(fpga_type, "XC3S200A-4FTG256I bottom layer HW14");
|
||||
} else if (signature == 0x4004) {
|
||||
strcpy(fpga_type, "ICE40HX4K-CB132 NBHW17");
|
||||
strcpy(fpga_type, "ICE40HX4K-CB132 HW17");
|
||||
} else if (signature == 0x4184) {
|
||||
strcpy(fpga_type, "ICE40HX4K-CB132 NBHW18 V1");
|
||||
strcpy(fpga_type, "ICE40HX4K-CB132 HW18 V1");
|
||||
} else if (signature == 0x012f) {
|
||||
strcpy(fpga_type, "LFE5U-12F-6BG381I NBHW18 V2");
|
||||
strcpy(fpga_type, "LFE5U-12F-6BG381I HW18 V2");
|
||||
} else {
|
||||
priv->signature = signature;
|
||||
goto abort;
|
||||
|
|
@ -183,6 +189,8 @@ abort:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
|
||||
#define print_out_string printf
|
||||
extern unsigned int a_uiRowCount;
|
||||
void printError(int code){
|
||||
|
|
@ -246,6 +254,8 @@ void printError(int code){
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void put_in_prog_mode(const struct nbhw_fpga_priv *priv)
|
||||
{
|
||||
/* Change the muxing to GPIO */
|
||||
|
|
@ -255,6 +265,7 @@ static void put_in_prog_mode(const struct nbhw_fpga_priv *priv)
|
|||
printf("Put FPGA in programming mode\n");
|
||||
dm_gpio_set_value(&priv->ss, 1);
|
||||
udelay(10);
|
||||
|
||||
dm_gpio_set_value(&priv->ss, 0);
|
||||
dm_gpio_set_value(&priv->sck, 1);
|
||||
dm_gpio_set_value(&priv->reset, 1);
|
||||
|
|
@ -268,6 +279,8 @@ static void put_in_prog_mode(const struct nbhw_fpga_priv *priv)
|
|||
udelay(800);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
|
||||
static void put_in_prog_mode_lattice_sspi(const struct nbhw_fpga_priv *priv)
|
||||
{
|
||||
/* Change the muxing to GPIO */
|
||||
|
|
@ -297,13 +310,15 @@ static void put_in_prog_mode_lattice_sspi(const struct nbhw_fpga_priv *priv)
|
|||
debug("Initialised Reset with pulling PROGRAM~\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void clean_up_after_programming(const struct nbhw_fpga_priv *priv)
|
||||
{
|
||||
/* Change the muxing back to Devbus */
|
||||
writel(0x55555555, MVEBU_MPP_BASE + 0x10);
|
||||
writel(0x06605505, MVEBU_MPP_BASE + 0x14);
|
||||
|
||||
//dm_gpio_set_value(&priv->reset_logic, 0); //TODO : that seems wrong (AO)
|
||||
dm_gpio_set_value(&priv->reset_logic, 0); //TODO : that seems wrong (AO)
|
||||
udelay(100);
|
||||
dm_gpio_set_value(&priv->reset_logic, 1);
|
||||
udelay(100);
|
||||
|
|
@ -326,13 +341,6 @@ static int fpga_load_bitstream (const struct nbhw_fpga_priv *priv, const u8* dat
|
|||
|
||||
debug("Configuration sent\n");
|
||||
|
||||
if (dm_gpio_get_value(&priv->cdone)) {
|
||||
printf("Error: Fpga does not signal done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("FPGA signals done\n");
|
||||
|
||||
/* Send some extra clocks for startup */
|
||||
for ( i=0; i<100; i++)
|
||||
{
|
||||
|
|
@ -344,25 +352,6 @@ static int fpga_load_bitstream (const struct nbhw_fpga_priv *priv, const u8* dat
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
|
||||
static int fpga_load_bitstream_lattice_sspi (const struct nbhw_fpga_priv *priv,
|
||||
const u8* pBitstreamAddr, int pBitstreamSize,
|
||||
const u8* pAlgoAddr, int pAlgoSize)
|
||||
{
|
||||
int siRetCode;
|
||||
siRetCode = SSPIEm_preset(pAlgoAddr, pAlgoSize, pBitstreamAddr, pBitstreamSize);
|
||||
siRetCode = SSPIEm(0xFFFFFFFF);
|
||||
if ( siRetCode != 2 ) {
|
||||
printError(siRetCode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int fpga_check_bitstream_lattice(const struct nbhw_fpga_priv *priv,
|
||||
const u8* fpgadata, int dataNumBytes,
|
||||
const u8** pBitstreamAddr, int* pBitstreamSize)
|
||||
|
|
@ -384,6 +373,23 @@ static int fpga_check_bitstream_lattice(const struct nbhw_fpga_priv *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
|
||||
static int fpga_load_bitstream_lattice_sspi (const struct nbhw_fpga_priv *priv,
|
||||
const u8* pBitstreamAddr, int pBitstreamSize,
|
||||
const u8* pAlgoAddr, int pAlgoSize)
|
||||
{
|
||||
int siRetCode;
|
||||
siRetCode = SSPIEm_preset(pAlgoAddr, pAlgoSize, pBitstreamAddr, pBitstreamSize);
|
||||
siRetCode = SSPIEm(0xFFFFFFFF);
|
||||
if ( siRetCode != 2 ) {
|
||||
printError(siRetCode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CHECKMARKER(index, a, b, c, d) ((fpgadata[index]==a) && (fpgadata[index+1]==b) \
|
||||
&& (fpgadata[index+2]==c) && (fpgadata[index+3]==d))
|
||||
|
||||
|
|
@ -432,6 +438,8 @@ abort:
|
|||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Legacy Xilinx check ported from PPC, seems to work */
|
||||
static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv,
|
||||
const u8* fpgadata, int dataNumBytes,
|
||||
|
|
@ -474,10 +482,6 @@ static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv,
|
|||
|
||||
printf(" design filename = \"%s\"\n", buffer);
|
||||
|
||||
/* verify fpga identifier */
|
||||
if (priv->fpga_id == 0xFFFFFFFF) {
|
||||
return 0;
|
||||
}
|
||||
p = strstr(buffer, "UserID=0x");
|
||||
if (p) {
|
||||
p += 9;
|
||||
|
|
@ -496,10 +500,13 @@ static int fpga_check_bitstream_xilinx(const struct nbhw_fpga_priv *priv,
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
if (fpgaid != priv->fpga_id) {
|
||||
printf("%s: User identifier not matched in bitstream\n",
|
||||
__FUNCTION__ );
|
||||
return -1;
|
||||
/* verify fpga identifier */
|
||||
if (priv->fpga_id != 0xFFFFFFFF) {
|
||||
if (fpgaid != priv->fpga_id) {
|
||||
printf("%s: User identifier not matched in bitstream\n",
|
||||
__FUNCTION__ );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("%s: User identifier not found in bitstream\n",
|
||||
|
|
@ -580,21 +587,24 @@ static int fpga_check_bitstream(const struct nbhw_fpga_priv *priv,
|
|||
|
||||
debug("check bitstream %d, %0x, %0x\n", *pBitstreamSize, fpgadata[0],
|
||||
fpgadata[1]);
|
||||
|
||||
/* Lattice header starts with 0xFF00 followed by comment */
|
||||
if (fpgadata[0] == 0xFF && fpgadata[1] == 0x00) {
|
||||
return fpga_check_bitstream_lattice(priv, fpgadata, dataNumBytes, pBitstreamAddr, pBitstreamSize);
|
||||
}
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
/* Lattice SSPI header starts with 0xae 0x00 0x00 0x01 (SEA tag) */
|
||||
else if(fpgadata[0] == 0xae && fpgadata[1] == 0x00) {
|
||||
return fpga_check_bitstream_lattice_sspi(priv, fpgadata, dataNumBytes,
|
||||
pBitstreamAddr, pBitstreamSize,
|
||||
pAlgoAddr, pAlgoSize);
|
||||
}
|
||||
#else
|
||||
/* Xilinx header starts with 0x00 0x09 which means header with 0x09 length */
|
||||
else if(fpgadata[0] == 0x00 && fpgadata[1] == 0x09) {
|
||||
if(fpgadata[0] == 0x00 && fpgadata[1] == 0x09) {
|
||||
return fpga_check_bitstream_xilinx(priv, fpgadata, dataNumBytes, pBitstreamAddr, pBitstreamSize);
|
||||
}
|
||||
|
||||
#endif
|
||||
printf("Unknown bitstream file format (not Xilinx nor Lattice)\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -675,7 +685,7 @@ static void setup_device_bus(void)
|
|||
|
||||
/* Device Bus Control Interface Register */
|
||||
val = readl(MV_DEV_BUS_REGS_OFFSET + 0xC0);
|
||||
debug("Device Bus Control Interface Regiseter (0x104C0): 0x%08X\n", val);
|
||||
debug("Device Bus Control Interface Register (0x104C0): 0x%08X\n", val);
|
||||
writel(0x5FFFF, MV_DEV_BUS_REGS_OFFSET + 0xC0);
|
||||
/* Device Bus Synchronous Control Register */
|
||||
val = readl(MV_DEV_BUS_REGS_OFFSET + 0xC8);
|
||||
|
|
@ -727,15 +737,15 @@ static int request_gpios(struct udevice *dev)
|
|||
printf("Could not request spi-gpio sdi\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
if (gpio_request_by_name(dev, "spi-sdo", 0, &priv->sdo, GPIOD_IS_IN) != 0) {
|
||||
printf("Could not request spi-gpio sdo\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (gpio_request_by_name(dev, "fpga-reset", 0, &priv->reset, GPIOD_IS_OUT) != 0) {
|
||||
printf("Could not request fpga-reset\n");
|
||||
return -1;
|
||||
debug("Could not request fpga-reset\n");
|
||||
}
|
||||
|
||||
if (gpio_request_by_name(dev, "fpga-cdone", 0, &priv->cdone, GPIOD_IS_IN) != 0) {
|
||||
|
|
@ -777,15 +787,15 @@ static int fpga_program(struct udevice *dev, unsigned long load_addr,
|
|||
}
|
||||
}
|
||||
|
||||
/* Make sure device bus works, because HW14 uses its gpios to do SPI */
|
||||
setup_device_bus();
|
||||
|
||||
/* NBHW_BASE_ADDRESS_FPGA points to base of FPGA registers */
|
||||
if (!fpga_boot_buffer(priv, (const u8*)load_addr, filesize)) {
|
||||
printf ("Loading FPGA over SPI failed.\n");
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* Make sure device bus works, becaus NBHW14 uses its gpios to do SPI */
|
||||
setup_device_bus();
|
||||
|
||||
/* Verify, if FPGA is loaded successfully */
|
||||
i = 0;
|
||||
do {
|
||||
|
|
@ -1032,6 +1042,7 @@ U_BOOT_DRIVER(gpio_nbhw_fpga) = {
|
|||
.ops = &nbhw_fpga_ops,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_FPGA_LATTICE_SSPI
|
||||
/* Lattice SSPI programming tool wrappers */
|
||||
|
||||
void FPGA_START(void) {
|
||||
|
|
@ -1060,3 +1071,4 @@ void FPGA_CS_HIGH(void)
|
|||
dm_gpio_set_value(&FPGA_PRIV->ss, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6,16 +6,16 @@
|
|||
#define FPGA_REG(x) *((volatile unsigned short*)( NBHW_BASE_ADDRESS_FPGA + ((unsigned int)x)))
|
||||
|
||||
typedef enum _fpga_type {
|
||||
FPGA_TYPE_NONE,
|
||||
FPGA_TYPE_XILINX,
|
||||
FPGA_TYPE_LATTICE,
|
||||
FPGA_TYPE_NONE,
|
||||
FPGA_TYPE_XILINX,
|
||||
FPGA_TYPE_LATTICE,
|
||||
}fpga_type;
|
||||
|
||||
typedef struct _fpga_prog_operation {
|
||||
void (*pre_programming)(void);
|
||||
void (*post_programming)(void);
|
||||
void (*spi_write)(u8);
|
||||
int (*check_bitstream_compatibility)(fpga_type, u32);
|
||||
int (*check_bitstream_compatibility)(fpga_type, u32);
|
||||
} fpga_prog_operation;
|
||||
|
||||
int nbhw_fpga_program(void);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -34,7 +34,7 @@ static void set_mac(int interface, uint8_t macaddress[], size_t size)
|
|||
/* Serial number consists of 1st MAC address */
|
||||
env_set("ethaddr", macstring);
|
||||
}
|
||||
/* Always set eth%daddr because newer u-boots expect it */
|
||||
/* Always set eth%daddr because newer u-boots expect it */
|
||||
{
|
||||
char ethaddr[32];
|
||||
|
||||
|
|
@ -45,23 +45,20 @@ static void set_mac(int interface, uint8_t macaddress[], size_t size)
|
|||
}
|
||||
}
|
||||
|
||||
void set_mac_addresses(int interfaces) {
|
||||
void set_mac_address(int interface, int mac) {
|
||||
uint8_t macaddress[6];
|
||||
int i;
|
||||
|
||||
/* If the compiler does inlining direct initialization of macaddress
|
||||
* fails, this is the safer way */
|
||||
/* If the compiler does inlining direct initialization of macaddress
|
||||
* fails, this is the safer way */
|
||||
memset(macaddress, 0x11, sizeof(macaddress));
|
||||
|
||||
for (i = 0; i < interfaces; i++) {
|
||||
if(bd_get_mac(i, macaddress, 6) == 0)
|
||||
set_mac(i, macaddress, 6);
|
||||
else {
|
||||
/* make temporary address */
|
||||
macaddress[0] = 0;
|
||||
macaddress[5] += 1;
|
||||
set_mac(i, macaddress, 6);
|
||||
}
|
||||
if (bd_get_mac(mac, macaddress, 6) == 0)
|
||||
set_mac(interface, macaddress, 6);
|
||||
else {
|
||||
/* make temporary address */
|
||||
macaddress[0] = 0;
|
||||
macaddress[5] += 1;
|
||||
set_mac(interface, macaddress, 6);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#ifndef _NBHW_INIT_H
|
||||
#define _NBHW_INIT_H
|
||||
|
||||
void set_mac_addresses(int interfaces);
|
||||
void set_mac_address(int interface, int mac);
|
||||
|
||||
#endif // _NBHW_INIT_H
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ static int has_slot_wlan(int slot)
|
|||
char pdValue[200];
|
||||
|
||||
sprintf(slotDescr, "slot=%d", slot);
|
||||
for (module=0; module<4; module++) {
|
||||
for (module=0; module<6; module++) {
|
||||
strcpy(pdValue, "" ); /*init with an empty string*/
|
||||
if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) {
|
||||
/* Wifi module needs PCIe */
|
||||
|
|
@ -127,7 +127,6 @@ static int has_pcie_link_on_slot(int slot)
|
|||
default:
|
||||
printf("Slot %d does not support PCIE\n", slot);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +226,7 @@ static void wait_for_reset(int reset_counter)
|
|||
* boot */
|
||||
static int do_wlan_fixup(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
#define MAX_RESET_COUNT 6
|
||||
int reset_counter = get_reset_counter();
|
||||
int ret;
|
||||
|
|
@ -244,11 +243,10 @@ static int do_wlan_fixup(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
|
|||
|
||||
/* Try it for at least one second */
|
||||
for (i = 0; i < 100; i++) {
|
||||
ret = 3;
|
||||
if (check_pcie_slot_status(0)) ret &= ~1;
|
||||
|
||||
if (check_pcie_slot_status(1)) ret &= ~2;
|
||||
|
||||
ret = 0x3f;
|
||||
for (j = 0; j < 6; j++) {
|
||||
if (check_pcie_slot_status(j)) ret &= ~(1 << j);
|
||||
}
|
||||
if (is_module_check_abort()) {
|
||||
puts("Abort WLAN module check\n");
|
||||
ret = 0;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 10’s timing only and only if Port 10 is
|
||||
* configured in RGMII mode" so it seems this is the way to go...
|
||||
*/
|
||||
miiphy_read(miidev, 0x16, 0x1a, &value);
|
||||
value |= 0x0600;
|
||||
miiphy_write(miidev, 0x16, 0x1a, value);
|
||||
|
||||
/* Configure external phy 8 and 9 led */
|
||||
for (i = 0x08; i <= 0x09; i++) {
|
||||
miiphy_read(miidev, i, 0x16, &page);
|
||||
miiphy_write(miidev, i, 0x16, 0x0003);
|
||||
miiphy_read(miidev, i, 0x10, &value);
|
||||
value &= ~0x0F0F;
|
||||
value |= 0x0E01;
|
||||
miiphy_write(miidev, i, 0x10, value);
|
||||
miiphy_write(miidev, i, 0x16, page);
|
||||
}
|
||||
|
||||
/*Enable PPU*/
|
||||
miiphy_write(miidev, 0x1b, 0x0004, 0x4080);
|
||||
|
||||
/* select eth1 */
|
||||
env_set("ethact", "ethernet@30000");
|
||||
|
||||
break;
|
||||
|
||||
case MVS_88E6060 :
|
||||
/* Disable bridging between external ethernet ports */
|
||||
miiphy_write(miidev, 0x08, 0x06, 0x0020);
|
||||
miiphy_write(miidev, 0x09, 0x06, 0x0020);
|
||||
miiphy_write(miidev, 0x0a, 0x06, 0x0020);
|
||||
miiphy_write(miidev, 0x0b, 0x06, 0x0020);
|
||||
miiphy_write(miidev, 0x0c, 0x06, 0x0020);
|
||||
miiphy_write(miidev, 0x0d, 0x06, 0x001f);
|
||||
|
||||
/* Enable all ethernet ports */
|
||||
miiphy_write(miidev, 0x08, 0x04, 0x0003);
|
||||
miiphy_write(miidev, 0x09, 0x04, 0x0003);
|
||||
miiphy_write(miidev, 0x0a, 0x04, 0x0003);
|
||||
miiphy_write(miidev, 0x0b, 0x04, 0x0003);
|
||||
miiphy_write(miidev, 0x0c, 0x04, 0x0003);
|
||||
miiphy_write(miidev, 0x0d, 0x04, 0x0003);
|
||||
|
||||
/* select eth0 */
|
||||
env_set("ethact", "ethernet@70000");
|
||||
|
||||
break;
|
||||
|
||||
case MVS_UNKNOWN :
|
||||
default :
|
||||
printf("No or unknown ethernet switch detected!");
|
||||
goto abort;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int configure_mvswitch(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = check_mvswitch();
|
||||
if (res) goto abort;
|
||||
|
||||
res = init_mvswitch();
|
||||
if (res) goto abort;
|
||||
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum MvSwitchType get_mvswitch_type(void)
|
||||
{
|
||||
return mvSwType;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -16,9 +16,14 @@ commonobj = ../common/bdparser.o \
|
|||
ccflags-y := -I../common
|
||||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-y := board.o nbhw_gpio.o nbhw_fpga_config.o $(commonobj)
|
||||
obj-y := board.o nbhw_gpio.o nbhw_fpga_config.o \
|
||||
$(commonobj)
|
||||
else
|
||||
obj-y := board.o nbhw_gpio.o ../common/nbhw_bd.o ../common/nbhw_partitions.o
|
||||
obj-y := board.o \
|
||||
../common/nbhw_bd.o \
|
||||
../common/nbhw_partitions.o \
|
||||
../common/bdparser.o \
|
||||
../common/nbhw_bd.o
|
||||
endif
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#define DEBUG
|
||||
#undef DEBUG
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <miiphy.h>
|
||||
|
|
@ -15,6 +15,10 @@
|
|||
#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>
|
||||
|
||||
|
|
@ -24,38 +28,60 @@
|
|||
#include "../common/nbhw_env.h"
|
||||
#include "../common/nbhw_bd.h"
|
||||
|
||||
#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h"
|
||||
#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
|
||||
#include <../serdes/a38x/high_speed_env_spec.h>
|
||||
|
||||
//#define EARLY_CONSOLE_OUTPUT
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Those values and defines are taken from the Marvell U-Boot version
|
||||
* "u-boot-2013.01-2014_T3.0"
|
||||
*/
|
||||
#define GPP_OUT_ENA_LOW (~(BIT(7) | BIT(19) | BIT(21))) /* 1=Input, default input */
|
||||
/* 21: RST_ETH_PHYS~, 26: FPGA_CFG_RESET, 27: WD_ENABLE~ */
|
||||
#define GPP_OUT_ENA_LOW (~(BIT(21) | BIT(26) /*| BIT(27) */)) /* 1=Input, default input */
|
||||
/* 41/9: RST_USB_HUB~, 44/12: RST_FPGA~, 47/15: WD_TRIG */
|
||||
#define GPP_OUT_ENA_MID (~(BIT(9) | BIT(12) | BIT(15)))
|
||||
|
||||
#define GPP_OUT_ENA_MID (~(BIT(9) | BIT(12)))
|
||||
#define GPP_OUT_VAL_LOW (BIT(21)) /* 1=pin on */
|
||||
#define GPP_OUT_VAL_MID (0x0)
|
||||
#define GPP_POL_LOW (0x0) /* 0=no inversion */
|
||||
#define GPP_POL_MID (0x0)
|
||||
|
||||
#define GPP_OUT_VAL_LOW (~(BIT(21) | BIT(26) | BIT(27)))
|
||||
#define GPP_OUT_VAL_MID (~(BIT(9) | BIT(12) | BIT(15)))
|
||||
#define GPP_POL_LOW (BIT(21)) /* 1=pin on */
|
||||
#define GPP_POL_MID 0x0
|
||||
|
||||
#define BD_EEPROM_ADDR (0x50) /* CPU BD EEPROM (8kByte) is at 50 (A0) */
|
||||
#define BD_ADDRESS (0x0000) /* Board descriptor at beginning of EEPROM */
|
||||
#define PD_ADDRESS (0x0200) /* Product descriptor */
|
||||
#define PARTITION_ADDRESS (0x0600) /* Partition Table */
|
||||
#define BD_EEPROM_ADDR (0x50) /* CPU BD EEPROM (8kByte) is at 50 (A0) */
|
||||
#define BD_ADDRESS (0x0000) /* Board descriptor at beginning of EEPROM */
|
||||
#define PD_ADDRESS (0x0200) /* Product descriptor */
|
||||
#define PARTITION_ADDRESS (0x0600) /* Partition Table */
|
||||
#define SERDES_CONFIG_ADDRESS (0x0800) /* SERDES config address */
|
||||
|
||||
#define DEV_CS0_BASE 0xfd000000
|
||||
|
||||
/* Chip select base addresses */
|
||||
#define NBHW_BASE_ADDRESS_FPGA DEV_CS0_BASE
|
||||
|
||||
/* Compute FPGA register addresses */
|
||||
#define FPGA_REG(x) *((volatile unsigned short*)( NBHW_BASE_ADDRESS_FPGA + ((unsigned int)x)))
|
||||
|
||||
#define PCIE_4_PCM_GPIO_EN (0x0430)
|
||||
#define PCIE_4_PCM_GPIO_DIR (0x0432)
|
||||
#define PCIE_4_PCM_GPIO_DAT (0x0434)
|
||||
|
||||
/* TODO: These platform specific SERDES default definitions are
|
||||
currently defined twice here and in by hws_board_topology_load().
|
||||
Actually these platform specific defaults should only be set
|
||||
in hws_board_topology_load().
|
||||
The defaults should there be set also for the case where we have
|
||||
a valid BD but that BD does not contain SERDES configuration
|
||||
info to support old HW14 boards.
|
||||
*/
|
||||
static struct serdes_map board_serdes_map[] = {
|
||||
{ PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 },
|
||||
{ SGMII1, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 },
|
||||
{ SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0 },
|
||||
{ SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 },
|
||||
{ PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 },
|
||||
{ USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0 }
|
||||
{ USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0 }
|
||||
};
|
||||
|
||||
enum serdes_type get_serdes_type(int index)
|
||||
|
|
@ -68,8 +94,223 @@ enum serdes_type get_serdes_type(int index)
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct __attribute__ ((packed)) EthPhyRegs {
|
||||
int page;
|
||||
int reg;
|
||||
int reserved;
|
||||
int data;
|
||||
} EthPhyRegs;
|
||||
|
||||
const EthPhyRegs NB2800_ETH_PHY_REGS[] = {
|
||||
{ 0x0003, 0x0010, 0, 0x1032 }, /* LED function control register */
|
||||
{ 0x0003, 0x0011, 0, 0x4405 }, /* LED polarity control register */
|
||||
{ 0x0003, 0x0012, 0, 0x4a08 }, /* LED timer control register */
|
||||
{ -1, -1, -1, -1 }
|
||||
};
|
||||
|
||||
const EthPhyRegs NB2810_ETH_PHY_REGS[] = {
|
||||
{ 0x0003, 0x0010, 0, 0x1418 }, /* LED function control register */
|
||||
{ 0x0003, 0x0011, 0, 0x442a }, /* LED polarity control register */
|
||||
{ 0x0003, 0x0012, 0, 0x4a08 }, /* LED timer control register */
|
||||
{ -1, -1, -1, -1 }
|
||||
};
|
||||
|
||||
const EthPhyRegs* sSelectedPhyRegs = 0;
|
||||
|
||||
static BD_Context bdctx[3]; /* The descriptor context */
|
||||
|
||||
static int _bd_init(void)
|
||||
{
|
||||
if (bd_get_context(&bdctx[0], BD_EEPROM_ADDR, BD_ADDRESS) != 0) {
|
||||
printf("%s() no valid bd found\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bd_get_context(&bdctx[1], BD_EEPROM_ADDR, PD_ADDRESS) != 0) {
|
||||
/* Ignore that, legacy boxes don't have a pd */
|
||||
}
|
||||
|
||||
if (bd_get_context(&bdctx[2], BD_EEPROM_ADDR, PARTITION_ADDRESS) != 0) {
|
||||
printf("%s() no valid partition table found\n", __func__);
|
||||
}
|
||||
|
||||
bd_register_context_list(bdctx, ARRAY_SIZE(bdctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct EEPROM_SERDES_CONFIG {
|
||||
uint8_t magic[2];
|
||||
uint8_t version;
|
||||
uint8_t spare_0;
|
||||
uint8_t serdes_cfg[6];
|
||||
uint8_t spare1[2];
|
||||
uint32_t crc32;
|
||||
} EEPROM_SERDES_CONFIG;
|
||||
|
||||
static struct EEPROM_SERDES_CONFIG eeprom_serdes_config;
|
||||
|
||||
static void read_eeprom_serdes_config(void)
|
||||
{
|
||||
uint32_t crc;
|
||||
if (i2c_read(BD_EEPROM_ADDR, SERDES_CONFIG_ADDRESS, 2, (uint8_t *)&eeprom_serdes_config, sizeof(eeprom_serdes_config))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
crc = crc32(0, (uint8_t *)&eeprom_serdes_config, sizeof(eeprom_serdes_config)-4);
|
||||
|
||||
if ((eeprom_serdes_config.magic[0] != 0x83) ||
|
||||
(eeprom_serdes_config.magic[1] != 0xfb) ||
|
||||
(eeprom_serdes_config.version != 0x01) ||
|
||||
(eeprom_serdes_config.crc32 != crc))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printf("Using user defined serdes config override\n");
|
||||
return;
|
||||
|
||||
fail:
|
||||
memset(&eeprom_serdes_config, 0xff, sizeof(eeprom_serdes_config));
|
||||
printf("Using default serdes config (No user defined override)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8_t get_eeprom_serdes_config(int serdes_index)
|
||||
{
|
||||
if ((serdes_index<0) || (serdes_index>=sizeof(eeprom_serdes_config.serdes_cfg))) return 0xff;
|
||||
return eeprom_serdes_config.serdes_cfg[serdes_index];
|
||||
}
|
||||
|
||||
|
||||
static inline int __maybe_unused read_eeprom(void)
|
||||
{
|
||||
int res = _bd_init();
|
||||
|
||||
read_eeprom_serdes_config();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define RESET_REASON_SHM_LOCATION (0x3ffff000)
|
||||
|
||||
extern int console_init_f(void);
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
|
||||
static int init_console(void)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *dev;
|
||||
char *consoledev;
|
||||
char buf[16] = "serial@12100";
|
||||
|
||||
debug("init console\n");
|
||||
|
||||
/* Make sure all devices are probed, it seems
|
||||
* that this stuff is buggy in U-Boot */
|
||||
ret = uclass_first_device(UCLASS_SERIAL, &dev);
|
||||
if (ret) {
|
||||
printf("Could not find any serial device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (list_is_last(&dev->uclass_node, &dev->uclass->dev_head) == 0) {
|
||||
uclass_next_device(&dev);
|
||||
}
|
||||
|
||||
set_console();
|
||||
|
||||
consoledev = env_get("consoledev");
|
||||
if (strncmp(consoledev, "ttyS0", 5) == 0) {
|
||||
strncpy(buf, "serial@12000", sizeof(buf));
|
||||
}
|
||||
|
||||
env_set("stdin", buf);
|
||||
env_set("stdout", buf);
|
||||
env_set("stderr", buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (read_eeprom() < 0){
|
||||
puts("Could not read board descriptor using default serdes config.\n");
|
||||
|
||||
board_serdes_map[0].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[0].serdes_mode = PEX_ROOT_COMPLEX_X1;
|
||||
board_serdes_map[0].serdes_type = PEX0;
|
||||
|
||||
board_serdes_map[1].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
board_serdes_map[1].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
board_serdes_map[1].serdes_type = SGMII1;
|
||||
|
||||
board_serdes_map[2].serdes_speed = SERDES_SPEED_3_GBPS;
|
||||
board_serdes_map[2].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
board_serdes_map[2].serdes_type = SATA1;
|
||||
|
||||
board_serdes_map[3].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
board_serdes_map[3].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
board_serdes_map[3].serdes_type = SGMII2;
|
||||
|
||||
board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[4].serdes_mode = PEX_ROOT_COMPLEX_X1;
|
||||
board_serdes_map[4].serdes_type = PEX2;
|
||||
|
||||
board_serdes_map[5].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[5].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
board_serdes_map[5].serdes_type = USB3_HOST1;
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_SIZE(board_serdes_map); i++) {
|
||||
enum serdes_type type;
|
||||
uint8_t user_config = get_eeprom_serdes_config(i);
|
||||
|
||||
if (user_config != 0xff) {
|
||||
/* if we have a user config we use that one */
|
||||
type = (enum serdes_type)user_config;
|
||||
} else {
|
||||
/* otherwise we use the config from the bd */
|
||||
type = bd_get_serdes_type(i);
|
||||
}
|
||||
|
||||
if (type < LAST_SERDES_TYPE) {
|
||||
if ((type >= SGMII0) && (type <= SGMII2)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
}
|
||||
else if ((type >= PEX0) && (type <= PEX3)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1;
|
||||
}
|
||||
else if ((type >= USB3_HOST0) && (type <= USB3_HOST1)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1;
|
||||
}
|
||||
else if ((type >= SATA0) && (type <= SATA3)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_3_GBPS;
|
||||
board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
}
|
||||
else if ((type == DEFAULT_SERDES)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
} else {
|
||||
printf("SERDES Type %d not supported\n", type);
|
||||
/* Keep default serdes configuration */
|
||||
type = board_serdes_map[i].serdes_type;
|
||||
}
|
||||
|
||||
debug("Configure SERDES %d to %d\n", i, type);
|
||||
|
||||
board_serdes_map[i].serdes_type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*serdes_map_array = board_serdes_map;
|
||||
*count = ARRAY_SIZE(board_serdes_map);
|
||||
return 0;
|
||||
|
|
@ -80,30 +321,65 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
|
|||
* be used by the DDR3 init code in the SPL U-Boot version to configure
|
||||
* the DDR3 controller.
|
||||
*/
|
||||
static struct hws_topology_map board_topology_map = {
|
||||
static struct mv_ddr_topology_map board_topology_map = {
|
||||
DEBUG_LEVEL_ERROR,
|
||||
0x1, /* active interfaces */
|
||||
/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
|
||||
{ { { {0x1, 0, 0, 0},
|
||||
{0x1, 0, 0, 0},
|
||||
{0x1, 0, 0, 0},
|
||||
{0x1, 0, 0, 0},
|
||||
{0x1, 0, 0, 0} },
|
||||
SPEED_BIN_DDR_1600K, /* speed_bin */
|
||||
BUS_WIDTH_16, /* memory_width */
|
||||
MEM_4G, /* mem_size */
|
||||
DDR_FREQ_667, /* frequency */
|
||||
7, 9, /* cas_l cas_wl */
|
||||
HWS_TEMP_HIGH} }, /* temperature */
|
||||
5, /* Num Of Bus Per Interface*/
|
||||
BUS_MASK_32BIT /* Busses mask */
|
||||
{0x1, 0, 0, 0},
|
||||
{0x1, 0, 0, 0},
|
||||
{0x1, 0, 0, 0},
|
||||
{0x1, 0, 0, 0} },
|
||||
SPEED_BIN_DDR_1600K, /* speed_bin */
|
||||
MV_DDR_DEV_WIDTH_16BIT, /* sdram device width */
|
||||
MV_DDR_DIE_CAP_4GBIT, /* die capacity */
|
||||
MV_DDR_FREQ_667, /* frequency */
|
||||
0, 0, /* cas_l cas_wl */
|
||||
MV_DDR_TEMP_HIGH} }, /* temperature */
|
||||
BUS_MASK_32BIT, /* subphys mask */
|
||||
MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
|
||||
{ {0} }, /* raw spd data */
|
||||
{0} /* timing parameters */
|
||||
};
|
||||
|
||||
struct hws_topology_map *ddr3_get_topology_map(void)
|
||||
struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
|
||||
{
|
||||
/* Return the board topology as defined in the board code */
|
||||
return &board_topology_map;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
|
||||
void watchdog_init(void)
|
||||
{
|
||||
/* NOTE: Global watchdog counter register is at 0xf1020334
|
||||
Could not find this in the manual. */
|
||||
if (uclass_get_device(UCLASS_WDT, 0, (struct udevice **)&(gd->watchdog))) {
|
||||
puts("Cannot enable watchdog!\n");
|
||||
} else {
|
||||
puts("Enabling watchdog\n");
|
||||
wdt_start(gd->watchdog, (u32) 25000000 * 150, 0); /* Timer runs at 25 MHz */
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by macro WATCHDOG_RESET */
|
||||
void watchdog_reset(void)
|
||||
{
|
||||
static ulong next_reset = 0;
|
||||
ulong now;
|
||||
|
||||
if (!(gd->watchdog)) return;
|
||||
|
||||
now = timer_get_us();
|
||||
|
||||
/* Do not reset the watchdog too often */
|
||||
if (now > next_reset) {
|
||||
wdt_reset(gd->watchdog);
|
||||
next_reset = now + 1000000;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
/* Configure MPP */
|
||||
|
|
@ -141,50 +417,22 @@ void spl_board_init(void)
|
|||
int err;
|
||||
struct mmc *mmcp;
|
||||
|
||||
err = mmc_initialize(NULL);
|
||||
err = mmc_initialize(0);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
puts("SPL: select partition\n");
|
||||
debug("SPL: select partition\n");
|
||||
mmcp = find_mmc_device(0);
|
||||
mmc_init(mmcp);
|
||||
printf("Partition found: %p\n", mmcp);
|
||||
/* select boot0 as bootpart */
|
||||
/* select boot0 as first boot partition */
|
||||
mmcp->part_config &= ~(PART_ACCESS_MASK << 3);
|
||||
mmcp->part_config |= (1 << 3);
|
||||
puts("Partition switched to boot0\n");
|
||||
debug("Boot partition set to boot0\n");
|
||||
}
|
||||
|
||||
static BD_Context bdctx[3]; /* The descriptor context */
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
|
||||
static int _bd_init(void)
|
||||
{
|
||||
if (bd_get_context(&bdctx[0], BD_EEPROM_ADDR, BD_ADDRESS) != 0) {
|
||||
printf("%s() no valid bd found\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bd_get_context(&bdctx[1], BD_EEPROM_ADDR, PD_ADDRESS) != 0) {
|
||||
/* Ignore that, legacy boxes don't have a pd */
|
||||
}
|
||||
|
||||
if (bd_get_context(&bdctx[2], BD_EEPROM_ADDR, PARTITION_ADDRESS) != 0) {
|
||||
printf("%s() no valid partition table found\n", __func__);
|
||||
}
|
||||
|
||||
bd_register_context_list(bdctx, ARRAY_SIZE(bdctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int __maybe_unused read_eeprom(void)
|
||||
{
|
||||
return _bd_init();
|
||||
}
|
||||
|
||||
static void set_gpios(void)
|
||||
{
|
||||
init_gpios();
|
||||
}
|
||||
|
||||
static void pass_hw_rev(void)
|
||||
{
|
||||
|
|
@ -205,39 +453,201 @@ static void pass_hw_rev(void)
|
|||
snprintf(new_env, sizeof(new_env), "%s %s", old_env, hw_versions);
|
||||
}
|
||||
else {
|
||||
snprintf(new_env, sizeof(new_env), "env_set bootargs $bootargs %s\n", hw_versions);
|
||||
snprintf(new_env, sizeof(new_env), "setenv bootargs $bootargs %s", hw_versions);
|
||||
}
|
||||
|
||||
env_set("add_version_bootargs", new_env);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
watchdog_init();
|
||||
#endif
|
||||
|
||||
/* address of boot parameters */
|
||||
gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
|
||||
|
||||
/* Setup the MBUS mapping for Devicebus CS0 */
|
||||
/* Setup the MBUS mapping for Devicebus CS0 (FPGA) */
|
||||
mbus_dt_setup_win(&mbus_state, DEV_CS0_BASE, 16 << 20,
|
||||
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS0);
|
||||
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS0 /* 0x3e */);
|
||||
|
||||
if (read_eeprom() < 0)
|
||||
puts("Could not get board ID.\n");
|
||||
|
||||
set_console();
|
||||
|
||||
set_gpios();
|
||||
|
||||
/* @@se: With this call we disable a debug feature, that allows one to read out the memory
|
||||
* over i2c at slave address 0x64. This feature is for some undocumented reasons enabled by default
|
||||
* the default value is 0x00370010, according to the documentation it should be 0x00330010. If we set
|
||||
* it back to this value address 0x64 is unused again. This is necessary because atsha204 uses 0x64 as
|
||||
* slave address.
|
||||
*/
|
||||
writel(0x00330010, INTER_REGS_BASE + 0x1108C);
|
||||
writel(0x00330010, SOC_REGS_PHY_BASE + 0x0001108c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_r(void)
|
||||
{
|
||||
/* We need to force mmc_initialization here, so that
|
||||
* we have mmc available for read of /boot/consoledev */
|
||||
mmc_initialize(gd->bd);
|
||||
/* We need to force the env relocation so that it won't overwritte the
|
||||
* serial devices that we set in init_console */
|
||||
env_relocate();
|
||||
gd->env_valid = ENV_VALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
|
||||
static bool get_button_state(void)
|
||||
{
|
||||
return (get_gpio(GPIO_RESET_BUTTON) == 0);
|
||||
}
|
||||
|
||||
static int check_reset_button(void)
|
||||
{
|
||||
int counter = 0;
|
||||
|
||||
/* Check how long button is pressed */
|
||||
do {
|
||||
if (!get_button_state())
|
||||
break;
|
||||
|
||||
udelay(100*1000); /* 100ms */
|
||||
counter += 100;
|
||||
|
||||
if (counter == 2000) {
|
||||
/* Indicate factory reset threshold */
|
||||
|
||||
/* let all green LEDs blink up */
|
||||
set_led(LED0_GREEN, 1);
|
||||
set_led(LED1_GREEN, 1);
|
||||
set_led(LED2_GREEN, 1);
|
||||
set_led(LED3_GREEN, 1);
|
||||
set_led(LED4_GREEN, 1);
|
||||
set_led(LED5_GREEN, 1);
|
||||
udelay(400000); /* 400ms */
|
||||
set_led(LED1_GREEN, 0);
|
||||
set_led(LED2_GREEN, 0);
|
||||
set_led(LED3_GREEN, 0);
|
||||
set_led(LED4_GREEN, 0);
|
||||
set_led(LED5_GREEN, 0);
|
||||
} else if (counter == 12000) {
|
||||
/* Indicate recovery boot threshold */
|
||||
|
||||
/* let all red LEDs blink up */
|
||||
set_led(LED0_GREEN, 0);
|
||||
set_led(LED0_RED, 1);
|
||||
set_led(LED1_RED, 1);
|
||||
set_led(LED2_RED, 1);
|
||||
set_led(LED3_RED, 1);
|
||||
set_led(LED4_RED, 1);
|
||||
set_led(LED5_RED, 1);
|
||||
udelay(400000); /* 400ms */
|
||||
set_led(LED0_RED, 0);
|
||||
set_led(LED1_RED, 0);
|
||||
set_led(LED2_RED, 0);
|
||||
set_led(LED3_RED, 0);
|
||||
set_led(LED4_RED, 0);
|
||||
set_led(LED5_RED, 0);
|
||||
set_led(LED0_GREEN, 1);
|
||||
}
|
||||
} while (counter < 12000);
|
||||
|
||||
if (counter < 2000) {
|
||||
/* Don't do anything for duration < 2s */
|
||||
}
|
||||
else if (counter < 12000)
|
||||
{
|
||||
/* Do factory reset for duration between 2s and 12s */
|
||||
char new_bootargs[512];
|
||||
char *bootargs = env_get("bootargs");
|
||||
|
||||
if (bootargs == 0) bootargs="";
|
||||
|
||||
printf("Do factory reset during boot...\n");
|
||||
|
||||
strncpy(new_bootargs, bootargs, sizeof(new_bootargs));
|
||||
strncat(new_bootargs, " factory-reset", sizeof(new_bootargs));
|
||||
|
||||
env_set("bootargs", new_bootargs);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Boot into recovery for duration > 12s */
|
||||
|
||||
printf("Booting recovery image...\n");
|
||||
|
||||
/* Set bootcmd to run recovery */
|
||||
env_set("bootcmd", "run recovery");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CMD_NB_TEST
|
||||
/*
|
||||
* Perform a hardware reset test. The complete test loops until
|
||||
* interrupted by ctrl-c or by pressed the RESET button.
|
||||
*/
|
||||
int do_hwreset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int gpio_cpu_value = 0;
|
||||
|
||||
printf(" Press RESET button for testing or ctrl-c to abort\n");
|
||||
|
||||
while (gpio_cpu_value == 0) {
|
||||
gpio_cpu_value = get_button_state() ? 1 : 0;
|
||||
|
||||
printf("RESET_BTN = %d\n",gpio_cpu_value);
|
||||
if (ctrlc()) {
|
||||
putc ('\n');
|
||||
return 1;
|
||||
}
|
||||
udelay(20*1000);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_CMD_NB_TEST */
|
||||
|
||||
|
||||
#endif /* !defined(CONFIG_SPL_BUILD) */
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
struct serdes_map* sm;
|
||||
u8 sm_count;
|
||||
|
||||
#ifdef EARLY_CONSOLE_OUTPUT
|
||||
init_console();
|
||||
console_init_f();
|
||||
#endif
|
||||
|
||||
/* Disable watchdog */
|
||||
debug("Disable watchdog\n");
|
||||
// set_gpio(GPIO_WD_ENABLE, 0);
|
||||
|
||||
/* Enable USB hub */
|
||||
debug("Enable USB Hub\n");
|
||||
set_gpio(GPIO_RST_USB_HUB, 0);
|
||||
udelay(10000);
|
||||
|
||||
/* Determine SERDES configuration */
|
||||
hws_board_topology_load(&sm, &sm_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
|
||||
static void set_phy_page(const char *miidev, int phy_addr, int page)
|
||||
{
|
||||
miiphy_write(miidev, phy_addr, 22, page);
|
||||
|
|
@ -246,20 +656,38 @@ static void set_phy_page(const char *miidev, int phy_addr, int page)
|
|||
static void set_phy_fast_blink_mode(int phy_addr)
|
||||
{
|
||||
const char *miidev = miiphy_get_current_dev();
|
||||
int numRegs = 0;
|
||||
|
||||
debug ("miidev: %s\n", miidev);
|
||||
|
||||
set_phy_page(miidev, phy_addr, 3);
|
||||
miiphy_write(miidev, phy_addr, 16, 0x1032);
|
||||
miiphy_write(miidev, phy_addr, 17, 0x4405);
|
||||
miiphy_write(miidev, phy_addr, 18, 0x4A08);
|
||||
while (sSelectedPhyRegs[numRegs].reserved != -1) {
|
||||
set_phy_page(miidev, phy_addr, sSelectedPhyRegs[numRegs].page);
|
||||
miiphy_write(miidev, phy_addr, sSelectedPhyRegs[numRegs].reg, sSelectedPhyRegs[numRegs].data);
|
||||
numRegs++;
|
||||
}
|
||||
set_phy_page(miidev, phy_addr, 0);
|
||||
}
|
||||
|
||||
static void set_devicetree_name(void)
|
||||
{
|
||||
char devicetreename[64];
|
||||
|
||||
if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) {
|
||||
printf("Devicetree name not found in BD\n");
|
||||
strncpy(devicetreename, "openwrt-nbhw17.dtb", sizeof(devicetreename));
|
||||
printf ("Selected default devicetree file\n");
|
||||
}
|
||||
|
||||
env_set("fdt_image", devicetreename);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
|
||||
gpio_request(21, "RST_ETH_PHY_N");
|
||||
gpio_direction_output(21, 0);
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
set_devicetree_name();
|
||||
set_gpio(GPIO_RST_ETH_PHY, 1);
|
||||
|
||||
find_and_set_active_partition();
|
||||
pass_hw_rev();
|
||||
|
|
@ -267,29 +695,86 @@ int board_late_init(void)
|
|||
/* Todo: It seems that something with the network is wrong */
|
||||
run_command("run load_fpga", CMD_FLAG_ENV);
|
||||
|
||||
#ifndef EARLY_CONSOLE_OUTPUT
|
||||
init_console();
|
||||
console_init_f();
|
||||
#endif
|
||||
|
||||
check_reset_button();
|
||||
|
||||
set_mac_addresses(2);
|
||||
#endif
|
||||
|
||||
/* Take phy out of reset after FPGA was loaded */
|
||||
gpio_set_value(21, 1);
|
||||
set_gpio(GPIO_RST_ETH_PHY, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
int board_network_enable(struct mii_dev *bus)
|
||||
{
|
||||
char prodName[20];
|
||||
|
||||
if (bd_get_prodname(prodName, sizeof(prodName)) != 0) {
|
||||
prodName[0] = 0;
|
||||
}
|
||||
|
||||
if (strcmp(prodName, "2810") == 0) {
|
||||
/* NB2810 */
|
||||
sSelectedPhyRegs = NB2810_ETH_PHY_REGS;
|
||||
} else {
|
||||
/* NB2800 or unknown */
|
||||
sSelectedPhyRegs = NB2800_ETH_PHY_REGS;
|
||||
}
|
||||
|
||||
set_phy_fast_blink_mode(0);
|
||||
set_phy_fast_blink_mode(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
puts("Board: NetModule NBHW17\n");
|
||||
debug("Board: NetModule NBHW17\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
/* SPL has enabled serial1 per default and will output everything
|
||||
* independend of /boot/consoledev */
|
||||
#define DEFAULT_DTB_NAME "armada-385-nbhw17-v1-spl"
|
||||
#else
|
||||
/* U-Boot will read /boot/consoledev and based on that it
|
||||
* enables its own serial console */
|
||||
#define DEFAULT_DTB_NAME "armada-385-nbhw17-v1"
|
||||
#endif
|
||||
|
||||
/* Check if name fits our dts */
|
||||
return strcmp(DEFAULT_DTB_NAME, name);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_FIXUP
|
||||
|
||||
|
||||
int fdt_enable_by_ofname(void *rw_fdt_blob, char *ofname)
|
||||
{
|
||||
int offset = fdt_path_offset(rw_fdt_blob, ofname);
|
||||
|
||||
return fdt_status_okay(rw_fdt_blob, offset);
|
||||
}
|
||||
|
||||
int board_fix_fdt(void *fdt_blob)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int pcie_lane_by_slot(int slot)
|
||||
{
|
||||
int serdes;
|
||||
|
|
@ -322,3 +807,91 @@ int pcie_lane_by_slot(int slot)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Enable additional nodes in DTS depending on board descriptor
|
||||
*******************************************************************************/
|
||||
|
||||
static void ft_enable_node(void* blob, const char* name)
|
||||
{
|
||||
int node_ofs = -1;
|
||||
|
||||
node_ofs = fdt_path_offset(blob, name);
|
||||
if (node_ofs >= 0) {
|
||||
fdt_setprop_string(blob, node_ofs, "status", "okay");
|
||||
}
|
||||
}
|
||||
|
||||
static void ft_netbox_dio_ptt_4(void *blob)
|
||||
{
|
||||
printf("FT: enable netbox_dio_ptt_4\n");
|
||||
|
||||
ft_enable_node(blob, "/netbox_dio_ptt_4");
|
||||
|
||||
// also reconfigure PCM lines in FPGA as GPIOs
|
||||
FPGA_REG(PCIE_4_PCM_GPIO_EN) = 0x0001; /* Enable GPIO functionality for slot 4 */
|
||||
FPGA_REG(PCIE_4_PCM_GPIO_DIR) = 0x0004; /* Set GPIO directions */
|
||||
FPGA_REG(PCIE_4_PCM_GPIO_DAT) = 0; /* Set output to 0 */
|
||||
}
|
||||
|
||||
void ft_set_eth_led_config(void *blob)
|
||||
{
|
||||
int node_ofs;
|
||||
int numRegs = 0;
|
||||
int i;
|
||||
int phy;
|
||||
EthPhyRegs* pBigEndianPhyRegs = 0;
|
||||
|
||||
if (!sSelectedPhyRegs) goto abort;
|
||||
|
||||
while (sSelectedPhyRegs[numRegs].reserved != -1) numRegs++;
|
||||
|
||||
/* DTS needs big endian so swap everything */
|
||||
|
||||
pBigEndianPhyRegs = malloc(numRegs * sizeof(NB2800_ETH_PHY_REGS));
|
||||
if (!pBigEndianPhyRegs) goto abort;
|
||||
|
||||
memcpy(pBigEndianPhyRegs, sSelectedPhyRegs, numRegs * sizeof(EthPhyRegs));
|
||||
|
||||
for (i=0; i<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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,53 +31,53 @@ typedef enum {
|
|||
TYPE_PCIE,
|
||||
} slot_type_t;
|
||||
|
||||
static slot_type_t get_pcie_slot_type(const int slot)
|
||||
{
|
||||
int module;
|
||||
char pdValue[200];
|
||||
char slotDescr[20];
|
||||
|
||||
sprintf(slotDescr, "slot=%d", slot);
|
||||
|
||||
for (module=0; module<4; module++) {
|
||||
strcpy(pdValue, "" ); /*init with an empty string*/
|
||||
if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) {
|
||||
|
||||
if ((strstr(pdValue, slotDescr)) && (strstr(pdValue, "wlan-"))) {
|
||||
/* Wifi module needs PCIe */
|
||||
return TYPE_PCIE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TYPE_USB;
|
||||
}
|
||||
|
||||
static int serdes_en_hack(struct gpio_desc *gpio)
|
||||
{
|
||||
slot_type_t slot_type = get_pcie_slot_type(0);
|
||||
|
||||
/* Lucky for us pcie slot1 has some muxes, to workaround buggy Sierra Wireless Modules */
|
||||
if (slot_type == TYPE_USB) {
|
||||
/* Buggy Sierra Wireless Modules don't like to have USB3 enabled
|
||||
* because the TX of the USB3 Lane is attached to it's system
|
||||
* reset which is the default (see dts) */
|
||||
printf("Slot1: wwan\n");
|
||||
}
|
||||
else if (slot_type == TYPE_PCIE) {
|
||||
dm_gpio_set_value(gpio, 1);
|
||||
printf("Slot1: wlan\n");
|
||||
}
|
||||
else {
|
||||
/* If once we would use other buggy Sierra Wireless modules, where they have
|
||||
* decided to use USB3 too, then we have to enable the SERDES, the reset signal
|
||||
* was moved away from this pins again (bravo!!!) */
|
||||
printf("Slot1: wwan (usb3)\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
//static slot_type_t get_pcie_slot_type(const int slot)
|
||||
//{
|
||||
// int module;
|
||||
// char pdValue[200];
|
||||
// char slotDescr[20];
|
||||
//
|
||||
// sprintf(slotDescr, "slot=%d", slot);
|
||||
//
|
||||
// for (module=0; module<4; module++) {
|
||||
// strcpy(pdValue, "" ); /*init with an empty string*/
|
||||
// if (bd_get_pd_module(module, pdValue, sizeof(pdValue))==0) {
|
||||
//
|
||||
// if ((strstr(pdValue, slotDescr)) && (strstr(pdValue, "wlan-"))) {
|
||||
// /* Wifi module needs PCIe */
|
||||
// return TYPE_PCIE;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return TYPE_USB;
|
||||
//}
|
||||
//
|
||||
//static int serdes_en_hack(struct gpio_desc *gpio)
|
||||
//{
|
||||
// slot_type_t slot_type = get_pcie_slot_type(0);
|
||||
//
|
||||
// /* Lucky for us pcie slot1 has some muxes, to workaround buggy Sierra Wireless Modules */
|
||||
// if (slot_type == TYPE_USB) {
|
||||
// /* Buggy Sierra Wireless Modules don't like to have USB3 enabled
|
||||
// * because the TX of the USB3 Lane is attached to it's system
|
||||
// * reset which is the default (see dts) */
|
||||
// printf("Slot1: wwan\n");
|
||||
// }
|
||||
// else if (slot_type == TYPE_PCIE) {
|
||||
// dm_gpio_set_value(gpio, 1);
|
||||
// printf("Slot1: wlan\n");
|
||||
// }
|
||||
// else {
|
||||
// /* If once we would use other buggy Sierra Wireless modules, where they have
|
||||
// * decided to use USB3 too, then we have to enable the SERDES, the reset signal
|
||||
// * was moved away from this pins again (bravo!!!) */
|
||||
// printf("Slot1: wwan (usb3)\n");
|
||||
// }
|
||||
//
|
||||
// return 0;
|
||||
//
|
||||
//}
|
||||
|
||||
struct pcie_slot_gpios {
|
||||
struct gpio_desc reset;
|
||||
|
|
@ -102,7 +102,7 @@ static int request_and_set_gpio_by_name(ofnode fdt,
|
|||
if (gpio_request_by_name_nodev(fdt, name, 0, desc,
|
||||
GPIOD_IS_OUT))
|
||||
{
|
||||
printf("Could not request gpio %s\n", name);
|
||||
debug("Could not request gpio %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -122,17 +122,19 @@ static int request_and_set_gpio_by_name(ofnode fdt,
|
|||
static int add_pcie_slot(ofnode fdt)
|
||||
{
|
||||
debug("%s\n", __func__);
|
||||
request_and_set_gpio_by_name(fdt, "reset",
|
||||
&pcie_slots[pcie_slot_count].reset);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "power",
|
||||
&pcie_slots[pcie_slot_count].power);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "reset",
|
||||
&pcie_slots[pcie_slot_count].reset);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "wdis-out",
|
||||
&pcie_slots[pcie_slot_count].wdis_out);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "wdis",
|
||||
&pcie_slots[pcie_slot_count].wdis);
|
||||
|
||||
pcie_slot_count++;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -140,35 +142,36 @@ static int add_pcie_slot(ofnode fdt)
|
|||
static int configure_pcie_slots(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
udelay(1200000); /* 1.2 s */
|
||||
|
||||
for (i = 0; i < pcie_slot_count;i ++) {
|
||||
dm_gpio_set_value(&pcie_slots[i].reset, 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < pcie_slot_count;i ++) {
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis_out, 1);
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis, 0);
|
||||
udelay(1000); /* 1 ms */
|
||||
}
|
||||
|
||||
/* Apply power to all PCIe slots */
|
||||
for (i = 0; i < pcie_slot_count;i ++) {
|
||||
for (i = 0; i < pcie_slot_count; i++) {
|
||||
dm_gpio_set_value(&pcie_slots[i].power, 1);
|
||||
udelay(200000); /* 200 ms */
|
||||
}
|
||||
|
||||
for (i = 0; i < pcie_slot_count;i ++) {
|
||||
/* Assert reset after power is enabled */
|
||||
for (i = 0; i < pcie_slot_count; i++) {
|
||||
dm_gpio_set_value(&pcie_slots[i].reset, 1);
|
||||
}
|
||||
|
||||
/* Deactivate WDIS */
|
||||
for (i = 0; i < pcie_slot_count; i++) {
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis_out, 1);
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis, 0);
|
||||
udelay(1000); /* 1 ms */
|
||||
udelay(2000); /* 2 ms needed by Reyax module as regulator is enabled by WDIS~*/
|
||||
}
|
||||
|
||||
udelay(12000); /* 12 ms */
|
||||
for (i = 0; i < pcie_slot_count;i ++) {
|
||||
|
||||
/* Deassert reset */
|
||||
for (i = 0; i < pcie_slot_count; i++) {
|
||||
dm_gpio_set_value(&pcie_slots[i].reset, 0);
|
||||
}
|
||||
|
||||
pci_init_board();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -189,112 +192,38 @@ static int configure_leds(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct hack_list_entry {
|
||||
const char* name;
|
||||
int (*fn)(struct gpio_desc *gpio);
|
||||
};
|
||||
|
||||
struct hack_list_entry hack_list[] = {
|
||||
{"serdes-en", serdes_en_hack}
|
||||
};
|
||||
|
||||
static int exec_hack_list_fn(const char *name, struct gpio_desc *gpio)
|
||||
// TODO: Check, if needed
|
||||
//struct hack_list_entry {
|
||||
// const char* name;
|
||||
// int (*fn)(struct gpio_desc *gpio);
|
||||
//};
|
||||
//
|
||||
//struct hack_list_entry hack_list[] = {
|
||||
// {"serdes-en", serdes_en_hack}
|
||||
//};
|
||||
//
|
||||
//static int exec_hack_list_fn(const char *name, struct gpio_desc *gpio)
|
||||
//{
|
||||
// int i;
|
||||
// for (i = 0; i < ARRAY_SIZE(hack_list); i++) {
|
||||
// if (strcmp(hack_list[i]. name, name) == 0) {
|
||||
// if (hack_list[i].fn(gpio)) {
|
||||
// printf("Hack for %s failed\n", name);
|
||||
// return -1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /* Not part of hacklist */
|
||||
// return 0;
|
||||
//}
|
||||
//
|
||||
void set_led(int index, int value)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(hack_list); i++) {
|
||||
if (strcmp(hack_list[i]. name, name) == 0) {
|
||||
if (hack_list[i].fn(gpio)) {
|
||||
printf("Hack for %s failed\n", name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ((index<0) || (index>=priv.led_count)) return;
|
||||
|
||||
/* Not part of hacklist */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int request_and_set_gpios(ofnode fdt,
|
||||
struct gpio_desc *gpios, u32 max_gpios)
|
||||
{
|
||||
int i = 0;
|
||||
int default_value = 0;
|
||||
int offset = 0;
|
||||
|
||||
|
||||
for (offset = fdt_first_property_offset(gd->fdt_blob, ofnode_to_offset(fdt));
|
||||
offset >= 0;
|
||||
offset = fdt_next_property_offset(gd->fdt_blob, offset)) {
|
||||
u32 gpio_array[4];
|
||||
const char *name;
|
||||
const struct fdt_property *prop;
|
||||
|
||||
|
||||
if (i >= max_gpios) {
|
||||
printf("Too many gpio entries (max %d)\n", max_gpios);
|
||||
break;
|
||||
}
|
||||
|
||||
prop = fdt_get_property_by_offset(gd->fdt_blob, offset, NULL);
|
||||
|
||||
name = fdt_string(gd->fdt_blob, fdt32_to_cpu(prop->nameoff));
|
||||
debug("Name: %s\n", name);
|
||||
if (name[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Request the gpio descriped by the property */
|
||||
if (gpio_request_by_name_nodev(fdt, name, 0, &gpios[i],
|
||||
GPIOD_IS_OUT))
|
||||
{
|
||||
printf("Could not request gpio %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the gpio array, to find out its default value (4 index) */
|
||||
if (ofnode_read_u32_array(fdt, name,
|
||||
gpio_array, 4)) {
|
||||
printf("Could not request gpio array %s\n", name);
|
||||
return -1;
|
||||
|
||||
}
|
||||
default_value = gpio_array[3];
|
||||
debug("Set GPIO %s to %d\n", name, default_value);
|
||||
dm_gpio_set_value(&gpios[i], default_value);
|
||||
|
||||
if (exec_hack_list_fn(name, &gpios[i])) {
|
||||
printf("Execution of hack for %s failed\n", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
debug("leave %s with %d gpios\n", __func__, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static int configure_misc(ofnode fdt)
|
||||
{
|
||||
struct gpio_desc misc_gpios[16];
|
||||
int gpio_count;
|
||||
debug("%s\n", __func__);
|
||||
|
||||
gpio_count = request_and_set_gpios(fdt,
|
||||
misc_gpios, ARRAY_SIZE(misc_gpios));
|
||||
if (gpio_count < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug("Free gpios\n");
|
||||
/* Free gpios so that we could use them via gpio subsystem */
|
||||
gpio_free_list_nodev(misc_gpios, gpio_count);
|
||||
debug("return %s\n", __func__);
|
||||
|
||||
return 0;
|
||||
dm_gpio_set_value(&leds[index], value);
|
||||
}
|
||||
|
||||
int nbhw_fpga_configure(void)
|
||||
|
|
@ -309,14 +238,10 @@ int nbhw_fpga_configure(void)
|
|||
name = ofnode_get_name(subnode);
|
||||
|
||||
debug("Try to configure %s\n", name);
|
||||
if (!strncmp("misc", name, 4)) {
|
||||
configure_misc(subnode);
|
||||
}
|
||||
|
||||
if (!strncmp("pcieslot", name, 4)) {
|
||||
add_pcie_slot(subnode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (configure_leds())
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -1,43 +1,97 @@
|
|||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <stdlib.h>
|
||||
#include "nbhw_gpio.h"
|
||||
|
||||
#define SET_LOGIC(enable,group,bit) \
|
||||
if (enable) \
|
||||
mvGppValueSet(group, bit, bit); \
|
||||
else \
|
||||
mvGppValueSet(group, bit, 0);
|
||||
struct gpio_node {
|
||||
struct gpio_node* next;
|
||||
struct gpio_desc desc;
|
||||
const char* name;
|
||||
int is_output;
|
||||
};
|
||||
|
||||
#define GPIO_RESET_BUTTON (14)
|
||||
static struct gpio_node* gl = NULL;
|
||||
|
||||
void init_gpios(void)
|
||||
{
|
||||
gpio_request(GPIO_RESET_BUTTON, "GPIO_RESET_BUTTON");
|
||||
gpio_direction_input(GPIO_RESET_BUTTON);
|
||||
static struct gpio_desc* lookup_gpio(const char* gpio_name, int is_output) {
|
||||
struct gpio_node* cur = gl;
|
||||
|
||||
while (cur) {
|
||||
if ((strcmp(gpio_name, cur->name)==0) &&
|
||||
(is_output == cur->is_output)) {
|
||||
return &(cur->desc);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void out_usb_power(int enable)
|
||||
{
|
||||
// SET_LOGIC(enable, 1, BIT9);
|
||||
static struct gpio_desc* acquire_gpio(const char* gpio_name, int is_output) {
|
||||
struct gpio_node* gn = 0;
|
||||
int node;
|
||||
|
||||
/* Check, if we already requested this gpio */
|
||||
struct gpio_desc* desc = lookup_gpio(gpio_name, is_output);
|
||||
|
||||
if (desc) return desc;
|
||||
|
||||
/* If we do not have it try to request it now. */
|
||||
node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "nm,gpios");
|
||||
if (node < 0) {
|
||||
goto abort;
|
||||
}
|
||||
|
||||
gn = (struct gpio_node*)malloc(sizeof(struct gpio_node));
|
||||
if (!gn) goto abort;
|
||||
|
||||
if (gpio_request_by_name_nodev(offset_to_ofnode(node), gpio_name, 0, &(gn->desc), is_output ? GPIOD_IS_OUT : GPIOD_IS_IN) < 0) {
|
||||
goto abort;
|
||||
}
|
||||
|
||||
gn->name = gpio_name;
|
||||
gn->is_output = is_output;
|
||||
gn->next = gl;
|
||||
gl = gn;
|
||||
|
||||
desc = &(gn->desc);
|
||||
|
||||
return desc;
|
||||
|
||||
abort:
|
||||
if (gn) free(gn);
|
||||
printk("Could not acquire gpio %s as %s!\n", gpio_name, is_output ? "output" : "input");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void out_watchdog(int enable)
|
||||
int get_gpio(const char* gpio_name)
|
||||
{
|
||||
// SET_LOGIC(enable, 0, BIT19);
|
||||
struct gpio_desc* d;
|
||||
int res;
|
||||
|
||||
d = acquire_gpio(gpio_name, 0);
|
||||
if (!d) goto abort;
|
||||
|
||||
res = dm_gpio_get_value(d);
|
||||
|
||||
return res;
|
||||
|
||||
abort:
|
||||
printf("Could not set gpio %s!\n", gpio_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void out_fpga_logic_reset(int enable)
|
||||
int set_gpio(const char* gpio_name, int value)
|
||||
{
|
||||
// SET_LOGIC(enable, 1, BIT12);
|
||||
struct gpio_desc* d;
|
||||
|
||||
d = acquire_gpio(gpio_name, 1);
|
||||
if (!d) goto abort;
|
||||
|
||||
dm_gpio_set_value(d, value);
|
||||
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
printf("Could not set gpio %s!\n", gpio_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void out_ext_reset_en(int enable)
|
||||
{
|
||||
// SET_LOGIC(enable, 0, BIT7);
|
||||
}
|
||||
|
||||
int in_reset_button(void)
|
||||
{
|
||||
return gpio_get_value(GPIO_RESET_BUTTON);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,30 @@
|
|||
#ifndef NBHW18_GPIO_H
|
||||
#define NBHW18_GPIO_H
|
||||
#include "../common/nbhw_gpio.h"
|
||||
#ifndef HW17_GPIO_H
|
||||
#define HW17_GPIO_H
|
||||
|
||||
void init_gpios(void);
|
||||
/* GPIO definitions */
|
||||
#define GPIO_WD_ENABLE "wd_enable"
|
||||
#define GPIO_RST_USB_HUB "rst_usb_hub"
|
||||
#define GPIO_RST_FPGA "rst_fpga"
|
||||
#define GPIO_RST_ETH_PHY "rst_eth_phy"
|
||||
#define GPIO_RESET_BUTTON "reset_button"
|
||||
|
||||
void out_usb_power(int enable);
|
||||
void out_watchdog(int enable);
|
||||
void out_fpga_logic_reset(int enable);
|
||||
int get_gpio(const char* gpio_name);
|
||||
int set_gpio(const char* gpio_name, int value);
|
||||
|
||||
int in_reset_button(void);
|
||||
int in_fpga_cdone(void);
|
||||
/* LED definitions */
|
||||
#define LED0_GREEN 0
|
||||
#define LED0_RED 1
|
||||
#define LED1_GREEN 2
|
||||
#define LED1_RED 3
|
||||
#define LED2_GREEN 4
|
||||
#define LED2_RED 5
|
||||
#define LED3_GREEN 6
|
||||
#define LED3_RED 7
|
||||
#define LED4_GREEN 8
|
||||
#define LED4_RED 9
|
||||
#define LED5_GREEN 10
|
||||
#define LED5_RED 11
|
||||
|
||||
void set_led(int index, int value);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
);
|
||||
|
||||
|
|
@ -17,6 +17,7 @@ ccflags-y := -I../common
|
|||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-y := board.o nbhw_gpio.o nbhw_fpga_config.o nbhw_mvswitch.o \
|
||||
../common/nbhw_sim.o nbhw_sim.o \
|
||||
../common/da9063.o \
|
||||
../common/lattice/core.o \
|
||||
../common/lattice/hardware.o \
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
#define DEV_CS0_BASE 0xfd000000
|
||||
|
||||
/* Default serdes configuration */
|
||||
static struct serdes_map board_serdes_map[] = {
|
||||
{ SGMII0, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 },
|
||||
{ USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0 },
|
||||
|
|
@ -205,31 +206,9 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
|
|||
int i;
|
||||
|
||||
if (read_eeprom() < 0){
|
||||
/* If we do not have a board descriptor use the default
|
||||
serdes configuration defined in board_serdes_map */
|
||||
puts("Could not read board descriptor using default serdes config.\n");
|
||||
|
||||
board_serdes_map[0].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
board_serdes_map[0].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
board_serdes_map[0].serdes_type = SGMII0;
|
||||
|
||||
board_serdes_map[1].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[1].serdes_mode = PEX_ROOT_COMPLEX_X1;
|
||||
board_serdes_map[1].serdes_type = USB3_HOST0;
|
||||
|
||||
board_serdes_map[2].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
board_serdes_map[2].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
board_serdes_map[2].serdes_type = SGMII1;
|
||||
|
||||
board_serdes_map[3].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[3].serdes_mode = PEX_ROOT_COMPLEX_X1;
|
||||
board_serdes_map[3].serdes_type = PEX3;
|
||||
|
||||
board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[4].serdes_mode = PEX_ROOT_COMPLEX_X1;
|
||||
board_serdes_map[4].serdes_type = PEX2;
|
||||
|
||||
board_serdes_map[5].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
board_serdes_map[5].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
board_serdes_map[5].serdes_type = SGMII2;
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_SIZE(board_serdes_map); i++) {
|
||||
enum serdes_type type;
|
||||
|
|
@ -243,7 +222,6 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
|
|||
type = bd_get_serdes_type(i);
|
||||
}
|
||||
|
||||
/* Do not touch serdes */
|
||||
if (type < LAST_SERDES_TYPE) {
|
||||
if ((type >= SGMII0) && (type <= SGMII2)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
|
|
@ -256,7 +234,12 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
|
|||
else if ((type >= USB3_HOST0) && (type <= USB3_HOST1)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_5_GBPS;
|
||||
board_serdes_map[i].serdes_mode = PEX_ROOT_COMPLEX_X1;
|
||||
} else if ((type == DEFAULT_SERDES)) {
|
||||
}
|
||||
else if ((type >= SATA0) && (type <= SATA3)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_3_GBPS;
|
||||
board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
}
|
||||
else if ((type == DEFAULT_SERDES)) {
|
||||
board_serdes_map[i].serdes_speed = SERDES_SPEED_1_25_GBPS;
|
||||
board_serdes_map[i].serdes_mode = SERDES_DEFAULT_MODE;
|
||||
} else {
|
||||
|
|
@ -653,7 +636,7 @@ static void set_phy_fast_blink_mode(int phy_addr)
|
|||
static void set_devicetree_name(void)
|
||||
{
|
||||
char devicetreename[64];
|
||||
/* add hardware versions to environment */
|
||||
|
||||
if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) {
|
||||
printf("Devicetree name not found, use legacy name\n");
|
||||
strcpy(devicetreename, "armada-385-nbhw18-prod1.dtb");
|
||||
|
|
@ -673,9 +656,7 @@ int board_late_init(void)
|
|||
find_and_set_active_partition();
|
||||
pass_hw_rev();
|
||||
|
||||
/* Todo: It seems that something with the network is wrong */
|
||||
run_command("run load_fpga", CMD_FLAG_ENV);
|
||||
|
||||
#endif
|
||||
|
||||
/* TODO: Move the following two lines up to misc_init_r when ttyS1 works without FPGA again */
|
||||
|
|
@ -688,7 +669,9 @@ int board_late_init(void)
|
|||
|
||||
set_devicetree_name();
|
||||
|
||||
set_mac_addresses(3);
|
||||
set_mac_address(0, 0);
|
||||
set_mac_address(1, 1);
|
||||
set_mac_address(2, 2);
|
||||
|
||||
/* Take phy out of reset after FPGA was loaded */
|
||||
gpio_set_value(29, 1);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <asm/io.h>
|
||||
#include <errno.h>
|
||||
#include "../common/nbhw_bd.h"
|
||||
#include "../common/nbhw_sim.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
|
@ -150,6 +151,8 @@ static int configure_pcie_slots(void)
|
|||
int i, res;
|
||||
char volt[10];
|
||||
|
||||
configure_sim_slots(4);
|
||||
|
||||
udelay(1200000); /* 1.2 s */
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
#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) {
|
||||
uint16_t sim_ctrl;
|
||||
uint16_t sim_shift;
|
||||
uint16_t slot_sel;
|
||||
|
||||
if (sim > 3) {
|
||||
if (sim > 1) {
|
||||
printf("Invalid sim %d selected, can't connect slot %d\n", sim, slot);
|
||||
return;
|
||||
}
|
||||
|
|
@ -32,4 +32,3 @@ void connect_sim_to_slot(int sim, int slot) {
|
|||
|
||||
FPGA_REG(SIM_CTRL) = sim_ctrl;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -791,7 +791,9 @@ static const init_fnc_t init_sequence_f[] = {
|
|||
env_init, /* initialize environment */
|
||||
init_baud_rate, /* initialze baudrate settings */
|
||||
serial_init, /* serial communications setup */
|
||||
#if !defined(CONFIG_PRE_CONSOLE_BUFFER)
|
||||
console_init_f, /* stage 1 init of console */
|
||||
#endif
|
||||
display_options, /* say that we are here */
|
||||
display_text_info, /* show debugging info if required */
|
||||
#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SH) || \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -7,11 +7,18 @@ CONFIG_TARGET_NM_NBHW17_V1=y
|
|||
CONFIG_SPL_MMC_SUPPORT=y
|
||||
CONFIG_SPL_SERIAL_SUPPORT=y
|
||||
CONFIG_SPL_LIBDISK_SUPPORT=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="armada-385-nbhw17-v1"
|
||||
CONFIG_DEFAULT_FDT_FILE="armada-385-nbhw17-v1"
|
||||
CONFIG_DEFAULT_DEVICE_TREE="armada-385-nbhw17-v1-spl"
|
||||
CONFIG_SMBIOS_PRODUCT_NAME="hw17"
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
|
||||
CONFIG_BOOTDELAY=3
|
||||
CONFIG_BOOTSTAGE_STASH_SIZE=4096
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
CONFIG_PRE_CONSOLE_BUFFER=y
|
||||
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||
CONFIG_PRE_CON_BUF_SZ=4096
|
||||
CONFIG_PRE_CON_BUF_ADDR=0x04000000
|
||||
# CONFIG_CONSOLE_MUX is not set
|
||||
CONFIG_DEFAULT_FDT_FILE="armada-385-nbhw17-v1-spl"
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x190
|
||||
|
|
@ -19,6 +26,7 @@ CONFIG_SPL_I2C_SUPPORT=y
|
|||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_CMD_BOOTZ=y
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
CONFIG_CMD_NB_TEST=y
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_SF=y
|
||||
|
|
@ -40,17 +48,19 @@ CONFIG_CMD_FS_GENERIC=y
|
|||
CONFIG_EFI_PARTITION=y
|
||||
# CONFIG_PARTITION_UUIDS is not set
|
||||
# CONFIG_SPL_PARTITION_UUIDS is not set
|
||||
CONFIG_OF_BOARD_FIXUP=y
|
||||
CONFIG_SPL_OF_TRANSLATE=y
|
||||
CONFIG_OF_LIST="armada-385-nbhw17-v1-spl armada-385-nbhw17-v1"
|
||||
CONFIG_MULTI_DTB_FIT=y
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_SDMA=y
|
||||
CONFIG_MMC_SDHCI_MV=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_MVNETA=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DEBUG_UART_BASE=0xd0012000
|
||||
CONFIG_DEBUG_UART_CLOCK=250000000
|
||||
CONFIG_DEBUG_UART_SHIFT=2
|
||||
# CONFIG_DEBUG_UART is not set
|
||||
# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
|
|
@ -58,4 +68,7 @@ CONFIG_USB_EHCI_HCD=y
|
|||
CONFIG_USB_EHCI_MARVELL=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_MVEBU_GPIO=y
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_CMD_EEPROM=y
|
||||
CONFIG_ENV_IS_IN_EEPROM=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_WDT_ORION=y
|
||||
|
|
|
|||
|
|
@ -83,7 +83,11 @@ static int pca953x_write_single(struct udevice *dev, int reg, u8 val,
|
|||
int off = offset / BANK_SZ;
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1);
|
||||
#else
|
||||
ret = i2c_write(info->addr, (reg << bank_shift) + off, 1, &val, 1);
|
||||
#endif
|
||||
if (ret) {
|
||||
dev_err(dev, "%s error\n", __func__);
|
||||
return ret;
|
||||
|
|
@ -101,7 +105,11 @@ static int pca953x_read_single(struct udevice *dev, int reg, u8 *val,
|
|||
int ret;
|
||||
u8 byte;
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = dm_i2c_read(dev, (reg << bank_shift) + off, &byte, 1);
|
||||
#else
|
||||
ret = i2c_read(info->addr, (reg << bank_shift) + off, 1, &byte, 1);
|
||||
#endif
|
||||
if (ret) {
|
||||
dev_err(dev, "%s error\n", __func__);
|
||||
return ret;
|
||||
|
|
@ -118,12 +126,24 @@ static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
|
|||
int ret = 0;
|
||||
|
||||
if (info->gpio_count <= 8) {
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = dm_i2c_read(dev, reg, val, 1);
|
||||
#else
|
||||
ret = i2c_read(info->addr, reg, 1, val, 1);
|
||||
#endif
|
||||
} else if (info->gpio_count <= 16) {
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = dm_i2c_read(dev, reg << 1, val, info->bank_count);
|
||||
#else
|
||||
ret = i2c_read(info->addr, reg << 1, 1, val, info->bank_count);
|
||||
#endif
|
||||
} else if (info->gpio_count == 40) {
|
||||
/* Auto increment */
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = dm_i2c_read(dev, (reg << 3) | 0x80, val, info->bank_count);
|
||||
#else
|
||||
ret = i2c_read(info->addr, (reg << 3) | 0x80, 1, val, info->bank_count);
|
||||
#endif
|
||||
} else {
|
||||
dev_err(dev, "Unsupported now\n");
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -1372,6 +1372,8 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
|
|||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
ctrl |= MVNETA_GMAC2_PORT_RGMII;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -43,11 +43,28 @@
|
|||
/* USB/EHCI configuration */
|
||||
#define CONFIG_EHCI_IS_TDI
|
||||
|
||||
/* Environment in SPI NOR flash */
|
||||
#define CONFIG_ENV_IS_IN_SPI_FLASH
|
||||
#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */
|
||||
#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */
|
||||
#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */
|
||||
/* Environment in I2C EEPROM */
|
||||
/**
|
||||
* Layout on the NBHW08 Board:
|
||||
* Offset Size Description
|
||||
* 0x0000 0x200 The NetModule Boarddescriptor
|
||||
* 0x0200 0x200 The NetModule Productdescriptor
|
||||
* 0x0400 0x200 The NetModule License Descriptor
|
||||
* 0x0600 0x400 The NetModule Parition table
|
||||
* 0x0A00 0x600 reserved
|
||||
* 0x1000 0xA00 The U-Boot environment
|
||||
* 0x1A00 0x600 reserved
|
||||
*/
|
||||
#define CONFIG_ENV_OFFSET (0x1000) /* The Environment is located at 4k */
|
||||
#define CONFIG_ENV_SIZE (0xA00) /* 64KiB */
|
||||
#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */
|
||||
|
||||
#define CONFIG_ENV_EEPROM_IS_ON_I2C
|
||||
#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* Main EEPROM */
|
||||
#define CONFIG_SYS_DEF_EEPROM_ADDR 0x50
|
||||
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN (2)
|
||||
#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 5
|
||||
#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 70
|
||||
|
||||
#define CONFIG_PHY_MARVELL /* there is a marvell phy */
|
||||
#define PHY_ANEG_TIMEOUT 8000 /* PHY needs a longer aneg time */
|
||||
|
|
@ -58,9 +75,20 @@
|
|||
#define CONFIG_PCI_SCAN_SHOW
|
||||
#endif
|
||||
|
||||
#if !defined(UBOOT_USER_BUILD) && !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT_ORION)
|
||||
#define CONFIG_WATCHDOG
|
||||
#endif
|
||||
|
||||
#define CONFIG_OF_BOARD_SETUP
|
||||
|
||||
#define CONFIG_SYS_ALT_MEMTEST
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
|
||||
#define CONFIG_NM_LOGIN
|
||||
#define CONFIG_CRYPT
|
||||
#define CONFIG_SUPPORT_EMMC_RPMB
|
||||
|
||||
#define KERNEL_ADDR "0x01000000"
|
||||
#define LOAD_ADDR "0x03000000"
|
||||
#define FDT_ADDR "0x02000000"
|
||||
|
|
@ -78,14 +106,14 @@
|
|||
"eth1addr=00:11:22:33:44:55\0" \
|
||||
"eth2addr=00:11:22:33:44:56\0" \
|
||||
"ethact=ethernet@30000\0" \
|
||||
"add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 console=ttyS1,115200 rootwait\0" \
|
||||
"add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 rootwait; run set_console_dev\0" \
|
||||
"add_version_bootargs=setenv bootargs $bootargs\0" \
|
||||
"fdt_skip_update=yes\0" \
|
||||
"sdbringup=echo Try bringup boot && ext4load mmc 0:$root_part $kernel_addr /boot/zImage && " \
|
||||
"ext4load mmc 0:$root_part $fdt_addr /boot/$fdt_image && setenv bootargs $bootargs rw;\0" \
|
||||
"sdprod=ext4load mmc 0:$root_part $kernel_addr /boot/$kernel_image && " \
|
||||
"ext4load mmc 0:$root_part $fdt_addr /boot/$fdt_image && setenv bootargs $bootargs ro;\0" \
|
||||
"sdboot=if mmc dev 0; then echo Load FPGA...; nbhw_wlan_fixup &&" \
|
||||
"sdboot=if mmc dev 0; then nbhw_wlan_fixup &&" \
|
||||
"echo Copying Linux from SD to RAM...; "\
|
||||
"if test -e mmc 0:$root_part /boot/$kernel_image; then run sdprod; " \
|
||||
"else run sdbringup; fi; " \
|
||||
|
|
@ -103,14 +131,15 @@
|
|||
"tftptimeoutcountmax=5\0" \
|
||||
"bootpretryperiod=2000\0" \
|
||||
"autoload=false\0" \
|
||||
"tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; setenv bootargs rdinit=/etc/preinit console=ttyO1,115200 debug; bootz $kernel_addr - $fdt_addr\0" \
|
||||
"defaultconsole=ttyS1\0" \
|
||||
"set_console_dev=if test -n ${consoledev}; then setenv bootargs $bootargs console=$consoledev,115200; fi; true\0" \
|
||||
"tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; setenv bootargs rdinit=/etc/preinit console=$defaultconsole,115200 debug; run add_version_bootargs; bootz $kernel_addr - $fdt_addr\0" \
|
||||
"pxe_recovery=sleep 3 && dhcp && pxe get && pxe boot\0" \
|
||||
"load_fpga=ext4load mmc 0:$root_part $kernel_addr /logic/LG00000000 && nbhw_fpga program lattice 0xffffffff $kernel_addr $filesize && nbhw_fpga configure\0" \
|
||||
"recovery=run pxe_recovery || setenv ipaddr $ipaddr; setenv serverip $serverip; run tftp_recovery\0" /* setenv ipaddr and serverip is necessary, because dhclient can destroy the IPs inernally */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* SPL */
|
||||
/*
|
||||
* Select the boot device here
|
||||
|
|
@ -134,6 +163,7 @@
|
|||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#define CONFIG_SYS_MALLOC_SIMPLE
|
||||
#define CONFIG_OF_STDOUT_VIA_ALIAS
|
||||
#endif
|
||||
|
||||
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
|
||||
|
|
@ -165,11 +195,27 @@
|
|||
/*
|
||||
* NBHW needs md5 support
|
||||
*/
|
||||
#ifndef CONFIG_MD5
|
||||
#define CONFIG_MD5
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We need some functions to be called after environment setup
|
||||
*/
|
||||
#define CONFIG_BOARD_LATE_INIT
|
||||
|
||||
#define CONFIG_AUTOBOOT_KEYED 1
|
||||
#define CONFIG_AUTOBOOT_PROMPT \
|
||||
"Press s to abort autoboot in %d seconds\n"
|
||||
#undef CONFIG_AUTOBOOT_DELAY_STR
|
||||
#define CONFIG_AUTOBOOT_STOP_STR "s"
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
#undef CONFIG_REQUIRE_SERIAL_CONSOLE
|
||||
/* Wee need early init r to actually print the pre console buffer
|
||||
* because u-boot is buggy */
|
||||
#define CONFIG_BOARD_EARLY_INIT_R
|
||||
#define CONFIG_MISC_INIT_R
|
||||
#endif
|
||||
|
||||
#endif /* _CONFIG_DB_88F6820_GP_H */
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@
|
|||
"eth2addr=00:11:22:33:44:56\0" \
|
||||
"eth3addr=00:11:22:33:44:57\0" \
|
||||
"ethact=ethernet@34000\0" \
|
||||
"add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 console=$consoledev,115200 rootwait loglevel=4\0" \
|
||||
"add_sd_bootargs=setenv bootargs $bootargs root=/dev/mmcblk0p$root_part rootfstype=ext4 rootwait loglevel=4; run set_console_dev\0" \
|
||||
"add_version_bootargs=setenv bootargs $bootargs\0" \
|
||||
"fdt_skip_update=yes\0" \
|
||||
"sdbringup=echo Try bringup boot && ext4load mmc 0:$root_part $kernel_addr /boot/zImage && " \
|
||||
|
|
@ -138,6 +138,7 @@
|
|||
"bootpretryperiod=2000\0" \
|
||||
"autoload=false\0" \
|
||||
"defaultconsole=ttyS1\0" \
|
||||
"set_console_dev=if test -n ${consoledev}; then setenv bootargs $bootargs console=$consoledev,115200; fi; true\0" \
|
||||
"tftp_recovery=tftpboot $kernel_addr recovery-image; tftpboot $fdt_addr recovery-dtb; setenv bootargs rdinit=/etc/preinit console=$defaultconsole,115200 debug; bootz $kernel_addr - $fdt_addr\0" \
|
||||
"pxe_recovery=sleep 3 && dhcp && pxe get && pxe boot\0" \
|
||||
"load_fpga=ext4load mmc 0:$root_part $kernel_addr /logic/LG00000000 && nbhw_fpga program lattice-sspi 0xffffffff $kernel_addr $filesize && nbhw_fpga configure\0" \
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#ifndef _LIBFDT_ENV_H
|
||||
#ifndef LIBFDT_ENV_H
|
||||
#define LIBFDT_ENV_H
|
||||
#define _LIBFDT_ENV_H
|
||||
|
||||
#include "compiler.h"
|
||||
|
|
@ -32,4 +33,4 @@ typedef __be64 fdt64_t;
|
|||
/* adding a ramdisk needs 0x44 bytes in version 2008.10 */
|
||||
#define FDT_RAMDISK_OVERHEAD 0x80
|
||||
|
||||
#endif /* _LIBFDT_ENV_H */
|
||||
#endif /* LIBFDT_ENV_H */
|
||||
|
|
|
|||
|
|
@ -12,12 +12,6 @@
|
|||
#include <linux/types.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
|
||||
* - the arch may override these in asm/bitops.h if they can be implemented
|
||||
|
|
@ -40,19 +34,23 @@ int __ilog2_u64(u64 n)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Determine whether some value is a power of two, where zero is
|
||||
/**
|
||||
* is_power_of_2() - check if a value is a power of two
|
||||
* @n: the value to check
|
||||
*
|
||||
* Determine whether some value is a power of two, where zero is
|
||||
* *not* considered a power of two.
|
||||
* Return: true if @n is a power of 2, otherwise false.
|
||||
*/
|
||||
|
||||
static inline __attribute__((const))
|
||||
bool is_power_of_2(unsigned long n)
|
||||
{
|
||||
return (n != 0 && ((n & (n - 1)) == 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* round up to nearest power of two
|
||||
/**
|
||||
* __roundup_pow_of_two() - round up to nearest power of two
|
||||
* @n: value to round up
|
||||
*/
|
||||
static inline __attribute__((const))
|
||||
unsigned long __roundup_pow_of_two(unsigned long n)
|
||||
|
|
@ -60,8 +58,9 @@ unsigned long __roundup_pow_of_two(unsigned long n)
|
|||
return 1UL << fls_long(n - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* round down to nearest power of two
|
||||
/**
|
||||
* __rounddown_pow_of_two() - round down to nearest power of two
|
||||
* @n: value to round down
|
||||
*/
|
||||
static inline __attribute__((const))
|
||||
unsigned long __rounddown_pow_of_two(unsigned long n)
|
||||
|
|
@ -70,19 +69,19 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
|
|||
}
|
||||
|
||||
/**
|
||||
* ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
|
||||
* @n - parameter
|
||||
* ilog2 - log base 2 of 32-bit or a 64-bit unsigned value
|
||||
* @n: parameter
|
||||
*
|
||||
* constant-capable log of base 2 calculation
|
||||
* - this can be used to initialise global variables from constant data, hence
|
||||
* the massive ternary operator construction
|
||||
* the massive ternary operator construction
|
||||
*
|
||||
* selects the appropriately-sized optimised version depending on sizeof(n)
|
||||
*/
|
||||
#define ilog2(n) \
|
||||
( \
|
||||
__builtin_constant_p(n) ? ( \
|
||||
(n) < 1 ? ____ilog2_NaN() : \
|
||||
(n) < 2 ? 0 : \
|
||||
(n) & (1ULL << 63) ? 63 : \
|
||||
(n) & (1ULL << 62) ? 62 : \
|
||||
(n) & (1ULL << 61) ? 61 : \
|
||||
|
|
@ -145,10 +144,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
|
|||
(n) & (1ULL << 4) ? 4 : \
|
||||
(n) & (1ULL << 3) ? 3 : \
|
||||
(n) & (1ULL << 2) ? 2 : \
|
||||
(n) & (1ULL << 1) ? 1 : \
|
||||
(n) & (1ULL << 0) ? 0 : \
|
||||
____ilog2_NaN() \
|
||||
) : \
|
||||
1) : \
|
||||
(sizeof(n) <= 4) ? \
|
||||
__ilog2_u32(n) : \
|
||||
__ilog2_u64(n) \
|
||||
|
|
@ -156,7 +152,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
|
|||
|
||||
/**
|
||||
* roundup_pow_of_two - round the given value up to nearest power of two
|
||||
* @n - parameter
|
||||
* @n: parameter
|
||||
*
|
||||
* round the given value up to the nearest power of two
|
||||
* - the result is undefined when n == 0
|
||||
|
|
@ -173,7 +169,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
|
|||
|
||||
/**
|
||||
* rounddown_pow_of_two - round the given value down to nearest power of two
|
||||
* @n - parameter
|
||||
* @n: parameter
|
||||
*
|
||||
* round the given value down to the nearest power of two
|
||||
* - the result is undefined when n == 0
|
||||
|
|
@ -186,6 +182,12 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
|
|||
__rounddown_pow_of_two(n) \
|
||||
)
|
||||
|
||||
static inline __attribute_const__
|
||||
int __order_base_2(unsigned long n)
|
||||
{
|
||||
return n > 1 ? ilog2(n - 1) + 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* order_base_2 - calculate the (rounded up) base 2 order of the argument
|
||||
* @n: parameter
|
||||
|
|
@ -199,7 +201,11 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
|
|||
* ob2(5) = 3
|
||||
* ... and so on.
|
||||
*/
|
||||
|
||||
#define order_base_2(n) ilog2(roundup_pow_of_two(n))
|
||||
|
||||
#define order_base_2(n) \
|
||||
( \
|
||||
__builtin_constant_p(n) ? ( \
|
||||
((n) == 0 || (n) == 1) ? 0 : \
|
||||
ilog2((n) - 1) + 1) : \
|
||||
__order_base_2(n) \
|
||||
)
|
||||
#endif /* _LINUX_LOG2_H */
|
||||
|
|
|
|||
219
lib/crypt.c
219
lib/crypt.c
|
|
@ -1,26 +1,19 @@
|
|||
#include <common.h>
|
||||
#include <u-boot/sha256.h>
|
||||
#include <malloc.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* The crypt source code was ported from busybox sources pw_crypt */
|
||||
|
||||
/* Used by pw_encrypt_XXX.c */
|
||||
static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
static char*
|
||||
to64(char *s, unsigned v, int n)
|
||||
{
|
||||
while (--n >= 0) {
|
||||
*s++ = ascii64[v & 0x3f];
|
||||
v >>= 6;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
/*
|
||||
* The crypt source code was ported from busybox sources pw_crypt, file
|
||||
* libbb/pw_encrypt_sha.c
|
||||
*
|
||||
* 20191108rs: Update to Busybox commit 49ecee0 (Jan 24, 2017)
|
||||
* Major cleanup, provide missing functions
|
||||
*/
|
||||
|
||||
/* SHA256 and SHA512-based Unix crypt implementation.
|
||||
* Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <u-boot/sha256.h>
|
||||
#include <malloc.h>
|
||||
#include <linux/types.h>
|
||||
/* Prefix for optional rounds specification. */
|
||||
static const char str_rounds[] = "rounds=%u$";
|
||||
|
||||
|
|
@ -33,50 +26,98 @@ static const char str_rounds[] = "rounds=%u$";
|
|||
/* Maximum number of rounds. */
|
||||
#define ROUNDS_MAX 999999999
|
||||
|
||||
char *sha_crypt(const char *key_data, const char *salt_data)
|
||||
/* Missing busybox functions */
|
||||
|
||||
static char* to64(char *s, unsigned v, int n)
|
||||
{
|
||||
static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
while (--n >= 0) {
|
||||
*s++ = ascii64[v & 0x3f];
|
||||
v >>= 6;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void* xzalloc(size_t size)
|
||||
{
|
||||
void *ptr = malloc(size);
|
||||
/* note: error check left out */
|
||||
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char *xstrdup(const char *s)
|
||||
{
|
||||
size_t len = strlen (s) + 1;
|
||||
char *ret = malloc (len);
|
||||
/* note: error check left out */
|
||||
|
||||
memcpy (ret, s, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0 /* currently not required, see note below */
|
||||
static char *xstrndup(const char *s, size_t n)
|
||||
{
|
||||
char *result;
|
||||
size_t len = strlen (s);
|
||||
if (n < len)
|
||||
len = n;
|
||||
printf("allocating %d bytes\n", len+1);
|
||||
result = malloc (len + 1);
|
||||
/* note: error check left out */
|
||||
result[len] = '\0';
|
||||
memcpy (result, s, len);
|
||||
return (char *)result;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data)
|
||||
{
|
||||
void (*sha_begin)(void *ctx);
|
||||
void (*sha_hash)(void *ctx, const void *buffer, size_t len);
|
||||
void* (*sha_end)( void *ctx, void *resbuf);
|
||||
void (*sha_end)(void *ctx, void *resbuf);
|
||||
int _32or64;
|
||||
|
||||
char *result, *resptr;
|
||||
|
||||
/* btw, sha256 needs [32] and uint32_t only */
|
||||
unsigned char alt_result[64] __attribute__((__aligned__(__alignof__(uint64_t))));
|
||||
unsigned char temp_result[64] __attribute__((__aligned__(__alignof__(uint64_t))));
|
||||
union {
|
||||
sha256_context x;
|
||||
#if 0
|
||||
sha512_ctx_t y;
|
||||
#endif
|
||||
} ctx;
|
||||
union {
|
||||
sha256_context x;
|
||||
#if 0
|
||||
sha512_ctx_t y;
|
||||
#endif
|
||||
} alt_ctx;
|
||||
struct {
|
||||
unsigned char alt_result[64];
|
||||
unsigned char temp_result[64];
|
||||
union {
|
||||
sha256_context x;
|
||||
/* sha512_ctx_t y; */
|
||||
} ctx;
|
||||
union {
|
||||
sha256_context x;
|
||||
/* sha512_ctx_t y; */
|
||||
} alt_ctx;
|
||||
} L;
|
||||
#define alt_result (L.alt_result )
|
||||
#define temp_result (L.temp_result)
|
||||
#define ctx (L.ctx )
|
||||
#define alt_ctx (L.alt_ctx )
|
||||
unsigned salt_len;
|
||||
unsigned key_len;
|
||||
unsigned cnt;
|
||||
unsigned rounds;
|
||||
char *cp;
|
||||
char is_sha512;
|
||||
char *tmp;
|
||||
|
||||
/* Analyze salt, construct already known part of result */
|
||||
cnt = strlen(salt_data) + 1 + 43 + 1;
|
||||
is_sha512 = salt_data[1];
|
||||
if (is_sha512 == '6') {
|
||||
printf("SHA-512 is not supported yet");
|
||||
return 0;
|
||||
/* cnt += 43; */
|
||||
}
|
||||
result = resptr = malloc(cnt); /* will provide NUL terminator */
|
||||
memset(result, 0, cnt);
|
||||
_32or64 = 32;
|
||||
if (salt_data[1] == '6') { /* sha512 */
|
||||
_32or64 *= 2; /*64*/
|
||||
cnt += 43;
|
||||
puts("SHA-512 is not supported");
|
||||
return 0;
|
||||
}
|
||||
result = resptr = xzalloc(cnt); /* will provide NUL terminator */
|
||||
*resptr++ = '$';
|
||||
*resptr++ = is_sha512;
|
||||
*resptr++ = salt_data[1];
|
||||
*resptr++ = '$';
|
||||
rounds = ROUNDS_DEFAULT;
|
||||
salt_data += 3;
|
||||
|
|
@ -95,50 +136,41 @@ char *sha_crypt(const char *key_data, const char *salt_data)
|
|||
resptr += sprintf(resptr, str_rounds, rounds);
|
||||
}
|
||||
}
|
||||
{
|
||||
char *salt_end = strchr(salt_data, '$');
|
||||
if (salt_end != 0) {
|
||||
salt_len = salt_end - salt_data;
|
||||
}
|
||||
else {
|
||||
salt_len = strnlen(salt_data, SALT_LEN_MAX);
|
||||
}
|
||||
}
|
||||
// salt_len = (int)strchrnul(salt_data, '$') - (int)salt_data;
|
||||
|
||||
salt_len = (int)strchrnul(salt_data, '$') - (int)salt_data;
|
||||
if (salt_len > SALT_LEN_MAX)
|
||||
salt_len = SALT_LEN_MAX;
|
||||
/* xstrdup assures suitable alignment; also we will use it
|
||||
as a scratch space later. */
|
||||
tmp = malloc(strnlen(salt_data, 128));
|
||||
memcpy(tmp, salt_data, strnlen(salt_data, 128));
|
||||
salt_data = tmp;
|
||||
//salt_data = xstrndup(salt_data, salt_len);
|
||||
|
||||
/* NOTE: Something is wrong here.
|
||||
* when <salt_len> bytes are reserved there is a problem later in
|
||||
* the code and computations are incorrect.
|
||||
* So far it is not clear what the root problem is.
|
||||
* By not truncating the buffer the code works fine
|
||||
*/
|
||||
/* salt_data = xstrndup(salt_data, salt_len); */
|
||||
salt_data = xstrdup(salt_data);
|
||||
/* add "salt$" to result */
|
||||
strcpy(resptr, salt_data);
|
||||
resptr += salt_len;
|
||||
*resptr++ = '$';
|
||||
/* key data doesn't need much processing */
|
||||
key_len = strlen(key_data);
|
||||
tmp = malloc(strnlen(key_data, 256));
|
||||
memcpy(tmp, key_data, strnlen(key_data, 256));
|
||||
key_data = tmp;
|
||||
// key_data = xstrdup(key_data);
|
||||
key_data = xstrdup(key_data);
|
||||
|
||||
/* Which flavor of SHAnnn ops to use? */
|
||||
sha_begin = (void*)sha256_starts;
|
||||
sha_hash = (void*)sha256_update;
|
||||
sha_end = (void*)sha256_finish;
|
||||
_32or64 = 32;
|
||||
/* Not supported */
|
||||
#if 0
|
||||
if (is_sha512 == '6') {
|
||||
/* SHA512 not supported */
|
||||
if (_32or64 != 32) {
|
||||
sha_begin = (void*)sha512_begin;
|
||||
sha_hash = (void*)sha512_hash;
|
||||
sha_end = (void*)sha512_end;
|
||||
_32or64 = 64;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add KEY, SALT. */
|
||||
sha_begin(&ctx);
|
||||
sha_hash(&ctx, key_data, key_len);
|
||||
|
|
@ -230,35 +262,30 @@ char *sha_crypt(const char *key_data, const char *salt_data)
|
|||
sha_end(&ctx, alt_result);
|
||||
}
|
||||
|
||||
|
||||
/* Append encrypted password to result buffer */
|
||||
//TODO: replace with something like
|
||||
// bb_uuencode(cp, src, length, bb_uuenc_tbl_XXXbase64);
|
||||
#define b64_from_24bit(B2, B1, B0, N) \
|
||||
do { \
|
||||
unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \
|
||||
resptr = to64(resptr, w, N); \
|
||||
do { \
|
||||
unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \
|
||||
resptr = to64(resptr, w, N); \
|
||||
} while (0)
|
||||
if (is_sha512 == '5') {
|
||||
if (_32or64 == 32) { /* sha256 */
|
||||
unsigned i = 0;
|
||||
unsigned j = 10;
|
||||
unsigned k = 20;
|
||||
/* strange swap of one byte (see below why) */
|
||||
unsigned char alt_result_31 = alt_result[31];
|
||||
alt_result[31] = alt_result[1];
|
||||
while (1) {
|
||||
unsigned j = i + 10;
|
||||
unsigned k = i + 20;
|
||||
if (j >= 30) j -= 30;
|
||||
if (k >= 30) k -= 30;
|
||||
b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4);
|
||||
if (i == 9)
|
||||
if (k == 29)
|
||||
break;
|
||||
i += 21; i = (((i >> 4) & 2) + i) & 0x1f;
|
||||
j += 21; j = (((j >> 4) & 2) + j) & 0x1f;
|
||||
k += 21; k = (((k >> 4) & 2) + k) & 0x1f;
|
||||
i = k + 1;
|
||||
}
|
||||
b64_from_24bit(0, alt_result_31, alt_result[30], 3);
|
||||
b64_from_24bit(0, alt_result[31], alt_result[30], 3);
|
||||
/* was:
|
||||
b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4);
|
||||
b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4);
|
||||
...............................^^^^^^^^^^^^^ why [1] and not [31]?
|
||||
b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4);
|
||||
b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4);
|
||||
b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4);
|
||||
|
|
@ -271,15 +298,15 @@ do { \
|
|||
*/
|
||||
} else {
|
||||
unsigned i = 0;
|
||||
unsigned j = 21;
|
||||
unsigned k = 42;
|
||||
while (1) {
|
||||
unsigned j = i + 21;
|
||||
unsigned k = i + 42;
|
||||
if (j >= 63) j -= 63;
|
||||
if (k >= 63) k -= 63;
|
||||
b64_from_24bit(alt_result[i], alt_result[j], alt_result[k], 4);
|
||||
if (i == 62)
|
||||
if (j == 20)
|
||||
break;
|
||||
i += 22; i = ((i >> 6) + i) & 0x3f;
|
||||
j += 22; j = ((j >> 6) + j) & 0x3f;
|
||||
k += 22; k = ((k >> 6) + k) & 0x3f;
|
||||
i = j + 1;
|
||||
}
|
||||
b64_from_24bit(0, 0, alt_result[63], 2);
|
||||
/* was:
|
||||
|
|
@ -309,21 +336,19 @@ do { \
|
|||
}
|
||||
/* *resptr = '\0'; - xzalloc did it */
|
||||
#undef b64_from_24bit
|
||||
|
||||
/* Clear the buffer for the intermediate result so that people
|
||||
attaching to processes or reading core dumps cannot get any
|
||||
information. */
|
||||
memset(temp_result, 0, sizeof(temp_result));
|
||||
memset(alt_result, 0, sizeof(alt_result));
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
memset(&alt_ctx, 0, sizeof(alt_ctx));
|
||||
memset(&L, 0, sizeof(L)); /* [alt]_ctx and XXX_result buffers */
|
||||
memset(key_data, 0, key_len); /* also p_bytes */
|
||||
memset(salt_data, 0, salt_len); /* also s_bytes */
|
||||
free(key_data);
|
||||
free(salt_data);
|
||||
#undef p_bytes
|
||||
#undef s_bytes
|
||||
|
||||
return result;
|
||||
#undef alt_result
|
||||
#undef temp_result
|
||||
#undef ctx
|
||||
#undef alt_ctx
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -743,7 +743,7 @@ int conf_write(const char *name)
|
|||
struct menu *menu;
|
||||
const char *basename;
|
||||
const char *str;
|
||||
char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
|
||||
char dirname[PATH_MAX+1], tmpname[PATH_MAX+14], newname[PATH_MAX+8];
|
||||
char *env;
|
||||
|
||||
dirname[0] = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue