mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
Merge tag 'u-boot-marvell-next-20260610' of https://source.denx.de/u-boot/custodians/u-boot-marvell into next
CI: https://source.denx.de/u-boot/custodians/u-boot-marvell/-/pipelines/30414 u-boot-marvell changes 2026-06-10: - arm: kirkwood: Remove unnecessary watchdog GPIO for ZyXEL NSA325 board (Tony) - net: mvpp2: fix NULL pointer dereference in mvpp2_phy_connect (Vincent) - mtd: nand: pxa3xx: Pass valid dev to dev_err() (Chris) - arm: mvebu: db-xc3-24g4xg: Remove marvell, nand-keep-config (Chris) - arm: mvebu: Add Allied Telesis x220 (Chris) - board: Synology: legacy.c: Include asm/io.h (Phil) - board: Synology: common: Fix typo in Makefile (Phil) - serial: serial_octeon_bootcmd.c: use correct Kconfig symbol (Heinrich) - arm: mvebu: Drop unnecessary BOARD_EARLY_INIT_F usage (Tom) - pinctrl: armada-38x: Staticize and constify driver ops (Marek) - arm: mach-mvebu: armada8k: cpuinfo and SAR (Vincent) - board: freebox: add Nodebox 10G board support (Vincent) - board: freebox: nbx10g: add emmcboot for dual-bank eMMC boot (Vincent) - board: freebox: nbx10g: add device serial and MAC address initialization (Vincent) - arm: dts: armada-8040-nbx: add U-Boot dtsi for conditional OP-TEE (Vincent) - timer: orion: Use dev_remap_addr_index() (Peng)
This commit is contained in:
@@ -137,6 +137,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \
|
||||
armada-388-gp.dtb \
|
||||
armada-388-helios4.dtb \
|
||||
armada-38x-controlcenterdc.dtb \
|
||||
armada-xp-atl-x220.dtb \
|
||||
armada-xp-crs305-1g-4s.dtb \
|
||||
armada-xp-crs305-1g-4s-bit.dtb \
|
||||
armada-xp-crs326-24g-2s.dtb \
|
||||
@@ -162,6 +163,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \
|
||||
armada-8040-clearfog-gt-8k.dtb \
|
||||
armada-8040-db.dtb \
|
||||
armada-8040-mcbin.dtb \
|
||||
armada-8040-nbx.dtb \
|
||||
armada-8040-puzzle-m801.dtb \
|
||||
cn9130-db-A.dtb \
|
||||
cn9130-db-B.dtb \
|
||||
|
||||
15
arch/arm/dts/armada-8040-nbx-u-boot.dtsi
Normal file
15
arch/arm/dts/armada-8040-nbx-u-boot.dtsi
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2026 Free Mobile, Vincent Jardin
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_OPTEE
|
||||
/ {
|
||||
firmware {
|
||||
optee {
|
||||
compatible = "linaro,optee-tz";
|
||||
method = "smc";
|
||||
};
|
||||
};
|
||||
};
|
||||
#endif
|
||||
259
arch/arm/dts/armada-8040-nbx.dts
Normal file
259
arch/arm/dts/armada-8040-nbx.dts
Normal file
@@ -0,0 +1,259 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Device Tree file for NBX board (Freebox Nodebox10G)
|
||||
* Based on Marvell Armada 8040 SoC
|
||||
*
|
||||
* Copyright (C) 2024
|
||||
*/
|
||||
|
||||
#include "armada-8040.dtsi"
|
||||
|
||||
/ {
|
||||
model = "NBX Armada 8040";
|
||||
compatible = "nbx,armada8040", "marvell,armada8040";
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
aliases {
|
||||
i2c0 = &cp0_i2c0;
|
||||
i2c1 = &cp0_i2c1;
|
||||
gpio0 = &ap_gpio0;
|
||||
gpio1 = &cp0_gpio0;
|
||||
gpio2 = &cp0_gpio1;
|
||||
};
|
||||
|
||||
memory@00000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x0 0x0 0x80000000>; /* 2GB */
|
||||
};
|
||||
};
|
||||
|
||||
/* AP806 UART - active */
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* AP806 pinctrl */
|
||||
&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 >;
|
||||
};
|
||||
|
||||
/* AP806 on-board eMMC */
|
||||
&ap_sdhci0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ap_emmc_pins>;
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CP0 pinctrl */
|
||||
&cp0_pinctl {
|
||||
/*
|
||||
* MPP Bus:
|
||||
* [0-31] = 0xff: Keep default CP0_shared_pins
|
||||
* [32,34] GE_MDIO/MDC
|
||||
* [35-36] I2C1
|
||||
* [37-38] I2C0
|
||||
* [57-58] MSS I2C
|
||||
*/
|
||||
/* 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 0xff 7 0 7 2 2 2 2 0
|
||||
0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 2 2 0
|
||||
0 0 0 >;
|
||||
|
||||
cp0_smi_pins: cp0-smi-pins {
|
||||
marvell,pins = <32 34>;
|
||||
marvell,function = <7>;
|
||||
};
|
||||
};
|
||||
|
||||
/* CP0 I2C0 */
|
||||
&cp0_i2c0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cp0_i2c0_pins>;
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
||||
/* CP0 I2C1 */
|
||||
&cp0_i2c1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cp0_i2c1_pins>;
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
||||
/* CP0 MSS I2C0 - Management SubSystem I2C (pins 57-58, func 2) */
|
||||
&cp0_mss_i2c0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CP0 MDIO for PHY */
|
||||
&cp0_mdio {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cp0_smi_pins>;
|
||||
|
||||
nbx_phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
/* CP0 ComPhy - SerDes configuration */
|
||||
&cp0_comphy {
|
||||
/*
|
||||
* CP0 Serdes Configuration:
|
||||
* Lane 0-3: Unconnected
|
||||
* Lane 4: SFI (10G Ethernet)
|
||||
* Lane 5: SGMII2 (1G Ethernet)
|
||||
*/
|
||||
phy0 {
|
||||
phy-type = <COMPHY_TYPE_UNCONNECTED>;
|
||||
};
|
||||
phy1 {
|
||||
phy-type = <COMPHY_TYPE_UNCONNECTED>;
|
||||
};
|
||||
phy2 {
|
||||
phy-type = <COMPHY_TYPE_UNCONNECTED>;
|
||||
};
|
||||
phy3 {
|
||||
phy-type = <COMPHY_TYPE_UNCONNECTED>;
|
||||
};
|
||||
phy4 {
|
||||
phy-type = <COMPHY_TYPE_SFI0>;
|
||||
phy-speed = <COMPHY_SPEED_10_3125G>;
|
||||
};
|
||||
phy5 {
|
||||
phy-type = <COMPHY_TYPE_SGMII2>;
|
||||
phy-speed = <COMPHY_SPEED_1_25G>;
|
||||
};
|
||||
};
|
||||
|
||||
/* CP0 Ethernet - only eth2 (MAC3) is active via SGMII */
|
||||
&cp0_ethernet {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cp0_eth2 {
|
||||
status = "okay";
|
||||
phy = <&nbx_phy0>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
|
||||
/* CP0 UTMI PHY for USB */
|
||||
&cp0_utmi {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cp0_utmi0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cp0_utmi1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CP0 USB3 Host controllers */
|
||||
&cp0_usb3_0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cp0_usb3_1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CP1 pinctrl */
|
||||
&cp1_pinctl {
|
||||
/*
|
||||
* MPP Bus:
|
||||
* [0-26] = Unconfigured
|
||||
* [27-28] GE_MDIO/MDC
|
||||
* [29-30] MSS I2C
|
||||
* [31] = Unconfigured
|
||||
* [32-62] = 0xff: Keep default CP1_shared_pins
|
||||
*/
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
pin-func = < 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
|
||||
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
|
||||
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x8 0x8 0x8
|
||||
0x8 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>;
|
||||
|
||||
cp1_mss_i2c_pins: cp1-mss-i2c-pins {
|
||||
marvell,pins = <29 30>;
|
||||
marvell,function = <8>;
|
||||
};
|
||||
};
|
||||
|
||||
/* CP1 MSS I2C0 - Management SubSystem I2C (pins 29-30, func 8) */
|
||||
&cp1_mss_i2c0 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cp1_mss_i2c_pins>;
|
||||
};
|
||||
|
||||
/* CP1 ComPhy - SerDes configuration */
|
||||
&cp1_comphy {
|
||||
/*
|
||||
* CP1 Serdes Configuration:
|
||||
* Lane 0: PCIe x1
|
||||
* Lane 1: USB3 Host
|
||||
* Lane 2-3: Unconnected
|
||||
* Lane 4: SFI (10G Ethernet)
|
||||
* Lane 5: Unconnected
|
||||
*/
|
||||
phy0 {
|
||||
phy-type = <COMPHY_TYPE_PEX0>;
|
||||
};
|
||||
phy1 {
|
||||
phy-type = <COMPHY_TYPE_USB3_HOST0>;
|
||||
};
|
||||
phy2 {
|
||||
phy-type = <COMPHY_TYPE_UNCONNECTED>;
|
||||
};
|
||||
phy3 {
|
||||
phy-type = <COMPHY_TYPE_UNCONNECTED>;
|
||||
};
|
||||
phy4 {
|
||||
phy-type = <COMPHY_TYPE_SFI0>;
|
||||
phy-speed = <COMPHY_SPEED_10_3125G>;
|
||||
};
|
||||
phy5 {
|
||||
phy-type = <COMPHY_TYPE_UNCONNECTED>;
|
||||
};
|
||||
};
|
||||
|
||||
/* CP1 PCIe x1 on lane 0 */
|
||||
&cp1_pcie0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CP1 USB3 Host on lane 1 */
|
||||
&cp1_usb3_0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* CP1 UTMI PHY for USB */
|
||||
&cp1_utmi {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cp1_utmi0 {
|
||||
status = "okay";
|
||||
};
|
||||
162
arch/arm/dts/armada-xp-atl-x220.dts
Normal file
162
arch/arm/dts/armada-xp-atl-x220.dts
Normal file
@@ -0,0 +1,162 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Device Tree file for x220 board
|
||||
*
|
||||
* Copyright (C) 2025 Allied Telesis Labs
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include "armada-xp-98dx3236.dtsi"
|
||||
#include "mvebu-u-boot.dtsi"
|
||||
|
||||
/ {
|
||||
model = "x220";
|
||||
compatible = "marvell,armadaxp-98dx3236", "marvell,armadaxp-mv78260",
|
||||
"marvell,armadaxp", "marvell,armada-370-xp";
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
bootargs = "console=ttyS0,115200";
|
||||
};
|
||||
|
||||
aliases {
|
||||
i2c0 = &i2c0;
|
||||
spi0 = &spi0;
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&L2 {
|
||||
arm,parity-enable;
|
||||
marvell,ecc-enable;
|
||||
};
|
||||
|
||||
&devbus_bootcs {
|
||||
status = "okay";
|
||||
|
||||
/* Device Bus parameters are required */
|
||||
|
||||
/* Read parameters */
|
||||
devbus,bus-width = <16>;
|
||||
devbus,turn-off-ps = <60000>;
|
||||
devbus,badr-skew-ps = <0>;
|
||||
devbus,acc-first-ps = <124000>;
|
||||
devbus,acc-next-ps = <248000>;
|
||||
devbus,rd-setup-ps = <0>;
|
||||
devbus,rd-hold-ps = <0>;
|
||||
|
||||
/* Write parameters */
|
||||
devbus,sync-enable = <0>;
|
||||
devbus,wr-high-ps = <60000>;
|
||||
devbus,wr-low-ps = <60000>;
|
||||
devbus,ale-wr-ps = <60000>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
rtc@68 {
|
||||
compatible = "dallas,ds1340";
|
||||
reg = <0x68>;
|
||||
};
|
||||
|
||||
adt7476a@2e {
|
||||
compatible = "adi,adt7476";
|
||||
reg = <0x2e>;
|
||||
};
|
||||
|
||||
sfpgpio: gpio@27 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nxp,pca9555";
|
||||
reg = <0x27>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
systemgpio: gpio@25 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nxp,pca9555";
|
||||
reg = <0x25>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
nand-protect {
|
||||
gpio-hog;
|
||||
gpios = <6 GPIO_ACTIVE_HIGH>;
|
||||
output-high;
|
||||
line-name = "nand-protect";
|
||||
};
|
||||
|
||||
usb-enable {
|
||||
gpio-hog;
|
||||
gpios = <9 GPIO_ACTIVE_HIGH>;
|
||||
output-high;
|
||||
line-name = "usb-enable";
|
||||
};
|
||||
|
||||
phy-reset {
|
||||
gpio-hog;
|
||||
gpios = <5 GPIO_ACTIVE_LOW>;
|
||||
output-high;
|
||||
line-name = "phy-reset";
|
||||
};
|
||||
|
||||
led-enable {
|
||||
gpio-hog;
|
||||
gpios = <13 GPIO_ACTIVE_HIGH>;
|
||||
output-low;
|
||||
line-name = "led-enable";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&watchdog {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-flash", "jedec,spi-nor";
|
||||
reg = <0>; /* Chip select 0 */
|
||||
spi-max-frequency = <20000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&nand_controller {
|
||||
compatible = "marvell,armada370-nand-controller";
|
||||
label = "pxa3xx_nand-0";
|
||||
status = "okay";
|
||||
nand-rb = <0>;
|
||||
nand-on-flash-bbt;
|
||||
nand-ecc-strength = <4>;
|
||||
nand-ecc-step-size = <512>;
|
||||
};
|
||||
|
||||
&{/} {
|
||||
boot-board {
|
||||
compatible = "atl,boot-board";
|
||||
present-gpio = <&systemgpio 12 GPIO_ACTIVE_HIGH>;
|
||||
override-gpio = <&gpio0 31 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
status = "okay";
|
||||
label = "pxa3xx_nand-0";
|
||||
nand-rb = <0>;
|
||||
marvell,nand-keep-config;
|
||||
nand-on-flash-bbt;
|
||||
nand-ecc-strength = <4>;
|
||||
nand-ecc-step-size = <512>;
|
||||
|
||||
@@ -166,6 +166,14 @@ config TARGET_MVEBU_ARMADA_8K
|
||||
select BOARD_LATE_INIT
|
||||
imply SCSI
|
||||
|
||||
config TARGET_NBX10G
|
||||
bool "Support Freebox Nodebox 10G"
|
||||
select ARMADA_8K
|
||||
select BOARD_LATE_INIT
|
||||
help
|
||||
Enable support for the Freebox Nodebox 10G board based on the
|
||||
Marvell Armada 8040 SoC with dual CP110 companion chips.
|
||||
|
||||
config TARGET_MVEBU_ALLEYCAT5
|
||||
bool "Support AlleyCat 5 platforms"
|
||||
select ALLEYCAT_5
|
||||
@@ -226,6 +234,10 @@ config TARGET_X240
|
||||
select ALLEYCAT_5
|
||||
imply BOOTSTD_DEFAULTS
|
||||
|
||||
config TARGET_X220
|
||||
bool "Support Allied Telesis x220"
|
||||
select 98DX3336
|
||||
|
||||
config TARGET_DB_XC3_24G4XG
|
||||
bool "Support DB-XC3-24G4XG"
|
||||
select 98DX3336
|
||||
@@ -310,6 +322,7 @@ config SYS_BOARD
|
||||
default "x530" if TARGET_X530
|
||||
default "x250" if TARGET_X250
|
||||
default "x240" if TARGET_X240
|
||||
default "x220" if TARGET_X220
|
||||
default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG
|
||||
default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236
|
||||
default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5
|
||||
@@ -335,6 +348,7 @@ config SYS_CONFIG_NAME
|
||||
default "x530" if TARGET_X530
|
||||
default "x250" if TARGET_X250
|
||||
default "x240" if TARGET_X240
|
||||
default "x220" if TARGET_X220
|
||||
default "db-xc3-24g4xg" if TARGET_DB_XC3_24G4XG
|
||||
default "crs3xx-98dx3236" if TARGET_CRS3XX_98DX3236
|
||||
default "mvebu_alleycat-5" if TARGET_MVEBU_ALLEYCAT5
|
||||
@@ -360,6 +374,7 @@ config SYS_VENDOR
|
||||
default "alliedtelesis" if TARGET_X530
|
||||
default "alliedtelesis" if TARGET_X250
|
||||
default "alliedtelesis" if TARGET_X240
|
||||
default "alliedtelesis" if TARGET_X220
|
||||
default "mikrotik" if TARGET_CRS3XX_98DX3236
|
||||
default "Marvell" if TARGET_MVEBU_ALLEYCAT5
|
||||
|
||||
@@ -508,5 +523,6 @@ config ARMADA_32BIT_SYSCON_SYSRESET
|
||||
|
||||
source "board/solidrun/clearfog/Kconfig"
|
||||
source "board/kobol/helios4/Kconfig"
|
||||
source "board/freebox/nbx10g/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
#
|
||||
# Copyright (C) 2016 Stefan Roese <sr@denx.de>
|
||||
|
||||
obj-y = cpu.o cache_llc.o dram.o
|
||||
obj-y = cpu.o cache_llc.o dram.o soc_info.o
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <asm/armv8/mmu.h>
|
||||
#include <mach/fw_info.h>
|
||||
|
||||
#include "soc_info.h"
|
||||
|
||||
/* Armada 7k/8k */
|
||||
#define MVEBU_RFU_BASE (MVEBU_REGISTER(0x6f0000))
|
||||
#define RFU_GLOBAL_SW_RST (MVEBU_RFU_BASE + 0x84)
|
||||
@@ -111,3 +113,13 @@ int mmc_get_env_dev(void)
|
||||
|
||||
return CONFIG_ENV_MMC_DEVICE_INDEX;
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_DISPLAY_CPUINFO))
|
||||
return 0;
|
||||
|
||||
soc_print_clock_info();
|
||||
soc_print_soc_info();
|
||||
return 0;
|
||||
}
|
||||
|
||||
194
arch/arm/mach-mvebu/armada8k/soc_info.c
Normal file
194
arch/arm/mach-mvebu/armada8k/soc_info.c
Normal file
@@ -0,0 +1,194 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2015 Marvell International Ltd.
|
||||
*
|
||||
* Marvell Armada 8K SoC info: SAR, Clock frequencies, LLC status
|
||||
* Ported from Marvell U-Boot 2015.01 to mainline U-Boot.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <stdio.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/soc.h>
|
||||
|
||||
/* Clock frequency units */
|
||||
#define KHz 1000
|
||||
#define MHz 1000000
|
||||
#define GHz 1000000000
|
||||
|
||||
/* AP806 SAR (Sample-At-Reset) register */
|
||||
#define AP806_SAR_REG_BASE (SOC_REGS_PHY_BASE + 0x6F4400)
|
||||
#define SAR_CLOCK_FREQ_MODE_OFFSET 0
|
||||
#define SAR_CLOCK_FREQ_MODE_MASK (0x1f << SAR_CLOCK_FREQ_MODE_OFFSET)
|
||||
|
||||
/* LLC (Last Level Cache) registers */
|
||||
#define LLC_BASE (SOC_REGS_PHY_BASE + 0x8000)
|
||||
#define LLC_CTRL 0x100
|
||||
#define LLC_CTRL_EN 0x1
|
||||
#define LLC_EXCLUSIVE_EN 0x100
|
||||
|
||||
/* MSS clock is fixed at 200MHz on AP806 */
|
||||
#define AP806_MSS_CLOCK (200 * MHz)
|
||||
|
||||
/* Clock ID indices in PLL frequency table */
|
||||
#define CPU_CLOCK_ID 0
|
||||
#define DDR_CLOCK_ID 1
|
||||
#define RING_CLOCK_ID 2
|
||||
|
||||
/* Clocking options (SAR field values) */
|
||||
enum clocking_options {
|
||||
CPU_2000_DDR_1200_RCLK_1200 = 0x0,
|
||||
CPU_2000_DDR_1050_RCLK_1050 = 0x1,
|
||||
CPU_1600_DDR_800_RCLK_800 = 0x4,
|
||||
CPU_1800_DDR_1200_RCLK_1200 = 0x6,
|
||||
CPU_1800_DDR_1050_RCLK_1050 = 0x7,
|
||||
CPU_1600_DDR_900_RCLK_900 = 0x0b,
|
||||
CPU_1600_DDR_1050_RCLK_1050 = 0x0d,
|
||||
CPU_1600_DDR_900_RCLK_900_2 = 0x0e,
|
||||
CPU_1000_DDR_650_RCLK_650 = 0x13,
|
||||
CPU_1300_DDR_800_RCLK_800 = 0x14,
|
||||
CPU_1300_DDR_650_RCLK_650 = 0x17,
|
||||
CPU_1200_DDR_800_RCLK_800 = 0x19,
|
||||
CPU_1400_DDR_800_RCLK_800 = 0x1a,
|
||||
CPU_600_DDR_800_RCLK_800 = 0x1b,
|
||||
CPU_800_DDR_800_RCLK_800 = 0x1c,
|
||||
CPU_1000_DDR_800_RCLK_800 = 0x1d,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL frequency table: maps SAR clock mode to actual frequencies.
|
||||
* Format: { CPU_freq, DDR_freq, RING_freq, SAR_value }
|
||||
*/
|
||||
static const u32 pll_freq_tbl[16][4] = {
|
||||
/* CPU */ /* DDR */ /* Ring */
|
||||
{2000 * MHz, 1200 * MHz, 1200 * MHz, CPU_2000_DDR_1200_RCLK_1200},
|
||||
{2000 * MHz, 1050 * MHz, 1050 * MHz, CPU_2000_DDR_1050_RCLK_1050},
|
||||
{1800 * MHz, 1200 * MHz, 1200 * MHz, CPU_1800_DDR_1200_RCLK_1200},
|
||||
{1800 * MHz, 1050 * MHz, 1050 * MHz, CPU_1800_DDR_1050_RCLK_1050},
|
||||
{1600 * MHz, 1050 * MHz, 1050 * MHz, CPU_1600_DDR_1050_RCLK_1050},
|
||||
{1600 * MHz, 900 * MHz, 900 * MHz, CPU_1600_DDR_900_RCLK_900_2},
|
||||
{1300 * MHz, 800 * MHz, 800 * MHz, CPU_1300_DDR_800_RCLK_800},
|
||||
{1300 * MHz, 650 * MHz, 650 * MHz, CPU_1300_DDR_650_RCLK_650},
|
||||
{1600 * MHz, 800 * MHz, 800 * MHz, CPU_1600_DDR_800_RCLK_800},
|
||||
{1600 * MHz, 900 * MHz, 900 * MHz, CPU_1600_DDR_900_RCLK_900},
|
||||
{1000 * MHz, 650 * MHz, 650 * MHz, CPU_1000_DDR_650_RCLK_650},
|
||||
{1200 * MHz, 800 * MHz, 800 * MHz, CPU_1200_DDR_800_RCLK_800},
|
||||
{1400 * MHz, 800 * MHz, 800 * MHz, CPU_1400_DDR_800_RCLK_800},
|
||||
{600 * MHz, 800 * MHz, 800 * MHz, CPU_600_DDR_800_RCLK_800},
|
||||
{800 * MHz, 800 * MHz, 800 * MHz, CPU_800_DDR_800_RCLK_800},
|
||||
{1000 * MHz, 800 * MHz, 800 * MHz, CPU_1000_DDR_800_RCLK_800}
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the clock frequency mode index from SAR register.
|
||||
* Returns index into pll_freq_tbl, or -1 if not found.
|
||||
*/
|
||||
static int sar_get_clock_freq_mode(void)
|
||||
{
|
||||
u32 i;
|
||||
u32 clock_freq;
|
||||
|
||||
clock_freq = (readl(AP806_SAR_REG_BASE) & SAR_CLOCK_FREQ_MODE_MASK)
|
||||
>> SAR_CLOCK_FREQ_MODE_OFFSET;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pll_freq_tbl); i++) {
|
||||
if (pll_freq_tbl[i][3] == clock_freq)
|
||||
return i;
|
||||
}
|
||||
|
||||
pr_err("SAR: unsupported clock freq mode %d\n", clock_freq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get CPU clock frequency in Hz.
|
||||
*/
|
||||
static u32 soc_cpu_clk_get(void)
|
||||
{
|
||||
int mode = sar_get_clock_freq_mode();
|
||||
|
||||
if (mode < 0)
|
||||
return 0;
|
||||
return pll_freq_tbl[mode][CPU_CLOCK_ID];
|
||||
}
|
||||
|
||||
/*
|
||||
* Get DDR clock frequency in Hz.
|
||||
*/
|
||||
static u32 soc_ddr_clk_get(void)
|
||||
{
|
||||
int mode = sar_get_clock_freq_mode();
|
||||
|
||||
if (mode < 0)
|
||||
return 0;
|
||||
return pll_freq_tbl[mode][DDR_CLOCK_ID];
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Ring (Fabric) clock frequency in Hz.
|
||||
*/
|
||||
static u32 soc_ring_clk_get(void)
|
||||
{
|
||||
int mode = sar_get_clock_freq_mode();
|
||||
|
||||
if (mode < 0)
|
||||
return 0;
|
||||
return pll_freq_tbl[mode][RING_CLOCK_ID];
|
||||
}
|
||||
|
||||
/*
|
||||
* Get MSS clock frequency in Hz.
|
||||
*/
|
||||
static u32 soc_mss_clk_get(void)
|
||||
{
|
||||
return AP806_MSS_CLOCK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get LLC status and mode.
|
||||
* Returns 1 if LLC is enabled, 0 otherwise.
|
||||
* If excl_mode is not NULL, sets it to 1 if exclusive mode is enabled.
|
||||
*/
|
||||
static int llc_mode_get(int *excl_mode)
|
||||
{
|
||||
u32 val;
|
||||
int ret = 0, excl = 0;
|
||||
|
||||
val = readl(LLC_BASE + LLC_CTRL);
|
||||
if (val & LLC_CTRL_EN) {
|
||||
ret = 1;
|
||||
if (val & LLC_EXCLUSIVE_EN)
|
||||
excl = 1;
|
||||
}
|
||||
if (excl_mode)
|
||||
*excl_mode = excl;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print SoC clock information.
|
||||
*/
|
||||
void soc_print_clock_info(void)
|
||||
{
|
||||
printf("Clock: CPU %-4d [MHz]\n", soc_cpu_clk_get() / MHz);
|
||||
printf("\tDDR %-4d [MHz]\n", soc_ddr_clk_get() / MHz);
|
||||
printf("\tFABRIC %-4d [MHz]\n", soc_ring_clk_get() / MHz);
|
||||
printf("\tMSS %-4d [MHz]\n", soc_mss_clk_get() / MHz);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print SoC-specific information: DDR width and LLC status.
|
||||
*/
|
||||
void soc_print_soc_info(void)
|
||||
{
|
||||
int llc_en, llc_excl_mode;
|
||||
|
||||
printf("\tDDR 64 Bit width\n");
|
||||
|
||||
llc_en = llc_mode_get(&llc_excl_mode);
|
||||
printf("\tLLC %s%s\n", llc_en ? "Enabled" : "Disabled",
|
||||
llc_excl_mode ? " (Exclusive Mode)" : "");
|
||||
}
|
||||
14
arch/arm/mach-mvebu/armada8k/soc_info.h
Normal file
14
arch/arm/mach-mvebu/armada8k/soc_info.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2015 Marvell International Ltd.
|
||||
*
|
||||
* Marvell Armada 8K SoC info functions
|
||||
*/
|
||||
|
||||
#ifndef _ARMADA8K_SOC_INFO_H_
|
||||
#define _ARMADA8K_SOC_INFO_H_
|
||||
|
||||
void soc_print_clock_info(void);
|
||||
void soc_print_soc_info(void);
|
||||
|
||||
#endif /* _ARMADA8K_SOC_INFO_H_ */
|
||||
@@ -102,11 +102,6 @@ static bool is_edpu_plus(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
#
|
||||
# Copyright (C) 2021 Phil Sutter <phil@nwl.cc>
|
||||
|
||||
obj-$(SUPPORT_PASSING_ATAGS) += legacy.o
|
||||
obj-$(CONFIG_SUPPORT_PASSING_ATAGS) += legacy.o
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <vsprintf.h>
|
||||
#include <env.h>
|
||||
#include <net.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include "legacy.h"
|
||||
|
||||
1
board/alliedtelesis/x220/.gitattributes
vendored
Normal file
1
board/alliedtelesis/x220/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
binary.0 binary
|
||||
1
board/alliedtelesis/x220/.gitignore
vendored
Normal file
1
board/alliedtelesis/x220/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
kwbimage.cfg
|
||||
8
board/alliedtelesis/x220/MAINTAINERS
Normal file
8
board/alliedtelesis/x220/MAINTAINERS
Normal file
@@ -0,0 +1,8 @@
|
||||
x220 BOARD
|
||||
M: Chris Packham <chris.packham@alliedtelesis.co.nz>
|
||||
S: Maintained
|
||||
F: board/alliedtelesis/x220
|
||||
F: include/configs/x220.h
|
||||
F: configs/x220_defconfig
|
||||
F: arch/arm/dts/armada-xp-atl-x220.dts
|
||||
F: doc/board/alliedtelesis/x220.rst
|
||||
14
board/alliedtelesis/x220/Makefile
Normal file
14
board/alliedtelesis/x220/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2025 Allied Telesis Labs
|
||||
|
||||
obj-y := x220.o
|
||||
extra-y := kwbimage.cfg
|
||||
|
||||
quiet_cmd_sed = SED $@
|
||||
cmd_sed = sed $(SEDFLAGS_$(@F)) $< >$(dir $@)$(@F)
|
||||
|
||||
SEDFLAGS_kwbimage.cfg =-e "s|^BINARY.*|BINARY $(srctree)/$(@D)/binary.0 0000005b 00000068|"
|
||||
$(obj)/kwbimage.cfg: $(src)/kwbimage.cfg.in include/autoconf.mk \
|
||||
include/config/auto.conf
|
||||
$(call if_changed,sed)
|
||||
11
board/alliedtelesis/x220/binary.0
Normal file
11
board/alliedtelesis/x220/binary.0
Normal file
@@ -0,0 +1,11 @@
|
||||
--------
|
||||
WARNING:
|
||||
--------
|
||||
This file should contain the bin_hdr generated by the original Marvell
|
||||
U-Boot implementation. As this is currently not included in this
|
||||
U-Boot version, we have added this placeholder, so that the U-Boot
|
||||
image can be generated without errors.
|
||||
|
||||
If you have a known to be working bin_hdr for your board, then you
|
||||
just need to replace this text file here with the binary header
|
||||
and recompile U-Boot.
|
||||
12
board/alliedtelesis/x220/kwbimage.cfg.in
Normal file
12
board/alliedtelesis/x220/kwbimage.cfg.in
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# Copyright (C) 2025 Allied Telesis Labs
|
||||
#
|
||||
|
||||
# Armada XP uses version 1 image format
|
||||
VERSION 1
|
||||
|
||||
# Boot Media configurations
|
||||
BOOT_FROM spi
|
||||
|
||||
# Binary Header (bin_hdr) with DDR3 training code
|
||||
BINARY board/alliedtelesis/x220/binary.0 0000005b 00000068
|
||||
67
board/alliedtelesis/x220/x220.c
Normal file
67
board/alliedtelesis/x220/x220.c
Normal file
@@ -0,0 +1,67 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2025 Allied Telesis Labs
|
||||
*/
|
||||
|
||||
#include <i2c.h>
|
||||
#include <init.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mbus.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/soc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define X220_GPP_OUT_ENA_LOW (~(BIT(12) | BIT(17) | BIT(18) | BIT(31)))
|
||||
#define X220_GPP_OUT_ENA_MID (~(0))
|
||||
#define X220_GPP_OUT_VAL_LOW (BIT(12) | BIT(18))
|
||||
#define X220_GPP_OUT_VAL_MID 0x0
|
||||
#define X220_GPP_POL_LOW 0x0
|
||||
#define X220_GPP_POL_MID 0x0
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
/* Configure MPP */
|
||||
writel(0x44042222, MVEBU_MPP_BASE + 0x00);
|
||||
writel(0x11000004, MVEBU_MPP_BASE + 0x04);
|
||||
writel(0x44444004, MVEBU_MPP_BASE + 0x08);
|
||||
writel(0x04444444, MVEBU_MPP_BASE + 0x0c);
|
||||
writel(0x00000004, MVEBU_MPP_BASE + 0x10);
|
||||
|
||||
/* Set GPP Out value */
|
||||
writel(X220_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
|
||||
writel(X220_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
|
||||
|
||||
/* Set GPP Polarity */
|
||||
writel(X220_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
|
||||
writel(X220_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);
|
||||
|
||||
/* Set GPP Out Enable */
|
||||
writel(X220_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
|
||||
writel(X220_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* address of boot parameters */
|
||||
gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
|
||||
|
||||
/* Disable MBUS Err Prop - in order to avoid data aborts */
|
||||
clrbits_le32(MVEBU_CPU_WIN_BASE + 0x200, (1 << 8));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DISPLAY_BOARDINFO
|
||||
int checkboard(void)
|
||||
{
|
||||
puts("Board: Allied Telesis x220\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
94
board/freebox/nbx10g/Kconfig
Normal file
94
board/freebox/nbx10g/Kconfig
Normal file
@@ -0,0 +1,94 @@
|
||||
if TARGET_NBX10G
|
||||
|
||||
config SYS_BOARD
|
||||
default "nbx10g"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "freebox"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "nbx10g"
|
||||
|
||||
config CMD_NBX_EMMCBOOT
|
||||
bool "emmcboot command"
|
||||
depends on MMC_SDHCI_XENON
|
||||
help
|
||||
Enable the emmcboot command for dual-bank boot from eMMC.
|
||||
This is a legacy boot format used on this board for many years.
|
||||
It implements a boot system with two image banks and automatic
|
||||
fallback on boot failures. The boot order depends on a reboot
|
||||
tracking counter (nrboot):
|
||||
- If healthy: try Bank1 (newer) first, then Bank0 (stable)
|
||||
- If degraded (>= 4 failures): try Bank0 first, then Bank1
|
||||
|
||||
Requires image_addr and fdt_addr environment variables to be set.
|
||||
|
||||
if CMD_NBX_EMMCBOOT
|
||||
|
||||
config NBX_MMC_PART_NRBOOT_OFFSET
|
||||
hex "NRBoot counter offset in eMMC"
|
||||
default 0x802000
|
||||
help
|
||||
Byte offset in eMMC where the reboot tracking counter is stored.
|
||||
Default: 0x802000 (8MB + 8KB)
|
||||
|
||||
config NBX_MMC_PART_BANK0_OFFSET
|
||||
hex "Bank0 image offset in eMMC"
|
||||
default 0x804000
|
||||
help
|
||||
Byte offset in eMMC where the stable (Bank0) boot image starts.
|
||||
Default: 0x804000 (8MB + 16KB)
|
||||
|
||||
config NBX_MMC_PART_BANK0_SIZE
|
||||
hex "Bank0 image maximum size"
|
||||
default 0x10000000
|
||||
help
|
||||
Maximum size of the Bank0 boot image.
|
||||
Default: 0x10000000 (256MB)
|
||||
|
||||
config NBX_MMC_PART_BANK1_OFFSET
|
||||
hex "Bank1 image offset in eMMC"
|
||||
default 0x10804000
|
||||
help
|
||||
Byte offset in eMMC where the newer (Bank1) boot image starts.
|
||||
Default: 0x10804000 (264MB + 16KB)
|
||||
|
||||
config NBX_MMC_PART_BANK1_SIZE
|
||||
hex "Bank1 image maximum size"
|
||||
default 0x10000000
|
||||
help
|
||||
Maximum size of the Bank1 boot image.
|
||||
Default: 0x10000000 (256MB)
|
||||
|
||||
endif
|
||||
|
||||
config CMD_NBX_FBXSERIAL
|
||||
bool "fbxserial command"
|
||||
depends on MMC_SDHCI_XENON
|
||||
help
|
||||
Enable the fbxserial command to read and display device
|
||||
serial information from eMMC. This includes:
|
||||
- Device serial number (type, version, manufacturer, date, number)
|
||||
- MAC address (used to set ethaddr environment variables)
|
||||
- Bundle information (if present)
|
||||
|
||||
The serial info is stored at a fixed offset in the eMMC user area.
|
||||
|
||||
Subcommands:
|
||||
- fbxserial show: display serial info (default)
|
||||
- fbxserial init: initialize ethaddr from serial info
|
||||
|
||||
Use CONFIG_PREBOOT="fbxserial init" to auto-initialize at boot.
|
||||
|
||||
if CMD_NBX_FBXSERIAL
|
||||
|
||||
config NBX_MMC_PART_SERIAL_OFFSET
|
||||
hex "Serial info offset in eMMC"
|
||||
default 0x800000
|
||||
help
|
||||
Byte offset in eMMC where the serial info structure is stored.
|
||||
Default: 0x800000 (8MB)
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
6
board/freebox/nbx10g/MAINTAINERS
Normal file
6
board/freebox/nbx10g/MAINTAINERS
Normal file
@@ -0,0 +1,6 @@
|
||||
NBX10G BOARD
|
||||
M: Vincent Jardin <vjardin@free.fr>
|
||||
S: Maintained
|
||||
F: board/freebox/nbx10g/
|
||||
F: configs/mvebu_nbx_88f8040_defconfig
|
||||
F: arch/arm/dts/armada-8040-nbx*
|
||||
5
board/freebox/nbx10g/Makefile
Normal file
5
board/freebox/nbx10g/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
obj-y := board.o
|
||||
obj-$(CONFIG_CMD_NBX_EMMCBOOT) += nbx_emmcboot.o
|
||||
obj-$(CONFIG_CMD_NBX_FBXSERIAL) += nbx_fbxserial.o
|
||||
53
board/freebox/nbx10g/board.c
Normal file
53
board/freebox/nbx10g/board.c
Normal file
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2017-2018 Freebox SA
|
||||
* Copyright (C) 2026 Free Mobile, Vincent Jardin <vjardin@free.fr>
|
||||
*
|
||||
* Freebox Nodebox 10G board support
|
||||
*/
|
||||
|
||||
#include <init.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
/* Management PHY reset GPIO */
|
||||
#define NBX_PHY_RESET_GPIO 83
|
||||
|
||||
/* Nodebox 10G ASCII art logo */
|
||||
static const char * const nbx_logo =
|
||||
" _ _ _ _ __ ___ _____\n"
|
||||
" | \\ | | | | | | /_ |/ _ \\ / ____|\n"
|
||||
" | \\| | ___ __| | ___| |__ _____ __ | | | | | | __\n"
|
||||
" | . ` |/ _ \\ / _` |/ _ \\ '_ \\ / _ \\ \\/ / | | | | | | |_ |\n"
|
||||
" | |\\ | (_) | (_| | __/ |_) | (_) > < | | |_| | |__| |\n"
|
||||
" |_| \\_|\\___/ \\__,_|\\___|_.__/ \\___/_/\\_\\ |_|\\___/ \\_____|\n";
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("%s\n", nbx_logo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Reset the management PHY */
|
||||
ret = gpio_request(NBX_PHY_RESET_GPIO, "phy-reset");
|
||||
if (ret) {
|
||||
printf("Failed to request PHY reset GPIO: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gpio_direction_output(NBX_PHY_RESET_GPIO, 0);
|
||||
mdelay(100);
|
||||
gpio_set_value(NBX_PHY_RESET_GPIO, 1);
|
||||
mdelay(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
357
board/freebox/nbx10g/nbx_emmcboot.c
Normal file
357
board/freebox/nbx10g/nbx_emmcboot.c
Normal file
@@ -0,0 +1,357 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Nodebox 10G dual-bank eMMC boot command with automatic fallback
|
||||
*
|
||||
* Copyright (C) 2026 Free Mobile, Freebox
|
||||
*
|
||||
* This implements a dual-bank boot system with automatic fallback:
|
||||
* - Bank0: Stable/fallback boot image
|
||||
* - Bank1: Newer/test boot image
|
||||
*
|
||||
* The boot order depends on the reboot tracking counter (nrboot):
|
||||
* - If healthy: try Bank1 first, then Bank0
|
||||
* - If degraded (>= 4 failures): try Bank0 first, then Bank1
|
||||
*/
|
||||
|
||||
#include <command.h>
|
||||
#include <env.h>
|
||||
#include <mmc.h>
|
||||
#include <malloc.h>
|
||||
#include <memalign.h>
|
||||
#include <vsprintf.h>
|
||||
#include <u-boot/crc.h>
|
||||
#include <u-boot/schedule.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/errno.h>
|
||||
#include "nbx_imagetag.h"
|
||||
#include "nbx_nrboot.h"
|
||||
|
||||
/* Partition offsets defined in Kconfig (CONFIG_NBX_MMC_PART_*) */
|
||||
|
||||
/* Image Tag Functions */
|
||||
|
||||
static int mvebu_imagetag_check(struct mvebu_image_tag *tag,
|
||||
unsigned long maxsize, const char *name)
|
||||
{
|
||||
if (be32_to_cpu(tag->magic) != MVEBU_IMAGE_TAG_MAGIC) {
|
||||
if (name)
|
||||
printf("%s: invalid TAG magic: %.8x\n", name,
|
||||
be32_to_cpu(tag->magic));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (be32_to_cpu(tag->version) != MVEBU_IMAGE_TAG_VERSION) {
|
||||
if (name)
|
||||
printf("%s: invalid TAG version: %.8x\n", name,
|
||||
be32_to_cpu(tag->version));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (be32_to_cpu(tag->total_size) < sizeof(*tag)) {
|
||||
if (name)
|
||||
printf("%s: tag size is too small!\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (be32_to_cpu(tag->total_size) > maxsize) {
|
||||
if (name)
|
||||
printf("%s: tag size is too big!\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (be32_to_cpu(tag->device_tree_offset) < sizeof(*tag) ||
|
||||
be32_to_cpu(tag->device_tree_offset) +
|
||||
be32_to_cpu(tag->device_tree_size) > maxsize) {
|
||||
if (name)
|
||||
printf("%s: bogus device tree offset/size!\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (be32_to_cpu(tag->kernel_offset) < sizeof(*tag) ||
|
||||
be32_to_cpu(tag->kernel_offset) +
|
||||
be32_to_cpu(tag->kernel_size) > maxsize) {
|
||||
if (name)
|
||||
printf("%s: bogus kernel offset/size!\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (be32_to_cpu(tag->rootfs_offset) < sizeof(*tag) ||
|
||||
be32_to_cpu(tag->rootfs_offset) +
|
||||
be32_to_cpu(tag->rootfs_size) > maxsize) {
|
||||
if (name)
|
||||
printf("%s: bogus rootfs offset/size!\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
/*
|
||||
* Ensure null-termination within the 32-byte fields
|
||||
* before printing to avoid displaying garbage.
|
||||
*/
|
||||
tag->image_name[sizeof(tag->image_name) - 1] = '\0';
|
||||
tag->build_date[sizeof(tag->build_date) - 1] = '\0';
|
||||
tag->build_user[sizeof(tag->build_user) - 1] = '\0';
|
||||
|
||||
printf("%s: Found valid tag: %s / %s / %s\n", name,
|
||||
tag->image_name, tag->build_date, tag->build_user);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mvebu_imagetag_crc(struct mvebu_image_tag *tag, const char *name)
|
||||
{
|
||||
u32 crc = ~0;
|
||||
|
||||
crc = crc32(crc, ((unsigned char *)tag) + 4,
|
||||
be32_to_cpu(tag->total_size) - 4);
|
||||
|
||||
if (be32_to_cpu(tag->crc) != crc) {
|
||||
if (name)
|
||||
printf("%s: invalid tag CRC!\n", name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* NRBoot (Reboot Tracking) Functions */
|
||||
|
||||
struct mvebu_nrboot {
|
||||
u16 nrboot;
|
||||
u16 nrsuccess;
|
||||
};
|
||||
|
||||
#define MVEBU_MAX_FAILURE 4
|
||||
|
||||
static int mvebu_count_bits(u16 val)
|
||||
{
|
||||
int i, found = 0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (val & (1 << i))
|
||||
found++;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int mvebu_check_nrboot(struct mmc *mmc, unsigned long offset)
|
||||
{
|
||||
struct blk_desc *bd = mmc_get_blk_desc(mmc);
|
||||
struct mvebu_nrboot *nr;
|
||||
uint blk_start = ALIGN(offset, bd->blksz) / bd->blksz;
|
||||
uint blk_cnt = ALIGN(sizeof(*nr), bd->blksz) / bd->blksz;
|
||||
uint n;
|
||||
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, buf, blk_cnt * bd->blksz);
|
||||
nr = (void *)buf;
|
||||
|
||||
n = blk_dread(bd, blk_start, blk_cnt, buf);
|
||||
if (n != blk_cnt)
|
||||
return 0;
|
||||
|
||||
printf(" - nr.nrboot = %04x\n", nr->nrboot);
|
||||
printf(" - nr.nrsuccess = %04x\n", nr->nrsuccess);
|
||||
|
||||
/* Sanity check on values */
|
||||
if (mvebu_count_bits(~nr->nrboot + 1) <= 1 &&
|
||||
mvebu_count_bits(~nr->nrsuccess + 1) <= 1) {
|
||||
int boot, success;
|
||||
|
||||
boot = 16 - mvebu_count_bits(nr->nrboot);
|
||||
success = 16 - mvebu_count_bits(nr->nrsuccess);
|
||||
|
||||
printf(" - Nrboot: %d / Nrsuccess: %d\n", boot, success);
|
||||
|
||||
if (boot == 16 || boot < success ||
|
||||
boot - success >= MVEBU_MAX_FAILURE) {
|
||||
printf(" - Nrboot exceeded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Increment boot attempt counter */
|
||||
boot++;
|
||||
nr->nrboot = ~((1 << boot) - 1);
|
||||
|
||||
printf(" - Setting Nrboot to %d\n", boot);
|
||||
|
||||
n = blk_dwrite(bd, blk_start, blk_cnt, buf);
|
||||
if (n != blk_cnt)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf(" - Invalid NR values\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* emmcboot Command */
|
||||
|
||||
static void mvebu_try_emmcboot(struct mmc *mmc, unsigned long offset,
|
||||
unsigned long maxsize, const char *bank)
|
||||
{
|
||||
struct blk_desc *bd = mmc_get_blk_desc(mmc);
|
||||
struct mvebu_image_tag *tag;
|
||||
ulong image_addr = 0;
|
||||
ulong fdt_addr = 0;
|
||||
ulong tag_addr;
|
||||
uint tag_blk_start = ALIGN(offset, bd->blksz) / bd->blksz;
|
||||
uint tag_blk_cnt = ALIGN(sizeof(*tag), bd->blksz) / bd->blksz;
|
||||
uint n;
|
||||
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, tag_buf, tag_blk_cnt * bd->blksz);
|
||||
tag = (void *)tag_buf;
|
||||
|
||||
schedule();
|
||||
|
||||
printf("## Trying %s boot...\n", bank);
|
||||
|
||||
/* Load tag header */
|
||||
n = blk_dread(bd, tag_blk_start, tag_blk_cnt, tag_buf);
|
||||
if (n != tag_blk_cnt) {
|
||||
printf("%s: failed to read tag header\n", bank);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mvebu_imagetag_check(tag, maxsize, bank) != 0)
|
||||
return;
|
||||
|
||||
if (tag->rootfs_size != 0) {
|
||||
printf("%s: rootfs in tag not supported\n", bank);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get image and device tree load addresses from environment */
|
||||
image_addr = env_get_ulong("image_addr", 16, 0);
|
||||
if (!image_addr) {
|
||||
puts("emmcboot needs image_addr\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fdt_addr = env_get_ulong("fdt_addr", 16, 0);
|
||||
if (!fdt_addr) {
|
||||
puts("emmcboot needs fdt_addr\n");
|
||||
return;
|
||||
}
|
||||
|
||||
tag_addr = image_addr;
|
||||
|
||||
/* Load full image, temporarily reuse image_addr for this */
|
||||
{
|
||||
uint data_blk_start = ALIGN(offset, bd->blksz) / bd->blksz;
|
||||
uint data_blk_cnt = ALIGN(mvebu_imagetag_total_size(tag),
|
||||
bd->blksz) / bd->blksz;
|
||||
|
||||
n = blk_dread(bd, data_blk_start, data_blk_cnt, (void *)tag_addr);
|
||||
if (n != data_blk_cnt) {
|
||||
printf("%s: failed to read full image\n", bank);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mvebu_imagetag_crc((void *)tag_addr, bank) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
schedule();
|
||||
|
||||
/* Copy image and device tree to the right addresses */
|
||||
/* We assume that image_addr + tag_size < fdt_addr */
|
||||
{
|
||||
tag = (void *)tag_addr;
|
||||
memcpy((void *)fdt_addr,
|
||||
((void *)tag_addr) + mvebu_imagetag_device_tree_offset(tag),
|
||||
mvebu_imagetag_device_tree_size(tag));
|
||||
memmove((void *)image_addr,
|
||||
((void *)tag_addr) + mvebu_imagetag_kernel_offset(tag),
|
||||
mvebu_imagetag_kernel_size(tag));
|
||||
}
|
||||
|
||||
schedule();
|
||||
|
||||
/* Set bootargs and boot */
|
||||
{
|
||||
char bootargs[256];
|
||||
char *console_env;
|
||||
|
||||
console_env = env_get("console");
|
||||
if (console_env)
|
||||
snprintf(bootargs, sizeof(bootargs), "%s bank=%s",
|
||||
console_env, bank);
|
||||
else
|
||||
snprintf(bootargs, sizeof(bootargs), "bank=%s", bank);
|
||||
|
||||
env_set("bootargs", bootargs);
|
||||
|
||||
printf("## Booting kernel from %s...\n", bank);
|
||||
printf(" Image addr: 0x%lx\n", image_addr);
|
||||
printf(" FDT addr: 0x%lx\n", fdt_addr);
|
||||
|
||||
/* Build and run booti command */
|
||||
{
|
||||
char cmd[128];
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "booti 0x%lx - 0x%lx",
|
||||
image_addr, fdt_addr);
|
||||
run_command(cmd, 0);
|
||||
}
|
||||
}
|
||||
|
||||
printf("## %s boot failed\n", bank);
|
||||
}
|
||||
|
||||
static int do_emmcboot(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
int dev;
|
||||
struct mmc *mmc;
|
||||
|
||||
dev = 0;
|
||||
if (argc >= 2)
|
||||
dev = dectoul(argv[1], NULL);
|
||||
|
||||
mmc = find_mmc_device(dev);
|
||||
if (!mmc) {
|
||||
printf("No MMC device %d found\n", dev);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
if (mmc_init(mmc)) {
|
||||
puts("MMC init failed\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
/* Switch to partition 0 (user data area) */
|
||||
if (blk_select_hwpart_devnum(UCLASS_MMC, dev, 0)) {
|
||||
puts("MMC partition switch failed\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
if (mvebu_check_nrboot(mmc, CONFIG_NBX_MMC_PART_NRBOOT_OFFSET)) {
|
||||
/* System is healthy: try newer bank first */
|
||||
mvebu_try_emmcboot(mmc, CONFIG_NBX_MMC_PART_BANK1_OFFSET,
|
||||
CONFIG_NBX_MMC_PART_BANK1_SIZE, "bank1");
|
||||
mvebu_try_emmcboot(mmc, CONFIG_NBX_MMC_PART_BANK0_OFFSET,
|
||||
CONFIG_NBX_MMC_PART_BANK0_SIZE, "bank0");
|
||||
} else {
|
||||
/* System is degraded: use stable bank first */
|
||||
mvebu_try_emmcboot(mmc, CONFIG_NBX_MMC_PART_BANK0_OFFSET,
|
||||
CONFIG_NBX_MMC_PART_BANK0_SIZE, "bank0");
|
||||
mvebu_try_emmcboot(mmc, CONFIG_NBX_MMC_PART_BANK1_OFFSET,
|
||||
CONFIG_NBX_MMC_PART_BANK1_SIZE, "bank1");
|
||||
}
|
||||
|
||||
puts("emmcboot: all boot attempts failed\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
emmcboot, 2, 0, do_emmcboot,
|
||||
"boot from MVEBU eMMC image banks",
|
||||
"[dev]\n"
|
||||
" - Boot from eMMC device <dev> (default 0)\n"
|
||||
" - Requires image_addr and fdt_addr environment variables\n"
|
||||
" - Uses dual-bank boot with automatic fallback\n"
|
||||
" - Bank selection based on reboot tracking (nrboot)"
|
||||
);
|
||||
286
board/freebox/nbx10g/nbx_fbxserial.c
Normal file
286
board/freebox/nbx10g/nbx_fbxserial.c
Normal file
@@ -0,0 +1,286 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* NBX Freebox Serial Info Support
|
||||
*
|
||||
* Copyright (C) 2025 Free Mobile, Freebox
|
||||
*
|
||||
* Reads device serial number and MAC address from eMMC.
|
||||
* The serial info is stored at a fixed offset in the eMMC user area.
|
||||
*
|
||||
* Serial format: TTTT-VV-M-(YY)WW-NN-NNNNN / FLAGS
|
||||
* Where:
|
||||
* TTTT = Device type (e.g., 9018)
|
||||
* VV = Board version
|
||||
* M = Manufacturer code (ASCII)
|
||||
* YY = Year (BCD)
|
||||
* WW = Week (1-53)
|
||||
* NNNNN = Serial number
|
||||
* FLAGS = Feature flags
|
||||
*/
|
||||
|
||||
#include <command.h>
|
||||
#include <dm/device.h>
|
||||
#include <env.h>
|
||||
#include <event.h>
|
||||
#include <mmc.h>
|
||||
#include <malloc.h>
|
||||
#include <memalign.h>
|
||||
#include <vsprintf.h>
|
||||
#include <u-boot/crc.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/errno.h>
|
||||
#include "nbx_fbxserial.h"
|
||||
|
||||
/* Partition offset defined in Kconfig (CONFIG_NBX_MMC_PART_SERIAL_OFFSET) */
|
||||
|
||||
/*
|
||||
* Validate serial info structure
|
||||
*/
|
||||
static int nbx_fbx_check_serial(struct nbx_fbx_serial *fs)
|
||||
{
|
||||
unsigned int sum, len;
|
||||
|
||||
/* Check magic first */
|
||||
if (be32_to_cpu(fs->magic) != NBX_FBXSERIAL_MAGIC) {
|
||||
printf("Invalid magic for serial info (%08x != %08x)!\n",
|
||||
be32_to_cpu(fs->magic), NBX_FBXSERIAL_MAGIC);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check struct version */
|
||||
if (be32_to_cpu(fs->struct_version) > NBX_FBXSERIAL_VERSION) {
|
||||
printf("Version too big for fbxserial info (0x%08x)!\n",
|
||||
be32_to_cpu(fs->struct_version));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check for silly len */
|
||||
len = be32_to_cpu(fs->len);
|
||||
if (len > NBX_FBXSERIAL_MAX_SIZE) {
|
||||
printf("Silly len for serial info (%d)\n", len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Validate CRC (crc32_no_comp: no one's complement) */
|
||||
sum = crc32_no_comp(0, (void *)fs + 4, len - 4);
|
||||
if (be32_to_cpu(fs->crc32) != sum) {
|
||||
printf("Invalid checksum for serial info (%08x != %08x)\n",
|
||||
sum, be32_to_cpu(fs->crc32));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nbx_fbx_read_serial(int dev_num, unsigned long offset,
|
||||
struct nbx_fbx_serial *fs)
|
||||
{
|
||||
struct mmc *mmc;
|
||||
struct blk_desc *bd;
|
||||
uint blk_start, blk_cnt;
|
||||
uint n;
|
||||
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, buf, ALIGN(sizeof(*fs), 512));
|
||||
mmc = find_mmc_device(dev_num);
|
||||
if (!mmc) {
|
||||
printf("No MMC device %d found\n", dev_num);
|
||||
nbx_fbxserial_set_default(fs);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (mmc_init(mmc)) {
|
||||
puts("MMC init failed\n");
|
||||
nbx_fbxserial_set_default(fs);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Switch to partition 0 (user data area) */
|
||||
if (blk_select_hwpart_devnum(UCLASS_MMC, dev_num, 0)) {
|
||||
puts("MMC partition switch failed\n");
|
||||
nbx_fbxserial_set_default(fs);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
bd = mmc_get_blk_desc(mmc);
|
||||
if (!bd) {
|
||||
puts("Failed to get MMC block descriptor\n");
|
||||
nbx_fbxserial_set_default(fs);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
blk_start = ALIGN(offset, bd->blksz) / bd->blksz;
|
||||
blk_cnt = ALIGN(sizeof(*fs), bd->blksz) / bd->blksz;
|
||||
|
||||
memset(fs, 0x42, sizeof(*fs));
|
||||
|
||||
n = blk_dread(bd, blk_start, blk_cnt, buf);
|
||||
if (n != blk_cnt) {
|
||||
printf("Failed to read serial info from MMC\n");
|
||||
nbx_fbxserial_set_default(fs);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memcpy(fs, buf, sizeof(*fs));
|
||||
|
||||
if (nbx_fbx_check_serial(fs) != 0) {
|
||||
nbx_fbxserial_set_default(fs);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nbx_fbx_dump_serial(struct nbx_fbx_serial *fs)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("Serial: %04u-%02u-%c-(%02u)%02u-%02u-%05u / %08x\n",
|
||||
ntohs(fs->type),
|
||||
fs->version,
|
||||
isprint(fs->manufacturer) ? fs->manufacturer : '?',
|
||||
ntohs(fs->year) / 100,
|
||||
ntohs(fs->year) % 100,
|
||||
fs->week,
|
||||
ntohl(fs->number),
|
||||
ntohl(fs->flags));
|
||||
|
||||
printf("Mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
fs->mac_addr_base[0],
|
||||
fs->mac_addr_base[1],
|
||||
fs->mac_addr_base[2],
|
||||
fs->mac_addr_base[3],
|
||||
fs->mac_addr_base[4],
|
||||
fs->mac_addr_base[5]);
|
||||
|
||||
/* Show bundle info */
|
||||
for (i = 0; i < be32_to_cpu(fs->extinfo_count); i++) {
|
||||
struct nbx_serial_extinfo *p;
|
||||
|
||||
if (i >= NBX_EXTINFO_MAX_COUNT)
|
||||
break;
|
||||
|
||||
p = &fs->extinfos[i];
|
||||
if (be32_to_cpu(p->type) == NBX_EXTINFO_TYPE_EXTDEV &&
|
||||
be32_to_cpu(p->u.extdev.type) == NBX_EXTDEV_TYPE_BUNDLE) {
|
||||
/* Ensure null termination */
|
||||
p->u.extdev.serial[sizeof(p->u.extdev.serial) - 1] = 0;
|
||||
printf("Bundle: %s\n", p->u.extdev.serial);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int nbx_fbx_init_ethaddr(int dev_num, unsigned long offset)
|
||||
{
|
||||
struct nbx_fbx_serial fs;
|
||||
char mac[32];
|
||||
int ret;
|
||||
|
||||
ret = nbx_fbx_read_serial(dev_num, offset, &fs);
|
||||
|
||||
/* Even on error, fs has default values set */
|
||||
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
fs.mac_addr_base[0], fs.mac_addr_base[1],
|
||||
fs.mac_addr_base[2], fs.mac_addr_base[3],
|
||||
fs.mac_addr_base[4], fs.mac_addr_base[5]);
|
||||
|
||||
nbx_fbx_dump_serial(&fs);
|
||||
|
||||
env_set("ethaddr", mac);
|
||||
env_set("eth1addr", mac);
|
||||
env_set("eth2addr", mac);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbxserial show - display serial info from eMMC
|
||||
*/
|
||||
static int do_fbxserial_show(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
struct nbx_fbx_serial fs;
|
||||
int dev = 0;
|
||||
unsigned long offset = CONFIG_NBX_MMC_PART_SERIAL_OFFSET;
|
||||
|
||||
if (argc >= 1)
|
||||
dev = dectoul(argv[0], NULL);
|
||||
|
||||
if (argc >= 2)
|
||||
offset = hextoul(argv[1], NULL);
|
||||
|
||||
if (nbx_fbx_read_serial(dev, offset, &fs) != 0)
|
||||
printf("Warning: Using default serial info\n");
|
||||
|
||||
nbx_fbx_dump_serial(&fs);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* fbxserial init - initialize ethaddr from serial info
|
||||
*/
|
||||
static int do_fbxserial_init(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
int dev = 0;
|
||||
unsigned long offset = CONFIG_NBX_MMC_PART_SERIAL_OFFSET;
|
||||
|
||||
if (argc >= 1)
|
||||
dev = dectoul(argv[0], NULL);
|
||||
|
||||
if (argc >= 2)
|
||||
offset = hextoul(argv[1], NULL);
|
||||
|
||||
return nbx_fbx_init_ethaddr(dev, offset);
|
||||
}
|
||||
|
||||
static struct cmd_tbl cmd_fbxserial_sub[] = {
|
||||
U_BOOT_CMD_MKENT(show, 3, 0, do_fbxserial_show, "", ""),
|
||||
U_BOOT_CMD_MKENT(init, 3, 0, do_fbxserial_init, "", ""),
|
||||
};
|
||||
|
||||
static int do_fbxserial(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
struct cmd_tbl *cp;
|
||||
|
||||
/* Default to 'show' if no subcommand */
|
||||
if (argc < 2)
|
||||
return do_fbxserial_show(cmdtp, flag, 0, NULL);
|
||||
|
||||
cp = find_cmd_tbl(argv[1], cmd_fbxserial_sub,
|
||||
ARRAY_SIZE(cmd_fbxserial_sub));
|
||||
|
||||
if (!cp)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
return cp->cmd(cmdtp, flag, argc - 2, argv + 2);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
fbxserial, 5, 0, do_fbxserial,
|
||||
"NBX serial info and MAC address initialization",
|
||||
"show [dev] [offset] - display serial info from eMMC\n"
|
||||
"fbxserial init [dev] [offset] - initialize ethaddr from serial info\n"
|
||||
" dev - MMC device number (default 0)\n"
|
||||
" offset - offset in eMMC in hex (default from Kconfig)"
|
||||
);
|
||||
|
||||
/*
|
||||
* Early init hook: Set MAC address from eMMC serial info before
|
||||
* network driver probes. EVT_SETTINGS_R is triggered after MMC
|
||||
* is available but before initr_net().
|
||||
*/
|
||||
static int nbx_fbx_settings_r(void)
|
||||
{
|
||||
if (!of_machine_is_compatible("nbx,armada8040"))
|
||||
return 0;
|
||||
|
||||
nbx_fbx_init_ethaddr(0, CONFIG_NBX_MMC_PART_SERIAL_OFFSET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVENT_SPY_SIMPLE(EVT_SETTINGS_R, nbx_fbx_settings_r);
|
||||
156
board/freebox/nbx10g/nbx_fbxserial.h
Normal file
156
board/freebox/nbx10g/nbx_fbxserial.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* NBX Freebox Serial Info Support
|
||||
*
|
||||
* Copyright (C) 2025 Free Mobile, Freebox
|
||||
*
|
||||
* Reads device serial number and MAC address from eMMC.
|
||||
* Used to identify the board and set network MAC addresses.
|
||||
*/
|
||||
|
||||
#ifndef NBX_FBXSERIAL_H
|
||||
#define NBX_FBXSERIAL_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* Extended info structure - variable data depending on type
|
||||
*/
|
||||
#define NBX_EXTINFO_SIZE 128
|
||||
#define NBX_EXTINFO_MAX_COUNT 16
|
||||
|
||||
/* Extended info types */
|
||||
#define NBX_EXTINFO_TYPE_EXTDEV 1
|
||||
|
||||
/* Extended device types */
|
||||
#define NBX_EXTDEV_TYPE_BUNDLE 1
|
||||
#define NBX_EXTDEV_TYPE_MAX 2
|
||||
|
||||
struct nbx_serial_extinfo {
|
||||
u32 type;
|
||||
|
||||
union {
|
||||
/* extdev */
|
||||
struct {
|
||||
u32 type;
|
||||
u32 model;
|
||||
char serial[64];
|
||||
} extdev;
|
||||
|
||||
/* raw access */
|
||||
unsigned char data[NBX_EXTINFO_SIZE];
|
||||
} u;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Master serial structure
|
||||
*/
|
||||
#define NBX_FBXSERIAL_VERSION 1
|
||||
#define NBX_FBXSERIAL_MAGIC 0x2d9521ab
|
||||
|
||||
#define NBX_MAC_ADDR_SIZE 6
|
||||
#define NBX_RANDOM_DATA_SIZE 32
|
||||
|
||||
/* Maximum size for CRC validation */
|
||||
#define NBX_FBXSERIAL_MAX_SIZE 8192
|
||||
|
||||
struct nbx_fbx_serial {
|
||||
u32 crc32;
|
||||
u32 magic;
|
||||
u32 struct_version;
|
||||
u32 len;
|
||||
|
||||
/* Board serial */
|
||||
u16 type;
|
||||
u8 version;
|
||||
u8 manufacturer;
|
||||
u16 year;
|
||||
u8 week;
|
||||
u32 number;
|
||||
u32 flags;
|
||||
|
||||
/* MAC address base */
|
||||
u8 mac_addr_base[NBX_MAC_ADDR_SIZE];
|
||||
|
||||
/* MAC address count */
|
||||
u8 mac_count;
|
||||
|
||||
/* Random data used to derive keys */
|
||||
u8 random_data[NBX_RANDOM_DATA_SIZE];
|
||||
|
||||
/* Last update of data (seconds since epoch) */
|
||||
u32 last_modified;
|
||||
|
||||
/* Count of following extinfo tags */
|
||||
u32 extinfo_count;
|
||||
|
||||
/* Beginning of extended info */
|
||||
struct nbx_serial_extinfo extinfos[NBX_EXTINFO_MAX_COUNT];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* nbx_fbxserial_set_default() - Initialize serial structure with defaults
|
||||
* @serial: Pointer to serial structure to initialize
|
||||
*
|
||||
* Sets the serial structure to default values (Freebox OUI, type 9018).
|
||||
* Used as fallback when serial info cannot be read from eMMC.
|
||||
*/
|
||||
static inline void nbx_fbxserial_set_default(struct nbx_fbx_serial *serial)
|
||||
{
|
||||
static const struct nbx_fbx_serial def = {
|
||||
.crc32 = 0,
|
||||
.magic = NBX_FBXSERIAL_MAGIC,
|
||||
.struct_version = NBX_FBXSERIAL_VERSION,
|
||||
.len = sizeof(struct nbx_fbx_serial),
|
||||
.type = 9018,
|
||||
.version = 0,
|
||||
.manufacturer = '_',
|
||||
.year = 0,
|
||||
.week = 0,
|
||||
.number = 0,
|
||||
.flags = 0,
|
||||
.mac_addr_base = { 0x00, 0x07, 0xCB, 0x00, 0x00, 0xFD },
|
||||
.mac_count = 1,
|
||||
.random_data = { 0 },
|
||||
.last_modified = 0,
|
||||
.extinfo_count = 0,
|
||||
};
|
||||
|
||||
memcpy(serial, &def, sizeof(def));
|
||||
}
|
||||
|
||||
/**
|
||||
* nbx_fbx_read_serial() - Read serial info from eMMC
|
||||
* @dev_num: MMC device number
|
||||
* @offset: Byte offset in eMMC where serial info is stored
|
||||
* @fs: Pointer to serial structure to fill
|
||||
*
|
||||
* Reads and validates the serial info from eMMC. On failure,
|
||||
* the structure is filled with default values.
|
||||
*
|
||||
* Return: 0 on success, negative on error (defaults still set)
|
||||
*/
|
||||
int nbx_fbx_read_serial(int dev_num, unsigned long offset,
|
||||
struct nbx_fbx_serial *fs);
|
||||
|
||||
/**
|
||||
* nbx_fbx_dump_serial() - Print serial info to console
|
||||
* @fs: Pointer to serial structure to display
|
||||
*
|
||||
* Prints the serial number, MAC address, and bundle info (if present).
|
||||
*/
|
||||
void nbx_fbx_dump_serial(struct nbx_fbx_serial *fs);
|
||||
|
||||
/**
|
||||
* nbx_fbx_init_ethaddr() - Initialize Ethernet addresses from serial info
|
||||
* @dev_num: MMC device number
|
||||
* @offset: Byte offset in eMMC where serial info is stored
|
||||
*
|
||||
* Reads serial info and sets ethaddr, eth1addr, eth2addr environment
|
||||
* variables from the MAC address in the serial structure.
|
||||
*
|
||||
* Return: 0 on success, negative on error
|
||||
*/
|
||||
int nbx_fbx_init_ethaddr(int dev_num, unsigned long offset);
|
||||
|
||||
#endif /* NBX_FBXSERIAL_H */
|
||||
78
board/freebox/nbx10g/nbx_imagetag.h
Normal file
78
board/freebox/nbx10g/nbx_imagetag.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* MVEBU Image Tag header
|
||||
*
|
||||
* Copyright (C) 2026 Free Mobile, Freebox
|
||||
*/
|
||||
|
||||
#ifndef __MVEBU_IMAGETAG_H
|
||||
#define __MVEBU_IMAGETAG_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define MVEBU_IMAGE_TAG_MAGIC 0x8d7c90bc
|
||||
#define MVEBU_IMAGE_TAG_VERSION 1
|
||||
|
||||
/**
|
||||
* struct mvebu_image_tag - MVEBU boot image tag structure
|
||||
*
|
||||
* All multi-byte fields are stored in big-endian format.
|
||||
*/
|
||||
struct mvebu_image_tag {
|
||||
u32 crc; /* CRC32-LE checksum (from offset 4) */
|
||||
u32 magic; /* Magic: 0x8d7c90bc */
|
||||
u32 version; /* Version: 1 */
|
||||
u32 total_size; /* Total image size including tag */
|
||||
u32 flags; /* Feature flags (reserved) */
|
||||
|
||||
u32 device_tree_offset; /* Offset from tag start to DTB */
|
||||
u32 device_tree_size; /* DTB size in bytes */
|
||||
|
||||
u32 kernel_offset; /* Offset from tag start to kernel */
|
||||
u32 kernel_size; /* Kernel size in bytes */
|
||||
|
||||
u32 rootfs_offset; /* Offset from tag start to rootfs */
|
||||
u32 rootfs_size; /* Rootfs size (must be 0) */
|
||||
|
||||
char image_name[32]; /* Image name (null-terminated) */
|
||||
char build_user[32]; /* Build user info */
|
||||
char build_date[32]; /* Build date info */
|
||||
};
|
||||
|
||||
/* Accessor functions for big-endian fields */
|
||||
static inline u32 mvebu_imagetag_device_tree_offset(struct mvebu_image_tag *tag)
|
||||
{
|
||||
return be32_to_cpu(tag->device_tree_offset);
|
||||
}
|
||||
|
||||
static inline u32 mvebu_imagetag_device_tree_size(struct mvebu_image_tag *tag)
|
||||
{
|
||||
return be32_to_cpu(tag->device_tree_size);
|
||||
}
|
||||
|
||||
static inline u32 mvebu_imagetag_kernel_offset(struct mvebu_image_tag *tag)
|
||||
{
|
||||
return be32_to_cpu(tag->kernel_offset);
|
||||
}
|
||||
|
||||
static inline u32 mvebu_imagetag_kernel_size(struct mvebu_image_tag *tag)
|
||||
{
|
||||
return be32_to_cpu(tag->kernel_size);
|
||||
}
|
||||
|
||||
static inline u32 mvebu_imagetag_rootfs_offset(struct mvebu_image_tag *tag)
|
||||
{
|
||||
return be32_to_cpu(tag->rootfs_offset);
|
||||
}
|
||||
|
||||
static inline u32 mvebu_imagetag_rootfs_size(struct mvebu_image_tag *tag)
|
||||
{
|
||||
return be32_to_cpu(tag->rootfs_size);
|
||||
}
|
||||
|
||||
static inline u32 mvebu_imagetag_total_size(struct mvebu_image_tag *tag)
|
||||
{
|
||||
return be32_to_cpu(tag->total_size);
|
||||
}
|
||||
|
||||
#endif /* __MVEBU_IMAGETAG_H */
|
||||
34
board/freebox/nbx10g/nbx_nrboot.h
Normal file
34
board/freebox/nbx10g/nbx_nrboot.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* MVEBU NRBoot (Number of Reboots) tracking header
|
||||
*
|
||||
* Copyright (C) 2026 Free Mobile, Freebox
|
||||
*/
|
||||
|
||||
#ifndef __MVEBU_NRBOOT_H
|
||||
#define __MVEBU_NRBOOT_H
|
||||
|
||||
#include <mmc.h>
|
||||
|
||||
/**
|
||||
* mvebu_check_nrboot() - Check and update reboot tracking counter
|
||||
* @mmc: MMC device
|
||||
* @offset: Byte offset in MMC where nrboot data is stored
|
||||
*
|
||||
* This function reads the reboot tracking counter, checks if we've
|
||||
* exceeded the maximum number of failed boots (4), and updates the
|
||||
* counter for the current boot attempt.
|
||||
*
|
||||
* The counter uses a bit-field encoding:
|
||||
* - nrboot: Running count of boot attempts
|
||||
* - nrsuccess: Count of successful boots
|
||||
*
|
||||
* If boot - success >= MAX_FAILURE (4), the system is considered
|
||||
* degraded and should use the fallback boot bank.
|
||||
*
|
||||
* Return: 1 if system is healthy (try newer bank first),
|
||||
* 0 if system is degraded (use stable bank first)
|
||||
*/
|
||||
int mvebu_check_nrboot(struct mmc *mmc, unsigned long offset);
|
||||
|
||||
#endif /* __MVEBU_NRBOOT_H */
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2014-2023 Tony Dinh <mibodhi@gmail.com>
|
||||
* Copyright (C) 2014-2025 Tony Dinh <mibodhi@gmail.com>
|
||||
*
|
||||
* Based on
|
||||
* Copyright (C) 2014 Jason Plum <jplum@archlinuxarm.org>
|
||||
@@ -51,11 +51,10 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define HDD1_GREEN_LED BIT(9)
|
||||
#define HDD1_RED_LED BIT(10)
|
||||
#define HDD2_POWER BIT(15)
|
||||
#define WATCHDOG_SIGNAL BIT(14)
|
||||
|
||||
#define NSA325_OE_HIGH (~(COPY_GREEN_LED | COPY_RED_LED | \
|
||||
HDD1_GREEN_LED | HDD1_RED_LED | HDD2_POWER | WATCHDOG_SIGNAL))
|
||||
#define NSA325_VAL_HIGH (WATCHDOG_SIGNAL | HDD2_POWER)
|
||||
HDD1_GREEN_LED | HDD1_RED_LED | HDD2_POWER))
|
||||
#define NSA325_VAL_HIGH (HDD2_POWER)
|
||||
|
||||
#define BTN_POWER 46
|
||||
#define BTN_RESET 36
|
||||
|
||||
@@ -23,7 +23,6 @@ CONFIG_SYS_PBSIZE=1048
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||
CONFIG_BOARD_EARLY_INIT_F=y
|
||||
CONFIG_SYS_PROMPT="eDPU>> "
|
||||
CONFIG_SYS_MAXARGS=32
|
||||
# CONFIG_CMD_ELF is not set
|
||||
|
||||
@@ -22,7 +22,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||
CONFIG_BOARD_EARLY_INIT_F=y
|
||||
CONFIG_SYS_MAXARGS=32
|
||||
CONFIG_CMD_FUSE=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
|
||||
@@ -24,7 +24,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||
CONFIG_BOARD_EARLY_INIT_F=y
|
||||
CONFIG_BOARD_LATE_INIT=y
|
||||
CONFIG_SYS_MAXARGS=32
|
||||
CONFIG_CMD_FUSE=y
|
||||
|
||||
@@ -23,7 +23,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||
CONFIG_BOARD_EARLY_INIT_F=y
|
||||
CONFIG_BOARD_LATE_INIT=y
|
||||
CONFIG_SYS_MAXARGS=32
|
||||
CONFIG_CMD_FUSE=y
|
||||
|
||||
75
configs/mvebu_nbx_88f8040_defconfig
Normal file
75
configs/mvebu_nbx_88f8040_defconfig
Normal file
@@ -0,0 +1,75 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_CPU_INIT=y
|
||||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_TEXT_BASE=0x00000000
|
||||
CONFIG_NR_DRAM_BANKS=2
|
||||
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
|
||||
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000
|
||||
CONFIG_TARGET_NBX10G=y
|
||||
CONFIG_ENV_SIZE=0x10000
|
||||
CONFIG_ENV_OFFSET=0x180000
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="armada-8040-nbx"
|
||||
CONFIG_FIT=y
|
||||
CONFIG_SYS_BOOTM_LEN=0x1000000
|
||||
CONFIG_SYS_LOAD_ADDR=0x800000
|
||||
CONFIG_PCI=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
# CONFIG_EFI_LOADER is not set
|
||||
CONFIG_USE_PREBOOT=y
|
||||
CONFIG_PREBOOT="echo (CRC warning is normal: no env saved yet)"
|
||||
CONFIG_SYS_PBSIZE=1048
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
CONFIG_LAST_STAGE_INIT=y
|
||||
CONFIG_SYS_PROMPT="nodebox10G>> "
|
||||
CONFIG_SYS_MAXARGS=32
|
||||
CONFIG_CMD_BOOTZ=y
|
||||
# CONFIG_BOOTM_VXWORKS is not set
|
||||
# CONFIG_CMD_ELF is not set
|
||||
CONFIG_CMD_MEMTEST=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_MISC=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_PCI=y
|
||||
# CONFIG_CMD_SF is not set
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_DHCP=y
|
||||
CONFIG_CMD_MII=y
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_TIMER=y
|
||||
CONFIG_CMD_NBX_EMMCBOOT=y
|
||||
CONFIG_CMD_NBX_FBXSERIAL=y
|
||||
CONFIG_CMD_EXT2=y
|
||||
CONFIG_CMD_EXT4=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_CMD_FS_GENERIC=y
|
||||
CONFIG_EFI_PARTITION=y
|
||||
CONFIG_ENV_OVERWRITE=y
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_ARP_TIMEOUT=200
|
||||
CONFIG_NET_RETRY_COUNT=50
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_MVTWSI=y
|
||||
CONFIG_I2C_MUX=y
|
||||
CONFIG_MISC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_XENON=y
|
||||
# CONFIG_SPI_FLASH is not set
|
||||
CONFIG_PHY_MARVELL=y
|
||||
CONFIG_PHY_GIGE=y
|
||||
CONFIG_MVPP2=y
|
||||
CONFIG_PCIE_DW_MVEBU=y
|
||||
CONFIG_PHY=y
|
||||
CONFIG_MVEBU_COMPHY_SUPPORT=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_ARMADA_8K=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
@@ -22,7 +22,6 @@ CONFIG_SYS_PBSIZE=1048
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||
CONFIG_BOARD_EARLY_INIT_F=y
|
||||
CONFIG_SYS_PROMPT="uDPU>> "
|
||||
CONFIG_SYS_MAXARGS=32
|
||||
# CONFIG_CMD_ELF is not set
|
||||
|
||||
76
configs/x220_defconfig
Normal file
76
configs/x220_defconfig
Normal file
@@ -0,0 +1,76 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_CPU_INIT=y
|
||||
CONFIG_ARCH_MVEBU=y
|
||||
CONFIG_SYS_KWD_CONFIG="board/alliedtelesis/x220/kwbimage.cfg"
|
||||
CONFIG_TEXT_BASE=0x00800000
|
||||
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
|
||||
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000
|
||||
CONFIG_TARGET_X220=y
|
||||
CONFIG_ENV_SIZE=0x10000
|
||||
CONFIG_ENV_OFFSET=0x100000
|
||||
CONFIG_ENV_SECT_SIZE=0x40000
|
||||
CONFIG_DEFAULT_DEVICE_TREE="armada-xp-atl-x220"
|
||||
CONFIG_SYS_LOAD_ADDR=0x800000
|
||||
CONFIG_PCI=y
|
||||
CONFIG_SYS_MEMTEST_START=0x00800000
|
||||
CONFIG_SYS_MEMTEST_END=0x00ffffff
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_FIT_BEST_MATCH=y
|
||||
CONFIG_USE_PREBOOT=y
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
CONFIG_SYS_MAXARGS=96
|
||||
CONFIG_CMD_MEMTEST=y
|
||||
CONFIG_SYS_ALT_MEMTEST=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_SPI=y
|
||||
CONFIG_CMD_USB=y
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
CONFIG_CMD_TFTPPUT=y
|
||||
CONFIG_CMD_DHCP=y
|
||||
CONFIG_CMD_MII=y
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_EXT2=y
|
||||
CONFIG_CMD_EXT4=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_CMD_FS_GENERIC=y
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_MTDIDS_DEFAULT="nand0=nand"
|
||||
CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:112M(user),8M(errlog),8M(nand-bbt)"
|
||||
CONFIG_CMD_UBI=y
|
||||
CONFIG_ENV_OVERWRITE=y
|
||||
CONFIG_ENV_IS_IN_SPI_FLASH=y
|
||||
CONFIG_ENV_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_ARP_TIMEOUT=200
|
||||
CONFIG_NET_RETRY_COUNT=50
|
||||
CONFIG_GPIO_HOG=y
|
||||
CONFIG_DM_PCA953X=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_MVTWSI=y
|
||||
# CONFIG_MMC is not set
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_SYS_NAND_USE_FLASH_BBT=y
|
||||
CONFIG_NAND_PXA3XX=y
|
||||
CONFIG_SYS_NAND_ONFI_DETECTION=y
|
||||
CONFIG_SPI_FLASH_SFDP_SUPPORT=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_SST=y
|
||||
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||
CONFIG_PCI_MVEBU=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_KIRKWOOD_SPI=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_HOST_ETHER=y
|
||||
CONFIG_USB_ETHER_ASIX=y
|
||||
CONFIG_USB_ETHER_ASIX88179=y
|
||||
CONFIG_USB_ETHER_MCS7830=y
|
||||
CONFIG_USB_ETHER_RTL8152=y
|
||||
CONFIG_USB_ETHER_SMSC95XX=y
|
||||
CONFIG_WDT=y
|
||||
CONFIG_WDT_ORION=y
|
||||
11
doc/board/alliedtelesis/index.rst
Normal file
11
doc/board/alliedtelesis/index.rst
Normal file
@@ -0,0 +1,11 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. Copyright (C) 2026 Allied Telesis Labs
|
||||
|
||||
Allied Telesis
|
||||
==============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
x220
|
||||
|
||||
39
doc/board/alliedtelesis/x220.rst
Normal file
39
doc/board/alliedtelesis/x220.rst
Normal file
@@ -0,0 +1,39 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. Copyright (C) 2026 Allied Telesis Labs
|
||||
|
||||
x220 Platforms
|
||||
==============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The x220 has is a range of L2+ switches using the Marvell AlleyCat3 switch with
|
||||
integrated ARMv7 CPU. It is also sold under some different brands for different
|
||||
markets.
|
||||
|
||||
- x220-52GP
|
||||
- x220-52GT
|
||||
- x220-28GS
|
||||
- GS980M/52PS
|
||||
- GS980M/52
|
||||
- x230-52
|
||||
|
||||
DDR Traning (binhdr)
|
||||
--------------------
|
||||
|
||||
The AlleyCat3 uses a binary blob for it's DDR training. This is launched by
|
||||
the built-in bootloader prior to U-Boot starting.
|
||||
|
||||
To generate binary.0 from Marvell's bin_hdr.elf use the following command
|
||||
|
||||
.. prompt:: bash $
|
||||
|
||||
arm-softfloat-linux-gnueabi-objcopy -S -O binary bin_hdr.elf \
|
||||
board/alliedtelesis/x220/binary.0
|
||||
|
||||
Alternatively, it is possible to extract the binary.0 from an existing U-Boot
|
||||
image
|
||||
|
||||
.. prompt:: bash $
|
||||
|
||||
./tools/dumpimage -T kwbimage -p 1 -o board/alliedtelesis/x220/binary.0 u-boot.kwb
|
||||
@@ -10,6 +10,7 @@ Board-specific doc
|
||||
actions/index
|
||||
advantech/index
|
||||
andestech/index
|
||||
alliedtelesis/index
|
||||
allwinner/index
|
||||
amlogic/index
|
||||
anbernic/index
|
||||
|
||||
@@ -184,6 +184,7 @@ struct pxa3xx_nand_host {
|
||||
struct pxa3xx_nand_info {
|
||||
struct nand_hw_control controller;
|
||||
struct pxa3xx_nand_platform_data *pdata;
|
||||
struct udevice *dev;
|
||||
|
||||
struct clk *clk;
|
||||
void __iomem *mmio_base;
|
||||
@@ -585,8 +586,7 @@ static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len)
|
||||
ts = get_timer(0);
|
||||
while (!(nand_readl(info, NDSR) & NDSR_RDDREQ)) {
|
||||
if (get_timer(ts) > TIMEOUT_DRAIN_FIFO) {
|
||||
dev_err(info->controller.active->mtd.dev,
|
||||
"Timeout on RDDREQ while draining the FIFO\n");
|
||||
dev_err(info->dev, "Timeout on RDDREQ while draining the FIFO\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -638,8 +638,7 @@ static void handle_data_pio(struct pxa3xx_nand_info *info)
|
||||
DIV_ROUND_UP(info->step_spare_size, 4));
|
||||
break;
|
||||
default:
|
||||
dev_err(info->controller.active->mtd.dev,
|
||||
"%s: invalid state %d\n", __func__, info->state);
|
||||
dev_err(info->dev, "%s: invalid state %d\n", __func__, info->state);
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -1557,8 +1556,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
|
||||
ecc->size = 512;
|
||||
|
||||
if (ecc_stepsize != 512 || !(nfc_layouts[i].strength)) {
|
||||
dev_err(info->controller.active->mtd.dev,
|
||||
"ECC strength %d at page size %d is not supported\n",
|
||||
dev_err(info->dev, "ECC strength %d at page size %d is not supported\n",
|
||||
strength, page_size);
|
||||
return -ENODEV;
|
||||
}
|
||||
@@ -1799,6 +1797,7 @@ static int pxa3xx_nand_probe(struct udevice *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
info->dev = dev;
|
||||
pdata = info->pdata;
|
||||
|
||||
ret = alloc_nand_resource(dev, info);
|
||||
|
||||
@@ -4528,7 +4528,7 @@ static void mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port)
|
||||
*/
|
||||
if (phy_dev &&
|
||||
phy_dev->drv->uid == 0xffffffff) {/* Generic phy */
|
||||
dev_warn(port->phy_dev->dev,
|
||||
dev_warn(dev,
|
||||
"Marking phy as invalid, link will not be checked\n");
|
||||
/* set phy_addr to invalid value */
|
||||
port->phyaddr = PHY_MAX_ADDR;
|
||||
@@ -4540,7 +4540,7 @@ static void mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port)
|
||||
|
||||
port->phy_dev = phy_dev;
|
||||
if (!phy_dev) {
|
||||
dev_err(port->phy_dev->dev, "cannot connect to phy\n");
|
||||
dev_err(dev, "cannot connect to phy\n");
|
||||
return;
|
||||
}
|
||||
phy_dev->supported &= PHY_GBIT_FEATURES;
|
||||
|
||||
@@ -550,7 +550,7 @@ static int armada_38x_pinctrl_probe(struct udevice *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pinctrl_ops armada_37xx_pinctrl_ops = {
|
||||
static const struct pinctrl_ops armada_37xx_pinctrl_ops = {
|
||||
.get_pins_count = armada_38x_pinctrl_get_pins_count,
|
||||
.get_pin_name = armada_38x_pinctrl_get_pin_name,
|
||||
.get_functions_count = armada_38x_pinctrl_get_functions_count,
|
||||
|
||||
@@ -1024,7 +1024,7 @@ config OCTEON_SERIAL_BOOTCMD
|
||||
bool "MIPS Octeon PCI remote bootcmd input"
|
||||
depends on ARCH_OCTEON
|
||||
depends on DM_SERIAL
|
||||
select SYS_IS_IN_ENV
|
||||
select SYS_CONSOLE_IS_IN_ENV
|
||||
select CONSOLE_MUX
|
||||
help
|
||||
This driver supports remote input over the PCIe bus from a host
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <config.h>
|
||||
#include <div64.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/fdtaddr.h>
|
||||
#include <timer.h>
|
||||
@@ -113,7 +114,7 @@ static int orion_timer_probe(struct udevice *dev)
|
||||
enum input_clock_type type = dev_get_driver_data(dev);
|
||||
struct orion_timer_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = devfdt_remap_addr_index(dev, 0);
|
||||
priv->base = dev_remap_addr_index(dev, 0);
|
||||
if (!priv->base) {
|
||||
debug("unable to map registers\n");
|
||||
return -ENOMEM;
|
||||
|
||||
29
include/configs/nbx10g.h
Normal file
29
include/configs/nbx10g.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2017-2018 Freebox SA
|
||||
* Copyright (C) 2026 Free Mobile, Vincent Jardin <vjardin@free.fr>
|
||||
*
|
||||
* Configuration for Freebox Nodebox 10G
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_NBX10G_H
|
||||
#define _CONFIG_NBX10G_H
|
||||
|
||||
#include "mvebu_armada-8k.h"
|
||||
|
||||
/* Override environment settings for NBX */
|
||||
#undef CFG_EXTRA_ENV_SETTINGS
|
||||
#define CFG_EXTRA_ENV_SETTINGS \
|
||||
"hostname=nodebox10G\0" \
|
||||
"ethrotate=no\0" \
|
||||
"image_addr=0x7000000\0" \
|
||||
"image_name=Image.nodebox10G\0" \
|
||||
"fdt_addr=0x6f00000\0" \
|
||||
"fdt_name=nodebox10G.dtb\0" \
|
||||
"console=ttyS0,115200\0" \
|
||||
"tftpboot=setenv bootargs console=${console} bank=tftp; " \
|
||||
"dhcp ${image_addr} ${image_name}; " \
|
||||
"tftp ${fdt_addr} ${fdt_name}; " \
|
||||
"booti ${image_addr} - ${fdt_addr}\0"
|
||||
|
||||
#endif /* _CONFIG_NBX10G_H */
|
||||
20
include/configs/x220.h
Normal file
20
include/configs/x220.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2025 Allied Telesis Labs
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_X220_H
|
||||
#define _CONFIG_X220_H
|
||||
|
||||
/* Keep device tree and initrd in lower memory so the kernel can access them */
|
||||
#define CFG_EXTRA_ENV_SETTINGS \
|
||||
"fdt_high=0x10000000\0" \
|
||||
"initrd_high=0x10000000\0"
|
||||
|
||||
/*
|
||||
* mv-common.h should be defined after CMD configs since it used them
|
||||
* to enable certain macros
|
||||
*/
|
||||
#include "mv-common.h"
|
||||
|
||||
#endif /* _CONFIG_X220_H */
|
||||
Reference in New Issue
Block a user