mvebu: add support for SolidRun ClearFog Pro

The SolidRun ClearFog Pro is a router based on the SolidRun CN9130 SOM.

Specs:
 - SoC: Quad-Core Cortex-A72 CN9130 SoC
 - RAM: 4GiB DDR4
 - Serial: Micro-USB port on front (FT232R, 115200 8n1)
 - Storage: 8GiB eMMC, microSD card slot, 8MiB SPI NOR flash
 - Ethernet: 7x GbE (1 port dedicated on SoC, 6 port switch with single GbE CPU port)
 - SFP: 1x SFP+
 - USB: 1x USB-A 3.1 Gen 1
 - PCIe: 2x mini PCIe (one slot with USB and SIM card socket)
 - SATA: 1x M.2 Key-B

In addition to the usual connectivity options this device also features
an internal mikroBUS expansion connector.

SATA is currently untested due to lack of a suitable M.2 SSD.

Installation
============

1. Write sdcard sysupgrade image to microSD card using dd or similar
2. Insert microSD card into router and apply power
3. Device boots into OpenWRT
4. (optional) dd sysupgrade image to /dev/mmcblk0 to install to eMMC

Signed-off-by: Tobias Schramm <tobias@t-sys.eu>
This commit is contained in:
Tobias Schramm 2024-02-26 12:47:29 +01:00 committed by Christian Lamparter
parent 1ed01ef606
commit 336a531c15
8 changed files with 583 additions and 10 deletions

View File

@ -32,6 +32,9 @@ marvell,armada7040-db)
marvell,armada8040-clearfog-gt-8k)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 eth2" "eth0 eth1"
;;
solidrun,clearfog-pro)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 lan5 lan6 eth0 eth1" "eth2"
;;
*)
ucidef_set_interface_lan "eth0"
;;

View File

@ -14,7 +14,8 @@ platform_check_image() {
iei,puzzle-m902|\
marvell,armada8040-mcbin-doubleshot|\
marvell,armada8040-mcbin-singleshot|\
marvell,armada8040-clearfog-gt-8k)
marvell,armada8040-clearfog-gt-8k|\
solidrun,clearfog-pro)
legacy_sdcard_check_image "$1"
;;
*)
@ -32,7 +33,8 @@ platform_do_upgrade() {
globalscale,mochabin|\
marvell,armada8040-mcbin-doubleshot|\
marvell,armada8040-mcbin-singleshot|\
marvell,armada8040-clearfog-gt-8k)
marvell,armada8040-clearfog-gt-8k|\
solidrun,clearfog-pro)
legacy_sdcard_do_upgrade "$1"
;;
*)
@ -47,7 +49,8 @@ platform_copy_config() {
iei,puzzle-m902|\
marvell,armada8040-mcbin-doubleshot|\
marvell,armada8040-mcbin-singleshot|\
marvell,armada8040-clearfog-gt-8k)
marvell,armada8040-clearfog-gt-8k|\
solidrun,clearfog-pro)
legacy_sdcard_copy_config
;;
esac

View File

@ -41,7 +41,9 @@ CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CRC_CCITT=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_EEPROM_AT24=y
CONFIG_FRAME_POINTER=y
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
@ -66,6 +68,9 @@ CONFIG_MVEBU_SEI=y
CONFIG_MVPP2=y
CONFIG_MV_XOR_V2=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_LAYOUT_ONIE_TLV=y
CONFIG_NVMEM_SYSFS=y
CONFIG_PARTITION_PERCPU=y
CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y
@ -74,6 +79,7 @@ CONFIG_PCIE_DW=y
CONFIG_PCIE_DW_HOST=y
# CONFIG_PCI_AARDVARK is not set
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PHY_MVEBU_CP110_COMPHY=y
CONFIG_PHY_MVEBU_CP110_UTMI=y

View File

