[U-Boot] [PATCH 3/3] marvell: armada385: Add the Turris Omnia board

Marek BehĂșn marek.behun at nic.cz
Fri May 12 14:10:08 UTC 2017


The Turris Omnia is a open-source router created by CZ.NIC.

The code is based on the Marvell/db-88f6820-gp by Stefan Roese
with modifications from Tomas Hlavacek in the CZ.NIC turris-omnia-uboot
repository, which can be found at
https://gitlab.labs.nic.cz/turris/turris-omnia-uboot

The code does not yet support reading the ATSHA204 cryptochip, which
stores the serial number of the device, as well as the base MAC
address.

Also, the device does by default use btrfs as the main filesystem, on
which kernel and device tree is stored. U-Boot does not yes support
btrfs, thus the configuration header defaults to ext4.

Signed-off-by: Marek Behun <marek.behun at nic.cz>
---
 arch/arm/dts/armada-385-turris-omnia.dts | 428 +++++++++++++++++++++++++++++++
 arch/arm/mach-mvebu/Kconfig              |   7 +
 board/CZ.NIC/turris_omnia/Makefile       |   7 +
 board/CZ.NIC/turris_omnia/kwbimage.cfg   |  12 +
 board/CZ.NIC/turris_omnia/turris_omnia.c | 364 ++++++++++++++++++++++++++
 configs/turris_omnia_defconfig           |  59 +++++
 include/configs/turris_omnia.h           | 181 +++++++++++++
 7 files changed, 1058 insertions(+)
 create mode 100644 arch/arm/dts/armada-385-turris-omnia.dts
 create mode 100644 board/CZ.NIC/turris_omnia/Makefile
 create mode 100644 board/CZ.NIC/turris_omnia/kwbimage.cfg
 create mode 100644 board/CZ.NIC/turris_omnia/turris_omnia.c
 create mode 100644 configs/turris_omnia_defconfig
 create mode 100644 include/configs/turris_omnia.h

