mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-26 14:40:41 +00:00
Merge git://www.denx.de/git/u-boot-marvell
This mainly adds support for some new boards, like the ARMv8 community boards MACCHIATOBin and ESPRESSBin
This commit is contained in:
commit
c1daa40773
51 changed files with 3921 additions and 175 deletions
|
@ -1284,6 +1284,7 @@ source "board/freescale/mx53evk/Kconfig"
|
|||
source "board/freescale/mx53loco/Kconfig"
|
||||
source "board/freescale/mx53smd/Kconfig"
|
||||
source "board/freescale/s32v234evb/Kconfig"
|
||||
source "board/gdsys/a38x/Kconfig"
|
||||
source "board/grinn/chiliboard/Kconfig"
|
||||
source "board/gumstix/pepper/Kconfig"
|
||||
source "board/h2200/Kconfig"
|
||||
|
|
|
@ -71,16 +71,19 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
|
|||
|
||||
dtb-$(CONFIG_ARCH_MVEBU) += \
|
||||
armada-3720-db.dtb \
|
||||
armada-3720-espressobin.dtb \
|
||||
armada-375-db.dtb \
|
||||
armada-388-clearfog.dtb \
|
||||
armada-388-gp.dtb \
|
||||
armada-385-amc.dtb \
|
||||
armada-7040-db.dtb \
|
||||
armada-8040-db.dtb \
|
||||
armada-8040-mcbin.dtb \
|
||||
armada-xp-gp.dtb \
|
||||
armada-xp-maxbcm.dtb \
|
||||
armada-xp-synology-ds414.dtb \
|
||||
armada-xp-theadorable.dtb
|
||||
armada-xp-theadorable.dtb \
|
||||
armada-38x-controlcenterdc.dtb
|
||||
|
||||
dtb-$(CONFIG_ARCH_UNIPHIER_LD11) += \
|
||||
uniphier-ld11-ref.dtb
|
||||
|
|
135
arch/arm/dts/armada-3720-espressobin.dts
Normal file
135
arch/arm/dts/armada-3720-espressobin.dts
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Device Tree file for Marvell Armada 3720 community board
|
||||
* (ESPRESSOBin)
|
||||
* Copyright (C) 2016 Marvell
|
||||
*
|
||||
* Gregory CLEMENT <gregory.clement@free-electrons.com>
|
||||
* Konstantin Porotchkin <kostap@marvell.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 free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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 , 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-372x.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Marvell Armada 3720 Community Board ESPRESSOBin";
|
||||
compatible = "marvell,armada-3720-espressobin", "marvell,armada3720", "marvell,armada3710";
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
aliases {
|
||||
ethernet0 = ð0;
|
||||
i2c0 = &i2c0;
|
||||
spi0 = &spi0;
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&comphy {
|
||||
max-lanes = <3>;
|
||||
phy0 {
|
||||
phy-type = <PHY_TYPE_PEX0>;
|
||||
phy-speed = <PHY_SPEED_2_5G>;
|
||||
};
|
||||
|
||||
phy1 {
|
||||
phy-type = <PHY_TYPE_USB3_HOST0>;
|
||||
phy-speed = <PHY_SPEED_5G>;
|
||||
};
|
||||
|
||||
phy2 {
|
||||
phy-type = <PHY_TYPE_SATA0>;
|
||||
phy-speed = <PHY_SPEED_5G>;
|
||||
};
|
||||
};
|
||||
|
||||
ð0 {
|
||||
status = "okay";
|
||||
phy-mode = "rgmii";
|
||||
phy_addr = <0x1>;
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CON3 */
|
||||
&sata {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "st,m25p128", "spi-flash";
|
||||
reg = <0>; /* Chip select 0 */
|
||||
spi-max-frequency = <50000000>;
|
||||
m25p,fast-read;
|
||||
};
|
||||
};
|
||||
|
||||
/* Exported on the micro USB connector CON32 through an FTDI */
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CON29 */
|
||||
&usb2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CON31 */
|
||||
&usb3 {
|
||||
status = "okay";
|
||||
};
|
|
@ -193,6 +193,20 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
pinctl0: pinctl@13830 { /* north bridge */
|
||||
compatible = "marvell,armada-3700-pinctl";
|
||||
bank-name = "armada-3700-nb";
|
||||
reg = <0x13830 0x4>;
|
||||
pin-count = <36>;
|
||||
};
|
||||
|
||||
pinctl1: pinctl@18830 { /* south bridge */
|
||||
compatible = "marvell,armada-3700-pinctl";
|
||||
bank-name = "armada-3700-sb";
|
||||
reg = <0x18830 0x4>;
|
||||
pin-count = <30>;
|
||||
};
|
||||
|
||||
comphy: comphy@18300 {
|
||||
compatible = "marvell,mvebu-comphy", "marvell,comphy-armada-3700";
|
||||
reg = <0x18300 0x28>,
|
||||
|
|
589
arch/arm/dts/armada-38x-controlcenterdc.dts
Normal file
589
arch/arm/dts/armada-38x-controlcenterdc.dts
Normal file
|
@ -0,0 +1,589 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
&gpio0 {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
finder_led {
|
||||
label = "finder-led";
|
||||
gpios = <&PCA22 25 0>;
|
||||
};
|
||||
|
||||
status_led {
|
||||
label = "status-led";
|
||||
gpios = <&gpio0 29 0>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -45,6 +45,7 @@
|
|||
* one CP110.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include "armada-ap806-quad.dtsi"
|
||||
#include "armada-cp110-master.dtsi"
|
||||
|
||||
|
|
293
arch/arm/dts/armada-8040-mcbin.dts
Normal file
293
arch/arm/dts/armada-8040-mcbin.dts
Normal file
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Marvell International Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
* https://spdx.org/licenses
|
||||
*/
|
||||
|
||||
#include "armada-8040.dtsi" /* include SoC device tree */
|
||||
|
||||
/ {
|
||||
model = "MACCHIATOBin-8040";
|
||||
compatible = "marvell,armada8040-mcbin",
|
||||
"marvell,armada8040";
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
aliases {
|
||||
i2c0 = &cpm_i2c0;
|
||||
i2c1 = &cpm_i2c1;
|
||||
spi0 = &cps_spi1;
|
||||
gpio0 = &ap_gpio0;
|
||||
gpio1 = &cpm_gpio0;
|
||||
gpio2 = &cpm_gpio1;
|
||||
};
|
||||
|
||||
memory@00000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x0 0x0 0x80000000>;
|
||||
};
|
||||
|
||||
simple-bus {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
reg_usb3h0_vbus: usb3-vbus0 {
|
||||
compatible = "regulator-fixed";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cpm_xhci_vbus_pins>;
|
||||
regulator-name = "reg-usb3h0-vbus";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
startup-delay-us = <500000>;
|
||||
enable-active-high;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
gpio = <&cpm_gpio1 15 GPIO_ACTIVE_HIGH>; /* GPIO[47] */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* Accessible over the mini-USB CON9 connector on the main board */
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ap_pinctl {
|
||||
/*
|
||||
* MPP Bus:
|
||||
* eMMC [0-10]
|
||||
* UART0 [11,19]
|
||||
*/
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
pin-func = < 1 1 1 1 1 1 1 1 1 1
|
||||
1 3 0 0 0 0 0 0 0 3 >;
|
||||
};
|
||||
|
||||
/* on-board eMMC */
|
||||
&ap_sdhci0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ap_emmc_pins>;
|
||||
bus-width= <8>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpm_pinctl {
|
||||
/*
|
||||
* MPP Bus:
|
||||
* [0-31] = 0xff: Keep default CP0_shared_pins:
|
||||
* [11] CLKOUT_MPP_11 (out)
|
||||
* [23] LINK_RD_IN_CP2CP (in)
|
||||
* [25] CLKOUT_MPP_25 (out)
|
||||
* [29] AVS_FB_IN_CP2CP (in)
|
||||
* [32,34] SMI
|
||||
* [33] MSS power down
|
||||
* [35-38] CP0 I2C1 and I2C0
|
||||
* [39] MSS CKE Enable
|
||||
* [40,41] CP0 UART1 TX/RX
|
||||
* [42,43] XSMI (controls two 10G phys)
|
||||
* [47] USB VBUS EN
|
||||
* [48] FAN PWM
|
||||
* [49] 10G port 1 interrupt
|
||||
* [50] 10G port 0 interrupt
|
||||
* [51] 2.5G SFP TX fault
|
||||
* [52] PCIe reset out
|
||||
* [53] 2.5G SFP mode
|
||||
* [54] 2.5G SFP LOS
|
||||
* [55] Micro SD card detect
|
||||
* [56-61] Micro SD
|
||||
* [62] CP1 KR SFP FAULT
|
||||
*/
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
|
||||
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
|
||||
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
|
||||
0xff 0 7 0xa 7 2 2 2 2 0xa
|
||||
7 7 8 8 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0xe 0xe 0xe 0xe
|
||||
0xe 0xe 0 >;
|
||||
|
||||
cpm_xhci_vbus_pins: cpm-xhci-vbus-pins {
|
||||
marvell,pins = < 47 >;
|
||||
marvell,function = <0>;
|
||||
};
|
||||
|
||||
cpm_pcie_reset_pins: cpm-pcie-reset-pins {
|
||||
marvell,pins = < 52 >;
|
||||
marvell,function = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
/* uSD slot */
|
||||
&cpm_sdhci0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cpm_sdhci_pins>;
|
||||
bus-width= <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* PCIe x4 */
|
||||
&cpm_pcie0 {
|
||||
num-lanes = <4>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cpm_pcie_reset_pins>;
|
||||
marvell,reset-gpio = <&cpm_gpio1 20 GPIO_ACTIVE_HIGH>; /* GPIO[52] */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpm_i2c0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cpm_i2c0_pins>;
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
||||
&cpm_i2c1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cpm_i2c1_pins>;
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
||||
&cpm_sata0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpm_comphy {
|
||||
/*
|
||||
* CP0 Serdes Configuration:
|
||||
* Lane 0: PCIe0 (x4)
|
||||
* Lane 1: PCIe0 (x4)
|
||||
* Lane 2: PCIe0 (x4)
|
||||
* Lane 3: PCIe0 (x4)
|
||||
* Lane 4: KR (10G)
|
||||
* Lane 5: SATA1
|
||||
*/
|
||||
phy0 {
|
||||
phy-type = <PHY_TYPE_PEX0>;
|
||||
};
|
||||
phy1 {
|
||||
phy-type = <PHY_TYPE_PEX0>;
|
||||
};
|
||||
phy2 {
|
||||
phy-type = <PHY_TYPE_PEX0>;
|
||||
};
|
||||
phy3 {
|
||||
phy-type = <PHY_TYPE_PEX0>;
|
||||
};
|
||||
phy4 {
|
||||
phy-type = <PHY_TYPE_KR>;
|
||||
};
|
||||
phy5 {
|
||||
phy-type = <PHY_TYPE_SATA1>;
|
||||
};
|
||||
};
|
||||
|
||||
&cps_sata0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cps_usb3_0 {
|
||||
vbus-supply = <®_usb3h0_vbus>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cps_utmi0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cps_pinctl {
|
||||
/*
|
||||
* MPP Bus:
|
||||
* [0-5] TDM
|
||||
* [6,7] CP1_UART 0
|
||||
* [8] CP1 10G SFP LOS
|
||||
* [9] CP1 10G PHY RESET
|
||||
* [10] CP1 10G SFP TX Disable
|
||||
* [11] CP1 10G SFP Mode
|
||||
* [12] SPI1 CS1n
|
||||
* [13] SPI1 MISO (TDM and SPI ROM shared)
|
||||
* [14] SPI1 CS0n
|
||||
* [15] SPI1 MOSI (TDM and SPI ROM shared)
|
||||
* [16] SPI1 CLK (TDM and SPI ROM shared)
|
||||
* [24] CP1 2.5G SFP TX Disable
|
||||
* [26] CP0 10G SFP TX Fault
|
||||
* [27] CP0 10G SFP Mode
|
||||
* [28] CP0 10G SFP LOS
|
||||
* [29] CP0 10G SFP TX Disable
|
||||
* [30] USB Over current indication
|
||||
* [31] 10G Port 0 phy reset
|
||||
* [32-62] = 0xff: Keep default CP1_shared_pins:
|
||||
*/
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
pin-func = < 0x4 0x4 0x4 0x4 0x4 0x4 0x8 0x8 0x0 0x0
|
||||
0x0 0x0 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff
|
||||
0xff 0xff 0xff 0xff 0x0 0xff 0x0 0x0 0x0 0x0
|
||||
0x0 0x0 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
|
||||
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
|
||||
0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
|
||||
0xff 0xff 0xff>;
|
||||
};
|
||||
|
||||
&cps_spi1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cps_spi1_pins>;
|
||||
status = "okay";
|
||||
|
||||
spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "U-Boot";
|
||||
reg = <0 0x200000>;
|
||||
};
|
||||
partition@400000 {
|
||||
label = "Filesystem";
|
||||
reg = <0x200000 0xce0000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&cps_comphy {
|
||||
/*
|
||||
* CP1 Serdes Configuration:
|
||||
* Lane 0: SGMII2
|
||||
* Lane 1: SATA 0
|
||||
* Lane 2: USB HOST 0
|
||||
* Lane 3: SATA1
|
||||
* Lane 4: KR (10G)
|
||||
* Lane 5: SGMII3
|
||||
*/
|
||||
phy0 {
|
||||
phy-type = <PHY_TYPE_SGMII2>;
|
||||
phy-speed = <PHY_SPEED_1_25G>;
|
||||
};
|
||||
phy1 {
|
||||
phy-type = <PHY_TYPE_SATA0>;
|
||||
};
|
||||
phy2 {
|
||||
phy-type = <PHY_TYPE_USB3_HOST0>;
|
||||
};
|
||||
phy3 {
|
||||
phy-type = <PHY_TYPE_SATA1>;
|
||||
};
|
||||
phy4 {
|
||||
phy-type = <PHY_TYPE_KR>;
|
||||
};
|
||||
phy5 {
|
||||
phy-type = <PHY_TYPE_SGMII3>;
|
||||
};
|
||||
};
|
|
@ -45,6 +45,7 @@
|
|||
* two CP110.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include "armada-ap806-quad.dtsi"
|
||||
#include "armada-cp110-master.dtsi"
|
||||
#include "armada-cp110-slave.dtsi"
|
||||
|
|
|
@ -158,6 +158,14 @@
|
|||
};
|
||||
};
|
||||
|
||||
ap_gpio0: gpio@6F5040 {
|
||||
compatible = "marvell,orion-gpio";
|
||||
reg = <0x6F5040 0x40>;
|
||||
ngpios = <20>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
xor@400000 {
|
||||
compatible = "marvell,mv-xor-v2";
|
||||
reg = <0x400000 0x1000>,
|
||||
|
|
|
@ -94,6 +94,10 @@
|
|||
marvell,pins = < 37 38 >;
|
||||
marvell,function = <2>;
|
||||
};
|
||||
cpm_i2c1_pins: cpm-i2c-pins-1 {
|
||||
marvell,pins = < 35 36 >;
|
||||
marvell,function = <2>;
|
||||
};
|
||||
cpm_ge2_rgmii_pins: cpm-ge-rgmii-pins-0 {
|
||||
marvell,pins = < 44 45 46 47 48 49 50 51
|
||||
52 53 54 55 >;
|
||||
|
@ -113,6 +117,24 @@
|
|||
};
|
||||
};
|
||||
|
||||
cpm_gpio0: gpio@440100 {
|
||||
compatible = "marvell,orion-gpio";
|
||||
reg = <0x440100 0x40>;
|
||||
ngpios = <32>;
|
||||
gpiobase = <20>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
cpm_gpio1: gpio@440140 {
|
||||
compatible = "marvell,orion-gpio";
|
||||
reg = <0x440140 0x40>;
|
||||
ngpios = <31>;
|
||||
gpiobase = <52>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
cpm_sata0: sata@540000 {
|
||||
compatible = "marvell,armada-8k-ahci";
|
||||
reg = <0x540000 0x30000>;
|
||||
|
|
|
@ -100,6 +100,24 @@
|
|||
};
|
||||
};
|
||||
|
||||
cps_gpio0: gpio@440100 {
|
||||
compatible = "marvell,orion-gpio";
|
||||
reg = <0x440100 0x40>;
|
||||
ngpios = <32>;
|
||||
gpiobase = <20>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
cps_gpio1: gpio@440140 {
|
||||
compatible = "marvell,orion-gpio";
|
||||
reg = <0x440140 0x40>;
|
||||
ngpios = <31>;
|
||||
gpiobase = <52>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
cps_sata0: sata@540000 {
|
||||
compatible = "marvell,armada-8k-ahci";
|
||||
reg = <0x540000 0x30000>;
|
||||
|
|
|
@ -74,8 +74,8 @@ config TARGET_CLEARFOG
|
|||
bool "Support ClearFog"
|
||||
select 88F6820
|
||||
|
||||
config TARGET_MVEBU_DB_88F3720
|
||||
bool "Support DB-88F3720 Armada 3720"
|
||||
config TARGET_MVEBU_ARMADA_37XX
|
||||
bool "Support Armada 37xx platforms"
|
||||
select ARMADA_3700
|
||||
|
||||
config TARGET_DB_88F6720
|
||||
|
@ -112,11 +112,15 @@ config TARGET_THEADORABLE
|
|||
select BOARD_LATE_INIT if USB
|
||||
select MV78260
|
||||
|
||||
config TARGET_CONTROLCENTERDC
|
||||
bool "Support CONTROLCENTERDC"
|
||||
select 88F6820
|
||||
|
||||
endchoice
|
||||
|
||||
config SYS_BOARD
|
||||
default "clearfog" if TARGET_CLEARFOG
|
||||
default "mvebu_db-88f3720" if TARGET_MVEBU_DB_88F3720
|
||||
default "mvebu_armada-37xx" if TARGET_MVEBU_ARMADA_37XX
|
||||
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
|
||||
|
@ -128,7 +132,7 @@ config SYS_BOARD
|
|||
|
||||
config SYS_CONFIG_NAME
|
||||
default "clearfog" if TARGET_CLEARFOG
|
||||
default "mvebu_db-88f3720" if TARGET_MVEBU_DB_88F3720
|
||||
default "mvebu_armada-37xx" if TARGET_MVEBU_ARMADA_37XX
|
||||
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
|
||||
|
@ -140,7 +144,7 @@ config SYS_CONFIG_NAME
|
|||
|
||||
config SYS_VENDOR
|
||||
default "Marvell" if TARGET_DB_MV784MP_GP
|
||||
default "Marvell" if TARGET_MVEBU_DB_88F3720
|
||||
default "Marvell" if TARGET_MVEBU_ARMADA_37XX
|
||||
default "Marvell" if TARGET_DB_88F6720
|
||||
default "Marvell" if TARGET_DB_88F6820_GP
|
||||
default "Marvell" if TARGET_DB_88F6820_AMC
|
||||
|
|
|
@ -230,6 +230,20 @@ static int serdes_max_lines_get(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests have shown that on some boards the default width of the
|
||||
* configuration pulse for the PEX link detection might lead to
|
||||
* non-established PCIe links (link down). Especially under certain
|
||||
* conditions (higher temperature) and with specific PCIe devices.
|
||||
* To enable a board-specific detection pulse width this weak
|
||||
* array "serdes_pex_pulse_width[4]" is introduced which can be
|
||||
* overwritten if needed by a board-specific version. If the board
|
||||
* code does not provide a non-weak version of this variable, the
|
||||
* default value will be used. So nothing is changed from the
|
||||
* current setup on the supported board.
|
||||
*/
|
||||
__weak u8 serdes_pex_pulse_width[4] = { 2, 2, 2, 2 };
|
||||
|
||||
int serdes_phy_config(void)
|
||||
{
|
||||
int status = MV_OK;
|
||||
|
@ -891,6 +905,23 @@ int serdes_phy_config(void)
|
|||
pex_unit = line_num >> 2;
|
||||
pex_line_num = line_num % 4;
|
||||
if (0 == pex_line_num) {
|
||||
/*
|
||||
* Configure the detection pulse with before
|
||||
* the reset is deasserted
|
||||
*/
|
||||
|
||||
/* Read the old value (indirect access) */
|
||||
reg_write(PEX_PHY_ACCESS_REG(pex_unit),
|
||||
(0x48 << 16) | (1 << 31) |
|
||||
(pex_line_num << 24));
|
||||
tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit));
|
||||
tmp &= ~(1 << 31); /* Clear read */
|
||||
tmp &= ~(3 << 6); /* Mask width */
|
||||
/* Insert new detection pulse width */
|
||||
tmp |= serdes_pex_pulse_width[pex_unit] << 6;
|
||||
/* Write value back */
|
||||
reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp);
|
||||
|
||||
reg_write(PEX_PHY_ACCESS_REG(pex_unit),
|
||||
(0xC1 << 16) | 0x24);
|
||||
DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
MVEBU_DB_88F3720 BOARD
|
||||
M: Stefan Roese <sr@denx.de>
|
||||
S: Maintained
|
||||
F: board/Marvell/mvebu_db-88f3720/
|
||||
F: include/configs/mvebu_db-88f3720.h
|
||||
F: board/Marvell/mvebu_armada-37xx/
|
||||
F: include/configs/mvebu_armada-37xx.h
|
||||
F: configs/mvebu_db-88f3720_defconfig
|
258
board/Marvell/mvebu_armada-37xx/board.c
Normal file
258
board/Marvell/mvebu_armada-37xx/board.c
Normal file
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Stefan Roese <sr@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <phy.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/soc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* IO expander I2C device */
|
||||
#define I2C_IO_EXP_ADDR 0x22
|
||||
#define I2C_IO_CFG_REG_0 0x6
|
||||
#define I2C_IO_DATA_OUT_REG_0 0x2
|
||||
#define I2C_IO_REG_0_SATA_OFF 2
|
||||
#define I2C_IO_REG_0_USB_H_OFF 1
|
||||
|
||||
/* The pin control values are the same for DB and Espressobin */
|
||||
#define PINCTRL_NB_REG_VALUE 0x000173fa
|
||||
#define PINCTRL_SB_REG_VALUE 0x00007a23
|
||||
|
||||
/* Ethernet switch registers */
|
||||
/* SMI addresses for multi-chip mode */
|
||||
#define MVEBU_PORT_CTRL_SMI_ADDR(p) (16 + (p))
|
||||
#define MVEBU_SW_G2_SMI_ADDR (28)
|
||||
|
||||
/* Multi-chip mode */
|
||||
#define MVEBU_SW_SMI_DATA_REG (1)
|
||||
#define MVEBU_SW_SMI_CMD_REG (0)
|
||||
#define SW_SMI_CMD_REG_ADDR_OFF 0
|
||||
#define SW_SMI_CMD_DEV_ADDR_OFF 5
|
||||
#define SW_SMI_CMD_SMI_OP_OFF 10
|
||||
#define SW_SMI_CMD_SMI_MODE_OFF 12
|
||||
#define SW_SMI_CMD_SMI_BUSY_OFF 15
|
||||
|
||||
/* Single-chip mode */
|
||||
/* Switch Port Registers */
|
||||
#define MVEBU_SW_LINK_CTRL_REG (1)
|
||||
#define MVEBU_SW_PORT_CTRL_REG (4)
|
||||
|
||||
/* Global 2 Registers */
|
||||
#define MVEBU_G2_SMI_PHY_CMD_REG (24)
|
||||
#define MVEBU_G2_SMI_PHY_DATA_REG (25)
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
const void *blob = gd->fdt_blob;
|
||||
const char *bank_name;
|
||||
const char *compat = "marvell,armada-3700-pinctl";
|
||||
int off, len;
|
||||
void __iomem *addr;
|
||||
|
||||
/* FIXME
|
||||
* Temporary WA for setting correct pin control values
|
||||
* until the real pin control driver is awailable.
|
||||
*/
|
||||
off = fdt_node_offset_by_compatible(blob, -1, compat);
|
||||
while (off != -FDT_ERR_NOTFOUND) {
|
||||
bank_name = fdt_getprop(blob, off, "bank-name", &len);
|
||||
addr = (void __iomem *)fdtdec_get_addr_size_auto_noparent(
|
||||
blob, off, "reg", 0, NULL, true);
|
||||
if (!strncmp(bank_name, "armada-3700-nb", len))
|
||||
writel(PINCTRL_NB_REG_VALUE, addr);
|
||||
else if (!strncmp(bank_name, "armada-3700-sb", len))
|
||||
writel(PINCTRL_SB_REG_VALUE, addr);
|
||||
|
||||
off = fdt_node_offset_by_compatible(blob, off, compat);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Board specific AHCI / SATA enable code */
|
||||
int board_ahci_enable(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
u8 buf[8];
|
||||
|
||||
/* Only DB requres this configuration */
|
||||
if (!of_machine_is_compatible("marvell,armada-3720-db"))
|
||||
return 0;
|
||||
|
||||
/* Configure IO exander PCA9555: 7bit address 0x22 */
|
||||
ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev);
|
||||
if (ret) {
|
||||
printf("Cannot find PCA9555: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to read IO expander value via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable SATA power via IO expander connected via I2C by setting
|
||||
* the corresponding bit to output mode to enable power for SATA
|
||||
*/
|
||||
buf[0] &= ~(1 << I2C_IO_REG_0_SATA_OFF);
|
||||
ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to set IO expander via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Board specific xHCI enable code */
|
||||
int board_xhci_enable(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
u8 buf[8];
|
||||
|
||||
/* Only DB requres this configuration */
|
||||
if (!of_machine_is_compatible("marvell,armada-3720-db"))
|
||||
return 0;
|
||||
|
||||
/* Configure IO exander PCA9555: 7bit address 0x22 */
|
||||
ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev);
|
||||
if (ret) {
|
||||
printf("Cannot find PCA9555: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Enable USB VBUS\n");
|
||||
|
||||
/*
|
||||
* Read configuration (direction) and set VBUS pin as output
|
||||
* (reset pin = output)
|
||||
*/
|
||||
ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to read IO expander value via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
buf[0] &= ~(1 << I2C_IO_REG_0_USB_H_OFF);
|
||||
ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to set IO expander via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Read VBUS output value and disable it */
|
||||
ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to read IO expander value via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
buf[0] &= ~(1 << I2C_IO_REG_0_USB_H_OFF);
|
||||
ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to set IO expander via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Required delay for configuration to settle - must wait for
|
||||
* power on port is disabled in case VBUS signal was high,
|
||||
* required 3 seconds delay to let VBUS signal fully settle down
|
||||
*/
|
||||
mdelay(3000);
|
||||
|
||||
/* Enable VBUS power: Set output value of VBUS pin as enabled */
|
||||
buf[0] |= (1 << I2C_IO_REG_0_USB_H_OFF);
|
||||
ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to set IO expander via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
mdelay(500); /* required delay to let output value settle */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function for accessing switch devices in multi-chip connection mode */
|
||||
static int mii_multi_chip_mode_write(struct mii_dev *bus, int dev_smi_addr,
|
||||
int smi_addr, int reg, u16 value)
|
||||
{
|
||||
u16 smi_cmd = 0;
|
||||
|
||||
if (bus->write(bus, dev_smi_addr, 0,
|
||||
MVEBU_SW_SMI_DATA_REG, value) != 0) {
|
||||
printf("Error writing to the PHY addr=%02x reg=%02x\n",
|
||||
smi_addr, reg);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
smi_cmd = (1 << SW_SMI_CMD_SMI_BUSY_OFF) |
|
||||
(1 << SW_SMI_CMD_SMI_MODE_OFF) |
|
||||
(1 << SW_SMI_CMD_SMI_OP_OFF) |
|
||||
(smi_addr << SW_SMI_CMD_DEV_ADDR_OFF) |
|
||||
(reg << SW_SMI_CMD_REG_ADDR_OFF);
|
||||
if (bus->write(bus, dev_smi_addr, 0,
|
||||
MVEBU_SW_SMI_CMD_REG, smi_cmd) != 0) {
|
||||
printf("Error writing to the PHY addr=%02x reg=%02x\n",
|
||||
smi_addr, reg);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Bring-up board-specific network stuff */
|
||||
int board_network_enable(struct mii_dev *bus)
|
||||
{
|
||||
if (!of_machine_is_compatible("marvell,armada-3720-espressobin"))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* FIXME: remove this code once Topaz driver gets available
|
||||
* A3720 Community Board Only
|
||||
* Configure Topaz switch (88E6341)
|
||||
* Set port 0,1,2,3 to forwarding Mode (through Switch Port registers)
|
||||
*/
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(0),
|
||||
MVEBU_SW_PORT_CTRL_REG, 0x7f);
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(1),
|
||||
MVEBU_SW_PORT_CTRL_REG, 0x7f);
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(2),
|
||||
MVEBU_SW_PORT_CTRL_REG, 0x7f);
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(3),
|
||||
MVEBU_SW_PORT_CTRL_REG, 0x7f);
|
||||
|
||||
/* RGMII Delay on Port 0 (CPU port), force link to 1000Mbps */
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(0),
|
||||
MVEBU_SW_LINK_CTRL_REG, 0xe002);
|
||||
|
||||
/* Power up PHY 1, 2, 3 (through Global 2 registers) */
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR,
|
||||
MVEBU_G2_SMI_PHY_DATA_REG, 0x1140);
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR,
|
||||
MVEBU_G2_SMI_PHY_CMD_REG, 0x9620);
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR,
|
||||
MVEBU_G2_SMI_PHY_CMD_REG, 0x9640);
|
||||
mii_multi_chip_mode_write(bus, 1, MVEBU_SW_G2_SMI_ADDR,
|
||||
MVEBU_G2_SMI_PHY_CMD_REG, 0x9660);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Stefan Roese <sr@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/soc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* IO expander I2C device */
|
||||
#define I2C_IO_EXP_ADDR 0x22
|
||||
#define I2C_IO_CFG_REG_0 0x6
|
||||
#define I2C_IO_DATA_OUT_REG_0 0x2
|
||||
#define I2C_IO_REG_0_SATA_OFF 2
|
||||
#define I2C_IO_REG_0_USB_H_OFF 1
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
/* Nothing to do (yet), perhaps later some pin-muxing etc */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Board specific AHCI / SATA enable code */
|
||||
int board_ahci_enable(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
u8 buf[8];
|
||||
|
||||
/* Configure IO exander PCA9555: 7bit address 0x22 */
|
||||
ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev);
|
||||
if (ret) {
|
||||
printf("Cannot find PCA9555: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to read IO expander value via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable SATA power via IO expander connected via I2C by setting
|
||||
* the corresponding bit to output mode to enable power for SATA
|
||||
*/
|
||||
buf[0] &= ~(1 << I2C_IO_REG_0_SATA_OFF);
|
||||
ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to set IO expander via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Board specific xHCI enable code */
|
||||
int board_xhci_enable(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
u8 buf[8];
|
||||
|
||||
/* Configure IO exander PCA9555: 7bit address 0x22 */
|
||||
ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev);
|
||||
if (ret) {
|
||||
printf("Cannot find PCA9555: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Enable USB VBUS\n");
|
||||
|
||||
/*
|
||||
* Read configuration (direction) and set VBUS pin as output
|
||||
* (reset pin = output)
|
||||
*/
|
||||
ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to read IO expander value via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
buf[0] &= ~(1 << I2C_IO_REG_0_USB_H_OFF);
|
||||
ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to set IO expander via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Read VBUS output value and disable it */
|
||||
ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to read IO expander value via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
buf[0] &= ~(1 << I2C_IO_REG_0_USB_H_OFF);
|
||||
ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to set IO expander via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Required delay for configuration to settle - must wait for
|
||||
* power on port is disabled in case VBUS signal was high,
|
||||
* required 3 seconds delay to let VBUS signal fully settle down
|
||||
*/
|
||||
mdelay(3000);
|
||||
|
||||
/* Enable VBUS power: Set output value of VBUS pin as enabled */
|
||||
buf[0] |= (1 << I2C_IO_REG_0_USB_H_OFF);
|
||||
ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
|
||||
if (ret) {
|
||||
printf("Failed to set IO expander via I2C\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
mdelay(500); /* required delay to let output value settle */
|
||||
|
||||
return 0;
|
||||
}
|
1
board/gdsys/a38x/.gitignore
vendored
Normal file
1
board/gdsys/a38x/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
kwbimage.cfg
|
36
board/gdsys/a38x/Kconfig
Normal file
36
board/gdsys/a38x/Kconfig
Normal file
|
@ -0,0 +1,36 @@
|
|||
if TARGET_CONTROLCENTERDC
|
||||
|
||||
config SYS_BOARD
|
||||
default "a38x"
|
||||
|
||||
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
|
||||
|
||||
endmenu
|
||||
|
||||
endif
|
7
board/gdsys/a38x/MAINTAINERS
Normal file
7
board/gdsys/a38x/MAINTAINERS
Normal file
|
@ -0,0 +1,7 @@
|
|||
A38X BOARD
|
||||
M: Dirk Eibach <eibach@gdsys.cc>
|
||||
M: Mario Six <six@gdsys.de>
|
||||
S: Maintained
|
||||
F: board/gdsys/a38x/
|
||||
F: include/configs/controlcenterdc.h
|
||||
F: configs/controlcenterdc_defconfig
|
44
board/gdsys/a38x/Makefile
Normal file
44
board/gdsys/a38x/Makefile
Normal file
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# 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),)
|
||||
|
||||
obj-$(CONFIG_TARGET_CONTROLCENTERDC) += hydra.o ihs_phys.o
|
||||
|
||||
extra-$(CONFIG_TARGET_CONTROLCENTERDC) += kwbimage.cfg
|
||||
|
||||
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
|
||||
|
||||
ifneq ($(CONFIG_SECURED_MODE_IMAGE),)
|
||||
KWB_REPLACE += CSK_INDEX
|
||||
KWB_CFG_CSK_INDEX = $(CONFIG_SECURED_MODE_CSK_INDEX)
|
||||
|
||||
KWB_REPLACE += SEC_BOOT_DEV
|
||||
KWB_CFG_SEC_BOOT_DEV=$(patsubst "%",%, \
|
||||
$(if $(findstring BOOT_SPI_NOR_FLASH,$(CONFIG_SPL_BOOT_DEVICE)),0x34) \
|
||||
$(if $(findstring BOOT_SDIO_MMC_CARD,$(CONFIG_SPL_BOOT_DEVICE)),0x31) \
|
||||
)
|
||||
|
||||
KWB_REPLACE += SEC_FUSE_DUMP
|
||||
KWB_CFG_SEC_FUSE_DUMP = a38x
|
||||
endif
|
||||
|
||||
$(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' \
|
||||
<$< >$(dir $<)$(@F)
|
||||
|
||||
endif
|
279
board/gdsys/a38x/controlcenterdc.c
Normal file
279
board/gdsys/a38x/controlcenterdc.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* 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 <dm.h>
|
||||
#include <miiphy.h>
|
||||
#include <tpm.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/cpu.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"
|
||||
#include "hydra.h"
|
||||
#include "ihs_phys.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
|
||||
|
||||
/*
|
||||
* 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 (!request_gpio_by_name(&gpio, "pca9698@22", 31, "fpga-program-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 (!request_gpio_by_name(&gpio, "pca9698@22", 19, "fpga-done-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 */
|
||||
if (!request_gpio_by_name(&gpio, "gpio@18100", 6, "cpu-to-fpga-reset")) {
|
||||
dm_gpio_set_dir_flags(&gpio, GPIOD_IS_OUT);
|
||||
dm_gpio_set_value(&gpio, 1);
|
||||
}
|
||||
|
||||
/* wait for FPGA ready */
|
||||
if (!request_gpio_by_name(&gpio, "pca9698@22", 27, "fpga-ready-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)
|
||||
{
|
||||
/* Address of boot parameters */
|
||||
gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
if (!get_fpga()) {
|
||||
puts("fpga was NULL\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* reset all FPGA-QSGMII instances */
|
||||
for (k = 0; k < 80; ++k)
|
||||
writel(1 << 31, get_fpga()->qsgmii_port_state[k]);
|
||||
|
||||
udelay(100);
|
||||
|
||||
for (k = 0; k < 80; ++k)
|
||||
writel(0, get_fpga()->qsgmii_port_state[k]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
hydra_initialize();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_fix_fdt(void *rw_fdt_blob)
|
||||
{
|
||||
struct udevice *bus = NULL;
|
||||
uint k;
|
||||
char name[64];
|
||||
int err;
|
||||
|
||||
err = uclass_get_device_by_name(UCLASS_I2C, "i2c@11000", &bus);
|
||||
|
||||
if (err) {
|
||||
printf("Could not get I2C bus.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
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(rw_fdt_blob, name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int last_stage_init(void)
|
||||
{
|
||||
#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;
|
||||
}
|
43
board/gdsys/a38x/dt_helpers.c
Normal file
43
board/gdsys/a38x/dt_helpers.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* (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 <fdt_support.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
#include <dm.h>
|
||||
|
||||
int fdt_disable_by_ofname(void *rw_fdt_blob, char *ofname)
|
||||
{
|
||||
int offset = fdt_path_offset(rw_fdt_blob, ofname);
|
||||
|
||||
return fdt_status_disabled(rw_fdt_blob, offset);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int request_gpio_by_name(struct gpio_desc *gpio, const char *gpio_dev_name,
|
||||
uint offset, char *gpio_name)
|
||||
{
|
||||
struct udevice *gpio_dev = NULL;
|
||||
|
||||
if (uclass_get_device_by_name(UCLASS_GPIO, gpio_dev_name, &gpio_dev))
|
||||
return 1;
|
||||
|
||||
gpio->dev = gpio_dev;
|
||||
gpio->offset = offset;
|
||||
gpio->flags = 0;
|
||||
|
||||
return dm_gpio_request(gpio, gpio_name);
|
||||
}
|
||||
|
16
board/gdsys/a38x/dt_helpers.h
Normal file
16
board/gdsys/a38x/dt_helpers.h
Normal file
|
@ -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
|
||||
|
||||
int fdt_disable_by_ofname(void *rw_fdt_blob, char *ofname);
|
||||
bool dm_i2c_simple_probe(struct udevice *bus, uint chip_addr);
|
||||
int request_gpio_by_name(struct gpio_desc *gpio, const char *gpio_dev_name,
|
||||
uint offset, char *gpio_name);
|
||||
|
||||
#endif /* __DT_HELPERS_H */
|
516
board/gdsys/a38x/hre.c
Normal file
516
board/gdsys/a38x/hre.c
Normal file
|
@ -0,0 +1,516 @@
|
|||
/*
|
||||
* (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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
38
board/gdsys/a38x/hre.h
Normal file
38
board/gdsys/a38x/hre.h
Normal file
|
@ -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 */
|
138
board/gdsys/a38x/hydra.c
Normal file
138
board/gdsys/a38x/hydra.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
#include <common.h>
|
||||
#include <console.h> /* ctrlc */
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "hydra.h"
|
||||
|
||||
enum {
|
||||
HWVER_100 = 0,
|
||||
HWVER_110 = 1,
|
||||
HWVER_120 = 2,
|
||||
};
|
||||
|
||||
static struct pci_device_id hydra_supported[] = {
|
||||
{ 0x6d5e, 0xcdc1 },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct ihs_fpga *fpga;
|
||||
|
||||
struct ihs_fpga *get_fpga(void)
|
||||
{
|
||||
return fpga;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#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"
|
||||
);
|
14
board/gdsys/a38x/hydra.h
Normal file
14
board/gdsys/a38x/hydra.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
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 */
|
||||
};
|
||||
|
||||
void print_hydra_version(uint index);
|
||||
void hydra_initialize(void);
|
||||
struct ihs_fpga *get_fpga(void);
|
355
board/gdsys/a38x/ihs_phys.c
Normal file
355
board/gdsys/a38x/ihs_phys.c
Normal file
|
@ -0,0 +1,355 @@
|
|||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <miiphy.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
#include "ihs_phys.h"
|
||||
#include "dt_helpers.h"
|
||||
|
||||
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 },
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
uint calculate_octo_phy_mask(void)
|
||||
{
|
||||
uint k;
|
||||
uint octo_phy_mask = 0;
|
||||
struct gpio_desc gpio = {};
|
||||
char gpio_name[64];
|
||||
static const char * const dev_name[] = {"pca9698@23", "pca9698@21",
|
||||
"pca9698@24", "pca9698@25",
|
||||
"pca9698@26"};
|
||||
|
||||
/* mark all octo phys that should be present */
|
||||
for (k = 0; k < 5; ++k) {
|
||||
snprintf(gpio_name, 64, "cat-gpio-%u", k);
|
||||
|
||||
if (request_gpio_by_name(&gpio, dev_name[k], 0x20, gpio_name))
|
||||
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(gpio_name, 64, "second-octo-gpio-%u", k);
|
||||
|
||||
if (request_gpio_by_name(&gpio, dev_name[k], 0x27, gpio_name)) {
|
||||
/* 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;
|
||||
|
||||
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_single_phy(struct porttype *porttype, struct mii_dev *bus,
|
||||
uint bus_idx, uint m, uint 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);
|
||||
|
||||
if (!phydev)
|
||||
puts("!");
|
||||
else
|
||||
ihs_phy_config(phydev, porttype->phy_invert_in_pol,
|
||||
porttype->phy_invert_out_pol);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
if (!m && octo_phy_mask & (0xf << octo_index)) {
|
||||
ret = register_miiphy_bus(bus_idx, &bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(octo_phy_mask & BIT(octo_index + m)))
|
||||
continue;
|
||||
|
||||
for (phy_idx = 0; phy_idx < 8; ++phy_idx)
|
||||
init_single_phy(porttype, bus, bus_idx, m,
|
||||
phy_idx);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* MII GPIO bitbang implementation
|
||||
* MDC MDIO bus
|
||||
* 13 14 PHY1-4
|
||||
* 25 45 PHY5-8
|
||||
* 46 24 PHY9-10
|
||||
*/
|
||||
|
||||
struct gpio_mii {
|
||||
int index;
|
||||
struct gpio_desc mdc_gpio;
|
||||
struct gpio_desc mdio_gpio;
|
||||
int mdc_num;
|
||||
int mdio_num;
|
||||
int mdio_value;
|
||||
} gpio_mii_set[] = {
|
||||
{ 0, {}, {}, 13, 14, 1 },
|
||||
{ 1, {}, {}, 25, 45, 1 },
|
||||
{ 2, {}, {}, 46, 24, 1 },
|
||||
};
|
||||
|
||||
static int mii_mdio_init(struct bb_miiphy_bus *bus)
|
||||
{
|
||||
struct gpio_mii *gpio_mii = bus->priv;
|
||||
char name[32] = {};
|
||||
struct udevice *gpio_dev1 = NULL;
|
||||
struct udevice *gpio_dev2 = NULL;
|
||||
|
||||
if (uclass_get_device_by_name(UCLASS_GPIO, "gpio@18100", &gpio_dev1) ||
|
||||
uclass_get_device_by_name(UCLASS_GPIO, "gpio@18140", &gpio_dev2)) {
|
||||
printf("Could not get GPIO device.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gpio_mii->mdc_num > 31) {
|
||||
gpio_mii->mdc_gpio.dev = gpio_dev2;
|
||||
gpio_mii->mdc_gpio.offset = gpio_mii->mdc_num - 32;
|
||||
} else {
|
||||
gpio_mii->mdc_gpio.dev = gpio_dev1;
|
||||
gpio_mii->mdc_gpio.offset = gpio_mii->mdc_num;
|
||||
}
|
||||
gpio_mii->mdc_gpio.flags = 0;
|
||||
snprintf(name, 32, "bb_miiphy_bus-%d-mdc", gpio_mii->index);
|
||||
dm_gpio_request(&gpio_mii->mdc_gpio, name);
|
||||
|
||||
if (gpio_mii->mdio_num > 31) {
|
||||
gpio_mii->mdio_gpio.dev = gpio_dev2;
|
||||
gpio_mii->mdio_gpio.offset = gpio_mii->mdio_num - 32;
|
||||
} else {
|
||||
gpio_mii->mdio_gpio.dev = gpio_dev1;
|
||||
gpio_mii->mdio_gpio.offset = gpio_mii->mdio_num;
|
||||
}
|
||||
gpio_mii->mdio_gpio.flags = 0;
|
||||
snprintf(name, 32, "bb_miiphy_bus-%d-mdio", gpio_mii->index);
|
||||
dm_gpio_request(&gpio_mii->mdio_gpio, name);
|
||||
|
||||
dm_gpio_set_dir_flags(&gpio_mii->mdc_gpio, GPIOD_IS_OUT);
|
||||
dm_gpio_set_value(&gpio_mii->mdc_gpio, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mii_mdio_active(struct bb_miiphy_bus *bus)
|
||||
{
|
||||
struct gpio_mii *gpio_mii = bus->priv;
|
||||
|
||||
dm_gpio_set_value(&gpio_mii->mdc_gpio, gpio_mii->mdio_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
|
||||
{
|
||||
struct gpio_mii *gpio_mii = bus->priv;
|
||||
|
||||
dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_IN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
|
||||
{
|
||||
struct gpio_mii *gpio_mii = bus->priv;
|
||||
|
||||
dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_OUT);
|
||||
dm_gpio_set_value(&gpio_mii->mdio_gpio, 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;
|
||||
|
||||
dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_IN);
|
||||
*v = (dm_gpio_get_value(&gpio_mii->mdio_gpio));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
|
||||
{
|
||||
struct gpio_mii *gpio_mii = bus->priv;
|
||||
|
||||
dm_gpio_set_value(&gpio_mii->mdc_gpio, 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 = ARRAY_SIZE(bb_miiphy_buses);
|
2
board/gdsys/a38x/ihs_phys.h
Normal file
2
board/gdsys/a38x/ihs_phys.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
uint calculate_octo_phy_mask(void);
|
||||
int init_octo_phys(uint octo_phy_mask);
|
158
board/gdsys/a38x/keyprogram.c
Normal file
158
board/gdsys/a38x/keyprogram.c
Normal file
|
@ -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;
|
||||
}
|
14
board/gdsys/a38x/keyprogram.h
Normal file
14
board/gdsys/a38x/keyprogram.h
Normal file
|
@ -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 */
|
12
board/gdsys/a38x/kwbimage.cfg.in
Normal file
12
board/gdsys/a38x/kwbimage.cfg.in
Normal file
|
@ -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
|
21
board/gdsys/a38x/spl.c
Normal file
21
board/gdsys/a38x/spl.c
Normal file
|
@ -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
|
||||
}
|
|
@ -115,6 +115,13 @@ MV_BIN_SERDES_CFG theadorable_serdes_cfg[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Define a board-specific detection pulse-width array for the SerDes PCIe
|
||||
* interfaces. If not defined in the board code, the default of currently 2
|
||||
* is used. Values from 0...3 are possible (2 bits).
|
||||
*/
|
||||
u8 serdes_pex_pulse_width[4] = { 0, 2, 2, 2 };
|
||||
|
||||
MV_DRAM_MODES *ddr3_get_static_ddr_mode(void)
|
||||
{
|
||||
/* Only one mode supported for this board */
|
||||
|
@ -287,3 +294,44 @@ int board_late_init(void)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_PCI)
|
||||
int do_pcie_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
pci_dev_t bdf;
|
||||
u16 ven_id, dev_id;
|
||||
|
||||
if (argc != 3)
|
||||
return cmd_usage(cmdtp);
|
||||
|
||||
ven_id = simple_strtoul(argv[1], NULL, 16);
|
||||
dev_id = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
printf("Checking for PCIe device: VendorID 0x%04x, DeviceId 0x%04x\n",
|
||||
ven_id, dev_id);
|
||||
|
||||
/*
|
||||
* Check if the PCIe device is detected (somtimes its not available
|
||||
* on the PCIe bus)
|
||||
*/
|
||||
bdf = pci_find_device(ven_id, dev_id, 0);
|
||||
if (bdf == -1) {
|
||||
/* PCIe device not found! */
|
||||
printf("Failed to find PCIe device\n");
|
||||
} else {
|
||||
/* PCIe device found! */
|
||||
printf("PCIe device found, resetting board...\n");
|
||||
|
||||
/* default handling: SOFT reset */
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
pcie, 3, 0, do_pcie_test,
|
||||
"Test for presence of a PCIe device",
|
||||
"<VendorID> <DeviceID>"
|
||||
);
|
||||
#endif
|
||||
|
|
|
@ -751,6 +751,13 @@ static int setup_reloc(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_FIXUP
|
||||
static int fix_fdt(void)
|
||||
{
|
||||
return board_fix_fdt((void *)gd->fdt_blob);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ARM calls relocate_code from its crt0.S */
|
||||
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
|
||||
!CONFIG_IS_ENABLED(X86_64)
|
||||
|
@ -1011,6 +1018,9 @@ static const init_fnc_t init_sequence_f[] = {
|
|||
display_new_sp,
|
||||
#ifdef CONFIG_SYS_EXTBDINFO
|
||||
setup_board_extra,
|
||||
#endif
|
||||
#ifdef CONFIG_OF_BOARD_FIXUP
|
||||
fix_fdt,
|
||||
#endif
|
||||
INIT_FUNC_WATCHDOG_RESET
|
||||
reloc_fdt,
|
||||
|
|
58
configs/controlcenterdc_defconfig
Normal file
58
configs/controlcenterdc_defconfig
Normal file
|
@ -0,0 +1,58 @@
|
|||
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="armada-38x-controlcenterdc"
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_SIGNATURE=y
|
||||
CONFIG_FIT_VERBOSE=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_EFI_PARTITION=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_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_MV=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_TPM_FLUSH_RESOURCES=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
|
|
@ -1,7 +1,7 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x2000
|
||||
CONFIG_TARGET_MVEBU_DB_88F3720=y
|
||||
CONFIG_TARGET_MVEBU_ARMADA_37XX=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="armada-3720-db"
|
||||
CONFIG_AHCI=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
|
@ -33,9 +33,11 @@ CONFIG_CMD_FS_GENERIC=y
|
|||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_ISO_PARTITION=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_CMD_MVEBU_BUBT=y
|
||||
CONFIG_SHA1=y
|
||||
CONFIG_SHA256=y
|
||||
CONFIG_BLOCK_CACHE=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_DM_I2C_COMPAT=y
|
||||
CONFIG_MISC=y
|
||||
CONFIG_DM_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
|
|
66
configs/mvebu_espressobin-88f3720_defconfig
Normal file
66
configs/mvebu_espressobin-88f3720_defconfig
Normal file
|
@ -0,0 +1,66 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x2000
|
||||
CONFIG_TARGET_MVEBU_ARMADA_37XX=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="armada-3720-espressobin"
|
||||
CONFIG_AHCI=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_ARCH_EARLY_INIT_R=y
|
||||
CONFIG_BOARD_EARLY_INIT_F=y
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_PART=y
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_SPI=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_USB=y
|
||||
# CONFIG_CMD_FPGA is not set
|
||||
# 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_EXT4=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_CMD_FS_GENERIC=y
|
||||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_ISO_PARTITION=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_CMD_MVEBU_BUBT=y
|
||||
CONFIG_SHA1=y
|
||||
CONFIG_SHA256=y
|
||||
CONFIG_BLOCK_CACHE=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_MISC=y
|
||||
CONFIG_DM_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_SDMA=y
|
||||
CONFIG_MMC_SDHCI_XENON=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_MVEBU_COMPHY_SUPPORT=y
|
||||
# CONFIG_SPL_SERIAL_PRESENT is not set
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DEBUG_MVEBU_A3700_UART=y
|
||||
CONFIG_DEBUG_UART_BASE=0xd0012000
|
||||
CONFIG_DEBUG_UART_CLOCK=25804800
|
||||
CONFIG_DEBUG_UART_SHIFT=2
|
||||
CONFIG_DEBUG_UART_ANNOUNCE=y
|
||||
CONFIG_MVEBU_A3700_UART=y
|
||||
CONFIG_MVEBU_A3700_SPI=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
74
configs/mvebu_mcbin-88f8040_defconfig
Normal file
74
configs/mvebu_mcbin-88f8040_defconfig
Normal file
|
@ -0,0 +1,74 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x2000
|
||||
CONFIG_TARGET_MVEBU_ARMADA_8K=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="armada-8040-mcbin"
|
||||
CONFIG_SMBIOS_PRODUCT_NAME=""
|
||||
CONFIG_AHCI=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_ARCH_EARLY_INIT_R=y
|
||||
CONFIG_BOARD_EARLY_INIT_F=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_PART=y
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_SPI=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_USB=y
|
||||
# CONFIG_CMD_FPGA is not set
|
||||
# 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_MVEBU_BUBT=y
|
||||
CONFIG_CMD_EXT4=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_CMD_FS_GENERIC=y
|
||||
CONFIG_MAC_PARTITION=y
|
||||
CONFIG_ISO_PARTITION=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
CONFIG_BLOCK_CACHE=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_MVTWSI=y
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_MVEBU_GPIO=y
|
||||
CONFIG_DM_REGULATOR_FIXED=y
|
||||
CONFIG_MISC=y
|
||||
CONFIG_DM_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_XENON=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_DM_PCI=y
|
||||
CONFIG_PCIE_DW_MVEBU=y
|
||||
CONFIG_MVEBU_COMPHY_SUPPORT=y
|
||||
CONFIG_PINCTRL=y
|
||||
# CONFIG_SPL_SERIAL_PRESENT is not set
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DEBUG_UART_BASE=0xf0512000
|
||||
CONFIG_DEBUG_UART_CLOCK=200000000
|
||||
CONFIG_DEBUG_UART_SHIFT=2
|
||||
CONFIG_DEBUG_UART_ANNOUNCE=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_SMBIOS_MANUFACTURER=""
|
49
doc/device-tree-bindings/pci/armada8k-pcie.txt
Normal file
49
doc/device-tree-bindings/pci/armada8k-pcie.txt
Normal file
|
@ -0,0 +1,49 @@
|
|||
Armada-8K PCIe DT details:
|
||||
==========================
|
||||
|
||||
Armada-8k uses synopsis designware PCIe controller.
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "marvell,armada8k-pcie", "snps,dw-pcie".
|
||||
- reg: base addresses and lengths of the pcie control and global control registers.
|
||||
"ctrl" registers points to the global control registers, while the "config" space
|
||||
points to the pcie configuration registers as mentioned in dw-pcie dt bindings in the link below.
|
||||
- interrupt-map-mask and interrupt-map, standard PCI properties to
|
||||
define the mapping of the PCIe interface to interrupt numbers.
|
||||
- All other definitions as per generic PCI bindings
|
||||
See Linux kernel documentation:
|
||||
"Documentation/devicetree/bindings/pci/designware-pcie.txt"
|
||||
|
||||
Optional properties:
|
||||
PHY support is still not supported for armada-8k, once it will, the following parameters can be used:
|
||||
- phys : phandle to phy node associated with pcie controller.
|
||||
- phy-names : must be "pcie-phy"
|
||||
- marvell,reset-gpio : specifies a gpio that needs to be activated for plug-in
|
||||
card reset signal release.
|
||||
Example:
|
||||
|
||||
cpm_pcie0: pcie@f2600000 {
|
||||
compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
|
||||
reg = <0 0xf2600000 0 0x10000>,
|
||||
<0 0xf6f00000 0 0x80000>;
|
||||
reg-names = "ctrl", "config";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
device_type = "pci";
|
||||
dma-coherent;
|
||||
|
||||
bus-range = <0 0xff>;
|
||||
ranges =
|
||||
/* downstream I/O */
|
||||
<0x81000000 0 0xf9000000 0 0xf9000000 0 0x10000
|
||||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xf6000000 0 0xf6000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&cpm_syscon0 1 13>;
|
||||
marvell,reset-gpio = <&cpm_gpio1 20 GPIO_ACTIVE_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
28
doc/device-tree-bindings/usb/marvell.xhci-usb.txt
Normal file
28
doc/device-tree-bindings/usb/marvell.xhci-usb.txt
Normal file
|
@ -0,0 +1,28 @@
|
|||
Marvell SOC USB controllers
|
||||
|
||||
This controller is integrated in Armada 3700/8K.
|
||||
It uses the same properties as a generic XHCI host controller
|
||||
|
||||
Required properties :
|
||||
- compatible: should be one or more of:
|
||||
- "marvell,armada3700-xhci", "generic-xhci" for Armada 37xx SoCs
|
||||
- "marvell,armada-8k-xhci", "generic-xhci" for Armada A8K SoCs
|
||||
- reg: should contain address and length of the standard XHCI
|
||||
register set for the device.
|
||||
- interrupts: one XHCI interrupt should be described here.
|
||||
|
||||
Optional properties:
|
||||
- clocks: phandle to system controller clock driving this unit
|
||||
- vbus-supply : If present, specifies the fixed regulator to be turned on
|
||||
for providing power to the USB VBUS rail.
|
||||
|
||||
Example:
|
||||
cpm_usb3_0: usb3@500000 {
|
||||
compatible = "marvell,armada-8k-xhci",
|
||||
"generic-xhci";
|
||||
reg = <0x500000 0x4000>;
|
||||
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpm_syscon0 1 22>;
|
||||
vbus-supply = <®_usb3h0_vbus>;
|
||||
status = "disabled";
|
||||
};
|
132
doc/driver-model/fdt-fixup.txt
Normal file
132
doc/driver-model/fdt-fixup.txt
Normal file
|
@ -0,0 +1,132 @@
|
|||
Pre-relocation device tree manipulation
|
||||
=======================================
|
||||
|
||||
Contents:
|
||||
|
||||
1. Purpose
|
||||
2. Implementation
|
||||
3. Example
|
||||
4. Work to be done
|
||||
|
||||
1. Purpose
|
||||
----------
|
||||
|
||||
In certain markets, it is beneficial for manufacturers of embedded devices to
|
||||
offer certain ranges of products, where the functionality of the devices within
|
||||
one series either don't differ greatly from another, or can be thought of as
|
||||
"extensions" of each other, where one device only differs from another in the
|
||||
addition of a small number of features (e.g. an additional output connector).
|
||||
|
||||
To realize this in hardware, one method is to have a motherboard, and several
|
||||
possible daughter boards that can be attached to this mother board. Different
|
||||
daughter boards then either offer the slightly different functionality, or the
|
||||
addition of the daughter board to the device realizes the "extension" of
|
||||
functionality to the device described previously.
|
||||
|
||||
For the software, we obviously want to reuse components for all these
|
||||
variations of the device. This means that the software somehow needs to cope
|
||||
with the situation that certain ICs may or may not be present on any given
|
||||
system, depending on which daughter boards are connected to the motherboard.
|
||||
|
||||
In the Linux kernel, one possible solution to this problem is to employ the
|
||||
device tree overlay mechanism: There exists one "base" device tree, which
|
||||
features only the components guaranteed to exist in all varieties of the
|
||||
device. At the start of the kernel, the presence and type of the daughter
|
||||
boards is then detected, and the corresponding device tree overlays are applied
|
||||
to support the components on the daughter boards.
|
||||
|
||||
Note that the components present on every variety of the board must, of course,
|
||||
provide a way to find out if and which daughter boards are installed for this
|
||||
mechanism to work.
|
||||
|
||||
In the U-Boot boot loader, support for device tree overlays has recently been
|
||||
integrated, and is used on some boards to alter the device tree that is later
|
||||
passed to Linux. But since U-Boot's driver model, which is device tree-based as
|
||||
well, is being used in more and more drivers, the same problem of altering the
|
||||
device tree starts cropping up in U-Boot itself as well.
|
||||
|
||||
An additional problem with the device tree in U-Boot is that it is read-only,
|
||||
and the current mechanisms don't allow easy manipulation of the device tree
|
||||
after the driver model has been initialized. While migrating to a live device
|
||||
tree (at least after the relocation) would greatly simplify the solution of
|
||||
this problem, it is a non-negligible task to implement it, an a interim
|
||||
solution is needed to address the problem at least in the medium-term.
|
||||
|
||||
Hence, we propose a solution to this problem by offering a board-specific
|
||||
call-back function, which is passed a writeable pointer to the device tree.
|
||||
This function is called before the device tree is relocated, and specifically
|
||||
before the main U-Boot's driver model is instantiated, hence the main U-Boot
|
||||
"sees" all modifications to the device tree made in this function. Furthermore,
|
||||
we have the pre-relocation driver model at our disposal at this stage, which
|
||||
means that we can query the hardware for the existence and variety of the
|
||||
components easily.
|
||||
|
||||
2. Implementation
|
||||
-----------------
|
||||
|
||||
To take advantage of the pre-relocation device tree manipulation mechanism,
|
||||
boards have to implement the function board_fix_fdt, which has the following
|
||||
signature:
|
||||
|
||||
int board_fix_fdt (void *rw_fdt_blob)
|
||||
|
||||
The passed-in void pointer is a writeable pointer to the device tree, which can
|
||||
be used to manipulate the device tree using e.g. functions from
|
||||
include/fdt_support.h. The return value should either be 0 in case of
|
||||
successful execution of the device tree manipulation or something else for a
|
||||
failure. Note that returning a non-null value from the function will
|
||||
unrecoverably halt the boot process, as with any function from init_sequence_f
|
||||
(in common/board_f.c).
|
||||
|
||||
Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the function
|
||||
to be called:
|
||||
|
||||
Device Tree Control
|
||||
-> [*] Board-specific manipulation of Device Tree
|
||||
|
||||
+----------------------------------------------------------+
|
||||
| WARNING: The actual manipulation of the device tree has |
|
||||
| to be the _last_ set of operations in board_fix_fdt! |
|
||||
| Since the pre-relocation driver model does not adapt to |
|
||||
| changes made to the device tree either, its references |
|
||||
| into the device tree will be invalid after manipulating |
|
||||
| it, and unpredictable behavior might occur when |
|
||||
| functions that rely on them are executed! |
|
||||
+----------------------------------------------------------+
|
||||
|
||||
Hence, the recommended layout of the board_fixup_fdt call-back function is the
|
||||
following:
|
||||
|
||||
int board_fix_fdt(void *rw_fdt_blob)
|
||||
{
|
||||
/* Collect information about device's hardware and store them in e.g.
|
||||
local variables */
|
||||
|
||||
/* Do device tree manipulation using the values previously collected */
|
||||
|
||||
/* Return 0 on successful manipulation and non-zero otherwise */
|
||||
}
|
||||
|
||||
If this convention is kept, both an "additive" approach, meaning that nodes for
|
||||
detected components are added to the device tree, as well as a "subtractive"
|
||||
approach, meaning that nodes for absent components are removed from the tree,
|
||||
as well as a combination of both approaches should work.
|
||||
|
||||
3. Example
|
||||
----------
|
||||
|
||||
The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features a
|
||||
board_fix_fdt function, in which six GPIO expanders (which might be present or
|
||||
not, since they are on daughter boards) on a I2C bus are queried for, and
|
||||
subsequently deactivated in the device tree if they are not present.
|
||||
|
||||
Note that the dm_i2c_simple_probe function does not use the device tree, hence
|
||||
it is safe to call it after the tree has already been manipulated.
|
||||
|
||||
4. Work to be done
|
||||
------------------
|
||||
|
||||
* The application of device tree overlay should be possible in board_fixup_fdt,
|
||||
but has not been tested at this stage.
|
||||
|
||||
2017-01-06, Mario Six <mario.six@gdsys.cc>
|
|
@ -191,11 +191,16 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
#define MVNETA_GMAC_AUTONEG_CONFIG 0x2c0c
|
||||
#define MVNETA_GMAC_FORCE_LINK_DOWN BIT(0)
|
||||
#define MVNETA_GMAC_FORCE_LINK_PASS BIT(1)
|
||||
#define MVNETA_GMAC_FORCE_LINK_UP (BIT(0) | BIT(1))
|
||||
#define MVNETA_GMAC_IB_BYPASS_AN_EN BIT(3)
|
||||
#define MVNETA_GMAC_CONFIG_MII_SPEED BIT(5)
|
||||
#define MVNETA_GMAC_CONFIG_GMII_SPEED BIT(6)
|
||||
#define MVNETA_GMAC_AN_SPEED_EN BIT(7)
|
||||
#define MVNETA_GMAC_SET_FC_EN BIT(8)
|
||||
#define MVNETA_GMAC_ADVERT_FC_EN BIT(9)
|
||||
#define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12)
|
||||
#define MVNETA_GMAC_AN_DUPLEX_EN BIT(13)
|
||||
#define MVNETA_GMAC_SAMPLE_TX_CFG_EN BIT(15)
|
||||
#define MVNETA_MIB_COUNTERS_BASE 0x3080
|
||||
#define MVNETA_MIB_LATE_COLLISION 0x7c
|
||||
#define MVNETA_DA_FILT_SPEC_MCAST 0x3400
|
||||
|
@ -404,6 +409,15 @@ static struct buffer_location buffer_loc;
|
|||
*/
|
||||
#define BD_SPACE (1 << 20)
|
||||
|
||||
/*
|
||||
* Dummy implementation that can be overwritten by a board
|
||||
* specific function
|
||||
*/
|
||||
__weak int board_network_enable(struct mii_dev *bus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Utility/helper methods */
|
||||
|
||||
/* Write helper method */
|
||||
|
@ -557,6 +571,13 @@ static void mvneta_rxq_buf_size_set(struct mvneta_port *pp,
|
|||
mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), val);
|
||||
}
|
||||
|
||||
static int mvneta_port_is_fixed_link(struct mvneta_port *pp)
|
||||
{
|
||||
/* phy_addr is set to invalid value for fixed link */
|
||||
return pp->phyaddr > PHY_MAX_ADDR;
|
||||
}
|
||||
|
||||
|
||||
/* Start the Ethernet port RX and TX activity */
|
||||
static void mvneta_port_up(struct mvneta_port *pp)
|
||||
{
|
||||
|
@ -807,10 +828,12 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
|
|||
/* Assign port SDMA configuration */
|
||||
mvreg_write(pp, MVNETA_SDMA_CONFIG, val);
|
||||
|
||||
/* Enable PHY polling in hardware for U-Boot */
|
||||
val = mvreg_read(pp, MVNETA_UNIT_CONTROL);
|
||||
val |= MVNETA_PHY_POLLING_ENABLE;
|
||||
mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
|
||||
/* Enable PHY polling in hardware if not in fixed-link mode */
|
||||
if (!mvneta_port_is_fixed_link(pp)) {
|
||||
val = mvreg_read(pp, MVNETA_UNIT_CONTROL);
|
||||
val |= MVNETA_PHY_POLLING_ENABLE;
|
||||
mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
|
||||
}
|
||||
|
||||
mvneta_set_ucast_table(pp, -1);
|
||||
mvneta_set_special_mcast_table(pp, -1);
|
||||
|
@ -1128,6 +1151,11 @@ static void mvneta_adjust_link(struct udevice *dev)
|
|||
struct phy_device *phydev = pp->phydev;
|
||||
int status_change = 0;
|
||||
|
||||
if (mvneta_port_is_fixed_link(pp)) {
|
||||
debug("Using fixed link, skip link adjust\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (phydev->link) {
|
||||
if ((pp->speed != phydev->speed) ||
|
||||
(pp->duplex != phydev->duplex)) {
|
||||
|
@ -1498,28 +1526,54 @@ static int mvneta_start(struct udevice *dev)
|
|||
mvneta_port_power_up(pp, pp->phy_interface);
|
||||
|
||||
if (!pp->init || pp->link == 0) {
|
||||
/* Set phy address of the port */
|
||||
mvreg_write(pp, MVNETA_PHY_ADDR, pp->phyaddr);
|
||||
phydev = phy_connect(pp->bus, pp->phyaddr, dev,
|
||||
pp->phy_interface);
|
||||
if (mvneta_port_is_fixed_link(pp)) {
|
||||
u32 val;
|
||||
|
||||
pp->phydev = phydev;
|
||||
phy_config(phydev);
|
||||
phy_startup(phydev);
|
||||
if (!phydev->link) {
|
||||
printf("%s: No link.\n", phydev->dev->name);
|
||||
return -1;
|
||||
pp->init = 1;
|
||||
pp->link = 1;
|
||||
mvneta_init(dev);
|
||||
|
||||
val = MVNETA_GMAC_FORCE_LINK_UP |
|
||||
MVNETA_GMAC_IB_BYPASS_AN_EN |
|
||||
MVNETA_GMAC_SET_FC_EN |
|
||||
MVNETA_GMAC_ADVERT_FC_EN |
|
||||
MVNETA_GMAC_SAMPLE_TX_CFG_EN;
|
||||
|
||||
if (pp->duplex)
|
||||
val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
|
||||
|
||||
if (pp->speed == SPEED_1000)
|
||||
val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
|
||||
else if (pp->speed == SPEED_100)
|
||||
val |= MVNETA_GMAC_CONFIG_MII_SPEED;
|
||||
|
||||
mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
|
||||
} else {
|
||||
/* Set phy address of the port */
|
||||
mvreg_write(pp, MVNETA_PHY_ADDR, pp->phyaddr);
|
||||
|
||||
phydev = phy_connect(pp->bus, pp->phyaddr, dev,
|
||||
pp->phy_interface);
|
||||
|
||||
pp->phydev = phydev;
|
||||
phy_config(phydev);
|
||||
phy_startup(phydev);
|
||||
if (!phydev->link) {
|
||||
printf("%s: No link.\n", phydev->dev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Full init on first call */
|
||||
mvneta_init(dev);
|
||||
pp->init = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Full init on first call */
|
||||
mvneta_init(dev);
|
||||
pp->init = 1;
|
||||
} else {
|
||||
/* Upon all following calls, this is enough */
|
||||
mvneta_port_up(pp);
|
||||
mvneta_port_enable(pp);
|
||||
}
|
||||
|
||||
/* Upon all following calls, this is enough */
|
||||
mvneta_port_up(pp);
|
||||
mvneta_port_enable(pp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1615,6 +1669,8 @@ static int mvneta_probe(struct udevice *dev)
|
|||
struct mii_dev *bus;
|
||||
unsigned long addr;
|
||||
void *bd_space;
|
||||
int ret;
|
||||
int fl_node;
|
||||
|
||||
/*
|
||||
* Allocate buffer area for descs and rx_buffers. This is only
|
||||
|
@ -1647,10 +1703,19 @@ static int mvneta_probe(struct udevice *dev)
|
|||
/* PHY interface is already decoded in mvneta_ofdata_to_platdata() */
|
||||
pp->phy_interface = pdata->phy_interface;
|
||||
|
||||
/* Now read phyaddr from DT */
|
||||
addr = fdtdec_get_int(blob, node, "phy", 0);
|
||||
addr = fdt_node_offset_by_phandle(blob, addr);
|
||||
pp->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
|
||||
/* fetch 'fixed-link' property from 'neta' node */
|
||||
fl_node = fdt_subnode_offset(blob, node, "fixed-link");
|
||||
if (fl_node != -FDT_ERR_NOTFOUND) {
|
||||
/* set phy_addr to invalid value for fixed link */
|
||||
pp->phyaddr = PHY_MAX_ADDR + 1;
|
||||
pp->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
|
||||
pp->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
|
||||
} else {
|
||||
/* Now read phyaddr from DT */
|
||||
addr = fdtdec_get_int(blob, node, "phy", 0);
|
||||
addr = fdt_node_offset_by_phandle(blob, addr);
|
||||
pp->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
|
||||
}
|
||||
|
||||
bus = mdio_alloc();
|
||||
if (!bus) {
|
||||
|
@ -1664,7 +1729,11 @@ static int mvneta_probe(struct udevice *dev)
|
|||
bus->priv = (void *)pp;
|
||||
pp->bus = bus;
|
||||
|
||||
return mdio_register(bus);
|
||||
ret = mdio_register(bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return board_network_enable(bus);
|
||||
}
|
||||
|
||||
static void mvneta_stop(struct udevice *dev)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <dm.h>
|
||||
#include <pci.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -461,6 +462,25 @@ static int pcie_dw_mvebu_probe(struct udevice *dev)
|
|||
struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
|
||||
struct udevice *ctlr = pci_get_controller(dev);
|
||||
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
|
||||
#ifdef CONFIG_DM_GPIO
|
||||
struct gpio_desc reset_gpio;
|
||||
|
||||
gpio_request_by_name(dev, "marvell,reset-gpio", 0, &reset_gpio,
|
||||
GPIOD_IS_OUT);
|
||||
/*
|
||||
* Issue reset to add-in card trough the dedicated GPIO.
|
||||
* Some boards are connecting the card reset pin to common system
|
||||
* reset wire and others are using separate GPIO port.
|
||||
* In the last case we have to release a reset of the addon card
|
||||
* using this GPIO.
|
||||
*/
|
||||
if (dm_gpio_is_valid(&reset_gpio)) {
|
||||
dm_gpio_set_value(&reset_gpio, 1);
|
||||
mdelay(200);
|
||||
}
|
||||
#else
|
||||
debug("PCIE Reset on GPIO support is missing\n");
|
||||
#endif /* CONFIG_DM_GPIO */
|
||||
|
||||
pcie->first_busno = dev->seq;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ config USB_XHCI_MVEBU
|
|||
bool "MVEBU USB 3.0 support"
|
||||
default y
|
||||
depends on ARCH_MVEBU
|
||||
select DM_REGULATOR
|
||||
help
|
||||
Choose this option to add support for USB 3.0 driver on mvebu
|
||||
SoCs, which includes Armada8K, Armada3700 and other Armada
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <usb.h>
|
||||
#include <power/regulator.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
#include "xhci.h"
|
||||
|
@ -44,12 +45,22 @@ static int xhci_usb_probe(struct udevice *dev)
|
|||
struct mvebu_xhci_platdata *plat = dev_get_platdata(dev);
|
||||
struct mvebu_xhci *ctx = dev_get_priv(dev);
|
||||
struct xhci_hcor *hcor;
|
||||
int len;
|
||||
int len, ret;
|
||||
struct udevice *regulator;
|
||||
|
||||
ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
|
||||
len = HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase));
|
||||
hcor = (struct xhci_hcor *)((uintptr_t)ctx->hcd + len);
|
||||
|
||||
ret = device_get_supply_regulator(dev, "vbus-supply", ®ulator);
|
||||
if (!ret) {
|
||||
ret = regulator_set_enable(regulator, true);
|
||||
if (ret) {
|
||||
printf("Failed to turn ON the VBUS regulator\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable USB xHCI (VBUS, reset etc) in board specific code */
|
||||
board_xhci_enable();
|
||||
|
||||
|
|
10
dts/Kconfig
10
dts/Kconfig
|
@ -14,6 +14,16 @@ config OF_CONTROL
|
|||
This feature provides for run-time configuration of U-Boot
|
||||
via a flattened device tree.
|
||||
|
||||
config OF_BOARD_FIXUP
|
||||
bool "Board-specific manipulation of Device Tree"
|
||||
help
|
||||
In certain circumstances it is necessary to be able to modify
|
||||
U-Boot's device tree (e.g. to delete device from it). This option
|
||||
make the Device Tree writeable and provides a board-specific
|
||||
"board_fix_fdt" callback (called during pre-relocation time), which
|
||||
enables the board initialization to modifiy the Device Tree. The
|
||||
modified copy is subsequently used by U-Boot after relocation.
|
||||
|
||||
config SPL_OF_CONTROL
|
||||
bool "Enable run-time configuration via Device Tree in SPL"
|
||||
depends on SPL && OF_CONTROL
|
||||
|
|
|
@ -497,6 +497,7 @@ extern ssize_t spi_write (uchar *, int, uchar *, int);
|
|||
|
||||
/* $(BOARD)/$(BOARD).c */
|
||||
int board_early_init_f (void);
|
||||
int board_fix_fdt (void *rw_fdt_blob); /* manipulate the U-Boot fdt before its relocation */
|
||||
int board_late_init (void);
|
||||
int board_postclk_init (void); /* after clocks/timebase, before env/serial */
|
||||
int board_early_init_r (void);
|
||||
|
|
228
include/configs/controlcenterdc.h
Normal file
228
include/configs/controlcenterdc.h
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* 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_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)
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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)
|
||||
#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 */
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_MVEBU_DB_88F3720_H
|
||||
#define _CONFIG_MVEBU_DB_88F3720_H
|
||||
#ifndef _CONFIG_MVEBU_ARMADA_37XX_H
|
||||
#define _CONFIG_MVEBU_ARMADA_37XX_H
|
||||
|
||||
/*
|
||||
* High Level Configuration Options (easy to change)
|
||||
|
@ -92,6 +92,7 @@
|
|||
#define CONFIG_PHY_GIGE /* GbE speed/duplex detect */
|
||||
#define CONFIG_ARP_TIMEOUT 200
|
||||
#define CONFIG_NET_RETRY_COUNT 50
|
||||
#define CONFIG_PHY_MARVELL
|
||||
|
||||
/* USB 2.0 */
|
||||
#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
|
||||
|
@ -126,4 +127,4 @@
|
|||
|
||||
#define CONFIG_SUPPORT_VFAT
|
||||
|
||||
#endif /* _CONFIG_MVEBU_DB_88F3720_H */
|
||||
#endif /* _CONFIG_MVEBU_ARMADA_37XX_H */
|
Loading…
Reference in a new issue