
On 23.11.2016 16:12, Mario Six wrote:
From: Dirk Eibach dirk.eibach@gdsys.cc
The gdsys ControlCenter Digital board is based on a Marvell Armada 38x SOC.
It boots from SPI-Flash but can be configured to boot from SD-card for factory programming and testing.
On board peripherals include:
- 2 x GbE
- Xilinx Kintex-7 FPGA connected via PCIe
- mSATA
- USB3 host
- Atmel TPM
Signed-off-by: Dirk Eibach dirk.eibach@gdsys.cc Signed-off-by: Mario Six mario.six@gdsys.cc
arch/arm/Kconfig | 1 + arch/arm/dts/Makefile | 3 +- arch/arm/dts/controlcenterdc.dts | 629 +++++++++++++++++++++++++++++++++
Could you perhaps rename this file (and board name as well?) to something like "armada-38x-controlcenterdc*" instead? Its much easier to match the files to the architecture this way. And until now, all Armada XP / 38x (etc) files match this rule.
arch/arm/mach-mvebu/Kconfig | 4 + board/gdsys/38x/.gitignore | 1 +
Perhaps better s/38x/a38x for "Armada"?
board/gdsys/38x/Kconfig | 42 +++ board/gdsys/38x/MAINTAINERS | 7 + board/gdsys/38x/Makefile | 30 ++ board/gdsys/38x/README | 18 + board/gdsys/38x/controlcenterdc.c | 717 ++++++++++++++++++++++++++++++++++++++ board/gdsys/38x/dt_helpers.c | 60 ++++ board/gdsys/38x/dt_helpers.h | 16 + board/gdsys/38x/hre.c | 517 +++++++++++++++++++++++++++ board/gdsys/38x/hre.h | 38 ++ board/gdsys/38x/keyprogram.c | 158 +++++++++ board/gdsys/38x/keyprogram.h | 14 + board/gdsys/38x/kwbimage.cfg.in | 12 + board/gdsys/38x/spl.c | 21 ++ configs/controlcenterdc_defconfig | 54 +++ include/configs/controlcenterdc.h | 244 +++++++++++++ 20 files changed, 2585 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/controlcenterdc.dts create mode 100644 board/gdsys/38x/.gitignore create mode 100644 board/gdsys/38x/Kconfig create mode 100644 board/gdsys/38x/MAINTAINERS create mode 100644 board/gdsys/38x/Makefile create mode 100644 board/gdsys/38x/README create mode 100644 board/gdsys/38x/controlcenterdc.c create mode 100644 board/gdsys/38x/dt_helpers.c create mode 100644 board/gdsys/38x/dt_helpers.h create mode 100644 board/gdsys/38x/hre.c create mode 100644 board/gdsys/38x/hre.h create mode 100644 board/gdsys/38x/keyprogram.c create mode 100644 board/gdsys/38x/keyprogram.h create mode 100644 board/gdsys/38x/kwbimage.cfg.in create mode 100644 board/gdsys/38x/spl.c create mode 100644 configs/controlcenterdc_defconfig create mode 100644 include/configs/controlcenterdc.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index acd689b..f4c236b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -970,6 +970,7 @@ source "board/freescale/mx53loco/Kconfig" source "board/freescale/mx53smd/Kconfig" source "board/freescale/s32v234evb/Kconfig" source "board/freescale/vf610twr/Kconfig" +source "board/gdsys/38x/Kconfig" source "board/gumstix/pepper/Kconfig" source "board/h2200/Kconfig" source "board/hisilicon/hikey/Kconfig" diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 2c5b2f2..b0bd507 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -76,7 +76,8 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-xp-gp.dtb \ armada-xp-maxbcm.dtb \ armada-xp-synology-ds414.dtb \
- armada-xp-theadorable.dtb
- armada-xp-theadorable.dtb \
- controlcenterdc.dtb
dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-ld11-ref.dtb \ diff --git a/arch/arm/dts/controlcenterdc.dts b/arch/arm/dts/controlcenterdc.dts new file mode 100644 index 0000000..baf0171 --- /dev/null +++ b/arch/arm/dts/controlcenterdc.dts @@ -0,0 +1,629 @@ +/*
- Device Tree file for the Guntermann & Drunck ControlCenter-Compact board
- Copyright (C) 2016 Mario Six mario.six@gdsys.cc
- based on the Device Tree file for Marvell Armada 388 evaluation board
- (DB-88F6820), which is
- Copyright (C) 2014 Marvell
- Thomas Petazzoni thomas.petazzoni@free-electrons.com
- SPDX-License-Identifier: GPL-2.0+
- */
+/dts-v1/;
+#include "armada-388.dtsi"
+&uart0 {
- u-boot,dm-pre-reloc;
+};
+&uart1 {
- u-boot,dm-pre-reloc;
+};
+/ {
- model = "Controlcenter Digital Compact";
- compatible = "marvell,a385-db", "marvell,armada388",
"marvell,armada385", "marvell,armada380";
- chosen {
bootargs = "console=ttyS1,115200 earlyprintk";
stdout-path = "/soc/internal-regs/serial@12100";
- };
- aliases {
ethernet0 = ð0;
ethernet2 = ð2;
mdio-gpio0 = &MDIO0;
mdio-gpio1 = &MDIO1;
mdio-gpio2 = &MDIO2;
spi0 = &spi0;
spi1 = &spi1;
i2c0 = &I2C0;
i2c1 = &I2C1;
- };
- memory {
device_type = "memory";
reg = <0x00000000 0x10000000>; /* 256 MB */
- };
- clocks {
sc16isclk: sc16isclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <11059200>;
};
- };
- soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
internal-regs {
spi0: spi@10600 {
status = "okay";
sc16is741: sc16is741@0 {
compatible = "nxp,sc16is741";
reg = <0>;
clocks = <&sc16isclk>;
spi-max-frequency = <4000000>;
interrupt-parent = <&gpio0>;
interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
};
};
spi1: spi@10680 {
status = "okay";
u-boot,dm-pre-reloc;
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "n25q016a";
reg = <0>; /* Chip select 0 */
spi-max-frequency = <108000000>;
};
spi-flash@1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "n25q128a11";
reg = <1>; /* Chip select 1 */
spi-max-frequency = <108000000>;
u-boot,dm-pre-reloc;
};
};
I2C0: i2c@11000 {
status = "okay";
clock-frequency = <1000000>;
u-boot,dm-pre-reloc;
PCA21: pca9698@21 {
compatible = "nxp,pca9698";
reg = <0x21>;
#gpio-cells = <2>;
gpio-controller;
};
PCA22: pca9698@22 {
compatible = "nxp,pca9698";
u-boot,dm-pre-reloc;
reg = <0x22>;
#gpio-cells = <2>;
gpio-controller;
};
PCA23: pca9698@23 {
compatible = "nxp,pca9698";
reg = <0x23>;
#gpio-cells = <2>;
gpio-controller;
};
PCA24: pca9698@24 {
compatible = "nxp,pca9698";
reg = <0x24>;
#gpio-cells = <2>;
gpio-controller;
};
PCA25: pca9698@25 {
compatible = "nxp,pca9698";
reg = <0x25>;
#gpio-cells = <2>;
gpio-controller;
};
PCA26: pca9698@26 {
compatible = "nxp,pca9698";
reg = <0x26>;
#gpio-cells = <2>;
gpio-controller;
};
};
I2C1: i2c@11100 {
status = "okay";
clock-frequency = <400000>;
at97sc3205t@29 {
compatible = "atmel,at97sc3204t";
reg = <0x29>;
u-boot,i2c-offset-len = <0>;
};
emc2305@2d {
compatible = "smsc,emc2305";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x2d>;
fan@0 {
reg = <0>;
};
fan@1 {
reg = <1>;
};
fan@2 {
reg = <2>;
};
fan@3 {
reg = <3>;
};
fan@4 {
reg = <4>;
};
};
lm77@48 {
compatible = "national,lm77";
reg = <0x48>;
};
ads1015@49 {
compatible = "ti,ads1015";
reg = <0x49>;
};
lm77@4a {
compatible = "national,lm77";
reg = <0x4a>;
};
ads1015@4b {
compatible = "ti,ads1015";
reg = <0x4b>;
};
emc2305@4c {
compatible = "smsc,emc2305";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x4c>;
fan@0 {
reg = <0>;
};
fan@1 {
reg = <1>;
};
fan@2 {
reg = <2>;
};
fan@3 {
reg = <3>;
};
fan@4 {
reg = <4>;
};
};
at24c512@54 {
compatible = "atmel,24c512";
reg = <0x54>;
u-boot,i2c-offset-len = <2>;
};
ds1339@68 {
compatible = "dallas,ds1339";
reg = <0x68>;
};
};
serial@12000 {
status = "okay";
};
serial@12100 {
status = "okay";
};
ethernet@34000 {
status = "okay";
phy = <&phy1>;
phy-mode = "sgmii";
};
usb@58000 {
status = "ok";
};
ethernet@70000 {
status = "okay";
phy = <&phy0>;
phy-mode = "sgmii";
};
mdio@72004 {
phy0: ethernet-phy@0 {
reg = <1>;
};
phy1: ethernet-phy@1 {
reg = <0>;
};
};
sata@a8000 {
status = "okay";
};
sdhci@d8000 {
broken-cd;
wp-inverted;
bus-width = <4>;
status = "okay";
no-1-8-v;
};
usb3@f0000 {
status = "okay";
};
};
pcie-controller {
status = "okay";
/*
* The two PCIe units are accessible through
* standard PCIe slots on the board.
*/
pcie@3,0 {
/* Port 0, Lane 0 */
status = "okay";
};
};
MDIO0: mdio0 {
compatible = "virtual,mdio-gpio";
#address-cells = <1>;
#size-cells = <0>;
gpios = < /*MDC*/ &gpio0 13 0
/*MDIO*/ &gpio0 14 0>;
mv88e1240@0 {
reg = <0x0>;
};
mv88e1240@1 {
reg = <0x1>;
};
mv88e1240@2 {
reg = <0x2>;
};
mv88e1240@3 {
reg = <0x3>;
};
mv88e1240@4 {
reg = <0x4>;
};
mv88e1240@5 {
reg = <0x5>;
};
mv88e1240@6 {
reg = <0x6>;
};
mv88e1240@7 {
reg = <0x7>;
};
mv88e1240@8 {
reg = <0x8>;
};
mv88e1240@9 {
reg = <0x9>;
};
mv88e1240@a {
reg = <0xa>;
};
mv88e1240@b {
reg = <0xb>;
};
mv88e1240@c {
reg = <0xc>;
};
mv88e1240@d {
reg = <0xd>;
};
mv88e1240@e {
reg = <0xe>;
};
mv88e1240@f {
reg = <0xf>;
};
mv88e1240@10 {
reg = <0x10>;
};
mv88e1240@11 {
reg = <0x11>;
};
mv88e1240@12 {
reg = <0x12>;
};
mv88e1240@13 {
reg = <0x13>;
};
mv88e1240@14 {
reg = <0x14>;
};
mv88e1240@15 {
reg = <0x15>;
};
mv88e1240@16 {
reg = <0x16>;
};
mv88e1240@17 {
reg = <0x17>;
};
mv88e1240@18 {
reg = <0x18>;
};
mv88e1240@19 {
reg = <0x19>;
};
mv88e1240@1a {
reg = <0x1a>;
};
mv88e1240@1b {
reg = <0x1b>;
};
mv88e1240@1c {
reg = <0x1c>;
};
mv88e1240@1d {
reg = <0x1d>;
};
mv88e1240@1e {
reg = <0x1e>;
};
mv88e1240@1f {
reg = <0x1f>;
};
};
MDIO1: mdio1 {
compatible = "virtual,mdio-gpio";
#address-cells = <1>;
#size-cells = <0>;
gpios = < /*MDC*/ &gpio0 25 0
/*MDIO*/ &gpio1 13 0>;
mv88e1240@0 {
reg = <0x0>;
};
mv88e1240@1 {
reg = <0x1>;
};
mv88e1240@2 {
reg = <0x2>;
};
mv88e1240@3 {
reg = <0x3>;
};
mv88e1240@4 {
reg = <0x4>;
};
mv88e1240@5 {
reg = <0x5>;
};
mv88e1240@6 {
reg = <0x6>;
};
mv88e1240@7 {
reg = <0x7>;
};
mv88e1240@8 {
reg = <0x8>;
};
mv88e1240@9 {
reg = <0x9>;
};
mv88e1240@a {
reg = <0xa>;
};
mv88e1240@b {
reg = <0xb>;
};
mv88e1240@c {
reg = <0xc>;
};
mv88e1240@d {
reg = <0xd>;
};
mv88e1240@e {
reg = <0xe>;
};
mv88e1240@f {
reg = <0xf>;
};
mv88e1240@10 {
reg = <0x10>;
};
mv88e1240@11 {
reg = <0x11>;
};
mv88e1240@12 {
reg = <0x12>;
};
mv88e1240@13 {
reg = <0x13>;
};
mv88e1240@14 {
reg = <0x14>;
};
mv88e1240@15 {
reg = <0x15>;
};
mv88e1240@16 {
reg = <0x16>;
};
mv88e1240@17 {
reg = <0x17>;
};
mv88e1240@18 {
reg = <0x18>;
};
mv88e1240@19 {
reg = <0x19>;
};
mv88e1240@1a {
reg = <0x1a>;
};
mv88e1240@1b {
reg = <0x1b>;
};
mv88e1240@1c {
reg = <0x1c>;
};
mv88e1240@1d {
reg = <0x1d>;
};
mv88e1240@1e {
reg = <0x1e>;
};
mv88e1240@1f {
reg = <0x1f>;
};
};
MDIO2: mdio2 {
compatible = "virtual,mdio-gpio";
#address-cells = <1>;
#size-cells = <0>;
gpios = < /*MDC*/ &gpio1 14 0
/*MDIO*/ &gpio0 24 0>;
mv88e1240@0 {
reg = <0x0>;
};
mv88e1240@1 {
reg = <0x1>;
};
mv88e1240@2 {
reg = <0x2>;
};
mv88e1240@3 {
reg = <0x3>;
};
mv88e1240@4 {
reg = <0x4>;
};
mv88e1240@5 {
reg = <0x5>;
};
mv88e1240@6 {
reg = <0x6>;
};
mv88e1240@7 {
reg = <0x7>;
};
mv88e1240@8 {
reg = <0x8>;
};
mv88e1240@9 {
reg = <0x9>;
};
mv88e1240@a {
reg = <0xa>;
};
mv88e1240@b {
reg = <0xb>;
};
mv88e1240@c {
reg = <0xc>;
};
mv88e1240@d {
reg = <0xd>;
};
mv88e1240@e {
reg = <0xe>;
};
mv88e1240@f {
reg = <0xf>;
};
mv88e1240@10 {
reg = <0x10>;
};
mv88e1240@11 {
reg = <0x11>;
};
mv88e1240@12 {
reg = <0x12>;
};
mv88e1240@13 {
reg = <0x13>;
};
mv88e1240@14 {
reg = <0x14>;
};
mv88e1240@15 {
reg = <0x15>;
};
};
- };
- cat_gpio_0 {
compatible = "generic,cat-gpio-0";
gpios = <&PCA23 0x20 0x0>;
- };
- cat_gpio_1 {
compatible = "generic,cat-gpio-1";
gpios = <&PCA21 0x20 0x0>;
- };
- cat_gpio_2 {
compatible = "generic,cat-gpio-2";
gpios = <&PCA24 0x20 0x0>;
- };
- cat_gpio_3 {
compatible = "generic,cat-gpio-3";
gpios = <&PCA25 0x20 0x0>;
- };
- cat_gpio_4 {
compatible = "generic,cat-gpio-4";
gpios = <&PCA26 0x20 0x0>;
- };
- second_octo_gpio_0 {
compatible = "generic,second-octo-gpio-0";
gpios = <&PCA23 0x27 0x0>;
- };
- fpga_program_gpio {
compatible = "generic,fpga-program-gpio";
u-boot,dm-pre-reloc;
gpios = <&PCA22 31 0>;
- };
- fpga_done_gpio {
compatible = "generic,fpga-done-gpio";
u-boot,dm-pre-reloc;
gpios = <&PCA22 19 0>;
- };
- fpga_ready_gpio {
compatible = "generic,fpga-ready-gpio";
u-boot,dm-pre-reloc;
gpios = <&PCA22 27 0>;
- };
- leds {
compatible = "gpio-leds";
finder_led {
label = "finder-led";
gpios = <&PCA22 25 0>;
};
status_led {
label = "status-led";
gpios = <&gpio0 29 0>;
};
- };
+}; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 1ca7b52..ac36894 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -102,6 +102,10 @@ config TARGET_THEADORABLE bool "Support theadorable Armada XP" select MV78260
+config TARGET_CONTROLCENTERDC
- bool "Support CONTROLCENTERDC"
- select 88F6820
endchoice
config SYS_BOARD diff --git a/board/gdsys/38x/.gitignore b/board/gdsys/38x/.gitignore new file mode 100644 index 0000000..775b934 --- /dev/null +++ b/board/gdsys/38x/.gitignore @@ -0,0 +1 @@ +kwbimage.cfg diff --git a/board/gdsys/38x/Kconfig b/board/gdsys/38x/Kconfig new file mode 100644 index 0000000..dd99ac5 --- /dev/null +++ b/board/gdsys/38x/Kconfig @@ -0,0 +1,42 @@ +if TARGET_CONTROLCENTERDC
+config SYS_BOARD
- default "38x"
+config SYS_VENDOR
- default "gdsys"
+config SYS_SOC
- default "mvebu"
+config SYS_CONFIG_NAME
- default "controlcenterdc"
+menu "Controlcenter DC board options"
+choice
- prompt "Select boot method"
+config SPL_BOOT_DEVICE_SPI
- bool "SPI"
+config SPL_BOOT_DEVICE_MMC
- bool "MMC"
- select SPL_LIBDISK_SUPPORT
+endchoice
+#config SPL_BOOT_DEVICE +# int +# default 1 if SPL_BOOT_DEVICE_SPI +# default 2 if SPL_BOOT_DEVICE_MMC
+config SYS_BOOTIMAGE_DEST_ADDR
- hex "Boot image destination address"
- default 0x007fffc0
- help
Blah
Hmmm, the help text is not really "helpful". ;)
This option is also not referenced, so perhaps you can remove it?
+endmenu
+endif diff --git a/board/gdsys/38x/MAINTAINERS b/board/gdsys/38x/MAINTAINERS new file mode 100644 index 0000000..5dbc6ec --- /dev/null +++ b/board/gdsys/38x/MAINTAINERS @@ -0,0 +1,7 @@ +38X BOARD +M: Dirk Eibach eibach@gdsys.cc +M: Mario Six six@gdsys.de +S: Maintained +F: board/gdsys/38x/ +F: include/configs/controlcenterdc.h +F: configs/controlcenterdc_defconfig diff --git a/board/gdsys/38x/Makefile b/board/gdsys/38x/Makefile new file mode 100644 index 0000000..6d17196 --- /dev/null +++ b/board/gdsys/38x/Makefile @@ -0,0 +1,30 @@ +# +# Copyright (C) 2015 Stefan Roese sr@denx.de +# Copyright (C) 2015 Reinhard Pfau reinhard.pfau@gdsys.cc +# Copyright (C) 2016 Mario Six mario.six@gdsys.cc +# +# SPDX-License-Identifier: GPL-2.0+ +#
+obj-$(CONFIG_TARGET_CONTROLCENTERDC) += controlcenterdc.o hre.o spl.o keyprogram.o dt_helpers.o
+ifeq ($(CONFIG_SPL_BUILD),)
+extra-$(CONFIG_TARGET_CONTROLCENTERDC) += kwbimage.cfg
+ifneq ($(CONFIG_TARGET_CONTROLCENTERDC),) +KWB_REPLACE += BOOT_FROM +ifneq ($(CONFIG_SPL_BOOT_DEVICE_SPI),)
- KWB_CFG_BOOT_FROM=spi
+endif +ifneq ($(CONFIG_SPL_BOOT_DEVICE_MMC),)
- KWB_CFG_BOOT_FROM=sdio
+endif +endif
Do you have multiple build targets for this directory? Do you need to have this check with CONFIG_TARGET_CONTROLCENTERDC?
+$(src)/kwbimage.cfg: $(src)/kwbimage.cfg.in include/autoconf.mk \
include/config/auto.conf
- $(Q)sed -ne '$(foreach V,$(KWB_REPLACE),s/^#@$(V)/$(V) $(KWB_CFG_$(V))/;)p' \
- <$< >$@
+endif diff --git a/board/gdsys/38x/README b/board/gdsys/38x/README new file mode 100644 index 0000000..9bea5b3 --- /dev/null +++ b/board/gdsys/38x/README @@ -0,0 +1,18 @@ +Update from original Marvell U-Boot to mainline U-Boot: +-------------------------------------------------------
+The resulting image including the SPL binary with the +full DDR setup is "u-boot-spl.kwb".
+To update the SPI NOR flash, please use the following +command:
+=> sf probe;tftpboot 2000000 db-88f6820-gp/u-boot-spl.kwb;\ +sf update 2000000 0 60000
+Note that the original Marvell U-Boot seems to have +problems with the "sf update" command. This does not +work reliable. So here this command should be used:
+=> sf probe;tftpboot 2000000 db-88f6820-gp/u-boot-spl.kwb;\ +sf erase 0 60000;sf write 2000000 0 60000
You copied this file from the Marvell directory. Does it really make sense to add it here as well? I suggest to just remove it.
diff --git a/board/gdsys/38x/controlcenterdc.c b/board/gdsys/38x/controlcenterdc.c new file mode 100644 index 0000000..f151265 --- /dev/null +++ b/board/gdsys/38x/controlcenterdc.c @@ -0,0 +1,717 @@ +/*
- Copyright (C) 2015 Stefan Roese sr@denx.de
- Copyright (C) 2016 Mario Six mario.six@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <console.h> /* disable_ctrlc */ +#include <miiphy.h> +#include <tpm.h> +#include <asm/io.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include <asm-generic/gpio.h>
+#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h" +#include "../arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h"
+#include "keyprogram.h" +#include "dt_helpers.h"
+DECLARE_GLOBAL_DATA_PTR;
+#define ETH_PHY_CTRL_REG 0 +#define ETH_PHY_CTRL_POWER_DOWN_BIT 11 +#define ETH_PHY_CTRL_POWER_DOWN_MASK (1 << ETH_PHY_CTRL_POWER_DOWN_BIT)
+#define DB_GP_88F68XX_GPP_OUT_ENA_LOW 0x7fffffff +#define DB_GP_88F68XX_GPP_OUT_ENA_MID 0xffffefff
+#define DB_GP_88F68XX_GPP_OUT_VAL_LOW 0x0 +#define DB_GP_88F68XX_GPP_OUT_VAL_MID 0x00001000 +#define DB_GP_88F68XX_GPP_POL_LOW 0x0 +#define DB_GP_88F68XX_GPP_POL_MID 0x0
+#ifndef CONFIG_SPL_BUILD +enum {
- HWVER_100 = 0,
- HWVER_110 = 1,
- HWVER_120 = 2,
+};
+enum {
- PORTTYPE_MAIN_CAT,
- PORTTYPE_TOP_CAT,
- PORTTYPE_16C_16F,
- PORTTYPE_UNKNOWN
+};
+static struct porttype {
- bool phy_invert_in_pol;
- bool phy_invert_out_pol;
+} porttypes[] = {
- { true, false },
- { false, true },
- { false, false },
+};
+struct ihs_fpga {
- u32 reflection_low; /* 0x0000 */
- u32 versions; /* 0x0004 */
- u32 fpga_version; /* 0x0008 */
- u32 fpga_features; /* 0x000c */
- u32 reserved0[4]; /* 0x0010 */
- u32 control; /* 0x0020 */
- u32 reserved1[375]; /* 0x0024 */
- u32 qsgmii_port_state[80]; /* 0x0600 */
+};
+static struct ihs_fpga *fpga;
+static struct pci_device_id hydra_supported[] = {
- { 0x6d5e, 0xcdc1 },
- {}
+}; +#endif
+/*
- 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 hws_topology_map ddr_topology_map = {
- 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_533, /* frequency */
0, 0, /* cas_l cas_wl */
HWS_TEMP_LOW} }, /* temperature */
- 5, /* Num Of Bus Per Interface*/
- BUS_MASK_32BIT /* Busses mask */
+};
+static struct serdes_map serdes_topology_map[] = {
- {SGMII0, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0},
- {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
- /* SATA tx polarity is inverted */
- {SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 1},
- {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0},
- {DEFAULT_SERDES, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
- {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}
+};
+int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) +{
- *serdes_map_array = serdes_topology_map;
- *count = ARRAY_SIZE(serdes_topology_map);
- return 0;
+}
+void board_pex_config(void) +{ +#ifdef CONFIG_SPL_BUILD
- uint k;
- struct gpio_desc gpio = {};
- if (get_gpio("generic,fpga-program-gpio", &gpio)) {
/* prepare FPGA reconfiguration */
dm_gpio_set_dir_flags(&gpio, GPIOD_IS_OUT);
dm_gpio_set_value(&gpio, 0);
/* give lunatic PCIe clock some time to stabilize */
mdelay(500);
/* start FPGA reconfiguration */
dm_gpio_set_dir_flags(&gpio, GPIOD_IS_IN);
- }
- /* wait for FPGA done */
- if (get_gpio("generic,fpga-done-gpio", &gpio)) {
for (k = 0; k < 20; ++k) {
if (dm_gpio_get_value(&gpio)) {
printf("FPGA done after %u rounds\n", k);
break;
}
mdelay(100);
}
- }
- /* disable FPGA reset */
- kw_gpio_set_valid(6, GPIO_OUTPUT_OK);
- kw_gpio_direction_output(6, 1);
Ah, here you use the "old" GPIO infrastucture. Please move to the DM GPIO driver and use the generic API instead.
- /* wait for FPGA ready */
- if (get_gpio("generic,fpga-ready-gpio", &gpio)) {
for (k = 0; k < 2; ++k) {
if (!dm_gpio_get_value(&gpio))
break;
mdelay(100);
}
- }
+#endif +}
+struct hws_topology_map *ddr3_get_topology_map(void) +{
- return &ddr_topology_map;
+}
+int board_early_init_f(void) +{ +#ifdef CONFIG_SPL_BUILD
- /* Configure MPP */
- writel(0x00111111, MVEBU_MPP_BASE + 0x00);
- writel(0x40040000, MVEBU_MPP_BASE + 0x04);
- writel(0x00466444, MVEBU_MPP_BASE + 0x08);
- writel(0x00043300, MVEBU_MPP_BASE + 0x0c);
- writel(0x44400000, MVEBU_MPP_BASE + 0x10);
- writel(0x20000334, MVEBU_MPP_BASE + 0x14);
- writel(0x40000000, MVEBU_MPP_BASE + 0x18);
- writel(0x00004444, MVEBU_MPP_BASE + 0x1c);
- /* Set GPP Out value */
- writel(DB_GP_88F68XX_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
- writel(DB_GP_88F68XX_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
- /* Set GPP Polarity */
- writel(DB_GP_88F68XX_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
- writel(DB_GP_88F68XX_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);
- /* Set GPP Out Enable */
- writel(DB_GP_88F68XX_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
- writel(DB_GP_88F68XX_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
+#endif
- return 0;
+}
+int board_init(void) +{
- /* adress of boot parameters */
- gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
- return 0;
+}
+int checkboard(void) +{
- puts("Board: Controlcenter Digital Compact\n");
- return 0;
+}
With DT support you should already get the board model printed from the DT. Do yo need this line here as well?
+#ifndef CONFIG_SPL_BUILD +static void ihs_phy_config(struct phy_device *phydev, bool qinpn, bool qoutpn) +{
- u16 reg;
- phy_config(phydev);
- /* enable QSGMII autonegotiation with flow control */
- phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0004);
- reg = phy_read(phydev, MDIO_DEVAD_NONE, 16);
- reg |= (3 << 6);
- phy_write(phydev, MDIO_DEVAD_NONE, 16, reg);
- /*
* invert QSGMII Q_INP/N and Q_OUTP/N if required
* and perform global reset
*/
- reg = phy_read(phydev, MDIO_DEVAD_NONE, 26);
- if (qinpn)
reg |= (1 << 13);
- if (qoutpn)
reg |= (1 << 12);
- reg |= (1 << 15);
- phy_write(phydev, MDIO_DEVAD_NONE, 26, reg);
- /* advertise 1000BASE-T full-duplex only */
- phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000);
- reg = phy_read(phydev, MDIO_DEVAD_NONE, 4);
- reg &= ~0x1e0;
- phy_write(phydev, MDIO_DEVAD_NONE, 4, reg);
- reg = phy_read(phydev, MDIO_DEVAD_NONE, 9);
- reg = (reg & ~0x300) | 0x200;
- phy_write(phydev, MDIO_DEVAD_NONE, 9, reg);
- /* copper power up */
- reg = phy_read(phydev, MDIO_DEVAD_NONE, 16);
- reg &= ~0x0004;
- phy_write(phydev, MDIO_DEVAD_NONE, 16, reg);
+}
+void init_host_phys(struct mii_dev *bus) +{
- uint k;
- for (k = 0; k < 2; ++k) {
struct phy_device *phydev;
phydev = phy_find_by_mask(bus, 1 << k,
PHY_INTERFACE_MODE_SGMII);
if (phydev)
phy_config(phydev);
- }
+}
+uint calculate_octo_phy_mask(void) +{
- uint k;
- uint octo_phy_mask = 0;
- struct gpio_desc gpio = {};
- char name[64];
- /* mark all octo phys that should be present */
- for (k = 0; k < 5; ++k) {
snprintf(name, 64, "generic,cat-gpio-%u", k);
if (!get_gpio(name, &gpio))
continue;
/* check CAT flag */
if (dm_gpio_get_value(&gpio))
octo_phy_mask |= (1 << (k * 2));
else
/* If CAT == 0, there's no second octo phy -> skip */
continue;
snprintf(name, 64, "generic,second-octo-gpio-%u", k);
if (!get_gpio(name, &gpio)) {
/* default: second octo phy is present */
octo_phy_mask |= (1 << (k * 2 + 1));
continue;
}
if (dm_gpio_get_value(&gpio) == 0)
octo_phy_mask |= (1 << (k * 2 + 1));
- }
- return octo_phy_mask;
+}
+int register_miiphy_bus(uint k, struct mii_dev **bus) +{
- int retval;
- struct mii_dev *mdiodev = mdio_alloc();
- char *name = bb_miiphy_buses[k].name;
I'm wondering how this works if "bb_miiphy_buses" is defined later in this file and you have no header file.
- if (!mdiodev)
return -ENOMEM;
- strncpy(mdiodev->name,
name,
MDIO_NAME_LEN);
- mdiodev->read = bb_miiphy_read;
- mdiodev->write = bb_miiphy_write;
- retval = mdio_register(mdiodev);
- if (retval < 0)
return retval;
- *bus = miiphy_get_dev_by_name(name);
- return 0;
+}
+struct porttype *get_porttype(uint octo_phy_mask, uint k) +{
- uint octo_index = k * 4;
- if (!k) {
if (octo_phy_mask & 0x01)
return &porttypes[PORTTYPE_MAIN_CAT];
else if (!(octo_phy_mask & 0x03))
return &porttypes[PORTTYPE_16C_16F];
- } else {
if (octo_phy_mask & (1 << octo_index))
return &porttypes[PORTTYPE_TOP_CAT];
- }
- return NULL;
+}
+int init_octo_phys(uint octo_phy_mask) +{
- uint bus_idx;
- /* there are up to four octo-phys on each mdio bus */
- for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; ++bus_idx) {
uint m;
uint octo_index = bus_idx * 4;
struct mii_dev *bus = NULL;
struct porttype *porttype = NULL;
int ret;
porttype = get_porttype(octo_phy_mask, bus_idx);
if (!porttype)
continue;
for (m = 0; m < 4; ++m) {
uint phy_idx;
/* Register a bus device if there is at least one phy
* on the current bus
*/
Multiline comment style please.
if (!m && octo_phy_mask & (0xf << octo_index)) {
ret = register_miiphy_bus(bus_idx, &bus);
if (ret)
return ret;
}
if (!(octo_phy_mask & (1 << (octo_index + m))))
continue;
for (phy_idx = 0; phy_idx < 8; ++phy_idx) {
struct phy_device *phydev = phy_find_by_mask(
bus, 1 << (m * 8 + phy_idx),
PHY_INTERFACE_MODE_MII);
printf(" %u", bus_idx * 32 + m * 8 + phy_idx);
ihs_phy_config(phydev,
porttype->phy_invert_in_pol,
porttype->phy_invert_out_pol);
}
}
- }
- return 0;
+}
+int ccdc_eth_init(void) +{
- uint k;
- uint octo_phy_mask = 0;
- int ret;
- struct mii_dev *bus;
- /* Init SoC's phys */
- bus = miiphy_get_dev_by_name("ethernet@34000");
- if (bus)
init_host_phys(bus);
- bus = miiphy_get_dev_by_name("ethernet@70000");
- if (bus)
init_host_phys(bus);
- /* Init octo phys */
- octo_phy_mask = calculate_octo_phy_mask();
- printf("IHS PHYS: %08x", octo_phy_mask);
- ret = init_octo_phys(octo_phy_mask);
- if (ret)
return ret;
- printf("\n");
- /* reset all FPGA-QSGMII instances */
- for (k = 0; k < 80; ++k)
writel(1 << 31, &fpga->qsgmii_port_state[k]);
- udelay(100);
- for (k = 0; k < 80; ++k)
writel(0, &fpga->qsgmii_port_state[k]);
- return 0;
+}
+void print_hydra_version(uint index) +{
- u32 versions = readl(&fpga->versions);
- u32 fpga_version = readl(&fpga->fpga_version);
- uint hardware_version = versions & 0xf;
- printf("FPGA%u: mapped to %p\n ", index, fpga);
- switch (hardware_version) {
- case HWVER_100:
printf("HW-Ver 1.00\n");
break;
- case HWVER_110:
printf("HW-Ver 1.10\n");
break;
- case HWVER_120:
printf("HW-Ver 1.20\n");
break;
- default:
printf("HW-Ver %d(not supported)\n",
hardware_version);
break;
- }
- printf(" FPGA V %d.%02d\n",
fpga_version / 100, fpga_version % 100);
+}
+static void hydra_initialize(void) +{
- uint i;
- pci_dev_t devno;
- /* Find and probe all the matching PCI devices */
- for (i = 0; (devno = pci_find_devices(hydra_supported, i)) >= 0; i++) {
u32 val;
/* Try to enable I/O accesses and bus-mastering */
val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
pci_write_config_dword(devno, PCI_COMMAND, val);
/* Make sure it worked */
pci_read_config_dword(devno, PCI_COMMAND, &val);
if (!(val & PCI_COMMAND_MEMORY)) {
puts("Can't enable I/O memory\n");
continue;
}
if (!(val & PCI_COMMAND_MASTER)) {
puts("Can't enable bus-mastering\n");
continue;
}
/* read FPGA details */
fpga = pci_map_bar(devno, PCI_BASE_ADDRESS_0,
PCI_REGION_MEM);
print_hydra_version(i);
- }
+} +#endif
+int board_late_init(void) +{ +#ifndef CONFIG_SPL_BUILD
- hydra_initialize();
+#endif
- return 0;
+}
+int board_fix_fdt(void) +{
- struct udevice *bus;
- uint k;
- char name[64];
- bus = dev_get_by_ofname("/soc/internal-regs/i2c@11000");
- for (k = 0x21; k <= 0x26; k++) {
snprintf(name, 64,
"/soc/internal-regs/i2c@11000/pca9698@%02x", k);
if (!dm_i2c_simple_probe(bus, k))
fdt_disable_by_ofname(name);
- }
- return 0;
+}
+int last_stage_init(void) +{
- disable_ctrlc(1);
+#ifndef CONFIG_SPL_BUILD
- ccdc_eth_init();
+#endif
- if (tpm_init() || tpm_startup(TPM_ST_CLEAR) ||
tpm_continue_self_test()) {
return 1;
- }
- mdelay(37);
- flush_keys();
- load_and_run_keyprog();
- return 0;
+}
+#ifndef CONFIG_SPL_BUILD
+#define REFL_PATTERN (0xdededede) +#define REFL_PATTERN_INV (~REFL_PATTERN)
+int do_hydrate(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{
- uint k = 0;
- void __iomem *pcie2_base = (void __iomem *)(MVEBU_REG_PCIE_BASE +
0x4000);
- if (!fpga)
return -1;
- while (1) {
u32 res;
writel(REFL_PATTERN, &fpga->reflection_low);
res = readl(&fpga->reflection_low);
if (res != REFL_PATTERN_INV)
printf("round %u: read %08x, expected %08x\n",
k, res, REFL_PATTERN_INV);
writel(REFL_PATTERN_INV, &fpga->reflection_low);
res = readl(&fpga->reflection_low);
if (res != REFL_PATTERN)
printf("round %u: read %08x, expected %08x\n",
k, res, REFL_PATTERN);
res = readl(pcie2_base + 0x118) & 0x1f;
if (res)
printf("FrstErrPtr %u\n", res);
res = readl(pcie2_base + 0x104);
if (res) {
printf("Uncorrectable Error Status 0x%08x\n", res);
writel(res, pcie2_base + 0x104);
}
if (!(++k % 10000))
printf("round %u\n", k);
if (ctrlc())
break;
- }
- return 0;
+}
+U_BOOT_CMD(
- hydrate, 1, 0, do_hydrate,
- "hydra reflection test",
- "hydra reflection test"
+);
+/*
- MII GPIO bitbang implementation
- MDC MDIO bus
- 13 14 PHY1-4
- 25 45 PHY5-8
- 46 24 PHY9-10
- */
+struct gpio_mii {
- int mdc;
- int mdio;
- int mdio_value;
+} gpio_mii_set[] = {
- { 13, 14, 1 },
- { 25, 45, 1 },
- { 46, 24, 1 },
+};
+static int mii_mdio_init(struct bb_miiphy_bus *bus) +{
- struct gpio_mii *gpio_mii = bus->priv;
- kw_gpio_set_valid(gpio_mii->mdc, GPIO_OUTPUT_OK);
- kw_gpio_set_valid(gpio_mii->mdio, GPIO_INPUT_OK | GPIO_OUTPUT_OK);
- kw_gpio_direction_output(gpio_mii->mdc, 1);
- return 0;
+}
+static int mii_mdio_active(struct bb_miiphy_bus *bus) +{
- struct gpio_mii *gpio_mii = bus->priv;
- kw_gpio_direction_output(gpio_mii->mdio, gpio_mii->mdio_value);
- return 0;
+}
+static int mii_mdio_tristate(struct bb_miiphy_bus *bus) +{
- struct gpio_mii *gpio_mii = bus->priv;
- kw_gpio_direction_input(gpio_mii->mdio);
- return 0;
+}
+static int mii_set_mdio(struct bb_miiphy_bus *bus, int v) +{
- struct gpio_mii *gpio_mii = bus->priv;
- kw_gpio_set_value(gpio_mii->mdio, v);
- gpio_mii->mdio_value = v;
- return 0;
+}
+static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v) +{
- struct gpio_mii *gpio_mii = bus->priv;
- *v = (kw_gpio_get_value(gpio_mii->mdio) != 0);
- return 0;
+}
+static int mii_set_mdc(struct bb_miiphy_bus *bus, int v) +{
- struct gpio_mii *gpio_mii = bus->priv;
- kw_gpio_set_value(gpio_mii->mdc, v);
- return 0;
+}
+static int mii_delay(struct bb_miiphy_bus *bus) +{
- udelay(1);
- return 0;
+}
+struct bb_miiphy_bus bb_miiphy_buses[] = {
- {
.name = "ihs0",
.init = mii_mdio_init,
.mdio_active = mii_mdio_active,
.mdio_tristate = mii_mdio_tristate,
.set_mdio = mii_set_mdio,
.get_mdio = mii_get_mdio,
.set_mdc = mii_set_mdc,
.delay = mii_delay,
.priv = &gpio_mii_set[0],
- },
- {
.name = "ihs1",
.init = mii_mdio_init,
.mdio_active = mii_mdio_active,
.mdio_tristate = mii_mdio_tristate,
.set_mdio = mii_set_mdio,
.get_mdio = mii_get_mdio,
.set_mdc = mii_set_mdc,
.delay = mii_delay,
.priv = &gpio_mii_set[1],
- },
- {
.name = "ihs2",
.init = mii_mdio_init,
.mdio_active = mii_mdio_active,
.mdio_tristate = mii_mdio_tristate,
.set_mdio = mii_set_mdio,
.get_mdio = mii_get_mdio,
.set_mdc = mii_set_mdc,
.delay = mii_delay,
.priv = &gpio_mii_set[2],
- },
+};
+int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
sizeof(bb_miiphy_buses[0]);
static? And can you use ARRAY_SIZE()?
+#endif
Perhaps its also a good idea to move at least some of this code (especiall the command and perhaps some MDIO stuff) into separate files that are only compiled for non-SPL U-Boot. This will remove some of the #ifdefs as well.
diff --git a/board/gdsys/38x/dt_helpers.c b/board/gdsys/38x/dt_helpers.c new file mode 100644 index 0000000..dedd048 --- /dev/null +++ b/board/gdsys/38x/dt_helpers.c @@ -0,0 +1,60 @@ +/*
- (C) Copyright 2016
- Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <i2c.h> +#include <dm.h> +#include <fdt_support.h> +#include <asm-generic/gpio.h>
+DECLARE_GLOBAL_DATA_PTR;
+bool get_gpio(char *name, struct gpio_desc *gpio) +{
- int node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, name);
- int ret;
- if (node < 0)
return false;
- ret = gpio_request_by_name_nodev(gd->fdt_blob, node, "gpios", 0, gpio,
0);
- if (ret < 0)
return false;
- return dm_gpio_is_valid(gpio);
+}
+int fdt_disable_by_ofname(char *ofname) +{
- void *blob = gd->fdt_blob;
- int offset;
- offset = fdt_path_offset(blob, ofname);
- return fdt_status_disabled(blob, offset);
+}
+struct udevice *dev_get_by_ofname(char *ofname) +{
- void *blob = gd->fdt_blob;
- int offset;
- struct udevice *dev;
- offset = fdt_path_offset(blob, ofname);
- device_get_global_by_of_offset(offset, &dev);
- return dev;
+}
+bool dm_i2c_simple_probe(struct udevice *bus, uint chip_addr) +{
- struct udevice *dev;
- return !dm_i2c_probe(bus, chip_addr, DM_I2C_CHIP_RD_ADDRESS |
DM_I2C_CHIP_WR_ADDRESS, &dev);
+}
At least some of this might be very helpful as common U-Boot functions available for all boards.
diff --git a/board/gdsys/38x/dt_helpers.h b/board/gdsys/38x/dt_helpers.h new file mode 100644 index 0000000..8052b94 --- /dev/null +++ b/board/gdsys/38x/dt_helpers.h @@ -0,0 +1,16 @@ +/*
- (C) Copyright 2016
- Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __DT_HELPERS_H +#define __DT_HELPERS_H
+bool get_gpio(char *name, struct gpio_desc *gpio); +int fdt_disable_by_ofname(char *ofname); +struct udevice *dev_get_by_ofname(char *ofname); +bool dm_i2c_simple_probe(struct udevice *bus, uint chip_addr);
+#endif /* __DT_HELPERS_H */ diff --git a/board/gdsys/38x/hre.c b/board/gdsys/38x/hre.c new file mode 100644 index 0000000..10bf1a0 --- /dev/null +++ b/board/gdsys/38x/hre.c @@ -0,0 +1,517 @@ +/*
- (C) Copyright 2013
- Reinhard Pfau, Guntermann & Drunck GmbH, reinhard.pfau@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <malloc.h> +#include <fs.h> +#include <i2c.h> +#include <mmc.h> +#include <tpm.h> +#include <u-boot/sha1.h> +#include <asm/byteorder.h> +#include <asm/unaligned.h> +#include <pca9698.h>
+#include "hre.h"
+/* other constants */ +enum {
- ESDHC_BOOT_IMAGE_SIG_OFS = 0x40,
- ESDHC_BOOT_IMAGE_SIZE_OFS = 0x48,
- ESDHC_BOOT_IMAGE_ADDR_OFS = 0x50,
- ESDHC_BOOT_IMAGE_TARGET_OFS = 0x58,
- ESDHC_BOOT_IMAGE_ENTRY_OFS = 0x60,
+};
+enum {
- I2C_SOC_0 = 0,
- I2C_SOC_1 = 1,
+};
+enum access_mode {
- HREG_NONE = 0,
- HREG_RD = 1,
- HREG_WR = 2,
- HREG_RDWR = 3,
+};
+/* register constants */ +enum {
- FIX_HREG_DEVICE_ID_HASH = 0,
- FIX_HREG_UNUSED1 = 1,
- FIX_HREG_UNUSED2 = 2,
- FIX_HREG_VENDOR = 3,
- COUNT_FIX_HREGS
+};
+static struct h_reg pcr_hregs[24]; +static struct h_reg fix_hregs[COUNT_FIX_HREGS]; +static struct h_reg var_hregs[8];
+/* hre opcodes */ +enum {
- /* opcodes w/o data */
- HRE_NOP = 0x00,
- HRE_SYNC = HRE_NOP,
- HRE_CHECK0 = 0x01,
- /* opcodes w/o data, w/ sync dst */
- /* opcodes w/ data */
- HRE_LOAD = 0x81,
- /* opcodes w/data, w/sync dst */
- HRE_XOR = 0xC1,
- HRE_AND = 0xC2,
- HRE_OR = 0xC3,
- HRE_EXTEND = 0xC4,
- HRE_LOADKEY = 0xC5,
+};
+/* hre errors */ +enum {
- HRE_E_OK = 0,
- HRE_E_TPM_FAILURE,
- HRE_E_INVALID_HREG,
+};
+static uint64_t device_id; +static uint64_t device_cl; +static uint64_t device_type;
+static uint32_t platform_key_handle;
+static uint32_t hre_tpm_err; +static int hre_err = HRE_E_OK;
+#define IS_PCR_HREG(spec) ((spec) & 0x20) +#define IS_FIX_HREG(spec) (((spec) & 0x38) == 0x08) +#define IS_VAR_HREG(spec) (((spec) & 0x38) == 0x10) +#define HREG_IDX(spec) ((spec) & (IS_PCR_HREG(spec) ? 0x1f : 0x7))
+static const uint8_t vendor[] = "Guntermann & Drunck";
+/**
- @brief get the size of a given (TPM) NV area
- @param index NV index of the area to get size for
- @param size pointer to the size
- @return 0 on success, != 0 on error
- */
+static int get_tpm_nv_size(uint32_t index, uint32_t *size) +{
- uint32_t err;
- uint8_t info[72];
- uint8_t *ptr;
- uint16_t v16;
- err = tpm_get_capability(TPM_CAP_NV_INDEX, index,
info, sizeof(info));
- if (err) {
printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n",
index, err);
return 1;
- }
- /* skip tag and nvIndex */
- ptr = info + 6;
- /* skip 2 pcr info fields */
- v16 = get_unaligned_be16(ptr);
- ptr += 2 + v16 + 1 + 20;
- v16 = get_unaligned_be16(ptr);
- ptr += 2 + v16 + 1 + 20;
- /* skip permission and flags */
- ptr += 6 + 3;
- *size = get_unaligned_be32(ptr);
- return 0;
+}
+/**
- @brief search for a key by usage auth and pub key hash.
- @param auth usage auth of the key to search for
- @param pubkey_digest (SHA1) hash of the pub key structure of the key
- @param[out] handle the handle of the key iff found
- @return 0 if key was found in TPM; != 0 if not.
- */
+static int find_key(const uint8_t auth[20], const uint8_t pubkey_digest[20],
uint32_t *handle)
+{
- uint16_t key_count;
- uint32_t key_handles[10];
- uint8_t buf[288];
- uint8_t *ptr;
- uint32_t err;
- uint8_t digest[20];
- size_t buf_len;
- unsigned int i;
- /* fetch list of already loaded keys in the TPM */
- err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
- if (err)
return -1;
- key_count = get_unaligned_be16(buf);
- ptr = buf + 2;
- for (i = 0; i < key_count; ++i, ptr += 4)
key_handles[i] = get_unaligned_be32(ptr);
- /* now search a(/ the) key which we can access with the given auth */
- for (i = 0; i < key_count; ++i) {
buf_len = sizeof(buf);
err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
if (err && err != TPM_AUTHFAIL)
return -1;
if (err)
continue;
sha1_csum(buf, buf_len, digest);
if (!memcmp(digest, pubkey_digest, 20)) {
*handle = key_handles[i];
return 0;
}
- }
- return 1;
+}
+/**
- @brief read CCDM common data from TPM NV
- @return 0 if CCDM common data was found and read, !=0 if something failed.
- */
+static int read_common_data(void) +{
- uint32_t size = 0;
- uint32_t err;
- uint8_t buf[256];
- sha1_context ctx;
- if (get_tpm_nv_size(NV_COMMON_DATA_INDEX, &size) ||
size < NV_COMMON_DATA_MIN_SIZE)
return 1;
- err = tpm_nv_read_value(NV_COMMON_DATA_INDEX,
buf, min(sizeof(buf), size));
- if (err) {
printf("tpm_nv_read_value() failed: %u\n", err);
return 1;
- }
- device_id = get_unaligned_be64(buf);
- device_cl = get_unaligned_be64(buf + 8);
- device_type = get_unaligned_be64(buf + 16);
- sha1_starts(&ctx);
- sha1_update(&ctx, buf, 24);
- sha1_finish(&ctx, fix_hregs[FIX_HREG_DEVICE_ID_HASH].digest);
- fix_hregs[FIX_HREG_DEVICE_ID_HASH].valid = true;
- platform_key_handle = get_unaligned_be32(buf + 24);
- return 0;
+}
+/**
- @brief get pointer to hash register by specification
- @param spec specification of a hash register
- @return pointer to hash register or NULL if @a spec does not qualify a
- valid hash register; NULL else.
- */
+static struct h_reg *get_hreg(uint8_t spec) +{
- uint8_t idx;
- idx = HREG_IDX(spec);
- if (IS_FIX_HREG(spec)) {
if (idx < ARRAY_SIZE(fix_hregs))
return fix_hregs + idx;
hre_err = HRE_E_INVALID_HREG;
- } else if (IS_PCR_HREG(spec)) {
if (idx < ARRAY_SIZE(pcr_hregs))
return pcr_hregs + idx;
hre_err = HRE_E_INVALID_HREG;
- } else if (IS_VAR_HREG(spec)) {
if (idx < ARRAY_SIZE(var_hregs))
return var_hregs + idx;
hre_err = HRE_E_INVALID_HREG;
- }
- return NULL;
+}
+/**
- @brief get pointer of a hash register by specification and usage.
- @param spec specification of a hash register
- @param mode access mode (read or write or read/write)
- @return pointer to hash register if found and valid; NULL else.
- This func uses @a get_reg() to determine the hash register for a given spec.
- If a register is found it is validated according to the desired access mode.
- The value of automatic registers (PCR register and fixed registers) is
- loaded or computed on read access.
- */
+static struct h_reg *access_hreg(uint8_t spec, enum access_mode mode) +{
- struct h_reg *result;
- result = get_hreg(spec);
- if (!result)
return NULL;
- if (mode & HREG_WR) {
if (IS_FIX_HREG(spec)) {
hre_err = HRE_E_INVALID_HREG;
return NULL;
}
- }
- if (mode & HREG_RD) {
if (!result->valid) {
if (IS_PCR_HREG(spec)) {
hre_tpm_err = tpm_pcr_read(HREG_IDX(spec),
result->digest, 20);
result->valid = (hre_tpm_err == TPM_SUCCESS);
} else if (IS_FIX_HREG(spec)) {
switch (HREG_IDX(spec)) {
case FIX_HREG_DEVICE_ID_HASH:
read_common_data();
break;
case FIX_HREG_VENDOR:
memcpy(result->digest, vendor, 20);
result->valid = true;
break;
}
} else {
result->valid = true;
}
}
if (!result->valid) {
hre_err = HRE_E_INVALID_HREG;
return NULL;
}
- }
- return result;
+}
+static void *compute_and(void *_dst, const void *_src, size_t n) +{
- uint8_t *dst = _dst;
- const uint8_t *src = _src;
- size_t i;
- for (i = n; i-- > 0; )
*dst++ &= *src++;
- return _dst;
+}
+static void *compute_or(void *_dst, const void *_src, size_t n) +{
- uint8_t *dst = _dst;
- const uint8_t *src = _src;
- size_t i;
- for (i = n; i-- > 0; )
*dst++ |= *src++;
- return _dst;
+}
+static void *compute_xor(void *_dst, const void *_src, size_t n) +{
- uint8_t *dst = _dst;
- const uint8_t *src = _src;
- size_t i;
- for (i = n; i-- > 0; )
*dst++ ^= *src++;
- return _dst;
+}
+static void *compute_extend(void *_dst, const void *_src, size_t n) +{
- uint8_t digest[20];
- sha1_context ctx;
- sha1_starts(&ctx);
- sha1_update(&ctx, _dst, n);
- sha1_update(&ctx, _src, n);
- sha1_finish(&ctx, digest);
- memcpy(_dst, digest, min(n, sizeof(digest)));
- return _dst;
+}
+static int hre_op_loadkey(struct h_reg *src_reg, struct h_reg *dst_reg,
const void *key, size_t key_size)
+{
- uint32_t parent_handle;
- uint32_t key_handle;
- if (!src_reg || !dst_reg || !src_reg->valid || !dst_reg->valid)
return -1;
- if (find_key(src_reg->digest, dst_reg->digest, &parent_handle))
return -1;
- hre_tpm_err = tpm_load_key2_oiap(parent_handle, key, key_size,
src_reg->digest, &key_handle);
- if (hre_tpm_err) {
hre_err = HRE_E_TPM_FAILURE;
return -1;
- }
- /* TODO remember key handle somehow? */
Is this comment still valid?
- return 0;
+}
+/**
- @brief executes the next opcode on the hash register engine.
- @param[in,out] ip pointer to the opcode (instruction pointer)
- @param[in,out] code_size (remaining) size of the code
- @return new instruction pointer on success, NULL on error.
- */
+static const uint8_t *hre_execute_op(const uint8_t **ip, size_t *code_size) +{
- bool dst_modified = false;
- uint32_t ins;
- uint8_t opcode;
- uint8_t src_spec;
- uint8_t dst_spec;
- uint16_t data_size;
- struct h_reg *src_reg, *dst_reg;
- uint8_t buf[20];
- const uint8_t *src_buf, *data;
- uint8_t *ptr;
- int i;
- void * (*bin_func)(void *, const void *, size_t);
- if (*code_size < 4)
return NULL;
- ins = get_unaligned_be32(*ip);
- opcode = **ip;
- data = *ip + 4;
- src_spec = (ins >> 18) & 0x3f;
- dst_spec = (ins >> 12) & 0x3f;
- data_size = (ins & 0x7ff);
- debug("HRE: ins=%08x (op=%02x, s=%02x, d=%02x, L=%d)\n", ins,
opcode, src_spec, dst_spec, data_size);
- if ((opcode & 0x80) && (data_size + 4) > *code_size)
return NULL;
- src_reg = access_hreg(src_spec, HREG_RD);
- if (hre_err || hre_tpm_err)
return NULL;
- dst_reg = access_hreg(dst_spec, (opcode & 0x40) ? HREG_RDWR : HREG_WR);
- if (hre_err || hre_tpm_err)
return NULL;
- switch (opcode) {
- case HRE_NOP:
goto end;
- case HRE_CHECK0:
if (src_reg) {
for (i = 0; i < 20; ++i) {
if (src_reg->digest[i])
return NULL;
}
}
break;
- case HRE_LOAD:
bin_func = memcpy;
goto do_bin_func;
- case HRE_XOR:
bin_func = compute_xor;
goto do_bin_func;
- case HRE_AND:
bin_func = compute_and;
goto do_bin_func;
- case HRE_OR:
bin_func = compute_or;
goto do_bin_func;
- case HRE_EXTEND:
bin_func = compute_extend;
+do_bin_func:
if (!dst_reg)
return NULL;
if (src_reg) {
src_buf = src_reg->digest;
} else {
if (!data_size) {
memset(buf, 0, 20);
src_buf = buf;
} else if (data_size == 1) {
memset(buf, *data, 20);
src_buf = buf;
} else if (data_size >= 20) {
src_buf = data;
} else {
src_buf = buf;
for (ptr = (uint8_t *)src_buf, i = 20; i > 0;
i -= data_size, ptr += data_size)
memcpy(ptr, data,
min_t(size_t, i, data_size));
}
}
bin_func(dst_reg->digest, src_buf, 20);
dst_reg->valid = true;
dst_modified = true;
break;
- case HRE_LOADKEY:
if (hre_op_loadkey(src_reg, dst_reg, data, data_size))
return NULL;
break;
- default:
return NULL;
- }
- if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) {
hre_tpm_err = tpm_extend(HREG_IDX(dst_spec), dst_reg->digest,
dst_reg->digest);
if (hre_tpm_err) {
hre_err = HRE_E_TPM_FAILURE;
return NULL;
}
- }
+end:
- *ip += 4;
- *code_size -= 4;
- if (opcode & 0x80) {
*ip += data_size;
*code_size -= data_size;
- }
- return *ip;
+}
+/**
- @brief runs a program on the hash register engine.
- @param code pointer to the (HRE) code.
- @param code_size size of the code (in bytes).
- @return 0 on success, != 0 on failure.
- */
+int hre_run_program(const uint8_t *code, size_t code_size) +{
- size_t code_left;
- const uint8_t *ip = code;
- code_left = code_size;
- hre_tpm_err = 0;
- hre_err = HRE_E_OK;
- while (code_left > 0)
if (!hre_execute_op(&ip, &code_left))
return -1;
- return hre_err;
+}
+int hre_verify_program(struct key_program *prg) +{
- uint32_t crc;
- crc = crc32(0, prg->code, prg->code_size);
- if (crc != prg->code_crc) {
printf("HRC crc mismatch: %08x != %08x\n",
crc, prg->code_crc);
return 1;
- }
- return 0;
+} diff --git a/board/gdsys/38x/hre.h b/board/gdsys/38x/hre.h new file mode 100644 index 0000000..84ce279 --- /dev/null +++ b/board/gdsys/38x/hre.h @@ -0,0 +1,38 @@ +/*
- (C) Copyright 2013
- Reinhard Pfau, Guntermann & Drunck GmbH, reinhard.pfau@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __HRE_H +#define __HRE_H
+struct key_program {
- uint32_t magic;
- uint32_t code_crc;
- uint32_t code_size;
- uint8_t code[];
+};
+struct h_reg {
- bool valid;
- uint8_t digest[20];
+};
+/* CCDM specific contants */ +enum {
- /* NV indices */
- NV_COMMON_DATA_INDEX = 0x40000001,
- /* magics for key blob chains */
- MAGIC_KEY_PROGRAM = 0x68726500,
- MAGIC_HMAC = 0x68616300,
- MAGIC_END_OF_CHAIN = 0x00000000,
- /* sizes */
- NV_COMMON_DATA_MIN_SIZE = 3 * sizeof(uint64_t) + 2 * sizeof(uint16_t),
+};
+int hre_verify_program(struct key_program *prg); +int hre_run_program(const uint8_t *code, size_t code_size);
+#endif /* __HRE_H */ diff --git a/board/gdsys/38x/keyprogram.c b/board/gdsys/38x/keyprogram.c new file mode 100644 index 0000000..a4a6f1c --- /dev/null +++ b/board/gdsys/38x/keyprogram.c @@ -0,0 +1,158 @@ +/*
- (C) Copyright 2016
- Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <tpm.h> +#include <malloc.h> +#include <linux/ctype.h> +#include <asm/unaligned.h>
+#include "hre.h"
+int flush_keys(void) +{
- u16 key_count;
- u8 buf[288];
- u8 *ptr;
- u32 err;
- uint i;
- /* fetch list of already loaded keys in the TPM */
- err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
- if (err)
return -1;
- key_count = get_unaligned_be16(buf);
- ptr = buf + 2;
- for (i = 0; i < key_count; ++i, ptr += 4) {
err = tpm_flush_specific(get_unaligned_be32(ptr), TPM_RT_KEY);
if (err && err != TPM_KEY_OWNER_CONTROL)
return err;
- }
- return 0;
+}
+int decode_hexstr(char *hexstr, u8 **result) +{
- int len = strlen(hexstr);
- int bytes = len / 2;
- int i;
- u8 acc = 0;
- if (len % 2 == 1)
return 1;
- *result = (u8 *)malloc(bytes);
- for (i = 0; i < len; i++) {
char cur = tolower(hexstr[i]);
u8 val;
if ((cur >= 'a' && cur <= 'f') || (cur >= '0' && cur <= '9')) {
val = cur - (cur > '9' ? 87 : 48);
if (i % 2 == 0)
acc = 16 * val;
else
(*result)[i / 2] = acc + val;
} else {
free(*result);
return 1;
}
- }
- return 0;
+}
+int extract_subprogram(u8 **progdata, u32 expected_magic,
struct key_program **result)
+{
- struct key_program *prog = *result;
- u32 magic, code_crc, code_size;
- magic = get_unaligned_be32(*progdata);
- code_crc = get_unaligned_be32(*progdata + 4);
- code_size = get_unaligned_be32(*progdata + 8);
- *progdata += 12;
- if (magic != expected_magic)
return -1;
- *result = malloc(sizeof(struct key_program) + code_size);
- if (!*result)
return -1;
- prog->magic = magic;
- prog->code_crc = code_crc;
- prog->code_size = code_size;
- memcpy(prog->code, *progdata, code_size);
- *progdata += code_size;
- if (hre_verify_program(prog)) {
free(prog);
return -1;
- }
- return 0;
+}
+struct key_program *parse_and_check_keyprog(u8 *progdata) +{
- struct key_program *result = NULL, *hmac = NULL;
- /* Part 1: Load key program */
- if (extract_subprogram(&progdata, MAGIC_KEY_PROGRAM, &result))
return NULL;
- /* Part 2: Load hmac program */
- if (extract_subprogram(&progdata, MAGIC_HMAC, &hmac))
return NULL;
- free(hmac);
- return result;
+}
+int load_and_run_keyprog(void) +{
- char *cmd = NULL;
- u8 *binprog = NULL;
- char *hexprog;
- struct key_program *prog;
- cmd = getenv("loadkeyprogram");
- if (!cmd || run_command(cmd, 0))
return 1;
- hexprog = getenv("keyprogram");
- if (decode_hexstr(hexprog, &binprog))
return 1;
- prog = parse_and_check_keyprog(binprog);
- free(binprog);
- if (!prog)
return 1;
- if (hre_run_program(prog->code, prog->code_size)) {
free(prog);
return 1;
- }
- printf("\nSD code ran successfully\n");
- free(prog);
- return 0;
+} diff --git a/board/gdsys/38x/keyprogram.h b/board/gdsys/38x/keyprogram.h new file mode 100644 index 0000000..a5ea7d3 --- /dev/null +++ b/board/gdsys/38x/keyprogram.h @@ -0,0 +1,14 @@ +/*
- (C) Copyright 2016
- Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __KEYPROGRAM_H +#define __KEYPROGRAM_H
+int load_and_run_keyprog(void); +int flush_keys(void);
+#endif /* __KEYPROGRAM_H */ diff --git a/board/gdsys/38x/kwbimage.cfg.in b/board/gdsys/38x/kwbimage.cfg.in new file mode 100644 index 0000000..72e67d7 --- /dev/null +++ b/board/gdsys/38x/kwbimage.cfg.in @@ -0,0 +1,12 @@ +# +# Copyright (C) 2014 Stefan Roese sr@denx.de +#
+# Armada 38x uses version 1 image format +VERSION 1
+# Boot Media configurations +#@BOOT_FROM
+# Binary Header (bin_hdr) with DDR3 training code +BINARY spl/u-boot-spl.bin 0000005b 00000068 diff --git a/board/gdsys/38x/spl.c b/board/gdsys/38x/spl.c new file mode 100644 index 0000000..2d05a9c --- /dev/null +++ b/board/gdsys/38x/spl.c @@ -0,0 +1,21 @@ +/*
- (C) Copyright 2016
- Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <config.h> +#include <asm/arch/cpu.h>
+void spl_board_init(void) +{ +#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SPI_NOR_FLASH
- u32 *bootrom_save = (u32 *)CONFIG_SPL_BOOTROM_SAVE;
- u32 *regs = (u32 *)(*bootrom_save);
- printf("Returning to BootROM (return address %08x)...\n", regs[13]);
- return_to_bootrom();
+#endif +} diff --git a/configs/controlcenterdc_defconfig b/configs/controlcenterdc_defconfig new file mode 100644 index 0000000..ee06c84 --- /dev/null +++ b/configs/controlcenterdc_defconfig @@ -0,0 +1,54 @@ +CONFIG_ARM=y +CONFIG_ARCH_MVEBU=y +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TARGET_CONTROLCENTERDC=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_DEFAULT_DEVICE_TREE="controlcenterdc" +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y +CONFIG_SYS_CONSOLE_INFO_QUIET=y +CONFIG_SPL=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_HUSH_PARSER=y +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_GO is not set +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_USB=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_TPM=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_OF_BOARD_FIXUP=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_DM_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0xd0012000 +CONFIG_DEBUG_UART_CLOCK=250000000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550=y +CONFIG_TPM_ATMEL_TWI=y +CONFIG_TPM_AUTH_SESSIONS=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_TPM=y +# CONFIG_EFI_LOADER is not set diff --git a/include/configs/controlcenterdc.h b/include/configs/controlcenterdc.h new file mode 100644 index 0000000..9097dce --- /dev/null +++ b/include/configs/controlcenterdc.h @@ -0,0 +1,244 @@ +/*
- Copyright (C) 2014 Stefan Roese sr@denx.de
- Copyright (C) 2016 Mario Six mario.six@gdsys.cc
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _CONFIG_CONTROLCENTERDC_H +#define _CONFIG_CONTROLCENTERDC_H
+/*
- High Level Configuration Options (easy to change)
- */
+#define CONFIG_CUSTOMER_BOARD_SUPPORT
+#define CONFIG_SKIP_LOWLEVEL_INIT /* disable board lowlevel_init */ +#define CONFIG_DISPLAY_BOARDINFO_LATE +#define CONFIG_BOARD_LATE_INIT +#define CONFIG_LAST_STAGE_INIT +#define CONFIG_SPL_BOARD_INIT
+/*
- 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 */
+#define CONFIG_LOADADDR 1000000
+#define CONFIG_SYS_NO_FLASH /* Declare no flash (NOR/SPI) */
+/*
- Commands configuration
- */
+#define CONFIG_CMD_ENV +#define CONFIG_CMD_I2C +#define CONFIG_CMD_PCI +#define CONFIG_CMD_SCSI +#define CONFIG_CMD_SPI
+/* SPI NOR flash default params, used by sf commands */ +#define CONFIG_SF_DEFAULT_BUS 1 +#define CONFIG_SF_DEFAULT_SPEED 1000000 +#define CONFIG_SF_DEFAULT_MODE SPI_MODE_3
+/*
- SDIO/MMC Card Configuration
- */
+#define CONFIG_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_SDHCI +#define CONFIG_MV_SDHCI +#define CONFIG_SYS_MMC_BASE MVEBU_SDIO_BASE
+/*
- SATA/SCSI/AHCI configuration
- */
+#define CONFIG_LIBATA +#define CONFIG_SCSI +#define CONFIG_SCSI_AHCI +#define CONFIG_SCSI_AHCI_PLAT +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 2 +#define CONFIG_SYS_SCSI_MAX_LUN 1 +#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
+/* Partition support */ +#define CONFIG_DOS_PARTITION +#define CONFIG_EFI_PARTITION
+/* Additional FS support/configuration */ +#define CONFIG_SUPPORT_VFAT
+/* USB/EHCI configuration */ +#define CONFIG_EHCI_IS_TDI
+/* Environment in SPI NOR flash */ +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_SPI_BUS 1 +#define CONFIG_ENV_OFFSET (1 << 20) /* 1MiB in */ +#define CONFIG_ENV_SIZE (64 << 10) /* 64KiB */ +#define CONFIG_ENV_SECT_SIZE (256 << 10) /* 256KiB sectors */
+#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 +#define CONFIG_PCI_MVEBU +#define CONFIG_PCI_PNP +#define CONFIG_PCI_SCAN_SHOW +#endif
+#define CONFIG_SYS_ALT_MEMTEST
+/*
- Software (bit-bang) MII driver configuration
- */
+#define CONFIG_BITBANGMII /* bit-bang MII PHY management */ +#define CONFIG_BITBANGMII_MULTI
+/*
- GPIO
- */
+#define CONFIG_KIRKWOOD_GPIO
+/* 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_SPI_NOR_FLASH
+/* Defines for SPL */ +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_SIZE (160 << 10)
+#if defined(CONFIG_SECURED_MODE_IMAGE) +#define CONFIG_SPL_TEXT_BASE 0x40002614 +#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x2614) +#else +#define CONFIG_SPL_TEXT_BASE 0x40000030 +#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x30) +#endif
+#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 +#endif
+#define CONFIG_SPL_STACK (0x40000000 + ((212 - 16) << 10)) +#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
+#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_I2C_SUPPORT
+#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 0x30000 +#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_SPL_MMC_SUPPORT +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 1 +#define CONFIG_SYS_MMC_U_BOOT_OFFS (168 << 10) +#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_MMC_U_BOOT_OFFS +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR (CONFIG_SYS_U_BOOT_OFFS / 512) +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS ((512 << 10) / 512) /* 512KiB */ +#ifdef CONFIG_SPL_BUILD +#define CONFIG_FIXED_SDHCI_ALIGNED_BUFFER 0x00180000 /* in SDRAM */ +#endif +#endif
+/*
- Environment Configuration
- */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_HOSTNAME ccdc +#define CONFIG_ROOTPATH "/opt/nfsroot" +#define CONFIG_BOOTFILE "ccdc.img"
+#define CONFIG_PREBOOT /* enable preboot variable */
+#define CONFIG_EXTRA_ENV_SETTINGS \
- "netdev=eth1\0" \
- "consoledev=ttyS1\0" \
- "u-boot=u-boot.bin\0" \
- "bootfile_addr=1000000\0" \
- "keyprogram_addr=3000000\0" \
- "keyprogram_file=keyprogram.img\0" \
- "fdtfile=controlcenterdc.dtb\0" \
- "load=tftpboot ${loadaddr} ${u-boot}\0" \
- "mmcdev=0:2\0" \
- "update=sf probe 1:0;" \
" sf erase 0 +${filesize};" \
" sf write ${fileaddr} 0 ${filesize}\0" \
- "upd=run load update\0" \
- "fdt_high=0x10000000\0" \
- "initrd_high=0x10000000\0" \
- "loadkeyprogram=tpm flush_keys;" \
" mmc rescan;" \
" ext4load mmc ${mmcdev} ${keyprogram_addr} ${keyprogram_file};"\
" source ${keyprogram_addr}:script@1\0" \
- "gpio1=gpio@22_25\0" \
- "gpio2=A29\0" \
- "blinkseq='0 0 0 0 2 0 2 2 3 1 3 1 0 0 2 2 3 1 3 3 2 0 2 2 3 1 1 1 " \
"2 0 2 2 3 1 3 1 0 0 2 0 3 3 3 1 2 0 0 0 3 1 1 1 0 0 0 0'\0" \
- "bootfail=for i in ${blinkseq}; do" \
" if test $i -eq 0; then" \
" gpio clear ${gpio1}; gpio set ${gpio2};" \
" elif test $i -eq 1; then" \
" gpio clear ${gpio1}; gpio clear ${gpio2};" \
" elif test $i -eq 2; then" \
" gpio set ${gpio1}; gpio set ${gpio2};" \
" else;" \
" gpio clear ${gpio1}; gpio set ${gpio2};" \
" fi; sleep 0.12; done\0"
+#define CONFIG_NFSBOOTCOMMAND \
- "setenv bootargs root=/dev/nfs rw " \
- "nfsroot=${serverip}:${rootpath} " \
- "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off " \
- "console=${consoledev},${baudrate} ${othbootargs}; " \
- "tftpboot ${bootfile_addr} ${bootfile}; " \
- "bootm ${bootfile_addr}"
+#define CONFIG_MMCBOOTCOMMAND \
- "setenv bootargs root=/dev/mmcblk0p3 rw rootwait " \
- "console=${consoledev},${baudrate} ${othbootargs}; " \
- "ext2load mmc 0:2 ${bootfile_addr} ${bootfile}; " \
- "bootm ${bootfile_addr}"
+#define CONFIG_BOOTCOMMAND \
- "if env exists keyprogram; then;" \
- " setenv keyprogram; run nfsboot;" \
" fi;" \
" run dobootfail"
+/*
- mv-common.h should be defined after CMD configs since it used them
- to enable certain macros
- */
+#include "mv-common.h"
+#endif /* _CONFIG_CONTROLCENTERDC_H */
Thanks, Stefan