diff --git a/arch/arm/dts/armada-385-turris-omnia.dts b/arch/arm/dts/armada-385-turris-omnia.dts
new file mode 100644
index 0000000..369b69a
--- /dev/null
+++ b/arch/arm/dts/armada-385-turris-omnia.dts
@@ -0,0 +1,428 @@
+/*
+ * Device Tree file for the Turris Omnia
+ *
+ * Copyright (C) 2014 Marvell
+ *
+ * Marek Behun <marek.behun at nic.cz)
+ * Gregory CLEMENT <gregory.clement at free-electrons.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "CZ.NIC Turris Omnia";
+	compatible = "marvell,a385-gp", "marvell,armada388", "marvell,armada380";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		ethernet0 = &eth0;
+		ethernet1 = &eth1;
+		i2c0 = &i2c0;
+		spi0 = &spi0;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000>; /* 2 GB */
+	};
+
+	soc {
+		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+
+		internal-regs {
+			spi at 10600 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&spi0_pins>;
+				status = "okay";
+				u-boot,dm-pre-reloc;
+
+				spi-flash at 0 {
+					u-boot,dm-pre-reloc;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					compatible = "st,m25p128", "jedec,spi-nor";
+					reg = <0>; /* Chip select 0 */
+					spi-max-frequency = <50000000>;
+					m25p,fast-read;
+				};
+			};
+
+			i2c at 11000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&i2c0_pins>;
+				status = "okay";
+				clock-frequency = <100000>;
+				u-boot,i2c-slave-addr = <0x0>;
+				/*
+				 * The EEPROM located at adresse 54 is needed
+				 * for the boot - DO NOT ERASE IT -
+				 */
+
+				expander0: pca9555 at 20 {
+					compatible = "nxp,pca9555";
+					pinctrl-names = "default";
+					pinctrl-0 = <&pca0_pins>;
+					interrupt-parent = <&gpio0>;
+					interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+					reg = <0x20>;
+				};
+
+				expander1: pca9555 at 21 {
+					compatible = "nxp,pca9555";
+					pinctrl-names = "default";
+					interrupt-parent = <&gpio0>;
+					interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+					gpio-controller;
+					#gpio-cells = <2>;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+					reg = <0x21>;
+				};
+
+			};
+
+			serial at 12000 {
+				/*
+				 * Exported on the micro USB connector CON16
+				 * through an FTDI
+				 */
+
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart0_pins>;
+				status = "okay";
+				u-boot,dm-pre-reloc;
+			};
+
+			/* GE1 CON15 */
+			ethernet at 30000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&ge1_rgmii_pins>;
+				status = "okay";
+				phy = <&phy1>;
+				phy-mode = "rgmii-id";
+			};
+
+			/* CON4 */
+			usb at 58000 {
+				vcc-supply = <&reg_usb2_0_vbus>;
+				status = "okay";
+			};
+
+			/* GE0 CON1 */
+			ethernet at 70000 {
+				pinctrl-names = "default";
+				/*
+				 * The Reference Clock 0 is used to provide a
+				 * clock to the PHY
+				 */
+				pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>;
+				status = "okay";
+				phy = <&phy0>;
+				phy-mode = "rgmii-id";
+			};
+
+			ethernet at 34000 {
+				status = "okay";
+				phy-mode = "sgmii";
+			};
+
+			mdio at 72004 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&mdio_pins>;
+
+				phy0: ethernet-phy at 1 {
+					reg = <1>;
+				};
+
+				phy1: ethernet-phy at 0 {
+					reg = <0>;
+				};
+			};
+
+			sata at a8000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&sata0_pins>, <&sata1_pins>;
+				status = "okay";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sata0: sata-port at 0 {
+					reg = <0>;
+					target-supply = <&reg_5v_sata0>;
+				};
+
+				sata1: sata-port at 1 {
+					reg = <1>;
+					target-supply = <&reg_5v_sata1>;
+				};
+			};
+
+			sata at e0000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&sata2_pins>, <&sata3_pins>;
+				status = "okay";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				sata2: sata-port at 0 {
+					reg = <0>;
+					target-supply = <&reg_5v_sata2>;
+				};
+
+				sata3: sata-port at 1 {
+					reg = <1>;
+					target-supply = <&reg_5v_sata3>;
+				};
+			};
+
+			sdhci at d8000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&sdhci_pins>;
+				cd-gpios = <&expander0 5 GPIO_ACTIVE_LOW>;
+				no-1-8-v;
+				wp-inverted;
+				bus-width = <8>;
+				status = "okay";
+			};
+
+			/* CON5 */
+			usb3 at f0000 {
+				vcc-supply = <&reg_usb2_1_vbus>;
+				status = "okay";
+			};
+
+			/* CON7 */
+			usb3 at f8000 {
+				vcc-supply = <&reg_usb3_vbus>;
+				status = "okay";
+			};
+		};
+
+		pcie-controller {
+			status = "okay";
+			/*
+			 * One PCIe units is accessible through
+			 * standard PCIe slot on the board.
+			 */
+			pcie at 1,0 {
+				/* Port 0, Lane 0 */
+				status = "okay";
+			};
+
+			/*
+			 * The two other PCIe units are accessible
+			 * through mini PCIe slot on the board.
+			 */
+			pcie at 2,0 {
+				/* Port 1, Lane 0 */
+				status = "okay";
+			};
+			pcie at 3,0 {
+				/* Port 2, Lane 0 */
+				status = "okay";
+			};
+		};
+
+		gpio-fan {
+			compatible = "gpio-fan";
+			gpios = <&expander1 3 GPIO_ACTIVE_HIGH>;
+			gpio-fan,speed-map = <	 0 0
+					      3000 1>;
+		};
+	};
+
+	reg_usb3_vbus: usb3-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb3-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		regulator-always-on;
+		gpio = <&expander1 15 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_usb2_0_vbus: v5-vbus0 {
+		compatible = "regulator-fixed";
+		regulator-name = "v5.0-vbus0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		regulator-always-on;
+		gpio = <&expander1 14 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_usb2_1_vbus: v5-vbus1 {
+		compatible = "regulator-fixed";
+		regulator-name = "v5.0-vbus1";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		regulator-always-on;
+		gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_usb2_1_vbus: v5-vbus1 {
+		compatible = "regulator-fixed";
+		regulator-name = "v5.0-vbus1";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+		regulator-always-on;
+		gpio = <&expander0 4 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_sata0: pwr-sata0 {
+		compatible = "regulator-fixed";
+		regulator-name = "pwr_en_sata0";
+		enable-active-high;
+		regulator-always-on;
+
+	};
+
+	reg_5v_sata0: v5-sata0 {
+		compatible = "regulator-fixed";
+		regulator-name = "v5.0-sata0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata0>;
+	};
+
+	reg_12v_sata0: v12-sata0 {
+		compatible = "regulator-fixed";
+		regulator-name = "v12.0-sata0";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata0>;
+	};
+
+	reg_sata1: pwr-sata1 {
+		regulator-name = "pwr_en_sata1";
+		compatible = "regulator-fixed";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		enable-active-high;
+		regulator-always-on;
+		gpio = <&expander0 3 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_5v_sata1: v5-sata1 {
+		compatible = "regulator-fixed";
+		regulator-name = "v5.0-sata1";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata1>;
+	};
+
+	reg_12v_sata1: v12-sata1 {
+		compatible = "regulator-fixed";
+		regulator-name = "v12.0-sata1";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata1>;
+	};
+
+	reg_sata2: pwr-sata2 {
+		compatible = "regulator-fixed";
+		regulator-name = "pwr_en_sata2";
+		enable-active-high;
+		regulator-always-on;
+		gpio = <&expander0 11 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_5v_sata2: v5-sata2 {
+		compatible = "regulator-fixed";
+		regulator-name = "v5.0-sata2";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata2>;
+	};
+
+	reg_12v_sata2: v12-sata2 {
+		compatible = "regulator-fixed";
+		regulator-name = "v12.0-sata2";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata2>;
+	};
+
+	reg_sata3: pwr-sata3 {
+		compatible = "regulator-fixed";
+		regulator-name = "pwr_en_sata3";
+		enable-active-high;
+		regulator-always-on;
+		gpio = <&expander0 12 GPIO_ACTIVE_HIGH>;
+	};
+
+	reg_5v_sata3: v5-sata3 {
+		compatible = "regulator-fixed";
+		regulator-name = "v5.0-sata3";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata3>;
+	};
+
+	reg_12v_sata3: v12-sata3 {
+		compatible = "regulator-fixed";
+		regulator-name = "v12.0-sata3";
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+		regulator-always-on;
+		vin-supply = <&reg_sata3>;
+	};
+};
+
+&pinctrl {
+	pca0_pins: pca0_pins {
+		marvell,pins = "mpp18";
+		marvell,function = "gpio";
+	};
+};
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 6ae54ef..c3e6c22 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -90,6 +90,10 @@ config TARGET_DB_88F6820_AMC
 	bool "Support DB-88F6820-AMC"
 	select 88F6820
 
+config TARGET_TURRIS_OMNIA
+	bool "Support Turris Omnia"
+	select 88F6820
+
 config TARGET_MVEBU_ARMADA_8K
 	bool "Support Armada 7k/8k platforms"
 	select ARMADA_8K
@@ -124,6 +128,7 @@ config SYS_BOARD
 	default "db-88f6720" if TARGET_DB_88F6720
 	default "db-88f6820-gp" if TARGET_DB_88F6820_GP
 	default "db-88f6820-amc" if TARGET_DB_88F6820_AMC
+	default "turris_omnia" if TARGET_TURRIS_OMNIA
 	default "mvebu_armada-8k" if TARGET_MVEBU_ARMADA_8K
 	default "db-mv784mp-gp" if TARGET_DB_MV784MP_GP
 	default "ds414" if TARGET_DS414
@@ -141,6 +146,7 @@ config SYS_CONFIG_NAME
 	default "ds414" if TARGET_DS414
 	default "maxbcm" if TARGET_MAXBCM
 	default "theadorable" if TARGET_THEADORABLE
+	default "turris_omnia" if TARGET_TURRIS_OMNIA
 
 config SYS_VENDOR
 	default "Marvell" if TARGET_DB_MV784MP_GP
@@ -151,6 +157,7 @@ config SYS_VENDOR
 	default "Marvell" if TARGET_MVEBU_ARMADA_8K
 	default "solidrun" if TARGET_CLEARFOG
 	default "Synology" if TARGET_DS414
+	default "CZ.NIC" if TARGET_TURRIS_OMNIA
 
 config SYS_SOC
 	default "mvebu"
diff --git a/board/CZ.NIC/turris_omnia/Makefile b/board/CZ.NIC/turris_omnia/Makefile
new file mode 100644
index 0000000..f2ae506
--- /dev/null
+++ b/board/CZ.NIC/turris_omnia/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2017 Marek Behun <marek.behun at nic.cz>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	:= turris_omnia.o
diff --git a/board/CZ.NIC/turris_omnia/kwbimage.cfg b/board/CZ.NIC/turris_omnia/kwbimage.cfg
new file mode 100644
index 0000000..cc05792
--- /dev/null
+++ b/board/CZ.NIC/turris_omnia/kwbimage.cfg
@@ -0,0 +1,12 @@
+#
+# Copyright (C) 2014 Stefan Roese <sr at denx.de>
+#
+
+# Armada XP uses version 1 image format
+VERSION		1
+
+# Boot Media configurations
+BOOT_FROM	spi
+
+# Binary Header (bin_hdr) with DDR3 training code
+BINARY spl/u-boot-spl.bin 0000005b 00000068
diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
new file mode 100644
index 0000000..10c7c98
--- /dev/null
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2017 Marek Behun <marek.behun at nic.cz>
+ * Copyright (C) 2016 Tomas Hlavacek <tomas.hlavacek at nic.cz>
+ *
+ * Derived from the code for
+ *   Marvell/db-88f6820-gp by Stefan Roese <sr at denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#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 <watchdog.h>
+
+#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h"
+#include <../serdes/a38x/high_speed_env_spec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define OMNIA_I2C_EEPROM_BUS		1
+#define OMNIA_I2C_EEPROM		0x54
+#define OMNIA_I2C_EEPROM_CONFIG_ADDR	0x0
+#define OMNIA_I2C_EEPROM_ADDRLEN	2
+#define OMNIA_I2C_EEPROM_MAGIC		0x0341a034
+
+#define OMNIA_I2C_MCU_BUS		1
+#define OMNIA_I2C_MCU_ADDR_STATUS	0x1
+#define OMNIA_I2C_MCU_SATA		0x20
+#define OMNIA_I2C_MCU_CARDDET		0x10
+#define OMNIA_I2C_MCU			0x2a
+#define OMNIA_I2C_MCU_WDT_ADDR		0x0b
+
+#define MVTWSI_ARMADA_DEBUG_REG		0x8c
+
+/*
+ * Those values and defines are taken from the Marvell U-Boot version
+ * "u-boot-2013.01-2014_T3.0"
+ */
+#define OMNIA_GPP_OUT_ENA_LOW					\
+	(~(BIT(1)  | BIT(4)  | BIT(6)  | BIT(7)  | BIT(8)  | BIT(9)  |	\
+	   BIT(10) | BIT(11) | BIT(19) | BIT(22) | BIT(23) | BIT(25) |	\
+	   BIT(26) | BIT(27) | BIT(29) | BIT(30) | BIT(31)))
+#define OMNIA_GPP_OUT_ENA_MID					\
+	(~(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(15) |	\
+	   BIT(16) | BIT(17) | BIT(18)))
+
+#define OMNIA_GPP_OUT_VAL_LOW	0x0
+#define OMNIA_GPP_OUT_VAL_MID	0x0
+#define OMNIA_GPP_POL_LOW	0x0
+#define OMNIA_GPP_POL_MID	0x0
+
+static struct serdes_map board_serdes_map_pex[] = {
+	{PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+	{USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+	{PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+	{USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+	{PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+	{SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+static struct serdes_map board_serdes_map_sata[] = {
+	{SATA0, SERDES_SPEED_6_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+	{USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+	{PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+	{USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+	{PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+	{SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+static bool omnia_detect_sata(void)
+{
+	struct udevice *dev;
+	int ret;
+	u16 mode;
+
+	puts("SERDES0 card detect: ");
+
+	ret = i2c_get_chip_for_busnum(OMNIA_I2C_MCU_BUS, OMNIA_I2C_MCU, 1, &dev);
+	if (ret) {
+		puts("Cannot find MCU BUS\n");
+		return false;
+	}
+
+	ret = dm_i2c_read(dev, OMNIA_I2C_MCU_ADDR_STATUS, (uchar *) &mode, 1);
+	if (ret) {
+		puts("I2C read failed, default PEX\n");
+		return false;
+	}
+
+	if (!(mode & OMNIA_I2C_MCU_CARDDET)) {
+		puts("NONE\n");
+		return false;
+	}
+
+	if (mode & OMNIA_I2C_MCU_SATA) {
+		puts("SATA\n");
+		return true;
+	} else {
+		puts("PEX\n");
+		return false;
+	}
+}
+
+int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
+{
+	if (omnia_detect_sata()) {
+		*serdes_map_array = board_serdes_map_sata;
+		*count = ARRAY_SIZE(board_serdes_map_sata);
+	} else {
+		*serdes_map_array = board_serdes_map_pex;
+		*count = ARRAY_SIZE(board_serdes_map_pex);
+	}
+
+	return 0;
+}
+
+struct omnia_eeprom {
+	u32 magic;
+	u32 ramsize;
+	char region[4];
+	u32 crc;
+};
+
+static int omnia_read_eeprom(struct omnia_eeprom *oep)
+{
+	struct udevice *dev;
+	int ret, crc, retry = 3;
+
+	ret = i2c_get_chip_for_busnum(OMNIA_I2C_EEPROM_BUS, OMNIA_I2C_EEPROM, OMNIA_I2C_EEPROM_ADDRLEN, &dev);
+	if (ret) {
+		puts("Cannot find EEPROM BUS\n");
+		return false;
+	}
+
+	for (; retry > 0; --retry) {
+		ret = dm_i2c_read(dev, OMNIA_I2C_EEPROM_CONFIG_ADDR, (uchar *) oep, sizeof(struct omnia_eeprom));
+		if (ret)
+			continue;
+
+		if (oep->magic != OMNIA_I2C_EEPROM_MAGIC) {
+			puts("I2C EEPROM missing magic number!\n");
+			continue;
+		}
+
+		crc = crc32(0, (unsigned char *) oep,
+			    sizeof(struct omnia_eeprom) - 4);
+		if (crc != oep->crc) {
+			printf("CRC of EEPROM memory config failed! "
+			       "calc=0x%04x saved=0x%04x\n", crc, oep->crc);
+			continue;
+		}
+	}
+
+	if (!retry) {
+		puts("I2C EEPROM read failed!\n");
+		return -1;
+	}
+
+	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 hws_topology_map board_topology_map_1g = {
+	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_800,		/* frequency */
+	    0, 0,			/* cas_l cas_wl */
+	    HWS_TEMP_NORMAL,		/* temperature */
+	    HWS_TIM_2T} },		/* timing (force 2t) */
+	5,				/* Num Of Bus Per Interface*/
+	BUS_MASK_32BIT			/* Busses mask */
+};
+
+static struct hws_topology_map board_topology_map_2g = {
+	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_8G,			/* mem_size */
+	    DDR_FREQ_800,		/* frequency */
+	    0, 0,			/* cas_l cas_wl */
+	    HWS_TEMP_NORMAL,		/* temperature */
+	    HWS_TIM_2T} },		/* timing (force 2t) */
+	5,				/* Num Of Bus Per Interface*/
+	BUS_MASK_32BIT			/* Busses mask */
+};
+
+struct hws_topology_map *ddr3_get_topology_map(void)
+{
+	static int mem = 1;
+	struct omnia_eeprom oep;
+
+	/* Get the board config from EEPROM */
+	if (mem == 0) {
+		if(omnia_read_eeprom(&oep))
+			goto out;
+
+		printf("Memory config in EEPROM: 0x%02x\n", oep.ramsize);
+
+		if (oep.ramsize == 0x2)
+			mem = 2;
+		else
+			mem = 1;
+	}
+
+	/* Hardcoded fallback */
+out:	if (mem == 0) {
+		puts("WARNING: Memory config from ATSHA204 EEPROM read failed.\n");
+		puts("Falling back to default 1GiB map.\n");
+		mem = 1;
+	}
+
+	/* Return the board topology as defined in the board code */
+	if (mem == 1)
+		return &board_topology_map_1g;
+	if (mem == 2)
+		return &board_topology_map_2g;
+
+	return &board_topology_map_1g;
+}
+
+#ifndef CONFIG_SPL_BUILD
+static int set_regdomain(void)
+{
+	struct omnia_eeprom oep;
+	char rd[3] = {' ', ' ', 0};
+
+	if(!(omnia_read_eeprom(&oep)))
+		memcpy(rd, &oep.region, 2);
+	else
+		puts("EEPROM regdomain read failed.\n");
+
+	printf("Regdomain set to %s\n", rd);
+	return setenv("regdomain", rd);
+}
+#endif
+
+int board_early_init_f(void)
+{
+	u32 i2c_debug_reg;
+
+	/* Configure MPP */
+	writel(0x11111111, MVEBU_MPP_BASE + 0x00);
+	writel(0x11111111, MVEBU_MPP_BASE + 0x04);
+	writel(0x11244011, MVEBU_MPP_BASE + 0x08);
+	writel(0x22222111, MVEBU_MPP_BASE + 0x0c);
+	writel(0x22200002, MVEBU_MPP_BASE + 0x10);
+	writel(0x30042022, MVEBU_MPP_BASE + 0x14);
+	writel(0x55550555, MVEBU_MPP_BASE + 0x18);
+	writel(0x00005550, MVEBU_MPP_BASE + 0x1c);
+
+	/* Set GPP Out value */
+	writel(OMNIA_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
+	writel(OMNIA_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
+
+	/* Set GPP Polarity */
+	writel(OMNIA_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
+	writel(OMNIA_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);
+
+	/* Set GPP Out Enable */
+	writel(OMNIA_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
+	writel(OMNIA_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
+
+	/* Disable I2C debug mode blocking 0x64 I2C address */
+	i2c_debug_reg = readl(MVEBU_TWSI_BASE + MVTWSI_ARMADA_DEBUG_REG);
+	i2c_debug_reg &= ~(1<<18);
+	writel(i2c_debug_reg, MVEBU_TWSI_BASE + MVTWSI_ARMADA_DEBUG_REG);
+
+	return 0;
+}
+
+#ifndef CONFIG_SPL_BUILD
+static int disable_mcu_watchdog(void)
+{
+	struct udevice *dev;
+	int ret, retry = 3;
+	uchar buf[1] = {0x0};
+
+	ret = i2c_get_chip_for_busnum(OMNIA_I2C_MCU_BUS, OMNIA_I2C_MCU, 1, &dev);
+	if (ret) {
+		puts("Cannot find MCU bus! Can not disable MCU WDT.\n");
+		return -1;
+	}
+
+	for (; retry > 0; --retry)
+		if (!dm_i2c_write(dev, OMNIA_I2C_MCU_WDT_ADDR, (uchar *) buf, 1))
+			break;
+
+	if (retry <= 0) {
+		puts("I2C MCU watchdog failed to disable!\n");
+		return -2;
+	}
+
+	return 0;
+}
+#endif
+
+int board_init(void)
+{
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
+
+#ifndef CONFIG_SPL_BUILD
+	puts("Enabling Armada 385 watchdog.\n");
+	hw_watchdog_init();
+
+	puts("Disabling MCU startup watchdog.\n");
+	disable_mcu_watchdog();
+
+	set_regdomain();
+#endif
+
+	return 0;
+}
+
+int board_late_init(void)
+{
+#ifndef CONFIG_SPL_BUILD
+	set_regdomain();
+#endif
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	/* TODO: read serial number from the atsha204 chip (needs driver) */
+
+	printf("Board: Turris Omnia (ver N/A). SN: N/A\n");
+
+	return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+	/* TODO: read base MAC address from the atsha204 chip and set in OF.
+	 * For now, the configuration uses random addresses. */
+
+	cpu_eth_init(bis); /* Built in controller(s) come first */
+	return pci_eth_init(bis);
+}
+
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
new file mode 100644
index 0000000..28da175
--- /dev/null
+++ b/configs/turris_omnia_defconfig
@@ -0,0 +1,59 @@
+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_TURRIS_OMNIA=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="armada-385-turris-omnia"
+CONFIG_BOOTDELAY=3
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_SPL=y
+CONFIG_SPL_I2C_SUPPORT=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+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_GO=y
+CONFIG_CMD_RUN=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_MEMORY=y
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_SETEXPR=y
+# CONFIG_PARTITION_UUIDS is not set
+# CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_DOS_PARTITION=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_MISC=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_NS16550=y
+CONFIG_DEBUG_UART_BASE=0xd0012000
+CONFIG_DEBUG_UART_CLOCK=250000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI=y
+CONFIG_USB_EHCI_MARVELL=y
+CONFIG_USB_STORAGE=y
+CONFIG_ARCH_MISC_INIT=y
+CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_CMDLINE=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="=> "
+# CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h
new file mode 100644
index 0000000..0c7960d
--- /dev/null
+++ b/include/configs/turris_omnia.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2017 Marek Behun <marek.behun at nic.cz>
+ * Copyright (C) 2016 Tomas Hlavacek <tomas.hlavacek at nic.cz>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _CONFIG_TURRIS_OMNIA_H
+#define _CONFIG_TURRIS_OMNIA_H
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+
+#define CONFIG_DISPLAY_BOARDINFO_LATE
+#define CONFIG_LIB_RAND
+#define CONFIG_NET_RANDOM_ETHADDR
+#define CONFIG_CMD_EXT4
+
+/*
+ * 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_ENV
+#define CONFIG_CMD_PCI
+#define CONFIG_SCSI
+
+/* RAW initrd support */
+#define CONFIG_SUPPORT_RAW_INITRD
+
+/*#define CONFIG_ATSHA204
+#define CONFIG_ATSHA204_ADDR	0x64*/
+
+/* I2C */
+#define CONFIG_DM_I2C
+#define CONFIG_SYS_I2C_MVTWSI
+
+/* Watchdog */
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_HW_WATCHDOG
+#define CONFIG_ORION_WATCHDOG
+#endif
+
+/* SPI NOR flash default params, used by sf commands */
+#define CONFIG_SF_DEFAULT_SPEED		1000000
+#define CONFIG_SF_DEFAULT_MODE		SPI_MODE_3
+#define CONFIG_SPI_FLASH_SPANSION
+
+/*
+ * SDIO/MMC Card Configuration
+ */
+#define CONFIG_SYS_MMC_BASE		MVEBU_SDIO_BASE
+
+/*
+ * SATA/SCSI/AHCI configuration
+ */
+#define CONFIG_LIBATA
+#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 */
+
+/* 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_OFFSET		(3*(1 << 18)) /* 768KiB 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_MVEBU
+#define CONFIG_PCI_SCAN_SHOW
+#endif
+
+#define CONFIG_SYS_ALT_MEMTEST
+
+/* Default boot environment. */
+#define CONFIG_BOOTCOMMAND			\
+	"i2c dev 1; "				\
+	"i2c read 0x2a 0x9 1 0x00FFFFF0; "	\
+	"setexpr.b rescue *0x00FFFFF0; "	\
+	"if test $rescue -ge 1; then "		\
+		"echo BOOT RESCUE; "		\
+		"run rescueboot; "		\
+	"else "					\
+		"echo BOOT eMMC FS; "		\
+		"run mmcboot; "			\
+	"fi"
+
+/* Keep device tree and initrd in lower memory so the kernel can access them */
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"fdt_high=0x10000000\0"		\
+	"initrd_high=0x10000000\0"	\
+	"ethact=neta2\0"		\
+	"mmcboot=setenv bootargs \"$bootargs cfg80211.freg=$regdomain\"; " \
+		"ext4load mmc 0 0x01000000 boot/zImage; " \
+		"ext4load mmc 0 0x02000000 boot/dtb; " \
+		"bootz 0x01000000 - 0x02000000\0" \
+	"rescueboot=i2c mw 0x2a.1 0x3 0x1c 1; " \
+		"i2c mw 0x2a.1 0x4 0x1c 1; " \
+		"mw.l 0x01000000 0x00ff000c; " \
+		"i2c write 0x01000000 0x2a.1 0x5 4 -s; " \
+		"setenv bootargs \"$bootargs omniarescue=$rescue\"; " \
+		"sf probe; " \
+		"sf read 0x1000000 0x100000 0x700000; " \
+		"bootz 0x1000000\0" \
+	"bootargs=earlyprintk console=ttyS0,115200 rootfstype=ext4 " \
+		"rootdelay=2 root=b301 rootflags=subvol=@,commit=5 rw\0"
+
+/* 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			(140 << 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
+#endif
+
+#define CONFIG_SPL_STACK		(0x40000000 + ((192 - 16) << 10))
+#define CONFIG_SPL_BOOTROM_SAVE		(CONFIG_SPL_STACK + 4)
+#define CONFIG_SPL_DRIVERS_MISC_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	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		(160 << 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
+#endif
+
+/*
+ * mv-common.h should be defined after CMD configs since it used them
+ * to enable certain macros
+ */
+#include "mv-common.h"
+
+#endif /* _CONFIG_TURRIS_OMNIA_H */
-- 
2.10.2



More information about the U-Boot mailing list