@ -0,0 +1,513 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright SolidRun Ltd.
* Copyright (C) 2024 Tobias Schramm <tobias@t-sys.eu>
*
* Device tree for the CN9130-based ClearFog Pro
*/
#include "cn9130.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
model = "SolidRun ClearFog Pro";
compatible = "solidrun,clearfog-pro", "marvell,armada-ap807-quad",
"marvell,armada-ap807";
chosen {
stdout-path = "serial0:115200n8";
};
aliases {
gpio1 = &cp0_gpio1;
gpio2 = &cp0_gpio2;
i2c0 = &cp0_i2c0;
ethernet0 = &cp0_eth0;
ethernet1 = &cp0_eth1;
ethernet2 = &cp0_eth2;
spi1 = &cp0_spi1;
};
memory@00000000 {
reg = <0x0 0x0 0x1 0x0>;
device_type = "memory";
};
/* Virtual regulator, root of power tree */
vin: regulator-vin {
compatible = "regulator-fixed";
regulator-name = "vin";
regulator-always-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
};
/* Regulators supplied by vin */
v_5v0: regulator-v_5v0 {
compatible = "regulator-fixed";
regulator-name = "v_5v0";
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vin>;
};
v_3v3: regulator-v_3v3 {
compatible = "regulator-fixed";
regulator-name = "v_3v3";
regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vin>;
};
/* Regulators supplied by v_5v0 */
v_1v8: regulator-v_1v8 {
compatible = "regulator-fixed";
regulator-name = "v_1v8";
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&v_5v0>;
};
v_5v0_usb3_hst_vbus: regulator-v_5v0_usb3_hst_vbus {
compatible = "regulator-fixed";
regulator-name = "v_5v0_usb3_hst_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&expander0 6 GPIO_ACTIVE_LOW>;
vin-supply = <&v_5v0>;
};
/* Regulators internal to SOM */
vqmmc: regulator-vqmmc {
compatible = "regulator-fixed";
regulator-name = "vqmmc";
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&v_5v0>;
};
cp0_usb3_0_phy1: cp0_usb3_phy@1 {
compatible = "usb-nop-xceiv";
vbus-supply = <&v_5v0_usb3_hst_vbus>;
};
cp0_sfp_eth0: sfp-eth@0 {
compatible = "sff,sfp";
i2c-bus = <&cp0_i2c1>;
los-gpio = <&expander0 12 GPIO_ACTIVE_HIGH>;
mod-def0-gpio = <&expander0 15 GPIO_ACTIVE_LOW>;
tx-disable-gpio = <&expander0 14 GPIO_ACTIVE_HIGH>;
tx-fault-gpio = <&expander0 13 GPIO_ACTIVE_HIGH>;
maximum-power-milliwatt = <2000>;
};
keys {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&cp0_button_pin>;
reset {
label = "Reset";
linux,code = <KEY_RESTART>;
gpios = <&cp0_gpio2 0 GPIO_ACTIVE_LOW>;
};
};
};
&uart0 {
status = "okay";
};
/* on-board eMMC */
&ap_sdhci0 {
bus-width = <8>;
pinctrl-names = "default";
vqmmc-supply = <&vqmmc>;
status = "okay";
};
&cp0_crypto {
status = "okay";
};
&cp0_ethernet {
status = "okay";
};
&cp0_gpio1 {
status = "okay";
};
&cp0_gpio2 {
status = "okay";
};
&cp0_i2c0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_i2c0_pins>;
clock-frequency = <100000>;
/*
* PCA9655 GPIO expander, up to 1MHz clock.
* 0-CON3 CLKREQ#
* 1-CON3 PERST#
* 2-CON2 PERST#
* 3-CON3 W_DISABLE
* 4-CON2 CLKREQ#
* 5-USB3 overcurrent
* 6-USB3 power
* 7-CON2 W_DISABLE
* 8-JP4 P1
* 9-JP4 P4
* 10-JP4 P5
* 11-m.2 DEVSLP
* 12-SFP_LOS
* 13-SFP_TX_FAULT
* 14-SFP_TX_DISABLE
* 15-SFP_MOD_DEF0
*/
expander0: gpio-expander@20 {
compatible = "nxp,pca9555";
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&cp0_gpio1>;
interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&cp0_expander0_pins>;
vcc-supply = <&v_3v3>;
pcie1_0_clkreq {
gpio-hog;
gpios = <0 GPIO_ACTIVE_LOW>;
input;
line-name = "pcie1.0-clkreq";
};
pcie1_0_w_disable {
gpio-hog;
gpios = <3 GPIO_ACTIVE_LOW>;
output-low;
line-name = "pcie1.0-w-disable";
};
pcie2_0_clkreq {
gpio-hog;
gpios = <4 GPIO_ACTIVE_LOW>;
input;
line-name = "pcie2.0-clkreq";
};
pcie2_0_w_disable {
gpio-hog;
gpios = <7 GPIO_ACTIVE_LOW>;
output-low;
line-name = "pcie2.0-w-disable";
};
usb3_ilimit {
gpio-hog;
gpios = <5 GPIO_ACTIVE_LOW>;
input;
line-name = "usb3-current-limit";
};
m2_devslp {
gpio-hog;
gpios = <11 GPIO_ACTIVE_HIGH>;
output-low;
line-name = "m.2 devslp";
};
};
/* ADC only for mikroBUS connector */
mcp3021@4c {
compatible = "microchip,mcp3021";
reg = <0x4c>;
};
/* EEPROM on the SOM */
eeprom@53 {
compatible = "atmel,24c02";
reg = <0x53>;
pagesize = <16>;
read-only;
nvmem-layout {
compatible = "onie,tlv-layout";
onie_tlv_macaddr: mac-address {
#nvmem-cell-cells = <1>;
};
};
};
};
/* SMBUS on mini PCIe sockets */
&cp0_i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_i2c1_pins>;
clock-frequency = <100000>;
};
&cp0_mdio {
status = "okay";
phy0: ethernet-phy@0 {
reg = <0>;
/* Green led blinks on activity, orange LED on link */
marvell,reg-init = <3 16 0 0x0064>;
};
switch@4 {
compatible = "marvell,mv88e6085";
reg = <4>;
interrupt-controller;
#interrupt-cells = <2>;
interrupt-parent = <&cp0_gpio1>;
interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&cp0_dsa0_pins>;
reset-gpios = <&cp0_gpio1 27 GPIO_ACTIVE_LOW>;
mdio-external {
compatible = "marvell,mv88e6xxx-mdio-external";
#address-cells = <1>;
#size-cells = <0>;
/* 88E1512 PHY */
port6_phy: ethernet-phy@1 {
reg = <1>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "lan5";
};
port@1 {
reg = <1>;
label = "lan4";
};
port@2 {
reg = <2>;
label = "lan3";
};
port@3 {
reg = <3>;
label = "lan2";
};
port@4 {
reg = <4>;
label = "lan1";
};
port@5 {
reg = <5>;
ethernet = <&cp0_eth1>;
label = "cpu";
phy-mode = "rgmii-id";
fixed-link {
speed = <1000>;
full-duplex;
};
};
port@6 {
/* 88E1512 external phy */
reg = <6>;
label = "lan6";
phy-handle = <&port6_phy>;
phy-mode = "rgmii-id";
};
};
};
};
/* SRDS #0 - SATA on bottom M.2 B-Key connector */
&cp0_sata0 {
status = "okay";
sata-port@0 {
status = "disabled";
};
sata-port@1 {
phys = <&cp0_comphy0 1>;
target-supply = <&v_3v3>;
};
};
&cp0_utmi {
status = "okay";
};
/* mini PCIe slot far from SOM, USB 2.0 only, SS lanes unused */
&cp0_usb3_0 {
status = "okay";
phys = <&cp0_utmi0>;
phy-names = "utmi";
dr_mode = "host";
};
/* SRDS #1 - USB-A 3.0 host port */
&cp0_usb3_1 {
status = "okay";
phys = <&cp0_utmi1>, <&cp0_comphy1 0>;
phy-names = "utmi", "usb";
usb-phy = <&cp0_usb3_0_phy1>;
dr_mode = "host";
};
/* SRDS #2 - SFP+ 10GE */
&cp0_eth0 {
status = "okay";
phy-mode = "10gbase-r";
phys = <&cp0_comphy2 0>;
managed = "in-band-status";
nvmem-cells = <&onie_tlv_macaddr 0>;
nvmem-cell-names = "mac-address";
sfp = <&cp0_sfp_eth0>;
};
/* SRDS #3 - SGMII 1GE to L2 switch */
&cp0_eth1 {
status = "okay";
phys = <&cp0_comphy3 1>;
phy-mode = "sgmii";
nvmem-cells = <&onie_tlv_macaddr 1>;
nvmem-cell-names = "mac-address";
fixed-link {
speed = <1000>;
full-duplex;
};
};
/* SRDS #4 - mini PCIe slot near SOM */
&cp0_pcie1 {
status = "okay";
phys = <&cp0_comphy4 1>;
num-lanes = <1>;
reset-gpios = <&expander0 2 GPIO_ACTIVE_LOW>;
};
/* SRDS #5 - mini PCIe slot far from SOM */
&cp0_pcie2 {
status = "okay";
phys = <&cp0_comphy5 2>;
num-lanes = <1>;
reset-gpios = <&expander0 1 GPIO_ACTIVE_LOW>;
};
/* GE PHY RGMII */
&cp0_eth2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_ge2_rgmii_pins>;
phy = <&phy0>;
phy-mode = "rgmii-id";
nvmem-cells = <&onie_tlv_macaddr 2>;
nvmem-cell-names = "mac-address";
};
/* micro SD card slot */
&cp0_sdhci0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_sdhci_pins &cp0_sdhci_cd_pins>;
bus-width = <4>;
cd-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>;
no-1-8-v;
vqmmc-supply = <&v_3v3>;
vmmc-supply = <&v_3v3>;
};
&cp0_spi1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&cp0_spi1_pins>;
spi-flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
#address-cells = <0x1>;
#size-cells = <0x1>;
spi-max-frequency = <10000000>;
};
};
&cp0_syscon0 {
cp0_pinctrl: pinctrl {
compatible = "marvell,cp115-standalone-pinctrl";
cp0_i2c0_pins: cp0-i2c0-pins {
marvell,pins = "mpp37", "mpp38";
marvell,function = "i2c0";
};
cp0_i2c1_pins: cp0-i2c1-pins {
marvell,pins = "mpp35", "mpp36";
marvell,function = "i2c1";
};
cp0_ge2_rgmii_pins: cp0-ge2-rgmii-pins {
marvell,pins = "mpp44", "mpp45", "mpp46",
"mpp47", "mpp48", "mpp49",
"mpp50", "mpp51", "mpp52",
"mpp53", "mpp54", "mpp55";
marvell,function = "ge1";
};
cp0_sdhci_cd_pins: cp0-sdhci-cd-pins {
marvell,pins = "mpp43";
marvell,function = "sdio";
};
cp0_sdhci_pins: cp0-sdhci-pins {
marvell,pins = "mpp56", "mpp57", "mpp58",
"mpp59", "mpp60", "mpp61";
marvell,function = "sdio";
};
cp0_spi1_pins: cp0-spi1-pins {
marvell,pins = "mpp12", "mpp13", "mpp14",
"mpp15", "mpp16";
marvell,function = "spi1";
};
cp0_dsa0_pins: cp0-dsa0-pins {
marvell,pins = "mpp27", "mpp29";
marvell,function = "gpio";
};
cp0_button_pin: cp0-button-pin {
marvell,pins = "mpp32";
marvell,function = "gpio";
};
cp0_expander0_pins: cp0-expander0-pins {
marvell,pins = "mpp4";
marvell,function = "gpio";
};
};
};

