parent
ea62802ceb
commit
b9d1ec9479
|
|
@ -86,6 +86,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \
|
|||
armada-385-hw14.dtb \
|
||||
armada-385-hw18.dtb \
|
||||
armada-385-hw17.dtb \
|
||||
armada-385-hw29.dtb \
|
||||
armada-3720-db.dtb \
|
||||
armada-3720-espressobin.dtb \
|
||||
armada-375-db.dtb \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* Device Tree file for the NetModule NBHW17 (NB2800)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "armada-385.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
model = "NetModule Router HW29 with Armada A385";
|
||||
compatible = "marvell,aramda385-nbhw29", "marvell,armada385", "marvell,armada380";
|
||||
|
||||
aliases {
|
||||
/* So that mvebu u-boot can update the MAC addresses */
|
||||
ethernet0 = ð0;
|
||||
ethernet1 = ð1;
|
||||
ethernet2 = ð2;
|
||||
};
|
||||
|
||||
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 */
|
||||
|
||||
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-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 19 0>; /* FPGA reset */
|
||||
fpga-reset-logic = <&gpio1 12 0>; /* FPGA reset logic (after load)*/
|
||||
};
|
||||
|
||||
fpga_conf: fpgaconf@0 {
|
||||
compatible = "nm,nbhw29-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>;
|
||||
|
||||
misc@0 {
|
||||
#gpio-cells = <4>;
|
||||
// gpio controller, gpio number, low/high_active, default value
|
||||
sd-card-enable = <&gpiofpga 65 GPIO_ACTIVE_HIGH 1>;
|
||||
rs232-enable = <&gpiofpga 288 GPIO_ACTIVE_HIGH 1>;
|
||||
};
|
||||
|
||||
// pcie slot 0
|
||||
pcieslot@0 {
|
||||
reset = <&gpiofpga 384 GPIO_ACTIVE_HIGH 1>;
|
||||
power = <&gpiofpga 400 GPIO_ACTIVE_HIGH 0>;
|
||||
power-3v8 = <&gpiofpga 464 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-out = <&gpiofpga 2053 GPIO_ACTIVE_HIGH 1>;
|
||||
wdis = <&gpiofpga 2069 GPIO_ACTIVE_LOW 1>;
|
||||
clk = <&gpiofpga 416 GPIO_ACTIVE_HIGH 1>;
|
||||
reset-1v8 = <&gpiofpga 2496 GPIO_ACTIVE_HIGH 0>;
|
||||
reset-3v3 = <&gpiofpga 2497 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-1v8 = <&gpiofpga 2498 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-3v3 = <&gpiofpga 2499 GPIO_ACTIVE_HIGH 0>;
|
||||
};
|
||||
|
||||
// pcie slot 1
|
||||
pcieslot@1 {
|
||||
reset = <&gpiofpga 385 GPIO_ACTIVE_HIGH 1>;
|
||||
power = <&gpiofpga 401 GPIO_ACTIVE_HIGH 0>;
|
||||
power-3v8 = <&gpiofpga 465 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-out = <&gpiofpga 4101 GPIO_ACTIVE_HIGH 1>;
|
||||
wdis = <&gpiofpga 4117 GPIO_ACTIVE_LOW 1>;
|
||||
clk = <&gpiofpga 417 GPIO_ACTIVE_HIGH 1>;
|
||||
reset-1v8 = <&gpiofpga 4544 GPIO_ACTIVE_HIGH 0>;
|
||||
reset-3v3 = <&gpiofpga 4545 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-1v8 = <&gpiofpga 4546 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-3v3 = <&gpiofpga 4547 GPIO_ACTIVE_HIGH 0>;
|
||||
};
|
||||
|
||||
// extension slot (ethernet switch)
|
||||
pcieslot@2 {
|
||||
reset = <&gpiofpga 386 GPIO_ACTIVE_HIGH 1>;
|
||||
power = <&gpiofpga 402 GPIO_ACTIVE_HIGH 0>;
|
||||
power-3v8 = <&gpiofpga 466 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-out = <&gpiofpga 6149 GPIO_ACTIVE_HIGH 1>;
|
||||
wdis = <&gpiofpga 6165 GPIO_ACTIVE_LOW 1>;
|
||||
clk = <&gpiofpga 418 GPIO_ACTIVE_HIGH 0>;
|
||||
reset-1v8 = <&gpiofpga 6592 GPIO_ACTIVE_HIGH 0>;
|
||||
reset-3v3 = <&gpiofpga 6593 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-1v8 = <&gpiofpga 6594 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-3v3 = <&gpiofpga 6595 GPIO_ACTIVE_HIGH 0>;
|
||||
};
|
||||
|
||||
// low end extension 0 (mapped in fpga as a pcie slot)
|
||||
pcieslot@3 {
|
||||
reset = <&gpiofpga 387 GPIO_ACTIVE_HIGH 1>;
|
||||
power = <&gpiofpga 403 GPIO_ACTIVE_HIGH 0>;
|
||||
power-3v8 = <&gpiofpga 467 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-out = <&gpiofpga 8197 GPIO_ACTIVE_HIGH 1>;
|
||||
wdis = <&gpiofpga 8213 GPIO_ACTIVE_LOW 1>;
|
||||
reset-1v8 = <&gpiofpga 8640 GPIO_ACTIVE_HIGH 0>;
|
||||
reset-3v3 = <&gpiofpga 8641 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-1v8 = <&gpiofpga 8642 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-3v3 = <&gpiofpga 8643 GPIO_ACTIVE_HIGH 0>;
|
||||
};
|
||||
|
||||
// low end extension 1 (mapped in fpga as a pcie slot)
|
||||
pcieslot@4 {
|
||||
reset = <&gpiofpga 388 GPIO_ACTIVE_HIGH 1>;
|
||||
power = <&gpiofpga 404 GPIO_ACTIVE_HIGH 0>;
|
||||
power-3v8 = <&gpiofpga 468 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-out = <&gpiofpga 10245 GPIO_ACTIVE_HIGH 1>;
|
||||
wdis = <&gpiofpga 10261 GPIO_ACTIVE_LOW 1>;
|
||||
reset-1v8 = <&gpiofpga 10688 GPIO_ACTIVE_HIGH 0>;
|
||||
reset-3v3 = <&gpiofpga 10689 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-1v8 = <&gpiofpga 10690 GPIO_ACTIVE_HIGH 0>;
|
||||
wdis-3v3 = <&gpiofpga 10691 GPIO_ACTIVE_HIGH 0>;
|
||||
};
|
||||
|
||||
// sfp (mapped in fpga also as a pcie slot)
|
||||
sfp@0 {
|
||||
power = <&gpiofpga 405 GPIO_ACTIVE_HIGH 1>;
|
||||
reset = <&gpiofpga 389 GPIO_ACTIVE_HIGH 0>;
|
||||
};
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
|
||||
sdhci@d8000 {
|
||||
broken-cd;
|
||||
wp-inverted;
|
||||
no-1-8-v;
|
||||
bus-width = <8>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
ð0 {
|
||||
status = "disabled";
|
||||
phy-mode = "sgmii";
|
||||
phy = <&phy1>;
|
||||
};
|
||||
|
||||
ð1 {
|
||||
status = "disabled";
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
ð2 {
|
||||
status = "disabled";
|
||||
phy-mode = "sgmii";
|
||||
phy = <&phy0>;
|
||||
};
|
||||
|
||||
&mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
marvell,reg-init = <3 16 0 0x101e>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
marvell,reg-init = <3 16 0 0x101e>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Device Tree file for the NetModule NBHW18 (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-hw29-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "NetModule Router HW29 with Armada A385 (NG1850)";
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
|
||||
soc {
|
||||
internal-regs {
|
||||
serial@12000 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ð0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
// SFP-Port
|
||||
ð1 {
|
||||
status = "disabled";
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
ð2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Device Tree file for the NetModule HW29 (NG1850) 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-hw29-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "NetModule Router HW29 with Armada A385 (NG1850)";
|
||||
|
||||
soc {
|
||||
gpiofpga: gpio@fd0000000 {
|
||||
fpga-cinit = <&gpio0 13 0>; /* FPGA cinit */
|
||||
fpga-cdone = <&gpio0 21 0>; /* FPGA cdone */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// LAN1 or SWITCH
|
||||
// In U-Boot we only support the configuration with two separate eth phys
|
||||
// without eth switch. This ensures that U-Boot initializes both eth phys
|
||||
// properly by calling drivers/net/phy/marvel.c:m88e1518_config(..) which
|
||||
// executes some quirks to work around some MV88E1512 phy erratas. Because
|
||||
// the linux kernel does not apply those quirks, the phys would otherwise
|
||||
// not work later in Linux, if they were not initialized by U-Boot.
|
||||
// (To use the ethernet switch in U-Boot, eth0/LAN1 would have to be
|
||||
// configured as fixed link like eth1. Then the switch would work in U-Boot,
|
||||
// but the phy for eth0/LAN1 would not be initialized.)
|
||||
ð0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
// SFP-Port
|
||||
ð1 {
|
||||
status = "disabled";
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
// LAN0
|
||||
ð2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
@ -100,6 +100,10 @@ config TARGET_NM_HW17
|
|||
bool "Support HW17"
|
||||
select 88F6820
|
||||
|
||||
config TARGET_NM_HW29
|
||||
bool "Support HW29"
|
||||
select 88F6820
|
||||
|
||||
config TARGET_TURRIS_OMNIA
|
||||
bool "Support Turris Omnia"
|
||||
select 88F6820
|
||||
|
|
@ -157,6 +161,7 @@ config SYS_BOARD
|
|||
default "hw14" if TARGET_NM_HW14
|
||||
default "hw18" if TARGET_NM_HW18
|
||||
default "hw17" if TARGET_NM_HW17
|
||||
default "hw29" if TARGET_NM_HW29
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "clearfog" if TARGET_CLEARFOG
|
||||
|
|
@ -173,6 +178,7 @@ config SYS_CONFIG_NAME
|
|||
default "armada-385-hw14" if TARGET_NM_HW14
|
||||
default "armada-385-hw18" if TARGET_NM_HW18
|
||||
default "armada-385-hw17" if TARGET_NM_HW17
|
||||
default "armada-385-hw29" if TARGET_NM_HW29
|
||||
|
||||
config SYS_VENDOR
|
||||
default "Marvell" if TARGET_DB_MV784MP_GP
|
||||
|
|
@ -187,6 +193,7 @@ config SYS_VENDOR
|
|||
default "nm" if TARGET_NM_HW14
|
||||
default "nm" if TARGET_NM_HW18
|
||||
default "nm" if TARGET_NM_HW17
|
||||
default "nm" if TARGET_NM_HW29
|
||||
|
||||
config SYS_SOC
|
||||
default "mvebu"
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#define PMIC_REG_GPIO_MODE0_7 0x1D /* Control register for GPIOs 0..7 */
|
||||
#define PMIC_REG_GPIO_MODE8_15 0x1E /* Control register for GPIOs 8..15 */
|
||||
|
||||
#define PMIC_REG_LDO6_CONT 0x2B
|
||||
|
||||
#define PMIC_REG_BBAT_CONT 0xC5 /* Control register for backup battery */
|
||||
|
||||
#define PMIC_REG_BUCK_ILIM_A 0x9A
|
||||
|
|
|
|||
|
|
@ -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,35 @@
|
|||
#
|
||||
# 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_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 \
|
||||
../common/nbhw_sim.o nbhw_sim.o \
|
||||
../common/da9063.o \
|
||||
../common/lattice/core.o \
|
||||
../common/lattice/hardware.o \
|
||||
../common/lattice/intrface.o \
|
||||
../common/lattice/SSPIEm.o \
|
||||
../common/lattice/util.o $(commonobj)
|
||||
else
|
||||
obj-y := board.o nbhw_gpio.o \
|
||||
../common/da9063.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,822 @@
|
|||
/*
|
||||
* 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 "../common/nbhw_init.h"
|
||||
#include "../common/nbhw_env.h"
|
||||
#include "../common/nbhw_bd.h"
|
||||
#include "../common/da9063.h"
|
||||
|
||||
#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
|
||||
#include <../serdes/a38x/high_speed_env_spec.h>
|
||||
|
||||
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(6) | BIT(19) | BIT(29))) /* 1=Input, default input */
|
||||
|
||||
#define GPP_OUT_ENA_MID (~(BIT(12) | BIT(15)))
|
||||
|
||||
#define GPP_OUT_VAL_LOW (BIT(29))
|
||||
#define GPP_OUT_VAL_MID (BIT(15))
|
||||
#define GPP_POL_LOW 0x0
|
||||
#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 SERDES_CONFIG_ADDRESS (0x0800) /* SERDES config address */
|
||||
|
||||
#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 }, /* ETH port 2 (same as HW18) */
|
||||
{ PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 }, /* NVMe slot (was extension connetor on HW18) */
|
||||
{ PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 }, /* PCIe for M.2 slot (was SFP on HW18) */
|
||||
{ PEX3, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0 }, /* Serdes for mPCIe slot (can be PEX3 or USB3_HOST1) (was first mPCIe slot on HW18) */
|
||||
{ USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0 }, /* USB3 for M.2 slot (was Serdes for second mPCIe slot on HW18) */
|
||||
{ SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0 } /* ETH port 1 (same as HW18) */
|
||||
};
|
||||
|
||||
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[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;
|
||||
}
|
||||
|
||||
/* TODO: Create DA9063 Accessor Module */
|
||||
#define CONFIG_PMIC_I2C_BUS 0
|
||||
#define CONFIG_PMIC_I2C_ADDR 0x58 /* Pages 0 and 1, Pages 2 and 3 -> 0x59 */
|
||||
|
||||
#define RESET_REASON_SHM_LOCATION (0x3ffff000)
|
||||
|
||||
extern int console_init_f(void);
|
||||
|
||||
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();
|
||||
|
||||
/* Don't use external console, if we have no FPGA,
|
||||
as it cannot work then. -> Switch to internal console then. */
|
||||
// if (readw(0xfd000000)!=0x012f) { /* Check for correct FPGA signature */
|
||||
printf("FPGA not ready. Forcing console to ttyS0\n");
|
||||
env_set("defaultconsole", "ttyS0");
|
||||
env_set("consoledev", "ttyS0");
|
||||
// }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
|
||||
{
|
||||
int i, j;
|
||||
int bd_config_is_broken = 0;
|
||||
|
||||
if (read_eeprom() < 0){
|
||||
/* If we do not have a board descriptor use the default
|
||||
serdes configuration defined in board_serdes_map */
|
||||
puts("Could not read board descriptor using default serdes config.\n");
|
||||
} else {
|
||||
/* Check for broken serdes config in BD -> If multiple serdes lines are
|
||||
configured for the same function something is obviously broken. */
|
||||
for (i = 0; i<ARRAY_SIZE(board_serdes_map); i++) {
|
||||
for (j = i+1; j<ARRAY_SIZE(board_serdes_map); j++) {
|
||||
if ((bd_get_serdes_type(i) == bd_get_serdes_type(j)) &&
|
||||
(bd_get_serdes_type(i) < DEFAULT_SERDES)) { // DEFAULT_SERDES & LAST_SERDES_TYPE are always ok
|
||||
printf("Serdes lines %d and %d are configured for same function %d\n",
|
||||
i, j, bd_get_serdes_type(i));
|
||||
bd_config_is_broken = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bd_config_is_broken) {
|
||||
printf("Serdes config in BD is broken! -> Ignoring BD serdes config\n");
|
||||
}
|
||||
|
||||
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 if it is not broken */
|
||||
if (bd_config_is_broken) {
|
||||
type = LAST_SERDES_TYPE;
|
||||
} else {
|
||||
type = bd_get_serdes_type(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* LAST_SERDES_TYPE means use compiled in default */
|
||||
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;
|
||||
}
|
||||
|
||||
if (i==3) {
|
||||
/* On V2 TX line for PCIe slot1 is inverted*/
|
||||
board_serdes_map[i].swap_tx = 1;
|
||||
}
|
||||
|
||||
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(0x00111111, MVEBU_MPP_BASE + 0x00);
|
||||
writel(0x40000000, MVEBU_MPP_BASE + 0x04);
|
||||
writel(0x55000444, MVEBU_MPP_BASE + 0x08);
|
||||
writel(0x55053350, MVEBU_MPP_BASE + 0x0c);
|
||||
writel(0x55555555, MVEBU_MPP_BASE + 0x10);
|
||||
writel(0x06605505, MVEBU_MPP_BASE + 0x14);
|
||||
writel(0x55550555, MVEBU_MPP_BASE + 0x18);
|
||||
writel(0x00005551, 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;
|
||||
|
||||
da9063_init(CONFIG_PMIC_I2C_BUS);
|
||||
|
||||
// FB 57727 Use synchronous mode for buck converters
|
||||
// This solves the occasional rail lock up problem
|
||||
da9063_set_reg(PMIC_REG_BCORE1_CONF, 0x81);
|
||||
da9063_set_reg(PMIC_REG_BCORE2_CONF, 0x81);
|
||||
da9063_set_reg(PMIC_REG_BIO_CONF, 0x81);
|
||||
da9063_set_reg(PMIC_REG_BMEM_CONF, 0x81);
|
||||
da9063_set_reg(PMIC_REG_BPERI_CONF, 0x81);
|
||||
|
||||
/* Enable LDO6 used for GNSS */
|
||||
da9063_set_reg(PMIC_REG_LDO6_CONT, 0x81);
|
||||
|
||||
da9063_reset_reason_update(RESET_REASON_SHM_LOCATION);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
static void set_gpios(void)
|
||||
{
|
||||
init_gpios();
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
|
||||
static void pass_hw_rev(void)
|
||||
{
|
||||
int hw_ver = 0, hw_rev = 0;
|
||||
char *old_env;
|
||||
char hw_versions[128];
|
||||
char new_env[256];
|
||||
|
||||
bd_get_hw_version(&hw_ver, &hw_rev);
|
||||
|
||||
snprintf(hw_versions, sizeof(hw_versions), "CP=%d.%d",
|
||||
hw_ver, hw_rev);
|
||||
|
||||
old_env = env_get("add_version_bootargs");
|
||||
|
||||
/* Normaly add_version_bootargs should already be set (see board include file) */
|
||||
if (old_env != 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
env_set("add_version_bootargs", new_env);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
#if defined(CONFIG_WATCHDOG)
|
||||
watchdog_init();
|
||||
#endif
|
||||
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
|
||||
|
||||
/* Setup the MBUS mapping for Devicebus CS0 */
|
||||
mbus_dt_setup_win(&mbus_state, DEV_CS0_BASE, 16 << 20,
|
||||
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_DEV_CS0);
|
||||
|
||||
if (read_eeprom() < 0)
|
||||
puts("Could not get board ID.\n");
|
||||
|
||||
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, 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)
|
||||
{
|
||||
u8 state = 0x00;
|
||||
|
||||
(void)da9063_get_reg(PMIC_REG_STATUS_A, &state);
|
||||
|
||||
return (state & 0x01) == 0x01;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Because U-Boot is buggy, we need to call this funktion again
|
||||
* it will print the pre console buffer */
|
||||
|
||||
/* TODO: Moved following two lines to board_late_init because ttyS1 is currently not working without loaded bitstream */
|
||||
// init_console();
|
||||
// console_init_f();
|
||||
|
||||
/* Configure PMIC */
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
|
||||
/* Enable PMIC LED */
|
||||
da9063_set_reg(0x1e, 0x08);
|
||||
|
||||
/* Enable PMIC RTC backup charger (charge with 6mA to 3.1V) */
|
||||
da9063_set_reg(PMIC_REG_BBAT_CONT, 0xff);
|
||||
#endif
|
||||
|
||||
/* Determine SERDES configuration */
|
||||
hws_board_topology_load(&sm, &sm_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_phy_page(const char *miidev, int phy_addr, int page)
|
||||
{
|
||||
miiphy_write(miidev, phy_addr, 22, page);
|
||||
}
|
||||
|
||||
static void set_phy_fast_blink_mode(int phy_addr)
|
||||
{
|
||||
const char *miidev = miiphy_get_current_dev();
|
||||
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);
|
||||
set_phy_page(miidev, phy_addr, 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, use legacy name\n");
|
||||
strcpy(devicetreename, "armada-385-hw29-prod1.dtb");
|
||||
}
|
||||
|
||||
env_set("fdt_image", devicetreename);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
gpio_request(29, "RST_ETH_PHY_N");
|
||||
gpio_direction_output(29, 0);
|
||||
|
||||
find_and_set_active_partition();
|
||||
pass_hw_rev();
|
||||
|
||||
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 */
|
||||
init_console();
|
||||
console_init_f();
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD)
|
||||
|
||||
check_reset_button();
|
||||
|
||||
set_devicetree_name();
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_network_enable(struct mii_dev *bus)
|
||||
{
|
||||
static int NETWORK_ENABLED = 0;
|
||||
|
||||
if (!NETWORK_ENABLED) {
|
||||
set_phy_fast_blink_mode(0);
|
||||
set_phy_fast_blink_mode(1);
|
||||
|
||||
NETWORK_ENABLED = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
debug("Board: NetModule NBHW29\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-hw29-spl"
|
||||
#else
|
||||
/* U-Boot will read /boot/consoledev and based on that it
|
||||
* enables its own serial console */
|
||||
#define DEFAULT_DTB_NAME "armada-385-hw29"
|
||||
#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 :
|
||||
serdes = 4;
|
||||
break;
|
||||
case 2 :
|
||||
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;
|
||||
}
|
||||
}
|
||||
/*
|
||||
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)
|
||||
{
|
||||
/* Enabled all components in dts depending on
|
||||
current serdes configuration */
|
||||
|
||||
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,393 @@
|
|||
#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"
|
||||
|
||||
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;
|
||||
struct gpio_desc clk;
|
||||
struct gpio_desc power_3v8;
|
||||
struct gpio_desc reset_1v8;
|
||||
struct gpio_desc reset_3v3;
|
||||
struct gpio_desc wdis_1v8;
|
||||
struct gpio_desc wdis_3v3;
|
||||
};
|
||||
|
||||
struct sfp_gpios {
|
||||
struct gpio_desc reset;
|
||||
struct gpio_desc power;
|
||||
};
|
||||
|
||||
#define PCIE_SLOT_COUNT 8
|
||||
static struct pcie_slot_gpios pcie_slots[PCIE_SLOT_COUNT];
|
||||
static struct sfp_gpios sfps;
|
||||
|
||||
static int pcie_slot_count = 0;
|
||||
|
||||
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_sfp(ofnode fdt)
|
||||
{
|
||||
debug("%s\n", __func__);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "power",
|
||||
&sfps.power);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "reset",
|
||||
&sfps.reset);
|
||||
|
||||
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);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "clk",
|
||||
&pcie_slots[pcie_slot_count].clk);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "power-3v8",
|
||||
&pcie_slots[pcie_slot_count].power_3v8);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "reset-1v8",
|
||||
&pcie_slots[pcie_slot_count].reset_1v8);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "reset-3v3",
|
||||
&pcie_slots[pcie_slot_count].reset_3v3);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "wdis-1v8",
|
||||
&pcie_slots[pcie_slot_count].wdis_1v8);
|
||||
|
||||
request_and_set_gpio_by_name(fdt, "wdis-3v3",
|
||||
&pcie_slots[pcie_slot_count].wdis_3v3);
|
||||
|
||||
pcie_slot_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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++) {
|
||||
/* Set supply voltage of PCIe slots */
|
||||
if ((bd_get_slot_supply_volt(i, volt, sizeof(volt)) == 0) &&
|
||||
(strncmp(volt, "3v8", 3)==0)) {
|
||||
dm_gpio_set_value(&pcie_slots[i].power_3v8, 1);
|
||||
} else {
|
||||
/* Default is 3v3 */
|
||||
dm_gpio_set_value(&pcie_slots[i].power_3v8, 0);
|
||||
}
|
||||
|
||||
/* Set reset signal voltage of PCIe slots */
|
||||
res = bd_get_slot_perst_volt(i, volt, sizeof(volt));
|
||||
if ((res == 0) && (strncmp(volt, "off", 3)==0)) {
|
||||
/* No pull up */
|
||||
dm_gpio_set_value(&pcie_slots[i].reset_1v8, 0);
|
||||
dm_gpio_set_value(&pcie_slots[i].reset_3v3, 0);
|
||||
} else if ((res == 0) && (strncmp(volt, "1v8", 3)==0)) {
|
||||
dm_gpio_set_value(&pcie_slots[i].reset_1v8, 1);
|
||||
dm_gpio_set_value(&pcie_slots[i].reset_3v3, 0);
|
||||
} else {
|
||||
/* Default is 3v3 */
|
||||
dm_gpio_set_value(&pcie_slots[i].reset_1v8, 0);
|
||||
dm_gpio_set_value(&pcie_slots[i].reset_3v3, 1);
|
||||
}
|
||||
|
||||
/* Set wdis signal voltage of PCIe slots */
|
||||
res = bd_get_slot_wdis_volt(i, volt, sizeof(volt));
|
||||
if ((res == 0) && (strncmp(volt, "off", 3)==0)) {
|
||||
/* No pull up */
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis_1v8, 0);
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis_3v3, 0);
|
||||
} else if ((res == 0) && (strncmp(volt, "1v8", 3)==0)) {
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis_1v8, 1);
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis_3v3, 0);
|
||||
} else {
|
||||
/* Default is 3v3 */
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis_1v8, 0);
|
||||
dm_gpio_set_value(&pcie_slots[i].wdis_3v3, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* Enable PCIe clock Note: Slot 1 has always clock. Slot 0 & extension
|
||||
slot cannot have clock at same time. */
|
||||
for (i = 0; i < 2; i ++) {
|
||||
if (has_slot_wlan(i)) {
|
||||
/* Only enable PCIe clock on WiFi modules as it confuses some LTE modems */
|
||||
dm_gpio_set_value(&pcie_slots[i].clk, 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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
debug("leave %s with %d gpios\n", __func__, i);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static int configure_misc(ofnode fdt)
|
||||
{
|
||||
struct gpio_desc misc_gpios[16];
|
||||
int gpio_count;
|
||||
debug("%s\n", __func__);
|
||||
|
||||
gpio_count = request_and_set_gpios(fdt,
|
||||
misc_gpios, ARRAY_SIZE(misc_gpios));
|
||||
if (gpio_count < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug("Free gpios\n");
|
||||
/* Free gpios so that we could use them via gpio subsystem */
|
||||
gpio_free_list_nodev(misc_gpios, gpio_count);
|
||||
debug("return %s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nbhw_fpga_configure(void)
|
||||
{
|
||||
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("misc", name, 4)) {
|
||||
configure_misc(subnode);
|
||||
}
|
||||
|
||||
if (!strncmp("pcieslot", name, 8)) {
|
||||
add_pcie_slot(subnode);
|
||||
}
|
||||
|
||||
if (!strncmp("sfp", name, 3)) {
|
||||
add_sfp(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,nbhw29-fpga-config" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(gpio_nbhw_fpga_config) = {
|
||||
.name = "nbhw29_fpga_config",
|
||||
.id = UCLASS_ROOT,
|
||||
.of_match = nbhw_fpga_config_ids,
|
||||
.bind = nbhw_fpga_config_bind,
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
#define GPIO_RESET_BUTTON (14)
|
||||
|
||||
void init_gpios(void)
|
||||
{
|
||||
gpio_request(GPIO_RESET_BUTTON, "GPIO_RESET_BUTTON");
|
||||
gpio_direction_input(GPIO_RESET_BUTTON);
|
||||
}
|
||||
|
||||
void out_usb_power(int enable)
|
||||
{
|
||||
// SET_LOGIC(enable, 1, BIT9);
|
||||
}
|
||||
|
||||
void out_watchdog(int enable)
|
||||
{
|
||||
// SET_LOGIC(enable, 0, BIT19);
|
||||
}
|
||||
|
||||
void out_fpga_logic_reset(int enable)
|
||||
{
|
||||
// SET_LOGIC(enable, 1, BIT12);
|
||||
}
|
||||
|
||||
void out_ext_reset_en(int enable)
|
||||
{
|
||||
// SET_LOGIC(enable, 0, BIT7);
|
||||
}
|
||||
|
||||
int in_reset_button(void)
|
||||
{
|
||||
return gpio_get_value(GPIO_RESET_BUTTON);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef NBHW29_GPIO_H
|
||||
#define NBHW29_GPIO_H
|
||||
#include "../common/nbhw_gpio.h"
|
||||
|
||||
void init_gpios(void);
|
||||
|
||||
void out_usb_power(int enable);
|
||||
void out_watchdog(int enable);
|
||||
void out_fpga_logic_reset(int enable);
|
||||
|
||||
int in_fpga_cdone(void);
|
||||
|
||||
#define LED0_GREEN 0
|
||||
#define LED0_RED 1
|
||||
#define LED1_GREEN 2
|
||||
#define LED1_RED 3
|
||||
#define LED2_GREEN 4
|
||||
#define LED2_RED 5
|
||||
#define LED3_GREEN 6
|
||||
#define LED3_RED 7
|
||||
#define LED4_GREEN 8
|
||||
#define LED4_RED 9
|
||||
#define LED5_GREEN 10
|
||||
#define LED5_RED 11
|
||||
|
||||
void set_led(int index, int value);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#include <common.h>
|
||||
#include "../common/nbhw_fpga_prog.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 > 1) {
|
||||
printf("Invalid sim %d selected, can't connect slot %d\n", sim, slot);
|
||||
return;
|
||||
}
|
||||
|
||||
if (slot < 0)
|
||||
slot_sel = 0;
|
||||
else if (slot <= 4) {
|
||||
slot_sel = slot + 1;
|
||||
}
|
||||
else {
|
||||
printf("Invalid slot %d selected, can't connect sim %d\n", slot, sim);
|
||||
return;
|
||||
}
|
||||
|
||||
sim_shift = sim * 4;
|
||||
|
||||
sim_ctrl = FPGA_REG(SIM_CTRL);
|
||||
|
||||
sim_ctrl &= ~(0xF << sim_shift);
|
||||
sim_ctrl |= slot_sel << sim_shift;
|
||||
|
||||
FPGA_REG(SIM_CTRL) = sim_ctrl;
|
||||
}
|
||||
|
|
@ -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_HW29=y
|
||||
CONFIG_SPL_MMC_SUPPORT=y
|
||||
CONFIG_SPL_SERIAL_SUPPORT=y
|
||||
CONFIG_SPL_LIBDISK_SUPPORT=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="armada-385-hw29-spl"
|
||||
CONFIG_SMBIOS_PRODUCT_NAME="hw29"
|
||||
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-hw29-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-hw29-spl armada-385-hw29"
|
||||
CONFIG_MULTI_DTB_FIT=y
|
||||
CONFIG_FPGA_LATTICE_SSPI=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_DM_GPIO=y
|
||||
CONFIG_CMD_EEPROM=y
|
||||
CONFIG_ENV_IS_IN_EEPROM=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_WDT_ORION=y
|
||||
|
|
@ -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=armada-385-hw29-prod1.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 nvme_core.default_ps_max_latency_us=0 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 && " \
|
||||
"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=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" \
|
||||
"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 */
|
||||
Loading…
Reference in New Issue