summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-06-10 09:18:15 -0600
committerTom Rini <[email protected]>2026-06-10 09:18:15 -0600
commit953653936cfc9e12f52df1165080fa6c7cbae1bc (patch)
tree407487ab8999b482dfe367b0561347c0f22f261a /arch
parent45cfba58dba911685700d6574b01f39329dce99c (diff)
parenteab66c3a9085e07b227847b0c442ee8d2efb241d (diff)
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)
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/dts/Makefile2
-rw-r--r--arch/arm/dts/armada-8040-nbx-u-boot.dtsi15
-rw-r--r--arch/arm/dts/armada-8040-nbx.dts259
-rw-r--r--arch/arm/dts/armada-xp-atl-x220.dts162
-rw-r--r--arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi1
-rw-r--r--arch/arm/mach-mvebu/Kconfig16
-rw-r--r--arch/arm/mach-mvebu/armada8k/Makefile2
-rw-r--r--arch/arm/mach-mvebu/armada8k/cpu.c12
-rw-r--r--arch/arm/mach-mvebu/armada8k/soc_info.c194
-rw-r--r--arch/arm/mach-mvebu/armada8k/soc_info.h14
10 files changed, 675 insertions, 2 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index b75f3ee4386..c647379c5ac 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -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 \
diff --git a/arch/arm/dts/armada-8040-nbx-u-boot.dtsi b/arch/arm/dts/armada-8040-nbx-u-boot.dtsi
new file mode 100644
index 00000000000..dec473b7156
--- /dev/null
+++ b/arch/arm/dts/armada-8040-nbx-u-boot.dtsi
@@ -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
diff --git a/arch/arm/dts/armada-8040-nbx.dts b/arch/arm/dts/armada-8040-nbx.dts
new file mode 100644
index 00000000000..b8b7298b4f5
--- /dev/null
+++ b/arch/arm/dts/armada-8040-nbx.dts
@@ -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";
+};
diff --git a/arch/arm/dts/armada-xp-atl-x220.dts b/arch/arm/dts/armada-xp-atl-x220.dts
new file mode 100644
index 00000000000..5b3307ed288
--- /dev/null
+++ b/arch/arm/dts/armada-xp-atl-x220.dts
@@ -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>;
+ };
+};
+
diff --git a/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi b/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi
index dc20643bfa3..ad64813e770 100644
--- a/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi
+++ b/arch/arm/dts/armada-xp-db-xc3-24g4xg-u-boot.dtsi
@@ -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>;
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 4afaee234ea..3465ccfc151 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -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
diff --git a/arch/arm/mach-mvebu/armada8k/Makefile b/arch/arm/mach-mvebu/armada8k/Makefile
index 0a4756717a3..723239d9894 100644
--- a/arch/arm/mach-mvebu/armada8k/Makefile
+++ b/arch/arm/mach-mvebu/armada8k/Makefile
@@ -2,4 +2,4 @@
#
# Copyright (C) 2016 Stefan Roese <[email protected]>
-obj-y = cpu.o cache_llc.o dram.o
+obj-y = cpu.o cache_llc.o dram.o soc_info.o
diff --git a/arch/arm/mach-mvebu/armada8k/cpu.c b/arch/arm/mach-mvebu/armada8k/cpu.c
index 3eb93c82387..220b32dd025 100644
--- a/arch/arm/mach-mvebu/armada8k/cpu.c
+++ b/arch/arm/mach-mvebu/armada8k/cpu.c
@@ -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;
+}
diff --git a/arch/arm/mach-mvebu/armada8k/soc_info.c b/arch/arm/mach-mvebu/armada8k/soc_info.c
new file mode 100644
index 00000000000..18cc083c0db
--- /dev/null
+++ b/arch/arm/mach-mvebu/armada8k/soc_info.c
@@ -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)" : "");
+}
diff --git a/arch/arm/mach-mvebu/armada8k/soc_info.h b/arch/arm/mach-mvebu/armada8k/soc_info.h
new file mode 100644
index 00000000000..41afe7a2508
--- /dev/null
+++ b/arch/arm/mach-mvebu/armada8k/soc_info.h
@@ -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_ */