View File

@ -0,0 +1,16 @@
# Standard Boot-Script
# use only well-known variable names provided by U-Boot Distro boot
# This script assumes the boot partition to be partition 1
# and that the root partition is always partition 2.
# The vendor u-boot ships without setexpr compiled in.
# figure out partition uuid to pass to the kernel as root=
part uuid ${devtype} ${devnum}:2 uuid
# generate bootargs (rootfs)
setenv bootargs root=PARTUUID=${uuid} rootfstype=auto rootwait
echo "Booting Linux with ${bootargs}"
load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} @DTB@.dtb
load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} Image
booti ${kernel_addr_r} - ${fdt_addr_r}

View File

@ -80,3 +80,13 @@ define Device/iei_puzzle-m902
DEVICE_PACKAGES += kmod-rtc-ds1307
endef
TARGET_DEVICES += iei_puzzle-m902
define Device/solidrun_clearfog-pro
$(call Device/Default-arm64)
SOC := cn9130
DEVICE_VENDOR := SolidRun
DEVICE_MODEL := ClearFog Pro
DEVICE_PACKAGES += kmod-i2c-mux-pca954x
BOOT_SCRIPT := clearfog-pro
endef
TARGET_DEVICES += solidrun_clearfog-pro

View File

@ -18,8 +18,6 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
drivers/cpufreq/armada-8k-cpufreq.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/cpufreq/armada-8k-cpufreq.c b/drivers/cpufreq/armada-8k-cpufreq.c
index b0fc5e84f857..8afefdea4d80 100644
--- a/drivers/cpufreq/armada-8k-cpufreq.c
+++ b/drivers/cpufreq/armada-8k-cpufreq.c
@@ -21,6 +21,13 @@
@ -36,7 +34,7 @@ index b0fc5e84f857..8afefdea4d80 100644
/*
* Setup the opps list with the divider for the max frequency, that
* will be filled at runtime.
@@ -127,7 +134,8 @@ static int __init armada_8k_cpufreq_init(void)
@@ -127,7 +134,8 @@ static int __init armada_8k_cpufreq_init
struct device_node *node;
struct cpumask cpus;
@ -46,7 +44,7 @@ index b0fc5e84f857..8afefdea4d80 100644
if (!node || !of_device_is_available(node)) {
of_node_put(node);
return -ENODEV;
@@ -204,12 +212,6 @@ static void __exit armada_8k_cpufreq_exit(void)
@@ -204,12 +212,6 @@ static void __exit armada_8k_cpufreq_exi
}
module_exit(armada_8k_cpufreq_exit);
@ -59,6 +57,3 @@ index b0fc5e84f857..8afefdea4d80 100644
MODULE_AUTHOR("Gregory Clement <gregory.clement@bootlin.com>");
MODULE_DESCRIPTION("Armada 8K cpufreq driver");
MODULE_LICENSE("GPL");
--
2.43.2

View File

@ -0,0 +1,27 @@
From: Tobias Schramm <tobias@t-sys.eu>
Subject: mvpp2: support fetching mac address from nvmem
The mvpp2 driver did not query nvmem for hardware mac addresses. This
patch adds querying of mac addresses stored in nvmem cells as a further
fallback option before assigning a random address.
Purposely added separately to fwnode_get_mac_address() above to maintain
existing behaviour with builtin adapter mac address still taking
precedence.
Signed-off-by: Tobias Schramm <tobias@t-sys.eu>
---
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -6134,6 +6134,12 @@ static void mvpp2_port_copy_mac_addr(str
}
}
+ if (!of_get_mac_address(to_of_node(fwnode), hw_mac_addr)) {
+ *mac_from = "nvmem cell";
+ eth_hw_addr_set(dev, hw_mac_addr);
+ return;
+ }
+
*mac_from = "random";
eth_hw_addr_random(dev);
}