new file mode 100644
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2018 NXP
+ * Copyright 2022 Josua Mayer <josua@solid-run.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This DPC configures SolidRun Clearfog-CX with 8x10Gbps SerDes & 1Gbps RGMII ports.
+ */
+
+/dts-v1/;
+
+/ {
+ resources {
+ icid_pools {
+
+ icid_pool@1 {
+ num = <0x64>;
+ base_icid = <0x0>;
+ };
+ };
+ };
+
+ mc_general {
+ log {
+ mode = "LOG_MODE_ON";
+ level = "LOG_LEVEL_WARNING";
+ timestamp = "LOG_TIMESTAMP_ON"; /* "LOG_TIMESTAMP_OFF" */
+ };
+
+ console {
+ mode = "CONSOLE_MODE_ON";
+ uart_id = <0x4>;
+ level = "LOG_LEVEL_WARNING";
+ };
+ };
+
+ controllers {
+ qbman {
+ /* Transform this number of 8-WQ channels into four times
+ * as many 2-WQ channels. This allows the creation of a
+ * larger number of DPCONs.
+ */
+ wq_ch_conversion = <32>;
+ };
+ };
+
+ board_info {
+ ports {
+ mac@3 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+
+ mac@4 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+
+ mac@5 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+
+ mac@6 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+
+ mac@7 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+
+ mac@8 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+
+ mac@9 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+
+ mac@10 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+
+ mac@17 {
+ link_type = "MAC_LINK_TYPE_PHY";
+ };
+ };
+ };
+};
new file mode 100644
@@ -0,0 +1,556 @@
+/*
+ * Copyright 2018 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the above-listed copyright holders nor the
+ * names of any contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+/ {
+ dpl-version = <10>;
+ /*****************************************************************
+ * Containers
+ *****************************************************************/
+ containers {
+
+ dprc@1 {
+ compatible = "fsl,dprc";
+ parent = "none";
+ options = "DPRC_CFG_OPT_SPAWN_ALLOWED", "DPRC_CFG_OPT_ALLOC_ALLOWED", "DPRC_CFG_OPT_OBJ_CREATE_ALLOWED", "DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED", "DPRC_CFG_OPT_IRQ_CFG_ALLOWED";
+
+ objects {
+
+ /* -------------- DPBPs --------------*/
+ obj_set@dpbp {
+ type = "dpbp";
+ ids = <0 >;
+ };
+
+ /* -------------- DPCONs --------------*/
+ obj_set@dpcon {
+ type = "dpcon";
+ ids = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 >;
+ };
+
+ /* -------------- DPIOs --------------*/
+ obj_set@dpio {
+ type = "dpio";
+ ids = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 >;
+ };
+
+ /* -------------- DPMACs --------------*/
+ obj_set@dpmac {
+ type = "dpmac";
+ ids = <3 4 5 6 7 8 9 10 17 >;
+ };
+
+ /* -------------- DPMCPs --------------*/
+ obj_set@dpmcp {
+ type = "dpmcp";
+ ids = <1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 >;
+ };
+
+ /* -------------- DPNIs --------------*/
+ obj_set@dpni {
+ type = "dpni";
+ ids = <0 >;
+ };
+
+ /* -------------- DPRTCs --------------*/
+ obj_set@dprtc {
+ type = "dprtc";
+ ids = <0 >;
+ };
+
+ /* -------------- DPSECIs --------------*/
+ obj_set@dpseci {
+ type = "dpseci";
+ ids = <0 >;
+ };
+ };
+ };
+ };
+
+ /*****************************************************************
+ * Objects
+ *****************************************************************/
+ objects {
+
+ dpbp@0 {
+ compatible = "fsl,dpbp";
+ };
+
+ dpcon@0 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@1 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@2 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@3 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@4 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@5 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@6 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@7 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@8 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@9 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@10 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@11 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@12 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@13 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@14 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpcon@15 {
+ compatible = "fsl,dpcon";
+ num_priorities = <0x2>;
+ };
+
+ dpio@0 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@1 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@2 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@3 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@4 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@5 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@6 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@7 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@8 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@9 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@10 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@11 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@12 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@13 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@14 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpio@15 {
+ compatible = "fsl,dpio";
+ channel_mode = "DPIO_LOCAL_CHANNEL";
+ num_priorities = <0x8>;
+ };
+
+ dpmac@3 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmac@4 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmac@5 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmac@6 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmac@7 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmac@8 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmac@9 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmac@10 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmac@17 {
+ compatible = "fsl,dpmac";
+ };
+
+ dpmcp@1 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@2 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@3 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@4 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@5 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@6 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@7 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@8 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@9 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@10 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@11 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@12 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@13 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@14 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@15 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@16 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@17 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@18 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@19 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@20 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@21 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@22 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@23 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@24 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@25 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@26 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@27 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@28 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@29 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@30 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@31 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@32 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@33 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@34 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@35 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@36 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@37 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@38 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@39 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@40 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@41 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@42 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@43 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@44 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@45 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@46 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@47 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@48 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@49 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@50 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@51 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpmcp@52 {
+ compatible = "fsl,dpmcp";
+ };
+
+ dpni@0 {
+ compatible = "fsl,dpni";
+ type = "DPNI_TYPE_NIC";
+ num_queues = <16>;
+ num_tcs = <1>;
+ num_cgs = <1>;
+ mac_filter_entries = <16>;
+ vlan_filter_entries = <0>;
+ fs_entries = <64>;
+ qos_entries = <0>;
+ dist_key_size = <56>;
+ };
+
+ dprtc@0 {
+ compatible = "fsl,dprtc";
+ };
+
+ dpseci@0 {
+ compatible = "fsl,dpseci";
+ priorities = <1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1>;
+ };
+ };
+
+ /*****************************************************************
+ * Connections
+ *****************************************************************/
+ connections {
+
+ connection@1{
+ endpoint1 = "dpni@0";
+ endpoint2 = "dpmac@17";
+ };
+ };
+};
new file mode 100644
@@ -0,0 +1,8 @@
+DEFAULT clearfog
+TIMEOUT 3
+
+LABEL clearfog
+ KERNEL /boot/Image
+ FDT /boot/fsl-lx2160a-clearfog-cx.dtb
+ APPEND root=LABEL=rootfs rw rootwait cma=256M
+ INITRD /boot/rootfs.cpio.gz
new file mode 100644
@@ -0,0 +1,84 @@
+# layout
+# 0x00000400 (4K) RCW (bl2_sd.pbl)
+# 0x00100000 (1M) u-boot FIP (fip.bin)
+# 0x00500000 (5M) U-Boot env (uboot-env.bin)
+# 0x00600000 (6M) GPT primary header + entries
+# 0x00800000 (8M) DDR PHY FIP (fip_ddr.bin)
+# 0x00A00000 (10M) MC firmware (mc.itb)
+# 0x00D00000 (13M) DPL
+# 0x00E00000 (14M) DPC
+# 0x01000000 (16M) First FAT partition (boot FAT)
+
+image sdcard.img {
+ hdimage {
+ partition-table-type = "dos"
+ }
+
+ partition rcw {
+ offset = 4K
+ in-partition-table = "no"
+ image = "bl2_sd.pbl"
+ }
+
+ partition u-boot {
+ offset = 1M
+ in-partition-table = "no"
+ image = "fip.bin"
+ }
+
+ partition u-boot-environment {
+ in-partition-table = "no"
+ image = "uboot-env.bin"
+ offset = 5M
+ }
+
+ partition ddr-phy {
+ in-partition-table = "no"
+ image = "fip_ddr.bin"
+ offset = 8M
+ }
+
+ partition dpaa2-mc {
+ in-partition-table = "no"
+ image = "mc.itb"
+ offset = 10M
+ }
+
+ partition dpaa2-dpl {
+ in-partition-table = "no"
+ image = "clearfog-cx-s1_8-s2_0-dpl.dtb"
+ offset = 13M
+ }
+
+ partition dpaa2-dpc {
+ in-partition-table = "no"
+ image = "clearfog-cx-s1_8-s2_0-dpc.dtb"
+ offset = 14M
+ }
+
+ # boot using uboot's sysboot
+ # uboot's `fstype mmc 0:1` shall return fat
+ partition boot {
+ # fat32 LBA
+ partition-type = 0x0c
+ bootable = "true"
+ offset = 16M
+ size = 40M
+ image = "boot.vfat"
+ }
+
+}
+
+image boot.vfat {
+ vfat {
+ label = "BOOT"
+ file "boot/Image" { image = "Image" }
+ file "boot/rootfs.cpio.gz" { image = "rootfs.cpio.gz" }
+ file "boot/fsl-lx2160a-clearfog-cx.dtb" { image = "fsl-lx2160a-clearfog-cx.dtb" }
+ file "boot/fsl-lx2160a-honeycomb.dtb" { image = "fsl-lx2160a-honeycomb.dtb" }
+ file "boot/extlinux/extlinux.conf" { image = "extlinux.conf" }
+ file "boot/u-boot.dtb" { image = "u-boot.dtb" }
+ files = { "boot.scr" }
+ }
+ size = 40M
+}
new file mode 100644
@@ -0,0 +1,636 @@
+CONFIG_BLK_DEV_NVME=y
+CONFIG_PMBUS=y
+CONFIG_SENSORS_AMC6821=y
+CONFIG_SENSORS_LTC2978=y
+CONFIG_SENSORS_LTC2978_REGULATOR=y
+CONFIG_DEFAULT_HOSTNAME="nodeboxv3"
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_BPF_STREAM_PARSER=y
+CONFIG_HAVE_EBPF_JIT=y
+CONFIG_NET_CLS_BPF=y
+CONFIG_BPF_JIT_ALWAYS_ON=y
+CONFIG_BPF_JIT=y
+CONFIG_XDP_SOCKETS=y
+CONFIG_PREEMPT=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_MEMCG=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_KEXEC_FILE=y
+CONFIG_ARCH_NXP=y
+CONFIG_ARCH_LAYERSCAPE=y
+# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set
+# CONFIG_ARM64_ERRATUM_826319 is not set
+# CONFIG_ARM64_ERRATUM_827319 is not set
+# CONFIG_ARM64_ERRATUM_824069 is not set
+# CONFIG_ARM64_ERRATUM_819472 is not set
+# CONFIG_ARM64_ERRATUM_832075 is not set
+# CONFIG_ARM64_ERRATUM_845719 is not set
+# CONFIG_ARM64_ERRATUM_843419 is not set
+# CONFIG_ARM64_ERRATUM_1024718 is not set
+# CONFIG_ARM64_ERRATUM_1418040 is not set
+# CONFIG_ARM64_ERRATUM_1165522 is not set
+# CONFIG_ARM64_ERRATUM_1530923 is not set
+# CONFIG_ARM64_ERRATUM_1463225 is not set
+# CONFIG_ARM64_ERRATUM_1508412 is not set
+# CONFIG_ARM64_ERRATUM_2051678 is not set
+# CONFIG_ARM64_ERRATUM_2077057 is not set
+# CONFIG_ARM64_ERRATUM_2658417 is not set
+# CONFIG_ARM64_ERRATUM_2054223 is not set
+# CONFIG_ARM64_ERRATUM_2067961 is not set
+# CONFIG_ARM64_ERRATUM_2457168 is not set
+# CONFIG_ARM64_ERRATUM_2645198 is not set
+# CONFIG_ARM64_ERRATUM_2966298 is not set
+# CONFIG_ARM64_ERRATUM_3117295 is not set
+# CONFIG_CAVIUM_ERRATUM_22375 is not set
+# CONFIG_CAVIUM_ERRATUM_23144 is not set
+# CONFIG_CAVIUM_ERRATUM_23154 is not set
+# CONFIG_CAVIUM_ERRATUM_27456 is not set
+# CONFIG_CAVIUM_ERRATUM_30115 is not set
+# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set
+# CONFIG_FUJITSU_ERRATUM_010001 is not set
+# CONFIG_HISILICON_ERRATUM_161600802 is not set
+# CONFIG_HISILICON_ERRATUM_162100801 is not set
+# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
+# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
+# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
+# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set
+# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set
+# CONFIG_ROCKCHIP_ERRATUM_3588001 is not set
+# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_NR_CPUS=16
+CONFIG_NUMA=y
+CONFIG_PARAVIRT=y
+CONFIG_COMPAT=y
+CONFIG_RANDOMIZE_BASE=y
+# CONFIG_EFI is not set
+# CONFIG_SUSPEND is not set
+CONFIG_PM=y
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_ENERGY_MODEL=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_QORIQ_CPUFREQ=y
+CONFIG_JUMP_LABEL=y
+# CONFIG_GCC_PLUGINS is not set
+CONFIG_MODULES=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_INTEGRITY=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_PAGE_REPORTING=y
+CONFIG_KSM=y
+CONFIG_MEMORY_FAILURE=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_CMA=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6_SIT is not set
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NETFILTER_XT_MARK=y
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_IPVS=y
+CONFIG_IP_VS=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_NAT=y
+CONFIG_IP6_NF_TARGET_MASQUERADE=y
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBS=y
+CONFIG_NET_SCH_ETF=y
+CONFIG_NET_SCH_TAPRIO=y
+CONFIG_NET_SCH_MQPRIO=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_CLS_BASIC=y
+CONFIG_NET_CLS_FLOWER=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_NET_ACT_GATE=y
+CONFIG_NET_SWITCHDEV=y
+# CONFIG_WIRELESS is not set
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_FAILOVER=y
+CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEASPM_PERFORMANCE=y
+CONFIG_PCI_IOV=y
+CONFIG_PCI_PASID=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_PCI_LAYERSCAPE_EP=y
+CONFIG_PCI_ENDPOINT=y
+CONFIG_PCI_ENDPOINT_CONFIGFS=y
+CONFIG_PCI_EPF_TEST=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_FSL_MC_UAPI_SUPPORT=y
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_SRAM=y
+CONFIG_PCI_ENDPOINT_TEST=y
+CONFIG_MD=y
+# CONFIG_MD_BITMAP_FILE is not set
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_VERITY=y
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_AGERE is not set
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_ASIX is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_DAVICOM is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_ENGLEDER is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+CONFIG_FSL_FMAN=y
+CONFIG_FSL_DPAA_ETH=y
+CONFIG_FSL_DPAA2_ETH=y
+# CONFIG_NET_VENDOR_FUNGIBLE is not set
+# CONFIG_NET_VENDOR_GOOGLE is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_LITEX is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_META is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+# CONFIG_NET_VENDOR_MICROSOFT is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETERION is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_VENDOR_PACKET_ENGINES is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VERTEXCOM is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WANGXUN is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_SFP=y
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
+# CONFIG_USB_NET_DRIVERS is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_FSL_LINFLEXUART=y
+CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_SLAVE=y
+# CONFIG_PTP_1588_CLOCK_KVM is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_MPC8XXX=y
+CONFIG_GPIO_AGGREGATOR=y
+CONFIG_POWER_RESET_XGENE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_NVMEM_REBOOT_MODE=y
+CONFIG_SENSORS_ARM_SCMI=y
+CONFIG_SENSORS_ARM_SCPI=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
+CONFIG_CPU_THERMAL=y
+CONFIG_QORIQ_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
+CONFIG_ARM_SBSA_WATCHDOG=y
+CONFIG_ARM_SMC_WATCHDOG=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_ULPI_BUS=y
+CONFIG_USB_CONN_GPIO=y
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_DWC3=y
+# CONFIG_USB_DWC3_HAPS is not set
+CONFIG_USB_DWC2=y
+CONFIG_USB_ULPI=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ESDHC=y
+CONFIG_MMC_CQHCI=y
+CONFIG_EDAC=y
+CONFIG_EDAC_LAYERSCAPE=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_FSL_FTM_ALARM=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+CONFIG_FSL_QDMA=y
+CONFIG_PL330_DMA=y
+CONFIG_FSL_DPAA2_QDMA=y
+CONFIG_SYNC_FILE=y
+CONFIG_VFIO=y
+CONFIG_VFIO_FSL_MC=y
+# CONFIG_VIRTIO_MENU is not set
+# CONFIG_VHOST_MENU is not set
+# CONFIG_SURFACE_PLATFORMS is not set
+CONFIG_COMMON_CLK_SCMI=y
+CONFIG_COMMON_CLK_SCPI=y
+CONFIG_COMMON_CLK_FSL_FLEXSPI=y
+# CONFIG_CLK_LS1028A_PLLDIG is not set
+CONFIG_HWSPINLOCK=y
+# CONFIG_HISILICON_ERRATUM_161010101 is not set
+# CONFIG_ARM64_ERRATUM_858921 is not set
+CONFIG_MAILBOX=y
+CONFIG_ARM_MHU=y
+CONFIG_PLATFORM_MHU=y
+CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
+CONFIG_IOMMU_IO_PGTABLE_DART=y
+CONFIG_ARM_SMMU=y
+CONFIG_ARM_SMMU_V3=y
+CONFIG_FSL_DPAA=y
+CONFIG_FSL_MC_DPIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_GPIO=y
+CONFIG_PHY_FSL_LYNX_28G=y
+CONFIG_PHY_DS250DFX10=y
+CONFIG_ARM_CCI_PMU=y
+CONFIG_ARM_CCN=y
+CONFIG_ARM_CMN=y
+CONFIG_ARM_SMMU_V3_PMU=y
+CONFIG_ARM_DSU_PMU=y
+CONFIG_ARM_SPE_PMU=y
+CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=y
+CONFIG_NVMEM_LAYERSCAPE_SFP=y
+CONFIG_NVMEM_RMEM=y
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_MUX_GPIO=y
+CONFIG_MUX_MMIO=y
+CONFIG_INTERCONNECT=y
+CONFIG_HTE=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_OVERLAY_FS=y
+CONFIG_EXFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_SQUASHFS=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_RAM=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_TEST=y
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_DH=y
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_CURVE25519=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_BLAKE2B=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_XXHASH=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_USER_API_RNG=y
+CONFIG_CRYPTO_CHACHA20_NEON=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA512_ARM64_CE=y
+CONFIG_CRYPTO_SHA3_ARM64=y
+CONFIG_CRYPTO_SM3_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_BS=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=y
+CONFIG_CRYPTO_DEV_CCREE=y
+CONFIG_CRYPTO_DEV_AMLOGIC_GXL=y
+CONFIG_ASYMMETRIC_KEY_TYPE=y
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+CONFIG_X509_CERTIFICATE_PARSER=y
+CONFIG_PKCS7_MESSAGE_PARSER=y
+CONFIG_SYSTEM_TRUSTED_KEYRING=y
+CONFIG_PACKING=y
+CONFIG_INDIRECT_PIO=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC7=y
+CONFIG_CRC8=y
+CONFIG_XZ_DEC=y
+CONFIG_DMA_RESTRICTED_POOL=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=32
+CONFIG_IRQ_POLL=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_CATU=y
+CONFIG_CORESIGHT_SINK_TPIU=y
+CONFIG_CORESIGHT_SINK_ETBV10=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_CPU_DEBUG=y
+CONFIG_CORESIGHT_CTI=y
+CONFIG_MEMTEST=y
+
+# TODO
+# missing non upstream
+# Common drivers iMX and Layerscape
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
+
+# S32 support
+CONFIG_SOC_S32V234=y
+CONFIG_PINCTRL_S32V234=y
+
+# Layerscape support
+CONFIG_INPHI_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REALTEK_PHY_HWMON=y
+# inphi missing with kernel upstream
+CONFIG_PHY_INPHI_IN112525_RETIMER=y
+CONFIG_FSL_DPAA2_MAC=y
+CONFIG_FSL_PPFE=y
+CONFIG_FSL_PPFE_UTIL_DISABLED=y
+# Qixis missing with kernel upstream
+# Qixis needed for Realtek Phy thru the mdio mux
+# XXX MFD shall be used instead
+#CONFIG_FSL_QIXIS=y
+# MTIP missing with kernel upstream
+CONFIG_MTIP_BACKPLANE_PHY=y
+CONFIG_PCS_LYNX=y
+
+CONFIG_RTC_DRV_PCF2127=y
+CONFIG_SENSORS_LM90=y
+CONFIG_SENSORS_INA2XX=y
+
+CONFIG_MFD_SL28CPLD=y
+# use it instead of the qixis FPGA MDIO driver
+CONFIG_MFD_SIMPLE_MFD_I2C=y
+# EOF missing non upstream
+
+# needed by FSL_QIXIS
+CONFIG_MFD_SEC_CORE=y
+
+#uio
+CONFIG_UIO=y
+CONFIG_UIO_PDRV_GENIRQ=y
+CONFIG_UIO_DMEM_GENIRQ=y
+CONFIG_UIO_PCI_GENERIC=y
+
+# VFIO: uio with iommu protection
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+
+# enable iommu passthrough by default for performance
+CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y
+
+# disable the "disable_bypass" temporarily to workaround the MC issue with it
+CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=n
+
+# general options
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SLAB=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_EXPERT=y
+CONFIG_PROC_KCORE=y
+
+# DPAA1 networking
+# disable the DPAA1 upstream driver
+# LX2 does not have any DPAA1
+CONFIG_FSL_DPAA=n
+CONFIG_FSL_FMAN=n
+CONFIG_FSL_DPAA_ETH=n
+
+CONFIG_QORIQ_CPUFREQ=y
+CONFIG_QORIQ_THERMAL=y
+
+CONFIG_MTD_NAND_FSL_IFC=y
+CONFIG_FSL_DPAA2_ETH=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_FSL_LINFLEXUART=y
+CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_DSPI=y
+CONFIG_SPI_FSL_LPSPI=y
+CONFIG_SPI_FSL_QUADSPI=y
+CONFIG_SPI_NXP_FLEXSPI=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_MTD=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_DEBUG=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_RTC_DRV_FSL_FTM_ALARM=y
+CONFIG_FSL_EDMA=y
+CONFIG_FSL_DPAA_1588=y
+CONFIG_FSL_MC_DPIO=y
+CONFIG_FSL_RCPM=y
+CONFIG_FSL_IFC=y
+CONFIG_PHY_FSL_LYNX_10G=y
+CONFIG_PHY_FSL_LYNX_28G=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=y
+CONFIG_FSL_DPAA2_SWITCH=y
+CONFIG_NET_DSA_MSCC_FELIX=y
+CONFIG_MSCC_FELIX_SWITCH_TSN=y
+CONFIG_FSL_MC_UAPI_SUPPORT=y
+CONFIG_FSL_MC_BUS=y
+
+CONFIG_MTIP_BACKPLANE_PHY=y
+
+CONFIG_EDAC_LAYERSCAPE=y
+CONFIG_ARCH_LAYERSCAPE=y
+CONFIG_PCI_LAYERSCAPE=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
+CONFIG_NVMEM_LAYERSCAPE_SFP=y
+
+CONFIG_FSL_DPAA2_PTP_CLOCK=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_NETWORK_PHY_TIMESTAMPING=y
+CONFIG_PPS=y
+
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_ARM_CPUIDLE=y
+
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XDP_SOCKETS_DIAG=y
+CONFIG_INET_UDP_DIAG=y
+CONFIG_INET_RAW_DIAG=y
+CONFIG_INET_DIAG_DESTROY=y
+CONFIG_NETLINK_DIAG=y
+
+# HW offload on dpni
+CONFIG_NET_SCH_TBF=y
+CONFIG_NET_ACT_SKBEDIT=y
+CONFIG_NET_CLS_U32=y
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_U32=y
+
+# Switchdev offload
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_VLAN_FILTERING=y
+
+# missing networking stack features
+CONFIG_MACVLAN=y
+CONFIG_IPV6_SEG6_LWTUNNEL=y
+CONFIG_IPV6_RPL_LWTUNNEL=y
+CONFIG_IPV6_IOAM6_LWTUNNEL=y
+CONFIG_LWTUNNEL=y
+CONFIG_TUN=y
+CONFIG_VXLAN=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+
+# high memory footprint ?
+CONFIG_FUNCTION_TRACER=y
+CONFIG_FTRACE=y
+CONFIG_KPROBES=y
+
+# DTS, including dynamic overlay
+CONFIG_OF_OVERLAY=y
+
+# /proc/config
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
new file mode 100644
@@ -0,0 +1,204 @@
+From d88ed58278a43ef670d125fce416c04c40bdbc70 Mon Sep 17 00:00:00 2001
+From: Rabeeh Khoury <rabeeh@solid-run.com>
+Date: Sun, 28 Nov 2021 14:00:07 +0200
+Subject: [PATCH 02/15] plat/nxp: lx2160a auto boot
+
+This patch adds support to patch RCW that already has SD/eMMC/SPI boot
+support embedded with conditional load and jump.
+The idea is to look for SD/eMMC/SPI boot, and modify src/dst/size
+address with the correct values; rather than adding blockread at the end
+of RCW code.
+
+With this patch images are unified and can be used to boot from SD /
+eMMC and SPI.
+
+Signed-off-by: Rabeeh Khoury <rabeeh@solid-run.com>
+---
+ .../plat_make_helper/plat_common_def.mk | 5 ++
+ plat/nxp/soc-lx2160a/soc.mk | 5 ++
+ tools/nxp/create_pbl/create_pbl.c | 74 ++++++++++++++++---
+ 3 files changed, 74 insertions(+), 10 deletions(-)
+
+diff --git a/plat/nxp/common/plat_make_helper/plat_common_def.mk b/plat/nxp/common/plat_make_helper/plat_common_def.mk
+index 86dacf83d..a1038a073 100644
+--- a/plat/nxp/common/plat_make_helper/plat_common_def.mk
++++ b/plat/nxp/common/plat_make_helper/plat_common_def.mk
+@@ -91,6 +91,11 @@ define add_boot_mode_define
+ else ifeq ($(1),flexspi_nor)
+ $$(eval $$(call SET_NXP_MAKE_FLAG,XSPI_NEEDED,BL2))
+ $$(eval $$(call add_define,FLEXSPI_NOR_BOOT))
++ else ifeq ($(1),auto)
++ $$(eval $$(call SET_FLAG,SD_MMC_NEEDED,BL2))
++ $$(eval $$(call add_define,EMMC_BOOT))
++ $$(eval $$(call SET_FLAG,XSPI_NEEDED,BL2))
++ $$(eval $$(call add_define,FLEXSPI_NOR_BOOT))
+ else
+ $$(error $(PLAT) Cannot Support Boot Mode: $(BOOT_MODE))
+ endif
+diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
+index 239442c20..a72b4113d 100644
+--- a/plat/nxp/soc-lx2160a/soc.mk
++++ b/plat/nxp/soc-lx2160a/soc.mk
+@@ -82,6 +82,11 @@ else
+ ifeq (${BOOT_MODE}, emmc)
+ $(eval $(call SET_NXP_MAKE_FLAG,SD_MMC_NEEDED,BL2))
+ $(eval $(call add_define,EMMC_BOOT))
++else ifeq (${BOOT_MODE}, auto)
++$(eval $(call SET_NXP_MAKE_FLAG,SD_MMC_NEEDED,BL2))
++$(eval $(call add_define,EMMC_BOOT))
++$(eval $(call SET_NXP_MAKE_FLAG,XSPI_NEEDED,BL2))
++$(eval $(call add_define,FLEXSPI_NOR_BOOT))
+ else
+ $(error Un-supported Boot Mode = ${BOOT_MODE})
+ endif
+diff --git a/tools/nxp/create_pbl/create_pbl.c b/tools/nxp/create_pbl/create_pbl.c
+index c277e391a..ddda4dc68 100644
+--- a/tools/nxp/create_pbl/create_pbl.c
++++ b/tools/nxp/create_pbl/create_pbl.c
+@@ -66,6 +66,7 @@ typedef enum {
+ FLXSPI_NOR_BOOT,
+ FLXSPI_NAND_BOOT,
+ FLXSPI_NAND4K_BOOT,
++ AUTO_BOOT,
+ MAX_BOOT /* must be last item in list */
+ } boot_src_t;
+
+@@ -140,6 +141,7 @@ char *boot_src_string[] = {
+ "FLXSPI_NOR_BOOT",
+ "FLXSPI_NAND_BOOT",
+ "FLXSPI_NAND4K_BOOT",
++ "AUTO_BOOT",
+ };
+
+ enum stop_command {
+@@ -193,7 +195,7 @@ struct pbl_image {
+ #define SOC_LS2088 2088
+ #define SOC_LX2160 2160
+
+-static uint32_t pbl_size;
++static uint32_t pbl_size = 0;
+ bool sb_flag;
+
+ /***************************************************************************
+@@ -703,6 +705,8 @@ int main(int argc, char **argv)
+ int ret = FAILURE;
+ bool bootptr_flag = false;
+ enum stop_command flag_stop_cmd = CRC_STOP_COMMAND;
++ int skip = 0;
++ uint32_t saved_src;
+
+ /* Initializing the global structure to zero. */
+ memset(&pblimg, 0x0, sizeof(struct pbl_image));
+@@ -802,6 +806,8 @@ int main(int argc, char **argv)
+ pblimg.boot_src = FLXSPI_NAND_BOOT;
+ } else if (strcmp(optarg, "flexspi_nand2k") == 0) {
+ pblimg.boot_src = FLXSPI_NAND4K_BOOT;
++ } else if (strcmp(optarg, "auto") == 0) {
++ pblimg.boot_src = AUTO_BOOT;
+ } else {
+ printf("CMD Error: Invalid boot source.\n");
+ goto exit_main;
+@@ -909,13 +915,14 @@ int main(int argc, char **argv)
+ printf("%s: Error reading PBI Cmd.\n", __func__);
+ goto exit_main;
+ }
++ saved_src = pblimg.src_addr;
+ while (word != 0x808f0000 && word != 0x80ff0000) {
+ pbl_size++;
+ /* 11th words in RCW has PBL length. Update it
+ * with new length. 2 commands get added
+ * Block copy + CCSR Write/CSF header write
+ */
+- if (pbl_size == 11) {
++ if ((pbl_size == 11) && (pblimg.boot_src != AUTO_BOOT)) {
+ word_1 = (word & PBI_LEN_MASK)
+ + (PBI_LEN_ADD << 20);
+ word = word & ~PBI_LEN_MASK;
+@@ -933,8 +940,50 @@ int main(int argc, char **argv)
+ goto exit_main;
+ }
+ }
+- if (fwrite(&word, sizeof(word), NUM_MEM_BLOCK,
+- fp_rcw_pbi_op) != NUM_MEM_BLOCK) {
++ if (pblimg.boot_src == AUTO_BOOT) {
++ if (word == 0x80000008) {
++ printf ("Found SD boot at %d\n",pbl_size);
++ pblimg.boot_src = SD_BOOT;
++ add_blk_cpy_cmd(fp_rcw_pbi_op, args);
++ skip = 4; // skip original blockcopy
++ pblimg.boot_src = AUTO_BOOT;
++ pblimg.src_addr = saved_src;
++ if (bootptr_flag == true) {
++ add_boot_ptr_cmd(fp_rcw_pbi_op);
++ skip += 2; // skip original bootlocptr write (low byte only)
++ printf("added bootptr\n");
++ }
++ }
++ if (word == 0x80000009) {
++ printf ("Found eMMC boot at %d\n",pbl_size);
++ pblimg.boot_src = EMMC_BOOT;
++ add_blk_cpy_cmd(fp_rcw_pbi_op, args);
++ skip = 4; // skip original blockcopy
++ pblimg.boot_src = AUTO_BOOT;
++ pblimg.src_addr = saved_src;
++ if (bootptr_flag == true) {
++ add_boot_ptr_cmd(fp_rcw_pbi_op);
++ skip += 2; // skip original bootlocptr write (low byte only)
++ printf("added bootptr\n");
++ }
++ }
++ if (word == 0x8000000f) {
++ printf ("Found SPI boot at %d\n",pbl_size);
++ pblimg.boot_src = FLXSPI_NOR_BOOT;
++ add_blk_cpy_cmd(fp_rcw_pbi_op, args);
++ skip = 4; // skip original blockcopy
++ pblimg.boot_src = AUTO_BOOT;
++ pblimg.src_addr = saved_src;
++ if (bootptr_flag == true) {
++ add_boot_ptr_cmd(fp_rcw_pbi_op);
++ skip += 2; // skip original bootlocptr write (low byte only)
++ printf("added bootptr\n");
++ }
++ }
++ }
++ if (!skip &&
++ (fwrite(&word, sizeof(word), NUM_MEM_BLOCK,
++ fp_rcw_pbi_op) != NUM_MEM_BLOCK)) {
+ printf("%s: [CH3] Error in Writing PBI Words\n",
+ __func__);
+ goto exit_main;
+@@ -951,8 +1000,11 @@ int main(int argc, char **argv)
+ } else if (word == STOP_CMD_ARM_CH3) {
+ flag_stop_cmd = STOP_COMMAND;
+ }
++
++ if (skip)
++ skip--;
+ }
+- if (bootptr_flag == true) {
++ if ((pblimg.boot_src != AUTO_BOOT) && (bootptr_flag == true)) {
+ /* Add command to set boot_loc ptr */
+ ret = add_boot_ptr_cmd(fp_rcw_pbi_op);
+ if (ret != SUCCESS) {
+@@ -963,11 +1015,13 @@ int main(int argc, char **argv)
+ }
+
+ /* Write acs write commands to output file */
+- ret = add_blk_cpy_cmd(fp_rcw_pbi_op, args);
+- if (ret != SUCCESS) {
+- printf("%s: Function add_blk_cpy_cmd return failure.\n",
+- __func__);
+- goto exit_main;
++ if (pblimg.boot_src != AUTO_BOOT) {
++ ret = add_blk_cpy_cmd(fp_rcw_pbi_op, args);
++ if (ret != SUCCESS) {
++ printf("%s: Function add_blk_cpy_cmd return failure.\n",
++ __func__);
++ goto exit_main;
++ }
+ }
+
+ /* Add stop command after adding pbi commands */
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,86 @@
+From 938dddf91666d98de8f1bbea9d9f5f5d653a3b7c Mon Sep 17 00:00:00 2001
+From: Jon Nettleton <jon@solid-run.com>
+Date: Tue, 8 Oct 2024 04:56:45 +0200
+Subject: [PATCH 03/15] dcfg: Take into account MEM_PLL_CFG_SHIFT for ddr
+ frequency
+
+The base ddr clock frequency is 1/4 the speed of the final
+ddr clock frequency. By default the RCW config is setting
+the CFG_SHIFT to be a 1/4 divider of the memory speed,
+i.e. 3200 / 4 (800MHz). The parent DDRCLK is 100MHz so PLL_RAT
+needs to be rounded to 100MHz. However using a divider of / 3 for
+a lower speed always us to match industry standard ddr4 speeds
+2666 and 2933 (2000 / 3 * 4 = 2666.67)
+
+This patch takes into account the PLL_CFG_SHIFT divider so these
+speeds can be configured in the RCW and then updates the helper
+function that reports ddr_clk_freq to properly multiply the
+clock fed into the DDRC * 4 to properly reflect the actual MTs
+that the memory is being configured for.
+
+Signed-off-by: Jon Nettleton <jon@solid-run.com>
+---
+ drivers/nxp/dcfg/dcfg.c | 6 ++++++
+ drivers/nxp/ddr/nxp-ddr/utility.c | 6 +++---
+ include/drivers/nxp/dcfg/dcfg_lsch3.h | 4 ++++
+ 3 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/nxp/dcfg/dcfg.c b/drivers/nxp/dcfg/dcfg.c
+index e5c4db437..4a5820a64 100644
+--- a/drivers/nxp/dcfg/dcfg.c
++++ b/drivers/nxp/dcfg/dcfg.c
+@@ -104,9 +104,15 @@ int get_clocks(struct sysinfo *sys)
+ sys->freq_ddr_pll0 *= (gur_in32(rcwsr0) >>
+ RCWSR0_MEM_PLL_RAT_SHIFT) &
+ RCWSR0_MEM_PLL_RAT_MASK;
++ sys->freq_ddr_pll0 /= ((gur_in32(rcwsr0) >>
++ RCWSR0_MEM_PLL_CFG_SHIFT) &
++ RCWSR0_MEM_PLL_CFG_MASK) + 1;
+ sys->freq_ddr_pll1 *= (gur_in32(rcwsr0) >>
+ RCWSR0_MEM2_PLL_RAT_SHIFT) &
+ RCWSR0_MEM2_PLL_RAT_MASK;
++ sys->freq_ddr_pll1 /= ((gur_in32(rcwsr0) >>
++ RCWSR0_MEM2_PLL_CFG_SHIFT) &
++ RCWSR0_MEM2_PLL_CFG_MASK) + 1;
+ if (sys->freq_platform == 0) {
+ return 1;
+ } else {
+diff --git a/drivers/nxp/ddr/nxp-ddr/utility.c b/drivers/nxp/ddr/nxp-ddr/utility.c
+index b6dffc872..3920b4488 100644
+--- a/drivers/nxp/ddr/nxp-ddr/utility.c
++++ b/drivers/nxp/ddr/nxp-ddr/utility.c
+@@ -47,11 +47,11 @@ unsigned long get_ddr_freq(struct sysinfo *sys, int ctrl_num)
+
+ switch (ctrl_num) {
+ case 0:
+- return sys->freq_ddr_pll0;
++ return sys->freq_ddr_pll0 * 4;
+ case 1:
+- return sys->freq_ddr_pll0;
++ return sys->freq_ddr_pll0 * 4;
+ case 2:
+- return sys->freq_ddr_pll1;
++ return sys->freq_ddr_pll1 * 4;
+ }
+
+ return 0;
+diff --git a/include/drivers/nxp/dcfg/dcfg_lsch3.h b/include/drivers/nxp/dcfg/dcfg_lsch3.h
+index cde86fe19..f9409d1a7 100644
+--- a/include/drivers/nxp/dcfg/dcfg_lsch3.h
++++ b/include/drivers/nxp/dcfg/dcfg_lsch3.h
+@@ -53,8 +53,12 @@
+ #define RCWSR0_OFFSET 0x100
+ #define RCWSR0_SYS_PLL_RAT_SHIFT 2
+ #define RCWSR0_SYS_PLL_RAT_MASK 0x1f
++#define RCWSR0_MEM_PLL_CFG_SHIFT 8
++#define RCWSR0_MEM_PLL_CFG_MASK 0x3
+ #define RCWSR0_MEM_PLL_RAT_SHIFT 10
+ #define RCWSR0_MEM_PLL_RAT_MASK 0x3f
++#define RCWSR0_MEM2_PLL_CFG_SHIFT 16
++#define RCWSR0_MEM2_PLL_CFG_MASK 0x3
+ #define RCWSR0_MEM2_PLL_RAT_SHIFT 18
+ #define RCWSR0_MEM2_PLL_RAT_MASK 0x3f
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,61 @@
+From 36bf5eae8356d2c89047e8b5f751d6f2c2d922a1 Mon Sep 17 00:00:00 2001
+From: Rabeeh Khoury <rabeeh@solid-run.com>
+Date: Sun, 28 Nov 2021 13:33:10 +0200
+Subject: [PATCH 04/15] lx2160a: assert optional S5 gpio from Makefile constant
+
+GPIO address and number for S5 are specific per board and should not be
+set globally across lx2160.
+
+Add support for setting gpio address and number form platform.mk, into
+soc.mk:
+
+- LX2160A_S5_GPIO_ADDR: gpio value register address
+- LX2160A_S5_GPIO: gpio number
+
+This feature can be enabled for individual boards by setting a non-zero
+address in platform.mk file, before including soc.mk.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ plat/nxp/soc-lx2160a/aarch64/lx2160a.S | 8 ++++++++
+ plat/nxp/soc-lx2160a/soc.mk | 8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/plat/nxp/soc-lx2160a/aarch64/lx2160a.S b/plat/nxp/soc-lx2160a/aarch64/lx2160a.S
+index cc679f2ba..67ade7b66 100644
+--- a/plat/nxp/soc-lx2160a/aarch64/lx2160a.S
++++ b/plat/nxp/soc-lx2160a/aarch64/lx2160a.S
+@@ -563,6 +563,14 @@ endfunc _soc_sys_reset
+ */
+ func _soc_sys_off
+
++#if defined(CONFIG_LX2160A_S5_GPIO_ADDR) && defined(CONFIG_LX2160A_S5_GPIO)
++ /* assert s5 gpio */
++ mov x3, # CONFIG_LX2160A_S5_GPIO_ADDR
++ ldr w1, [x3]
++ orr w1, w1, # 1 << (31 - CONFIG_LX2160A_S5_GPIO)
++ str w1, [x3]
++#endif
++
+ /* disable sec, QBman, spi and qspi */
+ ldr x2, =NXP_DCFG_ADDR
+ ldr x0, =DCFG_DEVDISR1_OFFSET
+diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
+index a72b4113d..20e64753c 100644
+--- a/plat/nxp/soc-lx2160a/soc.mk
++++ b/plat/nxp/soc-lx2160a/soc.mk
+@@ -177,3 +177,11 @@ include ${PLAT_PATH}/common/setup/common.mk
+
+ # Adding source files to generate separate DDR FIP image
+ include ${PLAT_SOC_PATH}/ddr_fip.mk
++
++# S5 GPIO (optional)
++LX2160A_S5_GPIO_ADDR ?= 0
++LX2160A_S5_GPIO ?= 0
++ifneq (${LX2160A_S5_GPIO_ADDR},0)
++$(eval $(call add_define_val,CONFIG_LX2160A_S5_GPIO_ADDR,$(LX2160A_S5_GPIO_ADDR)))
++$(eval $(call add_define_val,CONFIG_LX2160A_S5_GPIO,$(LX2160A_S5_GPIO)))
++endif
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,33 @@
+From 5f8f78883f22663b5b8088303f15f2b604812a80 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Fri, 18 Oct 2024 21:17:12 +0200
+Subject: [PATCH 05/15] lx2160a: support flexible value for CONFIG_DDR_NODIMM
+
+Add support for values other than 0 and 1 for CONFIG_DDR_NODIMM.
+This macro can be used for both enabling, and selecting a specific
+memory configuration at compile-time.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ plat/nxp/common/plat_make_helper/plat_common_def.mk | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/plat/nxp/common/plat_make_helper/plat_common_def.mk b/plat/nxp/common/plat_make_helper/plat_common_def.mk
+index a1038a073..ed6e0bdac 100644
+--- a/plat/nxp/common/plat_make_helper/plat_common_def.mk
++++ b/plat/nxp/common/plat_make_helper/plat_common_def.mk
+@@ -39,8 +39,9 @@ ifneq (${NUM_OF_DDRC},)
+ $(eval $(call add_define_val,NUM_OF_DDRC,${NUM_OF_DDRC}))
+ endif
+
+-ifeq (${CONFIG_DDR_NODIMM},1)
+-$(eval $(call add_define,CONFIG_DDR_NODIMM))
++CONFIG_DDR_NODIMM ?= 0
++ifneq (${CONFIG_DDR_NODIMM},0)
++$(eval $(call add_define_val,CONFIG_DDR_NODIMM,${CONFIG_DDR_NODIMM}))
+ DDRC_NUM_DIMM := 1
+ endif
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,48 @@
+From 1dea78ec49250e2c1983fc93ea4c6e3d82196353 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sat, 1 Mar 2025 12:32:03 +0100
+Subject: [PATCH 06/15] plat: nxp: layerscape: mmap dynamic configuration
+ region in bl2
+
+Even before DDR configuration BL2 may wish to modify dynamic
+configuration registers e.g. for changing pinmux and implementing an
+unstucking procedure on i2c bus.
+
+Add mapping for DCFG area in BL2 and increment MAX_MMAP_REGIONS by one.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ plat/nxp/common/include/default/plat_default_def.h | 2 +-
+ plat/nxp/common/setup/ls_common.c | 3 +++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/plat/nxp/common/include/default/plat_default_def.h b/plat/nxp/common/include/default/plat_default_def.h
+index 7f3298006..5669cbad9 100644
+--- a/plat/nxp/common/include/default/plat_default_def.h
++++ b/plat/nxp/common/include/default/plat_default_def.h
+@@ -147,7 +147,7 @@
+ /* Check if this size can be determined from array size */
+ #if defined(IMAGE_BL2)
+ #ifndef MAX_MMAP_REGIONS
+-#define MAX_MMAP_REGIONS 8
++#define MAX_MMAP_REGIONS 9
+ #endif
+ #ifndef MAX_XLAT_TABLES
+ #define MAX_XLAT_TABLES 6
+diff --git a/plat/nxp/common/setup/ls_common.c b/plat/nxp/common/setup/ls_common.c
+index 28d6b7266..bb9b3f565 100644
+--- a/plat/nxp/common/setup/ls_common.c
++++ b/plat/nxp/common/setup/ls_common.c
+@@ -31,6 +31,9 @@ const mmap_region_t *plat_ls_get_mmap(void);
+ #ifdef IMAGE_BL2
+ const mmap_region_t plat_ls_mmap[] = {
+ LS_MAP_CCSR,
++#ifdef NXP_DCSR_ADDR
++ LS_MAP_DCSR,
++#endif
+ {0}
+ };
+ #endif
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,384 @@
+From 12fe019cb30ef1c5e61267b490c5cd7a07e9248b Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Fri, 25 Oct 2024 15:36:57 +0200
+Subject: [PATCH 07/15] lx2160a: support flushing i2c bus before ddr init
+
+The i2c bus can get locked by a slave device holding sda low, when the
+cpu is reset during a transaction.
+Implement workaround according to LX2160A Chip Errata 07/2020 A-010650.
+
+The workaround is inactive by default and must be explicitly enabled
+through a board platform.mk file defining buses and muxes to flush:
+
+LX2160_FLUSH_IIC: 1D array, takes comma separate uint8 indicating
+human-readable i2c bus number,
+e.g: IIC1 & IIC2 = "1, 2".
+
+LX2160_FLUSH_IIC_MUX: 2D array, takes comma-separated 1D array
+initializer expressions with i2c bus number, mux address on the bus and
+a bitmask for channels to flush,
+e.g. IIC1 mux @ 77, channels 1&2 = "{1, 0x77, 0x03}".
+
+This includes a workaround for pinmux corruption separating between
+read-only and write-only memory for the pinmux values.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+Signed-off-by: Ahmad Shtewe <ahmad.shtewe@solid-run.com>
+---
+ plat/nxp/common/setup/common.mk | 1 +
+ plat/nxp/common/setup/include/plat_common.h | 2 +
+ plat/nxp/common/setup/ls_bl2_el3_setup.c | 1 +
+ plat/nxp/common/setup/ls_i2c_init.c | 289 ++++++++++++++++++++
+ plat/nxp/soc-lx2160a/soc.mk | 6 +
+ 5 files changed, 299 insertions(+)
+ create mode 100644 plat/nxp/common/setup/ls_i2c_init.c
+
+diff --git a/plat/nxp/common/setup/common.mk b/plat/nxp/common/setup/common.mk
+index b7e16ae60..6d952a811 100644
+--- a/plat/nxp/common/setup/common.mk
++++ b/plat/nxp/common/setup/common.mk
+@@ -80,6 +80,7 @@ BL2_SOURCES += drivers/io/io_fip.c \
+ plat/nxp/common/setup/ls_image_load.c \
+ plat/nxp/common/setup/ls_io_storage.c \
+ plat/nxp/common/setup/ls_bl2_el3_setup.c \
++ plat/nxp/common/setup/ls_i2c_init.c \
+ plat/nxp/common/setup/${ARCH}/ls_bl2_mem_params_desc.c
+
+ BL31_SOURCES += plat/nxp/common/setup/ls_bl31_setup.c \
+diff --git a/plat/nxp/common/setup/include/plat_common.h b/plat/nxp/common/setup/include/plat_common.h
+index 45832fa68..1c850ebe2 100644
+--- a/plat/nxp/common/setup/include/plat_common.h
++++ b/plat/nxp/common/setup/include/plat_common.h
+@@ -77,6 +77,8 @@ int open_backend(const uintptr_t spec);
+ void ls_bl2_plat_arch_setup(void);
+ void ls_bl2_el3_plat_arch_setup(void);
+
++void bl2_i2c_init(void);
++
+ enum boot_device {
+ BOOT_DEVICE_IFC_NOR,
+ BOOT_DEVICE_IFC_NAND,
+diff --git a/plat/nxp/common/setup/ls_bl2_el3_setup.c b/plat/nxp/common/setup/ls_bl2_el3_setup.c
+index a4cbaef45..63e3460d7 100644
+--- a/plat/nxp/common/setup/ls_bl2_el3_setup.c
++++ b/plat/nxp/common/setup/ls_bl2_el3_setup.c
+@@ -276,6 +276,7 @@ void bl2_el3_plat_prepare_exit(void)
+ */
+ void bl2_plat_preload_setup(void)
+ {
++ bl2_i2c_init();
+
+ soc_preload_setup();
+
+diff --git a/plat/nxp/common/setup/ls_i2c_init.c b/plat/nxp/common/setup/ls_i2c_init.c
+new file mode 100644
+index 000000000..bbb59c476
+--- /dev/null
++++ b/plat/nxp/common/setup/ls_i2c_init.c
+@@ -0,0 +1,289 @@
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <common/debug.h>
++#include <drivers/delay_timer.h>
++#include <i2c.h>
++#include <soc.h>
++
++#define NXP_IIC1_ADDR 0x02000000
++#define NXP_IIC2_ADDR 0x02010000
++#define NXP_IIC3_ADDR 0x02020000
++#define NXP_IIC4_ADDR 0x02030000
++#define NXP_IIC5_ADDR 0x02040000
++#define NXP_IIC6_ADDR 0x02050000
++#define NXP_IIC7_ADDR 0x02060000
++#define NXP_IIC8_ADDR 0x02070000
++
++#define RCWSR12R 0x01e0012c
++#define RCWSR12W 0x70010012c
++#define RCWSR12_IIC2_PMUX_MASK 0x00000007 /* [0..2] */
++#define RCWSR12_IIC2_PMUX_IIC2 0x00000000
++#define RCWSR12_IIC2_PMUX_GPIO 0x00000001
++#define RCWSR12_IIC3_PMUX_MASK 0x00000038 /* [3..5] */
++#define RCWSR12_IIC3_PMUX_IIC3 0x00000000
++#define RCWSR12_IIC3_PMUX_GPIO 0x00000008
++#define RCWSR12_IIC4_PMUX_MASK 0x000001c0 /* [6..8] */
++#define RCWSR12_IIC4_PMUX_IIC4 0x00000000
++#define RCWSR12_IIC4_PMUX_GPIO 0x00000040
++#define RCWSR12_IIC5_PMUX_MASK 0x00000e00 /* [9..11] */
++#define RCWSR12_IIC5_PMUX_IIC5 0x00000000
++#define RCWSR12_IIC5_PMUX_GPIO 0x00000200
++#define RCWSR12_IIC6_PMUX_MASK 0x00007000 /* [12..14] */
++#define RCWSR12_IIC6_PMUX_IIC6 0x00000000
++#define RCWSR12_IIC6_PMUX_GPIO 0x00001000
++#define RCWSR13R 0x01e00130
++#define RCWSR13W 0x700100130
++#define RCWSR12_SDHC2_DAT74_PMUX_MASK 0x00000003
++#define RCWSR12_SDHC2_DAT74_PMUX_SDHC2 0x00000000
++#define RCWSR12_SDHC2_DAT74_PMUX_IIC78 0x00000001
++#define RCWSR14R 0x01e00134
++#define RCWSR14W 0x700100134
++#define RCWSR14_IIC1_PMUX_MASK 0x00000400 /* [10] */
++#define RCWSR14_IIC1_PMUX_IIC1 0x00000000
++#define RCWSR14_IIC1_PMUX_GPIO 0x00000400
++
++static void ls_i2c_flush_pca9547(uint8_t busno, const char *busname, uint8_t address, uint8_t channels);
++static void ls_i2c_flush(uint8_t busno, const char *busname);
++
++/**
++ * Flush i2c buses to make slave devices release sda,
++ * in case the system was reset during a transaction.
++ */
++void bl2_i2c_init() {
++ const uint8_t bus_flush_list[] = {CONFIG_LX2160_FLUSH_IIC};
++ /*
++ * List of muxes and channels to flush. Takes 2D array:
++ * {<bus number>, <mux chip address>, <channel bitmask>},
++ */
++ const uint8_t mux_flush_list[][3] = {CONFIG_LX2160_FLUSH_IIC_MUX};
++ const uintptr_t iic_base_addr[] = {
++ NXP_IIC1_ADDR,
++ NXP_IIC2_ADDR,
++ NXP_IIC3_ADDR,
++ NXP_IIC4_ADDR,
++ NXP_IIC5_ADDR,
++ NXP_IIC6_ADDR,
++ };
++ const char *iic_name[] = {
++ "IIC1",
++ "IIC2",
++ "IIC3",
++ "IIC4",
++ "IIC5",
++ "IIC6",
++ };
++ int i;
++ uint8_t busno;
++ uint8_t address;
++ uint8_t channels;
++
++ /* flush i2c buses */
++ for (i = 0; i < ARRAY_SIZE(bus_flush_list); i++) {
++ busno = bus_flush_list[i] - 1;
++ i2c_init(iic_base_addr[busno]);
++ ls_i2c_flush(busno, iic_name[busno]);
++ }
++
++ /* flush muxes channels */
++ for (i = 0; i < ARRAY_SIZE(mux_flush_list); i++) {
++ busno = mux_flush_list[i][0] - 1;
++ address = mux_flush_list[i][1];
++ channels = mux_flush_list[i][2];
++ i2c_init(iic_base_addr[busno]);
++ ls_i2c_flush_pca9547(busno, iic_name[busno], address, channels);
++ }
++}
++
++static void ls_i2c_flush_pca9547(uint8_t busno, const char *busname, uint8_t chip, uint8_t channels) {
++ uint8_t channel, creg = 0;
++ char buffer[64];
++ int ret;
++
++ /* try read configuration register */
++ ret = i2c_read(chip, 0x00, 1, &creg, 1);
++ if(ret != 0) {
++ /* no device responding at address, skip */
++ return;
++ }
++
++ /* after reset configuration register reads 0x08 */
++ if(creg != 0x08) {
++ /* probably not a pca9547, skip */
++ return;
++ }
++
++ /* flush selected channels */
++ for(uint8_t i = 8; i > 0; i--) {
++ if (!(channels & (1 << (i-1))))
++ continue;
++
++ /* select channel i */
++ channel = 0x08 | (i-1);
++ i2c_write(chip, 0x00, 1, &channel, 1);
++
++ /* flush channel */
++ snprintf(buffer, sizeof(buffer), "%s mux@%02x channel %u", busname, chip, i-1);
++ ls_i2c_flush(busno, buffer);
++ }
++}
++
++static struct i2c_bus_info {
++ uintptr_t pinmux_addr_r;
++ uintptr_t pinmux_addr_w;
++ uint32_t pinmux_mask;
++ uint32_t pinmux_sel;
++ uintptr_t gpio_addr;
++ uint8_t gpio_scl;
++ uint8_t gpio_sda;
++} ls_i2c_bus_info[] = {
++ {
++ .pinmux_addr_r = RCWSR14R,
++ .pinmux_addr_w = RCWSR14W,
++ .pinmux_mask = RCWSR14_IIC1_PMUX_MASK,
++ .pinmux_sel = RCWSR14_IIC1_PMUX_GPIO,
++ .gpio_addr = NXP_GPIO1_ADDR,
++ .gpio_scl = 3, /* GPIO1_DAT03 */
++ .gpio_sda = 2, /* GPIO1_DAT02 */
++ },
++ {
++ .pinmux_addr_r = RCWSR12R,
++ .pinmux_addr_w = RCWSR12W,
++ .pinmux_mask = RCWSR12_IIC2_PMUX_MASK,
++ .pinmux_sel = RCWSR12_IIC2_PMUX_GPIO,
++ .gpio_addr = NXP_GPIO1_ADDR,
++ .gpio_scl = 31, /* GPIO1_DAT31 */
++ .gpio_sda = 30, /* GPIO1_DAT30 */
++ },
++ {
++ .pinmux_addr_r = RCWSR12R,
++ .pinmux_addr_w = RCWSR12W,
++ .pinmux_mask = RCWSR12_IIC3_PMUX_MASK,
++ .pinmux_sel = RCWSR12_IIC3_PMUX_GPIO,
++ .gpio_addr = NXP_GPIO1_ADDR,
++ .gpio_scl = 29, /* GPIO1_DAT29 */
++ .gpio_sda = 28, /* GPIO1_DAT28 */
++ },
++ {
++ .pinmux_addr_r = RCWSR12R,
++ .pinmux_addr_w = RCWSR12W,
++ .pinmux_mask = RCWSR12_IIC4_PMUX_MASK,
++ .pinmux_sel = RCWSR12_IIC4_PMUX_GPIO,
++ .gpio_addr = NXP_GPIO1_ADDR,
++ .gpio_scl = 27, /* GPIO1_DAT27 */
++ .gpio_sda = 26, /* GPIO1_DAT26 */
++ },
++ {
++ .pinmux_addr_r = RCWSR12R,
++ .pinmux_addr_w = RCWSR12W,
++ .pinmux_mask = RCWSR12_IIC5_PMUX_MASK,
++ .pinmux_sel = RCWSR12_IIC5_PMUX_GPIO,
++ .gpio_addr = NXP_GPIO1_ADDR,
++ .gpio_scl = 25, /* GPIO1_DAT25 */
++ .gpio_sda = 24, /* GPIO1_DAT24 */
++ },
++ {
++ .pinmux_addr_r = RCWSR12R,
++ .pinmux_addr_w = RCWSR12W,
++ .pinmux_mask = RCWSR12_IIC6_PMUX_MASK,
++ .pinmux_sel = RCWSR12_IIC6_PMUX_GPIO,
++ .gpio_addr = NXP_GPIO1_ADDR,
++ .gpio_scl = 23, /* GPIO1_DAT23 */
++ .gpio_sda = 22, /* GPIO1_DAT22 */
++ },
++ {
++ .pinmux_addr_r = RCWSR13R,
++ .pinmux_addr_w = RCWSR13W,
++ .pinmux_mask = RCWSR12_SDHC2_DAT74_PMUX_MASK,
++ .pinmux_sel = RCWSR12_SDHC2_DAT74_PMUX_IIC78,
++ .gpio_addr = NXP_GPIO2_ADDR,
++ .gpio_scl = 16, /* GPIO2_DAT16 */
++ .gpio_sda = 15, /* GPIO2_DAT15 */
++ },
++ {
++ .pinmux_addr_r = RCWSR13R,
++ .pinmux_addr_w = RCWSR13W,
++ .pinmux_mask = RCWSR12_SDHC2_DAT74_PMUX_MASK,
++ .pinmux_sel = RCWSR12_SDHC2_DAT74_PMUX_IIC78,
++ .gpio_addr = NXP_GPIO2_ADDR,
++ .gpio_scl = 18, /* GPIO2_DAT18 */
++ .gpio_sda = 17, /* GPIO2_DAT17 */
++ },
++};
++
++/*
++ * Flush the i2c bus through any muxes with 9 clock cycles
++ * to ensure all slave devices release their locks on SDA.
++ * This is a work-around for i2c slave devices locking SDA,
++ * when the system has been reset during a transaction.
++ *
++ * The implementation is inspired by LX2160A Chip Errata 07/2020 A-010650.
++ */
++static void ls_i2c_flush(uint8_t busno, const char *busname) {
++ struct i2c_bus_info *info;
++ uintptr_t gpdir_addr, gpodr_addr, gpdat_addr;
++ uint32_t pinmux, gpdir, gpodr, gpdat;
++ struct {
++ uint32_t pinmux, gpdir, gpodr, gpdat;
++ } backup;
++ uint32_t scl_mask, sda_mask;
++
++ if(busno >= 8) {
++ ERROR("failed to flush i2c bus %u %s: invalid bus number!\n", busno, busname);
++ return;
++ }
++ /* load i2c bus specific information */
++ info = &ls_i2c_bus_info[busno];
++ gpdir_addr = info->gpio_addr + 0x0;
++ gpodr_addr = info->gpio_addr + 0x4;
++ gpdat_addr = info->gpio_addr + 0x8;
++ scl_mask = 0x80000000 >> info->gpio_scl;
++ sda_mask = 0x80000000 >> info->gpio_sda;
++
++ /* backup configuration registers */
++ pinmux = backup.pinmux = mmio_read_32(info->pinmux_addr_r);
++ gpdir = backup.gpdir = mmio_read_32(gpdir_addr);
++ gpodr = backup.gpodr = mmio_read_32(gpodr_addr);
++ gpdat = backup.gpdat = mmio_read_32(gpdat_addr);
++
++ /* configure SCL+SDA as GPIOs */
++ pinmux = (pinmux & ~info->pinmux_mask) | info->pinmux_sel;
++ mmio_write_32(info->pinmux_addr_w, pinmux);
++
++ /* configure SCL+SDA as output open drain */
++ gpdir |= scl_mask | sda_mask;
++ gpodr |= scl_mask | sda_mask;
++ gpdat |= scl_mask | sda_mask;
++ mmio_write_32(gpdat_addr, gpdat);
++ mmio_write_32(gpodr_addr, gpodr);
++ mmio_write_32(gpdir_addr, gpdir);
++
++ /* allow short delay for changes to propagate */
++ udelay(10);
++
++ /*
++ * reliable detection of blocked bus is hard
++ * because sda depends on the last sent bit.
++ * Flush unconditionally instead.
++ */
++
++ VERBOSE("flushing i2c bus %u (%s)\n", busno, busname);
++
++ /* toggle clock 9 times */
++ for(uint8_t i = 0; i < 9; i++) {
++ mmio_write_32(gpdat_addr, gpdat & ~scl_mask);
++ udelay(10);
++ mmio_write_32(gpdat_addr, gpdat | scl_mask);
++ udelay(10);
++ }
++
++ /* restore configuration registers */
++ mmio_write_32(gpdir_addr, backup.gpdir);
++ mmio_write_32(gpodr_addr, backup.gpodr);
++ mmio_write_32(gpdat_addr, backup.gpdat);
++ mmio_write_32(info->pinmux_addr_w, backup.pinmux);
++
++ return;
++}
+diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
+index 20e64753c..fa8c63251 100644
+--- a/plat/nxp/soc-lx2160a/soc.mk
++++ b/plat/nxp/soc-lx2160a/soc.mk
+@@ -185,3 +185,9 @@ ifneq (${LX2160A_S5_GPIO_ADDR},0)
+ $(eval $(call add_define_val,CONFIG_LX2160A_S5_GPIO_ADDR,$(LX2160A_S5_GPIO_ADDR)))
+ $(eval $(call add_define_val,CONFIG_LX2160A_S5_GPIO,$(LX2160A_S5_GPIO)))
+ endif
++
++# I2C Bus Flushing (optional)
++LX2160_FLUSH_IIC ?= ""
++LX2160_FLUSH_IIC_MUX ?= ""
++$(eval $(call add_define_val,CONFIG_LX2160_FLUSH_IIC,"$(LX2160_FLUSH_IIC)"))
++$(eval $(call add_define_val,CONFIG_LX2160_FLUSH_IIC_MUX,"$(LX2160_FLUSH_IIC_MUX)"))
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,40 @@
+From b275d59644e4423427b8cae2890096061d04264c Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Wed, 12 Feb 2025 17:33:41 +0100
+Subject: [PATCH 08/15] nxp: ddr: dump SPD EEPROM content on debug builds
+
+When building with DDR_DEBUG=yes dump the raw SPD EEPROM byte for byte
+on each DIMM.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/nxp/ddr/nxp-ddr/ddr.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c
+index 17c2bbb2a..9b788c6c4 100644
+--- a/drivers/nxp/ddr/nxp-ddr/ddr.c
++++ b/drivers/nxp/ddr/nxp-ddr/ddr.c
+@@ -550,6 +550,19 @@ static int parse_spd(struct ddr_info *priv)
+ continue;
+ }
+
++#ifdef DDR_DEBUG
++ /* dump SPD */
++ printf("RAW SPD:");
++ for (size_t k = 0; k < sizeof(struct ddr4_spd); k++) {
++ unsigned char byte = ((unsigned char *)&spd[spd_idx])[k];
++ if (!(k % 16))
++ printf("\n%02x", byte);
++ else
++ printf(" %02x", byte);
++ }
++ printf("\n");
++#endif
++
+ spd_checksum[spd_idx] =
+ (spd[spd_idx].crc[1] << 24) |
+ (spd[spd_idx].crc[0] << 16) |
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,35 @@
+From d762fa8d3509be534d0c4b8f07b52e87a1d0a663 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Wed, 12 Feb 2025 17:35:04 +0100
+Subject: [PATCH 09/15] nxp: ddr: disarm error when using non-identical DIMMs
+
+Some DDR4 SO-DIMM report different timings when they are installed in
+different slots. This triggers an error as LX2160A intends to only
+support identical DIMMs.
+
+Disarm the error and continue with timings read from first DIMM SPD.
+An error is printed advising users to carefully check their memory.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/nxp/ddr/nxp-ddr/ddr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c
+index 9b788c6c4..0a9cd7f87 100644
+--- a/drivers/nxp/ddr/nxp-ddr/ddr.c
++++ b/drivers/nxp/ddr/nxp-ddr/ddr.c
+@@ -584,8 +584,8 @@ static int parse_spd(struct ddr_info *priv)
+
+ if (spd_idx != 0 && spd_checksum[0] !=
+ spd_checksum[spd_idx]) {
+- ERROR("Not identical DIMMs.\n");
+- return -EINVAL;
++ ERROR("SPD different between DIMMs, using first DIMM timings for all slots.\n");
++ ERROR("Timings might be wrong, replace or carefully validate your memory!\n");
+ }
+ conf->dimm_in_use[j] = 1;
+ valid_mask |= 1 << addr_idx;
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,83 @@
+From 54ec59537e12bb9f653b5375803c5f4f03d17060 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Thu, 26 Sep 2024 16:35:40 +0200
+Subject: [PATCH 10/15] nxp: ddr: add debug output for dimm parameters parsed
+ from spd or static
+
+Add debug prints for all members of struct dimm_params, after either
+parsing of SPD - or from static (no-dimm) configuration.
+
+This enables comparison of parameters derived from SPD with static
+configuration.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/nxp/ddr/nxp-ddr/ddr.c | 52 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 52 insertions(+)
+
+diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c
+index 0a9cd7f87..b8b28c55a 100644
+--- a/drivers/nxp/ddr/nxp-ddr/ddr.c
++++ b/drivers/nxp/ddr/nxp-ddr/ddr.c
+@@ -629,6 +629,58 @@ static int parse_spd(struct ddr_info *priv)
+ /* now we have valid and identical DIMMs on controllers */
+ #endif /* CONFIG_DDR_NODIMM */
+
++ debug("DIMM: n_ranks = %u\n", dimm->n_ranks);
++ debug("DIMM: die_density = %u\n", dimm->die_density);
++ debug("DIMM: rank_density = %llu\n", dimm->rank_density);
++ debug("DIMM: capacity = %llu\n", dimm->capacity);
++ debug("DIMM: primary_sdram_width = %u\n", dimm->primary_sdram_width);
++ debug("DIMM: ec_sdram_width = %u\n", dimm->ec_sdram_width);
++ debug("DIMM: rdimm = %u\n", dimm->rdimm);
++ debug("DIMM: package_3ds = %u\n", dimm->package_3ds);
++ debug("DIMM: device_width = %u\n", dimm->device_width);
++ debug("DIMM: rc = %u\n", dimm->rc);
++
++ debug("DIMM: n_row_addr = %u\n", dimm->n_row_addr);
++ debug("DIMM: n_col_addr = %u\n", dimm->n_col_addr);
++ debug("DIMM: edc_config = %u\n", dimm->edc_config);
++ debug("DIMM: bank_addr_bits = %u\n", dimm->bank_addr_bits);
++ debug("DIMM: bank_group_bits = %u\n", dimm->bank_group_bits);
++ debug("DIMM: burst_lengths_bitmask = %u\n", dimm->burst_lengths_bitmask);
++
++ debug("DIMM: mirrored_dimm = %u\n", dimm->mirrored_dimm);
++
++ debug("DIMM: mtb_ps = %d\n", dimm->mtb_ps);
++ debug("DIMM: ftb_10th_ps = %d\n", dimm->ftb_10th_ps);
++ debug("DIMM: taa_ps = %d\n", dimm->taa_ps);
++ debug("DIMM: tfaw_ps = %d\n", dimm->tfaw_ps);
++
++ debug("DIMM: tckmin_x_ps = %d\n", dimm->tckmin_x_ps);
++ debug("DIMM: tckmax_ps = %d\n", dimm->tckmax_ps);
++
++ debug("DIMM: caslat_x = %u\n", dimm->caslat_x);
++
++ debug("DIMM: trcd_ps = %d\n", dimm->trcd_ps);
++ debug("DIMM: trp_ps = %d\n", dimm->trp_ps);
++ debug("DIMM: tras_ps = %d\n", dimm->tras_ps);
++
++ debug("DIMM: trfc1_ps = %d\n", dimm->trfc1_ps);
++ debug("DIMM: trfc2_ps = %d\n", dimm->trfc2_ps);
++ debug("DIMM: trfc4_ps = %d\n", dimm->trfc4_ps);
++ debug("DIMM: trrds_ps = %d\n", dimm->trrds_ps);
++ debug("DIMM: trrdl_ps = %d\n", dimm->trrdl_ps);
++ debug("DIMM: tccdl_ps = %d\n", dimm->tccdl_ps);
++ debug("DIMM: trfc_slr_ps = %d\n", dimm->trfc_slr_ps);
++
++ debug("DIMM: trc_ps = %d\n", dimm->trc_ps);
++ debug("DIMM: twr_ps = %d\n", dimm->twr_ps);
++
++ debug("DIMM: refresh_rate_ps = %u\n", dimm->refresh_rate_ps);
++ debug("DIMM: extended_op_srt = %u\n", dimm->extended_op_srt);
++
++ debug("DIMM: rcw = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n", (unsigned int)dimm->rcw[0], (unsigned int)dimm->rcw[1], (unsigned int)dimm->rcw[2], (unsigned int)dimm->rcw[3], (unsigned int)dimm->rcw[4], (unsigned int)dimm->rcw[5], (unsigned int)dimm->rcw[6], (unsigned int)dimm->rcw[7], (unsigned int)dimm->rcw[8], (unsigned int)dimm->rcw[9], (unsigned int)dimm->rcw[10], (unsigned int)dimm->rcw[11], (unsigned int)dimm->rcw[12], (unsigned int)dimm->rcw[13], (unsigned int)dimm->rcw[14], (unsigned int)dimm->rcw[15]);
++ debug("DIMM: dq_mapping = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n", dimm->dq_mapping[0], dimm->dq_mapping[1], dimm->dq_mapping[2], dimm->dq_mapping[3], dimm->dq_mapping[4], dimm->dq_mapping[5], dimm->dq_mapping[6], dimm->dq_mapping[7], dimm->dq_mapping[8], dimm->dq_mapping[9], dimm->dq_mapping[10], dimm->dq_mapping[11], dimm->dq_mapping[12], dimm->dq_mapping[13], dimm->dq_mapping[14], dimm->dq_mapping[15], dimm->dq_mapping[16], dimm->dq_mapping[17]);
++ debug("DIMM: dq_mapping_ors = %u\n", dimm->dq_mapping_ors);
++
+ debug("cal cs\n");
+ conf->cs_in_use = 0;
+ for (j = 0; j < DDRC_NUM_DIMM; j++) {
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,49 @@
+From 7d2945375429a4e28b6252c548b8a60114fb791f Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Tue, 30 Jul 2024 17:45:33 +0300
+Subject: [PATCH 11/15] plat: lx2160a: fix building without
+ NXP_NV_SW_MAINT_LAST_EXEC_DATA
+
+Fix compiler errors encountered when disabling non-volatile storage of
+execution state (NXP_NV_SW_MAINT_LAST_EXEC_DATA := no) while keeping
+watchdog restart enabled (NXP_WDOG_RESTART := yes).
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/nxp/ddr/phy-gen2/phy.h | 2 +-
+ plat/nxp/soc-lx2160a/soc.c | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nxp/ddr/phy-gen2/phy.h b/drivers/nxp/ddr/phy-gen2/phy.h
+index 5e80f3638..7ddc7c7c6 100644
+--- a/drivers/nxp/ddr/phy-gen2/phy.h
++++ b/drivers/nxp/ddr/phy-gen2/phy.h
+@@ -6,7 +6,7 @@
+ #if !defined(PHY_H) && defined(NXP_WARM_BOOT)
+ #define PHY_H
+
+-#include <flash_info.h>
++#include <drivers/nxp/flexspi/flash_info.h>
+
+ /* To store sector size to be erase on flash*/
+ #define PHY_ERASE_SIZE F_SECTOR_ERASE_SZ
+diff --git a/plat/nxp/soc-lx2160a/soc.c b/plat/nxp/soc-lx2160a/soc.c
+index ca6ae8c93..17556f19d 100644
+--- a/plat/nxp/soc-lx2160a/soc.c
++++ b/plat/nxp/soc-lx2160a/soc.c
+@@ -524,10 +524,12 @@ void soc_init(void)
+ static uint64_t wdog_interrupt_handler(uint32_t id, uint32_t flags,
+ void *handle, void *cookie)
+ {
++#ifdef NXP_NV_SW_MAINT_LAST_EXEC_DATA
+ uint8_t data = WDOG_RESET_FLAG;
+
+ wr_nv_app_data(WDT_RESET_FLAG_OFFSET,
+ (uint8_t *)&data, sizeof(data));
++#endif
+
+ mmio_write_32(NXP_RST_ADDR + RSTCNTL_OFFSET, SW_RST_REQ_INIT);
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,33 @@
+From 1b4b3d575f085bdaa078b68a70fc8800a2be4f81 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Tue, 30 Jul 2024 17:45:38 +0300
+Subject: [PATCH 12/15] plat: lx2160a: fix boot without spi flash / disable
+ non-volatile storage
+
+Watchdog restart function does not require book-keeping on non-volatile
+storage.
+Remove explicit enabling of NXP_NV_SW_MAINT_LAST_EXEC_DATA.
+
+This fixed hang during boot where atf gets stuck trying to erase a
+sector of spi flash.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ plat/nxp/soc-lx2160a/soc.mk | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/plat/nxp/soc-lx2160a/soc.mk b/plat/nxp/soc-lx2160a/soc.mk
+index fa8c63251..4e864e164 100644
+--- a/plat/nxp/soc-lx2160a/soc.mk
++++ b/plat/nxp/soc-lx2160a/soc.mk
+@@ -28,7 +28,6 @@ NXP_WDOG_RESTART := yes
+
+ # for features enabled above.
+ ifeq (${NXP_WDOG_RESTART}, yes)
+-NXP_NV_SW_MAINT_LAST_EXEC_DATA := yes
+ LS_EL3_INTERRUPT_HANDLER := yes
+ $(eval $(call add_define, NXP_WDOG_RESTART))
+ endif
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,423 @@
+From 227479dca0dd27a5dddfd1b35c3fa4442c8bedac Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Fri, 18 Oct 2024 15:11:53 +0200
+Subject: [PATCH 13/15] add separate platform for solidrun cex7 module
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ plat/nxp/soc-lx2160a/lx2160acex7/ddr_init.c | 116 ++++++++++++++++++
+ plat/nxp/soc-lx2160a/lx2160acex7/plat_def.h | 105 ++++++++++++++++
+ plat/nxp/soc-lx2160a/lx2160acex7/platform.c | 29 +++++
+ plat/nxp/soc-lx2160a/lx2160acex7/platform.mk | 61 +++++++++
+ .../soc-lx2160a/lx2160acex7/platform_def.h | 14 +++
+ plat/nxp/soc-lx2160a/lx2160acex7/policy.h | 38 ++++++
+ 6 files changed, 363 insertions(+)
+ create mode 100644 plat/nxp/soc-lx2160a/lx2160acex7/ddr_init.c
+ create mode 100644 plat/nxp/soc-lx2160a/lx2160acex7/plat_def.h
+ create mode 100644 plat/nxp/soc-lx2160a/lx2160acex7/platform.c
+ create mode 100644 plat/nxp/soc-lx2160a/lx2160acex7/platform.mk
+ create mode 100644 plat/nxp/soc-lx2160a/lx2160acex7/platform_def.h
+ create mode 100644 plat/nxp/soc-lx2160a/lx2160acex7/policy.h
+
+diff --git a/plat/nxp/soc-lx2160a/lx2160acex7/ddr_init.c b/plat/nxp/soc-lx2160a/lx2160acex7/ddr_init.c
+new file mode 100644
+index 000000000..340a20455
+--- /dev/null
++++ b/plat/nxp/soc-lx2160a/lx2160acex7/ddr_init.c
+@@ -0,0 +1,116 @@
++/*
++ * Copyright 2021 NXP
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ *
++ */
++
++#include <assert.h>
++#include <errno.h>
++#include <stdbool.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <common/debug.h>
++#include <ddr.h>
++#include <lib/utils.h>
++#include <load_img.h>
++
++#include "plat_common.h"
++#include <platform_def.h>
++
++#if defined(CONFIG_STATIC_DDR) || defined(CONFIG_DDR_NODIMM)
++#error not implemented
++#endif /* defined(CONFIG_STATIC_DDR) || defined(CONFIG_DDR_NODIMM) */
++
++int ddr_board_options(struct ddr_info *priv)
++{
++ struct memctl_opt *popts = &priv->opt;
++ const struct ddr_conf *conf = &priv->conf;
++
++ popts->vref_dimm = U(0x24); /* range 1, 83.4% */
++ popts->rtt_override = 0U;
++ popts->rtt_park = U(240);
++ popts->otf_burst_chop_en = 0;
++ popts->burst_length = U(DDR_BL8);
++ popts->trwt_override = 1U;
++ popts->bstopre = 0U; /* auto precharge */
++ popts->addr_hash = 1;
++
++ /* Set ODT impedance on PHY side */
++ switch (conf->cs_on_dimm[1]) {
++ case 0xc: /* Two slots dual rank */
++ case 0x4: /* Two slots single rank, not valid for interleaving */
++ popts->trwt = U(0xf);
++ popts->twrt = U(0x7);
++ popts->trrt = U(0x7);
++ popts->twwt = U(0x7);
++ popts->vref_phy = U(0x6B); /* 83.6% */
++ popts->odt = U(60);
++ popts->phy_tx_impedance = U(28);
++ break;
++ case 0: /* One slot used */
++ default:
++ popts->trwt = U(0x3);
++ popts->twrt = U(0x3);
++ popts->trrt = U(0x3);
++ popts->twwt = U(0x3);
++ popts->vref_phy = U(0x60); /* 75% */
++ popts->odt = U(48);
++ popts->phy_tx_impedance = U(28);
++ break;
++ }
++
++ return 0;
++}
++
++long long init_ddr(void)
++{
++ int spd_addr[] = { 0x51, 0x52, 0x53, 0x54 };
++ struct ddr_info info;
++ struct sysinfo sys;
++ long long dram_size;
++
++ zeromem(&sys, sizeof(sys));
++ if (get_clocks(&sys) != 0) {
++ ERROR("System clocks are not set\n");
++ panic();
++ }
++ debug("platform clock %lu\n", sys.freq_platform);
++ debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0);
++ debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1);
++
++ zeromem(&info, sizeof(info));
++
++ /* Set two DDRC. Unused DDRC will be removed automatically. */
++ info.num_ctlrs = NUM_OF_DDRC;
++ info.spd_addr = spd_addr;
++ info.ddr[0] = (void *)NXP_DDR_ADDR;
++ info.ddr[1] = (void *)NXP_DDR2_ADDR;
++ info.phy[0] = (void *)NXP_DDR_PHY1_ADDR;
++ info.phy[1] = (void *)NXP_DDR_PHY2_ADDR;
++ info.clk = get_ddr_freq(&sys, 0);
++ info.img_loadr = load_img;
++ info.phy_gen2_fw_img_buf = PHY_GEN2_FW_IMAGE_BUFFER;
++ if (info.clk == 0) {
++ info.clk = get_ddr_freq(&sys, 1);
++ }
++ info.dimm_on_ctlr = DDRC_NUM_DIMM;
++
++ info.warm_boot_flag = DDR_WRM_BOOT_NT_SUPPORTED;
++
++ dram_size = dram_init(&info
++#if defined(NXP_HAS_CCN504) || defined(NXP_HAS_CCN508)
++ , NXP_CCN_HN_F_0_ADDR
++#endif
++ );
++
++
++ if (dram_size < 0) {
++ ERROR("DDR init failed.\n");
++ }
++
++ return dram_size;
++}
+diff --git a/plat/nxp/soc-lx2160a/lx2160acex7/plat_def.h b/plat/nxp/soc-lx2160a/lx2160acex7/plat_def.h
+new file mode 100644
+index 000000000..02f51e74d
+--- /dev/null
++++ b/plat/nxp/soc-lx2160a/lx2160acex7/plat_def.h
+@@ -0,0 +1,105 @@
++/*
++ * Copyright 2021 NXP
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ *
++ */
++
++#ifndef PLAT_DEF_H
++#define PLAT_DEF_H
++
++#include <arch.h>
++#include <cortex_a72.h>
++/* Required without TBBR.
++ * To include the defines for DDR PHY
++ * Images.
++ */
++#include <tbbr_img_def.h>
++
++#include <policy.h>
++#include <soc.h>
++
++#if defined(IMAGE_BL31)
++#define LS_SYS_TIMCTL_BASE 0x2890000
++#define PLAT_LS_NSTIMER_FRAME_ID 0
++#define LS_CONFIG_CNTACR 1
++#endif
++
++#define NXP_SYSCLK_FREQ 100000000
++#define NXP_DDRCLK_FREQ 100000000
++
++/* UART related definition */
++#define NXP_CONSOLE_ADDR NXP_UART_ADDR
++#define NXP_CONSOLE_BAUDRATE 115200
++
++/* Size of cacheable stacks */
++#if defined(IMAGE_BL2)
++#if defined(TRUSTED_BOARD_BOOT)
++#define PLATFORM_STACK_SIZE 0x2000
++#else
++#define PLATFORM_STACK_SIZE 0x1000
++#endif
++#elif defined(IMAGE_BL31)
++#define PLATFORM_STACK_SIZE 0x1000
++#endif
++
++/* SD block buffer */
++#define NXP_SD_BLOCK_BUF_SIZE (0x8000)
++#define NXP_SD_BLOCK_BUF_ADDR (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
++ - NXP_SD_BLOCK_BUF_SIZE)
++
++#ifdef SD_BOOT
++#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \
++ - NXP_SD_BLOCK_BUF_SIZE)
++#else
++#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE)
++#endif
++
++/* IO defines as needed by IO driver framework */
++#define MAX_IO_DEVICES 4
++#define MAX_IO_BLOCK_DEVICES 1
++#define MAX_IO_HANDLES 4
++
++#define PHY_GEN2_FW_IMAGE_BUFFER (NXP_OCRAM_ADDR + CSF_HDR_SZ)
++
++/*
++ * FIP image defines - Offset at which FIP Image would be present
++ * Image would include Bl31 , Bl33 and Bl32 (optional)
++ */
++#ifdef POLICY_FUSE_PROVISION
++#define MAX_FIP_DEVICES 3
++#endif
++
++#ifndef MAX_FIP_DEVICES
++#define MAX_FIP_DEVICES 2
++#endif
++
++/*
++ * ID of the secure physical generic timer interrupt used by the BL32.
++ */
++#define BL32_IRQ_SEC_PHY_TIMER 29
++
++#define BL31_WDOG_SEC 89
++
++#define BL31_NS_WDOG_WS1 108
++
++/*
++ * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3
++ * terminology. On a GICv2 system or mode, the lists will be merged and treated
++ * as Group 0 interrupts.
++ */
++#define PLAT_LS_G1S_IRQ_PROPS(grp) \
++ INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
++ GIC_INTR_CFG_EDGE)
++
++/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */
++#define NXP_IRQ_SEC_SGI_7 15
++
++#define PLAT_LS_G0_IRQ_PROPS(grp) \
++ INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \
++ GIC_INTR_CFG_EDGE), \
++ INTR_PROP_DESC(BL31_NS_WDOG_WS1, GIC_HIGHEST_SEC_PRIORITY, grp, \
++ GIC_INTR_CFG_EDGE), \
++ INTR_PROP_DESC(NXP_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
++ GIC_INTR_CFG_LEVEL)
++#endif
+diff --git a/plat/nxp/soc-lx2160a/lx2160acex7/platform.c b/plat/nxp/soc-lx2160a/lx2160acex7/platform.c
+new file mode 100644
+index 000000000..b00adb51d
+--- /dev/null
++++ b/plat/nxp/soc-lx2160a/lx2160acex7/platform.c
+@@ -0,0 +1,29 @@
++/*
++ * Copyright 2021 NXP
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ *
++ */
++
++#include <plat_common.h>
++
++#pragma weak board_enable_povdd
++#pragma weak board_disable_povdd
++
++bool board_enable_povdd(void)
++{
++#ifdef CONFIG_POVDD_ENABLE
++ return true;
++#else
++ return false;
++#endif
++}
++
++bool board_disable_povdd(void)
++{
++#ifdef CONFIG_POVDD_ENABLE
++ return true;
++#else
++ return false;
++#endif
++}
+diff --git a/plat/nxp/soc-lx2160a/lx2160acex7/platform.mk b/plat/nxp/soc-lx2160a/lx2160acex7/platform.mk
+new file mode 100644
+index 000000000..0b064bbbf
+--- /dev/null
++++ b/plat/nxp/soc-lx2160a/lx2160acex7/platform.mk
+@@ -0,0 +1,61 @@
++#
++# Copyright 2021 NXP
++#
++# SPDX-License-Identifier: BSD-3-Clause
++#
++
++# board-specific build parameters
++
++BOOT_MODE ?= flexspi_nor
++BOARD ?= lx2160acex7
++POVDD_ENABLE := no
++NXP_COINED_BB := no
++
++ # DDR Compilation Configs
++NUM_OF_DDRC := 2
++DDRC_NUM_DIMM := 2
++DDRC_NUM_CS := 4
++DDR_ECC_EN := yes
++ #enable address decoding feature
++DDR_ADDR_DEC := yes
++APPLY_MAX_CDD := yes
++
++# S5 GPIO
++LX2160A_S5_GPIO_ADDR := NXP_GPIO3_ADDR
++LX2160A_S5_GPIO := 7
++
++# I2C Bus Flushing: IIC1
++LX2160_FLUSH_IIC := 1,
++# I2C Mux Flushing: IIC1: PCA9547@77: Channel 0 (SPD EEPROM)
++LX2160_FLUSH_IIC_MUX := { 1, 0x77, 0x01 },
++
++# DDR Errata
++ERRATA_DDR_A011396 := 1
++ERRATA_DDR_A050450 := 1
++
++ # On-Board Flash Details
++FLASH_TYPE := MT35XU512A
++XSPI_FLASH_SZ := 0x10000000
++NXP_XSPI_NOR_UNIT_SIZE := 0x20000
++BL2_BIN_XSPI_NOR_END_ADDRESS := 0x100000
++# CONFIG_FSPI_ERASE_4K is required to erase 4K sector sizes. This
++# config is enabled for future use cases.
++FSPI_ERASE_4K := 0
++
++ # Platform specific features.
++WARM_BOOT := no
++
++ # Adding Platform files build files
++BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\
++ ${BOARD_PATH}/platform.c
++
++SUPPORTED_BOOT_MODE := flexspi_nor \
++ sd \
++ emmc \
++ auto
++
++# Adding platform board build info
++include plat/nxp/common/plat_make_helper/plat_common_def.mk
++
++ # Adding SoC build info
++include plat/nxp/soc-lx2160a/soc.mk
+diff --git a/plat/nxp/soc-lx2160a/lx2160acex7/platform_def.h b/plat/nxp/soc-lx2160a/lx2160acex7/platform_def.h
+new file mode 100644
+index 000000000..666099800
+--- /dev/null
++++ b/plat/nxp/soc-lx2160a/lx2160acex7/platform_def.h
+@@ -0,0 +1,14 @@
++/*
++ * Copyright 2021 NXP
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ *
++ */
++
++#ifndef PLATFORM_DEF_H
++#define PLATFORM_DEF_H
++
++#include "plat_def.h"
++#include "plat_default_def.h"
++
++#endif
+diff --git a/plat/nxp/soc-lx2160a/lx2160acex7/policy.h b/plat/nxp/soc-lx2160a/lx2160acex7/policy.h
+new file mode 100644
+index 000000000..19ad6dbec
+--- /dev/null
++++ b/plat/nxp/soc-lx2160a/lx2160acex7/policy.h
+@@ -0,0 +1,38 @@
++/*
++ * Copyright 2021 NXP
++ *
++ * SPDX-License-Identifier: BSD-3-Clause
++ *
++ */
++
++#ifndef POLICY_H
++#define POLICY_H
++
++/* Following defines affect the PLATFORM SECURITY POLICY */
++
++/* set this to 0x0 if the platform is not using/responding to ECC errors
++ * set this to 0x1 if ECC is being used (we have to do some init)
++ */
++#define POLICY_USING_ECC 0x0
++
++/* Set this to 0x0 to leave the default SMMU page size in sACR
++ * Set this to 0x1 to change the SMMU page size to 64K
++ */
++#define POLICY_SMMU_PAGESZ_64K 0x1
++
++/*
++ * POLICY_PERF_WRIOP = 0 : No Performance enhancement for WRIOP RN-I
++ * POLICY_PERF_WRIOP = 1 : No Performance enhancement for WRIOP RN-I = 7
++ * POLICY_PERF_WRIOP = 2 : No Performance enhancement for WRIOP RN-I = 23
++ */
++#define POLICY_PERF_WRIOP 0
++
++/*
++ * set this to '1' if the debug clocks need to remain enabled during
++ * system entry to low-power (LPM20) - this should only be necessary
++ * for testing and NEVER set for normal production
++ */
++#define POLICY_DEBUG_ENABLE 0
++
++
++#endif /* POLICY_H */
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,67 @@
+From 77fc969e546ffdb9e369ff5a926b770c035f7522 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sat, 9 Aug 2025 17:50:40 +0200
+Subject: [PATCH] psci: add build-time flag to disable SYSTEM_OFF function
+
+Add support for build-time flag DISABLE_PSCI_SYSTEM_OFF to remove
+support for SYSTEM_OFF from psci, which can be used to prevent operating
+systems from powering off the system.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ Makefile | 2 ++
+ make_helpers/defaults.mk | 4 ++++
+ plat/nxp/common/psci/include/plat_psci.h | 4 ++++
+ 3 files changed, 10 insertions(+)
+
+diff --git a/Makefile b/Makefile
+index ea5701347..12d92fc7e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -662,6 +662,7 @@
+ PRESERVE_DSU_PMU_REGS \
+ HOB_LIST \
+ LFA_SUPPORT \
++ DISABLE_S5 \
+ )))
+
+ # Numeric_Flags
+@@ -900,6 +901,7 @@
+ HOB_LIST \
+ HW_CONFIG_BASE \
+ LFA_SUPPORT \
++ DISABLE_S5 \
+ )))
+
+ ifeq (${PLATFORM_REPORT_CTX_MEM_USE}, 1)
+diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
+index ec2a32767..bffd922dc 100644
+--- a/make_helpers/defaults.mk
++++ b/make_helpers/defaults.mk
+@@ -449,5 +449,9 @@
+ # Enable support for arm DSU driver.
+ USE_DSU_DRIVER := 0
+
++# Build option to disable S5 state.
++# Disabled by default.
++DISABLE_S5 := 0
++
+ # Define the separation of BL2 flag, by default it is disabled.
+ SEPARATE_BL2_FIP := 0
+diff --git a/plat/nxp/common/psci/include/plat_psci.h b/plat/nxp/common/psci/include/plat_psci.h
+index 7fc48fb73..d26602c2a 100644
+--- a/plat/nxp/common/psci/include/plat_psci.h
++++ b/plat/nxp/common/psci/include/plat_psci.h
+@@ -101,6 +101,10 @@
+ #define SOC_SYSTEM_PWR_DWN 0x1
+ #endif
+
++#if DISABLE_S5
++#define SOC_SYSTEM_OFF 0x0
++#endif
++
+ #ifndef SOC_SYSTEM_OFF
+ #define SOC_SYSTEM_OFF 0x1
+ #endif
+--
+2.43.0
new file mode 100644
@@ -0,0 +1,39 @@
+From b9c71f412bc8ce51383d230756fa40118d5cb31b Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Mon, 25 Aug 2025 19:19:38 +0200
+Subject: [PATCH 04/13] arm64: dts: lx2160a-cex7: add interrupts for rtc and
+ ethernet phy
+
+SolidRun LX2160A CEX-7 module has interrupts wired for both the rtc and
+ethernet phy.
+
+Add description for those interrupts to the rtc and phy nodes.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
+index d32a52ab00a4..8f9007ca4941 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
+@@ -41,6 +41,7 @@ &emdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <1>;
+ qca,smarteee-tw-us-1g = <24>;
++ interrupts-extended = <&gpio2 4 IRQ_TYPE_EDGE_FALLING>;
+ };
+ };
+
+@@ -159,6 +160,7 @@ &i2c4 {
+ rtc@51 {
+ compatible = "nxp,pcf2129";
+ reg = <0x51>;
++ interrupts-extended = <&gpio2 8 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,40 @@
+From ac06d0c2e7787ccdcb693445a43cb21b29865b49 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sun, 20 Oct 2024 14:19:43 +0200
+Subject: [PATCH 05/13] arm64: dts: lx2160a-clearfog-itx: enable pcie nodes for
+ x4 and x8 slots
+
+SolidRun Clearfog CX and Honeycomb have LX2160A PEX3 and PEX5 exposed on
+physical connectors.
+Vendor U-Boot used to patch status properties such that it went
+undiscovered these nodes have their status set disabled.
+
+Set status okay for pcie3 and pcie5 nodes.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ .../boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
+index a7dcbecc1f41..af6258b2fe82 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
+@@ -96,6 +96,14 @@ &esdhc0 {
+ status = "okay";
+ };
+
++&pcie3 {
++ status = "okay";
++};
++
++&pcie5 {
++ status = "okay";
++};
++
+ &pcs_mdio7 {
+ status = "okay";
+ };
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,62 @@
+From 082f9738584eee0b9b09cc03e0e5a2ecb4c2f164 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Mon, 25 Aug 2025 18:59:33 +0200
+Subject: [PATCH 06/13] rtc: pcf2127: clear minute/second interrupt
+
+PCF2127 can generate interrupt every full second or minute configured
+from control and status register 1, bits MI (1) and SI (0).
+
+On interrupt control register 2 bit MSF (7) is set and must be cleared
+to continue normal operation.
+
+While the driver never enables this interrupt on its own, users or
+firmware may do so - e.g. as an easy way to test the interrupt.
+
+Add preprocessor definition for MSF bit and include it in the irq
+bitmask to ensure minute and second interrupts are cleared when fired.
+
+This fixes an issue where the rtc enters a test mode and becomes
+unresponsive after a second interrupt has fired and is not cleared in
+time. In this state register writes to control registers have no
+effect and the interrupt line is kept asserted [1]:
+
+[1] userspace commands to put rtc into unresponsive state:
+$ i2cget -f -y 2 0x51 0x00
+0x04
+$ i2cset -f -y 2 0x51 0x00 0x05 # set bit 0 SI
+$ i2cget -f -y 2 0x51 0x00
+0x84 # bit 8 EXT_TEST set
+$ i2cset -f -y 2 0x51 0x00 0x05 # try overwrite control register
+$ i2cget -f -y 2 0x51 0x00
+0x84 # no change
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/rtc/rtc-pcf2127.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c
+index 9c04c4e1a49c..083d402e96f9 100644
+--- a/drivers/rtc/rtc-pcf2127.c
++++ b/drivers/rtc/rtc-pcf2127.c
+@@ -41,6 +41,7 @@
+ #define PCF2127_BIT_CTRL2_AF BIT(4)
+ #define PCF2127_BIT_CTRL2_TSF2 BIT(5)
+ #define PCF2127_BIT_CTRL2_WDTF BIT(6)
++#define PCF2127_BIT_CTRL2_MSF BIT(7)
+ /* Control register 3 */
+ #define PCF2127_REG_CTRL3 0x02
+ #define PCF2127_BIT_CTRL3_BLIE BIT(0)
+@@ -94,7 +95,8 @@
+ #define PCF2127_CTRL2_IRQ_MASK ( \
+ PCF2127_BIT_CTRL2_AF | \
+ PCF2127_BIT_CTRL2_WDTF | \
+- PCF2127_BIT_CTRL2_TSF2)
++ PCF2127_BIT_CTRL2_TSF2 | \
++ PCF2127_BIT_CTRL2_MSF)
+
+ #define PCF2127_MAX_TS_SUPPORTED 4
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,502 @@
+From a8889bce584f0caa8777eabdb4e5ff45fab9f9e5 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Wed, 12 Oct 2022 18:46:09 +0300
+Subject: [PATCH 10/13] net: phy: create driver for ds250df4x10 retimer
+
+Create driver for the TI DS250DF410 and DS250DF810 retimers.
+Both variants feature either 4 or 8 channels to be configured
+individually from 20.2752 to 25.8Gbps, while also supporting subrates by
+dividing either with 2 or 4.
+
+Configuration is provided to other drivers by implementing a generic phy
+with support for set_mode.
+
+3 standard configurations for 1/10/25G Ethernet are supported:
+- PHY_INTERFACE_MODE_SGMII: 1.25 Gbps
+- PHY_INTERFACE_MODE_10GBASER: 10.3125 Gbps
+- PHY_INTERFACE_MODE_25GBASER: 25.78125Gbps
+
+The driver also hardcodes signal conditioning parameters.
+Future revisions shall read those from device-tree instead.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/phy/ti/Kconfig | 9 +
+ drivers/phy/ti/Makefile | 1 +
+ drivers/phy/ti/phy-ti-ds250dfx10.c | 432 +++++++++++++++++++++++++++++
+ 3 files changed, 442 insertions(+)
+ create mode 100644 drivers/phy/ti/phy-ti-ds250dfx10.c
+
+diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig
+index af5653f24cbc..4a0fd2a59670 100644
+--- a/drivers/phy/ti/Kconfig
++++ b/drivers/phy/ti/Kconfig
+@@ -84,6 +84,15 @@ config TI_PIPE3
+ This driver interacts with the "OMAP Control PHY Driver" to power
+ on/off the PHY.
+
++config PHY_DS250DFX10
++ tristate "Texas Instruments DS250DFX10 Retimer"
++ depends on OF
++ select GENERIC_PHY
++ help
++ Enable to support runtime configuration of DS250DFX10 retimers.
++ The retimers are modeled as generic PHYs,
++ currently supporting 10 & 25 GBASER link speeds.
++
+ config PHY_TUSB1210
+ tristate "TI TUSB1210 ULPI PHY module"
+ depends on USB_ULPI_BUS
+diff --git a/drivers/phy/ti/Makefile b/drivers/phy/ti/Makefile
+index e68445ddd848..f1459b9e5fab 100644
+--- a/drivers/phy/ti/Makefile
++++ b/drivers/phy/ti/Makefile
+@@ -4,6 +4,7 @@ obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o
+ obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o
+ obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
+ obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o
++obj-$(CONFIG_PHY_DS250DFX10) += phy-ti-ds250dfx10.o
+ obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o
+ obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
+ obj-$(CONFIG_PHY_AM654_SERDES) += phy-am654-serdes.o
+diff --git a/drivers/phy/ti/phy-ti-ds250dfx10.c b/drivers/phy/ti/phy-ti-ds250dfx10.c
+new file mode 100644
+index 000000000000..bab1a29669c3
+--- /dev/null
++++ b/drivers/phy/ti/phy-ti-ds250dfx10.c
+@@ -0,0 +1,432 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Driver for the TI DS250DF410 Retimer
++ *
++ * Copyright (C) 2022-2023 Josua Mayer <josua@solid-run.com>
++ */
++
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/phy.h>
++#include <linux/phy/phy.h>
++
++#define DS250DF410_REG_CHAN_CONFIG_ID 0xEF
++#define DS250DF410_MASK_CHAN_CONFIG_ID GENMASK(3, 0)
++#define DS250DF410_REG_VERSION 0xF0
++#define DS250DF410_REG_DEVICE_ID 0xF1
++#define DS250DF410_REG_CHAN_VERSION 0xF3
++#define DS250DF410_MASK_CHAN_VERSION GENMASK(7, 4)
++#define DS250DF410_MASK_SHARE_VERSION GENMASK(3, 0)
++
++struct ds250dfx10_phy_priv {
++ struct i2c_client *client;
++ uint8_t channel;
++};
++
++struct ds250dfx10_priv {
++ struct phy *phy[8];
++ struct phy_provider *provider;
++};
++
++static int ds250dfx10_read_register(struct i2c_client *client, uint8_t address, uint8_t *value,
++ uint8_t mask)
++{
++ s32 res;
++
++ res = i2c_smbus_read_byte_data(client, address);
++ if (res < 0) {
++ dev_err(&client->dev, "failed to read register %#04x: %d\n", address,
++ res);
++ return -EIO;
++ }
++
++ *value = res & mask;
++ return 0;
++}
++
++static int ds250dfx10_write_register(struct i2c_client *client, uint8_t address, uint8_t value,
++ uint8_t mask)
++{
++ int ret;
++ uint8_t tmp;
++ s32 res;
++
++ // combine with current value according to mask
++ if (mask != 0xFF) {
++ ret = ds250dfx10_read_register(client, address, &tmp, ~mask);
++ if (ret)
++ return ret;
++
++ value = (value & mask) | tmp;
++ }
++
++ // write new value
++ res = i2c_smbus_write_byte_data(client, address, value);
++ if (res < 0) {
++ dev_err(&client->dev, "failed to write register %#04x=%#04x: %d\n",
++ address, value, res);
++ return -EIO;
++ }
++
++ return 0;
++}
++
++static void ds250dfx10_config_1g(struct i2c_client *client, uint8_t channel)
++{
++ int ret = 0;
++
++ // enable smbus access to single channel
++ ret |= ds250dfx10_write_register(client, 0xFF, 0x01, 0x03);
++
++ // select channel
++ ret |= ds250dfx10_write_register(client, 0xFC, 1 << channel, 0xFF);
++
++ // reset channel registers
++ ret |= ds250dfx10_write_register(client, 0x00, 0x04, 0x04);
++
++ // assert cdr
++ ret |= ds250dfx10_write_register(client, 0x0A, 0x0C, 0x0C);
++
++ // set manual data rate override to 1.25Gbps
++ ret |= ds250dfx10_write_register(client, 0x60, 0x00, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x61, 0xb2, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x62, 0x00, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x63, 0xb2, 0xFF);
++
++ // set maximum ppm delta tolerance
++ ret |= ds250dfx10_write_register(client, 0x64, 0xFF, 0xFF);
++
++ // enable manual divider override
++ ret |= ds250dfx10_write_register(client, 0x09, 0x04, 0x04);
++
++ // set divider to 16
++ ret |= ds250dfx10_write_register(client, 0x18, 0x40, 0x70);
++
++ // enable pre- and post-fir
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x80, 0x80);
++
++ // set main cursor magnitude +15
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x00, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x0F, 0x1F);
++
++ // set pre cursor magnitude -4
++ ret |= ds250dfx10_write_register(client, 0x3E, 0x40, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3E, 0x04, 0x0F);
++
++ // set post cursor magnitude -4
++ ret |= ds250dfx10_write_register(client, 0x3F, 0x40, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3F, 0x04, 0x0F);
++
++ // deassert cdr
++ ret |= ds250dfx10_write_register(client, 0x0A, 0x00, 0x0C);
++
++ if (!ret)
++ dev_info(&client->dev, "configured channel %u for 1G\n", channel);
++}
++
++static void ds250dfx10_config_10g(struct i2c_client *client, uint8_t channel)
++{
++ int ret = 0;
++
++ // enable smbus access to single channel
++ ret |= ds250dfx10_write_register(client, 0xFF, 0x01, 0x03);
++
++ // select channel
++ ret |= ds250dfx10_write_register(client, 0xFC, 1 << channel, 0xFF);
++
++ // reset channel registers
++ ret |= ds250dfx10_write_register(client, 0x00, 0x04, 0x04);
++
++ // assert cdr
++ ret |= ds250dfx10_write_register(client, 0x0A, 0x0C, 0x0C);
++
++ // disable manual data rate override
++ ret |= ds250dfx10_write_register(client, 0x60, 0x00, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x61, 0x00, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x62, 0x00, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x63, 0x00, 0xFF);
++
++ // set minimum ppm delta tolerance (reset-default)
++ ret |= ds250dfx10_write_register(client, 0x64, 0x00, 0xFF);
++
++ // disable manual divider override
++ ret |= ds250dfx10_write_register(client, 0x09, 0x00, 0x04);
++
++ // select 10.3125 rate
++ ret |= ds250dfx10_write_register(client, 0x2F, 0x00, 0xF0);
++
++ // enable pre- and post-fir
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x80, 0x80);
++
++ // set main cursor magnitude +15
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x00, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x0F, 0x1F);
++
++ // set pre cursor magnitude -4
++ ret |= ds250dfx10_write_register(client, 0x3E, 0x40, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3E, 0x04, 0x0F);
++
++ // set post cursor magnitude -4
++ ret |= ds250dfx10_write_register(client, 0x3F, 0x40, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3F, 0x04, 0x0F);
++
++ // deassert cdr
++ ret |= ds250dfx10_write_register(client, 0x0A, 0x00, 0x0C);
++
++ if (!ret)
++ dev_info(&client->dev, "configured channel %u for 10G\n", channel);
++}
++
++static void ds250dfx10_config_25g(struct i2c_client *client, uint8_t channel)
++{
++ int ret = 0;
++
++ // enable smbus access to single channel
++ ret |= ds250dfx10_write_register(client, 0xFF, 0x01, 0x03);
++
++ // select channel
++ ret |= ds250dfx10_write_register(client, 0xFC, 1 << channel, 0xFF);
++
++ // reset channel registers
++ ret |= ds250dfx10_write_register(client, 0x00, 0x04, 0x04);
++
++ // assert cdr
++ ret |= ds250dfx10_write_register(client, 0x0A, 0x0C, 0x0C);
++
++ // disable manual data rate override
++ ret |= ds250dfx10_write_register(client, 0x60, 0x00, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x61, 0x00, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x62, 0x00, 0xFF);
++ ret |= ds250dfx10_write_register(client, 0x63, 0x00, 0xFF);
++
++ // set minimum ppm delta tolerance (reset-default)
++ ret |= ds250dfx10_write_register(client, 0x64, 0x00, 0xFF);
++
++ // disable manual divider override
++ ret |= ds250dfx10_write_register(client, 0x09, 0x00, 0x04);
++
++ // select 25.78125 rate
++ ret |= ds250dfx10_write_register(client, 0x2F, 0x50, 0xF0);
++
++ // enable pre- and post-fir
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x80, 0x80);
++
++ // set main cursor magnitude +15
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x00, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3D, 0x0F, 0x1F);
++
++ // set pre cursor magnitude -4
++ ret |= ds250dfx10_write_register(client, 0x3E, 0x40, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3E, 0x04, 0x0F);
++
++ // set post cursor magnitude -4
++ ret |= ds250dfx10_write_register(client, 0x3F, 0x40, 0x40);
++ ret |= ds250dfx10_write_register(client, 0x3F, 0x04, 0x0F);
++
++ // deassert cdr
++ ret |= ds250dfx10_write_register(client, 0x0A, 0x00, 0x0C);
++
++ if (!ret)
++ dev_info(&client->dev, "configured channel %u for 25G\n", channel);
++}
++
++static int ds250dfx10_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
++{
++ struct ds250dfx10_phy_priv *priv = phy_get_drvdata(phy);
++
++ if (mode != PHY_MODE_ETHERNET)
++ return -EOPNOTSUPP;
++
++ switch (submode) {
++ case PHY_INTERFACE_MODE_SGMII:
++ ds250dfx10_config_1g(priv->client, priv->channel);
++ break;
++ case PHY_INTERFACE_MODE_10GBASER:
++ ds250dfx10_config_10g(priv->client, priv->channel);
++ break;
++ case PHY_INTERFACE_MODE_25GBASER:
++ ds250dfx10_config_25g(priv->client, priv->channel);
++ break;
++ default:
++ dev_err(&priv->client->dev, "unsupported interface submode %i\n",
++ submode);
++ return -EOPNOTSUPP;
++ }
++
++ return 0;
++}
++
++static const struct phy_ops ds250dfx10_phy_ops = {
++ .set_mode = ds250dfx10_phy_set_mode,
++ .owner = THIS_MODULE,
++};
++
++static struct phy *ds250dfx10_of_xlate(struct device *dev, const struct of_phandle_args *args)
++{
++ struct ds250dfx10_priv *phy_priv = dev_get_drvdata(dev);
++ int channel;
++
++ if (args->args_count != 1) {
++ dev_err(phy_priv->provider->dev, "DT did not pass correct no of args\n");
++ return ERR_PTR(-ENODEV);
++ }
++
++ channel = args->args[0];
++ if (WARN_ON(channel >= ARRAY_SIZE(phy_priv->phy))
++ || !phy_priv->phy[channel])
++ return ERR_PTR(-ENODEV);
++
++ return phy_priv->phy[channel];
++}
++
++static int ds250dfx10_probe(struct i2c_client *client)
++{
++ struct ds250dfx10_priv *priv;
++ struct ds250dfx10_phy_priv *phy_priv;
++ struct device_node *child;
++ uint8_t chan_config_id, device_id, version, chan_version, share_version, channels;
++ uint8_t reg;
++ int ret, i;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv) {
++ ret = -ENOMEM;
++ goto no_phys;
++ }
++ i2c_set_clientdata(client, priv);
++
++ /* read device identification */
++ ret = ds250dfx10_read_register(client, DS250DF410_REG_DEVICE_ID, ®, 0xFF);
++ if (ret)
++ goto no_phys;
++ device_id = reg;
++
++ /* read device version */
++ ret = ds250dfx10_read_register(client, DS250DF410_REG_VERSION, ®, 0xFF);
++ if (ret)
++ goto no_phys;
++ version = reg;
++
++ // report device id
++ dev_info(&client->dev, "device id %#04x version %#04x\n", device_id, version);
++
++ switch (device_id) {
++ case 0x10:
++ break;
++ default:
++ dev_warn(&client->dev, "unknown device id, expect problems!\n");
++ }
++
++ // read channel config id
++ ret = ds250dfx10_read_register(client, DS250DF410_REG_CHAN_CONFIG_ID, ®,
++ DS250DF410_MASK_CHAN_CONFIG_ID);
++ if (ret)
++ goto no_phys;
++ chan_config_id = reg;
++
++ switch (chan_config_id) {
++ case 0xC:
++ channels = 8;
++ break;
++ case 0xE:
++ channels = 4;
++ break;
++ default:
++ dev_err(&client->dev, "unknown channel configuration id %#03x\n", chan_config_id);
++ ret = -EINVAL;
++ goto no_phys;
++ }
++ dev_info(&client->dev, "%u channels\n", channels);
++
++ // read channel version
++ ret = ds250dfx10_read_register(client, DS250DF410_REG_CHAN_VERSION, ®, 0xFF);
++ if (ret)
++ goto no_phys;
++ chan_version = (reg & DS250DF410_MASK_CHAN_VERSION) >> 4;
++ share_version = reg & DS250DF410_MASK_SHARE_VERSION;
++
++ dev_info(&client->dev, "channel version %#03x share version %#03x\n",
++ chan_version, share_version);
++
++ // create PHY objects for all channels
++ for (i = 0; i < channels; i++) {
++ priv->phy[i] = devm_phy_create(&client->dev, child, &ds250dfx10_phy_ops);
++ if (IS_ERR(priv->phy[i])) {
++ ret = PTR_ERR(priv->phy[i]);
++ priv->phy[i] = NULL;
++ of_node_put(child);
++ goto no_provider;
++ }
++
++ phy_priv = devm_kzalloc(&client->dev, sizeof(*phy_priv), GFP_KERNEL);
++ if (!phy_priv) {
++ ret = -ENOMEM;
++ goto no_provider;
++ }
++ phy_set_drvdata(priv->phy[i], phy_priv);
++
++ phy_priv->client = client;
++ phy_priv->channel = i;
++
++ dev_info(&client->dev, "created phy for channel %u\n", i);
++ }
++ of_node_put(child);
++
++ // register self as phy provider with generic lookup function
++ priv->provider = devm_of_phy_provider_register(&client->dev, ds250dfx10_of_xlate);
++
++ return 0;
++
++ devm_of_phy_provider_unregister(&client->dev, priv->provider);
++no_provider:
++ for (i = 0; i < 8; i++) {
++ if (priv->phy[i])
++ devm_phy_destroy(&client->dev, priv->phy[i]);
++ }
++no_phys:
++ return ret;
++}
++
++static void ds250dfx10_remove(struct i2c_client *client)
++{
++ struct ds250dfx10_priv *priv = i2c_get_clientdata(client);
++ int i;
++
++ for (i = 0; i < 8; i++)
++ if (priv->phy[i])
++ devm_phy_destroy(&client->dev, priv->phy[i]);
++}
++
++#ifdef CONFIG_OF
++static const struct of_device_id ds250dfx10_dt_ids[] = {
++ { .compatible = "ti,ds250df410", },
++ { .compatible = "ti,ds250df810", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ds250dfx10_dt_ids);
++#endif
++
++static struct i2c_device_id ds250dfx10_idtable[] = {
++ { "ds250df410", 0 },
++ { "ds250df810", 1 },
++ { }
++};
++
++MODULE_DEVICE_TABLE(i2c, ds250dfx10_idtable);
++
++static struct i2c_driver ds250dfx10_driver = {
++ .driver = {
++ .name = "ds250dfx10",
++ .of_match_table = of_match_ptr(ds250dfx10_dt_ids),
++ },
++
++ .id_table = ds250dfx10_idtable,
++ .probe = ds250dfx10_probe,
++ .remove = ds250dfx10_remove,
++};
++
++module_i2c_driver(ds250dfx10_driver);
++
++MODULE_AUTHOR("Josua Mayer <josua@solid-run.com>");
++MODULE_DESCRIPTION("TI DS250DFX10 Retimer Driver");
++MODULE_LICENSE("GPL");
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,81 @@
+From 0ad1b0e326062f8c32f3006d3960f4381fdac61b Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Thu, 31 Oct 2024 15:46:16 +0100
+Subject: [PATCH 12/13] arm64: dts: lx2160a-clearfog-cx: add description for
+ retimers
+
+SolidRun Clearfog-CX (unlike Honeycomb) has QSFP connector driven by
+retimers to support long copper wires.
+
+Add descriptions for both retimers and link them to the relevant
+ethernet interfaces.
+
+Retimers were added with board revision 1.3, earlier baords can use the
+honeycomb dts.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ .../boot/dts/freescale/fsl-lx2160a-cex7.dtsi | 2 +-
+ .../dts/freescale/fsl-lx2160a-clearfog-cx.dts | 36 +++++++++++++++++++
+ 2 files changed, 37 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
+index 8f9007ca4941..3fae11353813 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
+@@ -112,7 +112,7 @@ regulator@5c {
+ };
+ };
+
+- i2c@3 {
++ i2c_smb: i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts
+index 86a9b771428d..050d2b565650 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts
++++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts
+@@ -13,3 +13,39 @@ / {
+ compatible = "solidrun,clearfog-cx",
+ "solidrun,lx2160a-cex7", "fsl,lx2160a";
+ };
++
++&dpmac3 {
++ phys = <&serdes_1 7>, <&retimer0 3>, <&retimer1 3>;
++ phy-names = "serdes", "retimer", "retimer";
++};
++
++&dpmac4 {
++ phys = <&serdes_1 6>, <&retimer0 2>, <&retimer1 2>;
++ phy-names = "serdes", "retimer", "retimer";
++};
++
++&dpmac5 {
++ phys = <&serdes_1 5>, <&retimer0 1>, <&retimer1 1>;
++ phy-names = "serdes", "retimer", "retimer";
++};
++
++&dpmac6 {
++ phys = <&serdes_1 4>, <&retimer0 0>, <&retimer1 0>;
++ phy-names = "serdes", "retimer", "retimer";
++};
++
++&i2c_smb {
++ /* tx direction */
++ retimer0: retimer@22 {
++ compatible = "ti,ds250df410";
++ reg = <0x22>;
++ #phy-cells = <1>;
++ };
++
++ /* rx direction */
++ retimer1: retimer@23 {
++ compatible = "ti,ds250df410";
++ reg = <0x23>;
++ #phy-cells = <1>;
++ };
++};
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,55 @@
+From 8d262bafc2bb4b57ce2331b6eb31d7ad749eaf6c Mon Sep 17 00:00:00 2001
+From: Rabeeh Khoury <rabeeh@solid-run.com>
+Date: Mon, 23 Mar 2020 12:16:13 +0200
+Subject: [PATCH 02/10] add loadc, jumpc and jump to pbi instructions
+
+Add 'load conditional', 'jump condidional' and 'jump' to PBI
+instructions.
+
+Signed-off-by: Rabeeh Khoury <rabeeh@solid-run.com>
+---
+ rcw.py | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/rcw.py b/rcw.py
+index e7d3795..bcd088d 100755
+--- a/rcw.py
++++ b/rcw.py
+@@ -330,6 +330,34 @@ def build_pbi(lines):
+ v2 = struct.pack(endianess + 'L', p2)
+ subsection += v1
+ subsection += v2
++ elif op == 'loadc':
++ if p1 == None or p2 == None:
++ print('Error: "loadc" instruction requires two parameters')
++ return ''
++ v1 = struct.pack(endianess + 'L', 0x80140000)
++ v2 = struct.pack(endianess + 'L', p1)
++ v3 = struct.pack(endianess + 'L', p2)
++ subsection += v1
++ subsection += v2
++ subsection += v3
++ elif op == 'jumpc':
++ if p1 == None or p2 == None:
++ print('Error: "jumpc" instruction requires two parameters')
++ return ''
++ v1 = struct.pack(endianess + 'L', 0x80850000)
++ v2 = struct.pack(endianess + 'L', p1)
++ v3 = struct.pack(endianess + 'L', p2)
++ subsection += v1
++ subsection += v2
++ subsection += v3
++ elif op == 'jump':
++ if p1 == None:
++ print('Error: "jump" instruction requires a parameter')
++ return ''
++ v1 = struct.pack(endianess + 'L', 0x80840000)
++ v2 = struct.pack(endianess + 'L', p1)
++ subsection += v1
++ subsection += v2
+ elif op == 'awrite':
+ if opsize == '.b5':
+ # altconfig write with B=5 (16 bytes)
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,80 @@
+From e6d93b4dfb67a89339527c90ec1c50c2325b025b Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Mon, 7 Oct 2024 14:37:13 +0200
+Subject: [PATCH 03/10] lx2160asi: add bootlocptr script for automatic boot
+ from SD/eMMC/SPI
+
+For each boot source test rcw source, and set bootlocl/h accordingly.
+
+For single boot-source atf create_pbl adds block copy commands
+and sets boot location pointer.
+Automatic boot relies on rcw to include the blockcopy and bootlocptr
+commands, create_pbl then replaces their arguments with actual load
+addresses.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ lx2160asi/bootlocptr_auto.rcw | 51 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+ create mode 100644 lx2160asi/bootlocptr_auto.rcw
+
+diff --git a/lx2160asi/bootlocptr_auto.rcw b/lx2160asi/bootlocptr_auto.rcw
+new file mode 100644
+index 0000000..08e7916
+--- /dev/null
++++ b/lx2160asi/bootlocptr_auto.rcw
+@@ -0,0 +1,51 @@
++/*
++ * Generic code for auto booting.
++ *
++ * For each boot source test rcw source, and set bootlocl/h accordingly.
++ *
++ * For single boot-source atf create_pbl adds block copy commands
++ * and sets boot location pointer.
++ * Automatic boot relies on rcw to include the blockcopy and bootlocptr
++ * commands, create_pbl then replaces their arguments.
++ *
++ * Copyright 2020 Rabeeh Khoury <rabeeh@solid-run.com>
++ * Copyright 2024 Josua Mayer <josua@solid-run.com>
++ *
++ * Changelog:
++ * - 28/09/2024: changed formatting and comments
++ * - 07/10/2024: removed unnecessary commands to reduce size
++ */
++.pbi
++/* Load condition PORSR1 and mask RCW_SRC */
++loadc 0x01e00000,0x07800000
++
++/* If condition is 0x8 << 23 (SDHC1) then skip the following jump command */
++jumpc 0x00000014,0x04000000
++
++/* skip sdhc1 boot */
++jump 0x20 /* this jump + blockcopy = (4+4+4+4)+(4+4)=24 bytes */
++
++/* copy blocks from sdhc1 (atf create_pbl will fixup arguments) */
++blockcopy 0x08,0x0000a000,0x1800d000,0x00020000
++write 0x01e00400,0x1800d000
++
++/* If condition is 0x9 << 23 (SDHC2) then skip the following jump command */
++jumpc 0x00000014,0x04800000
++
++/* skip sdhc2 boot */
++jump 0x20 /* this jump + blockcopy = (4+4+4+4)+(4+4)=24 bytes */
++
++/* copy blocks from sdhc1 (atf create_pbl will fixup arguments) */
++blockcopy 0x09,0x0000a000,0x1800d000,0x00020000
++write 0x01e00400,0x1800d000
++
++/* If condition is 0xf << 23 (XSPI) then skip the following jump command */
++jumpc 0x00000014,0x07800000
++
++/* skip xspi boot */
++jump 0x20 /* this jump + blockcopy = (4+4+4+4)+(4+4)=24 bytes */
++
++/* copy blocks from xspi (atf create_pbl will fixup arguments) */
++blockcopy 0x0f,0x20009000,0x1800d000,0x00020000
++write 0x01e00400,0x1800d000
++.end
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,132 @@
+From 2f6d70d10856e7620619af7fa2961cefa68fd2b4 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Wed, 6 Aug 2025 19:14:37 +0200
+Subject: [PATCH 04/10] lx2160asi: add procedure splitting sd1 lanes A-D 40GE.2
+ into 4x10g
+
+Implement custom procedure to reconfigure SD1 protocols 19/20 splitting
+the 40GE.2 port on lanes A-D into 4x XFI.
+
+The procedure is implemented in new rcw file e40g2_split.rcw, following
+the existing e100g1_split.rcw closely.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ lx2160asi/e40g2_split.rcw | 68 +++++++++++++++++++++++++++++++++++++++
+ serdes_28g.rcw | 18 +++++++++++
+ 2 files changed, 86 insertions(+)
+ create mode 100644 lx2160asi/e40g2_split.rcw
+
+diff --git a/lx2160asi/e40g2_split.rcw b/lx2160asi/e40g2_split.rcw
+new file mode 100644
+index 0000000..fa5bb96
+--- /dev/null
++++ b/lx2160asi/e40g2_split.rcw
+@@ -0,0 +1,68 @@
++/*
++ * Split the 40G MAC.2 into 4 x 10G MAC
++ *
++ * NOTICE: The DPC file must be updated as below in order for the MC firmware
++ * to pick up on the change.
++ *
++ * board_info {
++ * serdes {
++ * /* Do not rely on the RCW protocol number, but rather read
++ * * the protocol status registers (PSSR) for each SerDes
++ * * block. That information will be used to enable/disable
++ * * the appropriate MACs.
++ * */
++/* follow_hw_pssr;
++ * };
++ * };
++ */
++#define SRDS_BASE 0x1ea0000 /* SerDes 1 */
++#include <../serdes_28g.rcw>
++
++.pbi
++/* Issue a halt request on all the lanes (A-D) */
++write LNmTRSTCTL(0), T_HLT_REQ(1)
++write LNmRRSTCTL(0), R_HLT_REQ(1)
++
++write LNmTRSTCTL(1), T_HLT_REQ(1)
++write LNmRRSTCTL(1), R_HLT_REQ(1)
++
++write LNmTRSTCTL(2), T_HLT_REQ(1)
++write LNmRRSTCTL(2), R_HLT_REQ(1)
++
++write LNmTRSTCTL(3), T_HLT_REQ(1)
++write LNmRRSTCTL(3), R_HLT_REQ(1)
++
++wait 100
++
++/* Convert Lanes to be configured for 10G. Only the LNmGCR0 needs to be
++ * updated, all other per lane registers are the same between 10G and 40G.
++ */
++write LNmGCR0(0), PORT_RST_LEFT(0) | PORT_LN0_B(0) | PROTO_SEL(0xA) | IF_WIDTH(0x2)
++write LNmGCR0(1), PORT_RST_LEFT(0) | PORT_LN0_B(0) | PROTO_SEL(0xA) | IF_WIDTH(0x2)
++write LNmGCR0(2), PORT_RST_LEFT(0) | PORT_LN0_B(0) | PROTO_SEL(0xA) | IF_WIDTH(0x2)
++write LNmGCR0(3), PORT_RST_LEFT(0) | PORT_LN0_B(0) | PROTO_SEL(0xA) | IF_WIDTH(0x2)
++
++/* Configure the PCC registers */
++/* Only the 40G MAC.1 will remain enabled. PCCE: 0x11000000 -> 0x10000000 */
++write PCCE, E40GA_CFG(1)
++
++/* Enable the 10G protocol converters for XFI. PCCE: 0x00000000 -> 0x00009999 */
++write PCCC, SXGMIIGA_CFG(1) | SXGMIIGB_CFG(1) | SXGMIIGC_CFG(1) | SXGMIIGD_CFG(1) | SXGMIIGA_XFI(1) | SXGMIIGB_XFI(1) | SXGMIIGC_XFI(1) | SXGMIIGD_XFI(1)
++
++/* Issue a reset request on all the lanes (E-H) */
++write LNmTRSTCTL(0), T_RST_REQ(1)
++write LNmRRSTCTL(0), R_RST_REQ(1)
++
++write LNmTRSTCTL(1), T_RST_REQ(1)
++write LNmRRSTCTL(1), R_RST_REQ(1)
++
++write LNmTRSTCTL(2), T_RST_REQ(1)
++write LNmRRSTCTL(2), R_RST_REQ(1)
++
++write LNmTRSTCTL(3), T_RST_REQ(1)
++write LNmRRSTCTL(3), R_RST_REQ(1)
++
++wait 100
++.end
++
++#undef SRDS_BASE
+diff --git a/serdes_28g.rcw b/serdes_28g.rcw
+index e57be41..89de7c3 100644
+--- a/serdes_28g.rcw
++++ b/serdes_28g.rcw
+@@ -59,6 +59,22 @@
+
+ /* PCCD contains the protocol configuration for SXGMII/XFI */
+ #define PCCC (SRDS_BASE + 0x10B0)
++#define SXGMIIGA_XFI(x) (((x) << 31) & 0x80000000)
++#define SXGMIIGB_XFI(x) (((x) << 27) & 0x08000000)
++#define SXGMIIGC_XFI(x) (((x) << 23) & 0x00800000)
++#define SXGMIIGD_XFI(x) (((x) << 19) & 0x00080000)
++#define SXGMIIGE_XFI(x) (((x) << 15) & 0x00008000)
++#define SXGMIIGF_XFI(x) (((x) << 11) & 0x00000800)
++#define SXGMIIGG_XFI(x) (((x) << 7) & 0x00000080)
++#define SXGMIIGH_XFI(x) (((x) << 3) & 0x00000008)
++#define SXGMIIGA_CFG(x) (((x) << 28) & 0x70000000)
++#define SXGMIIGB_CFG(x) (((x) << 24) & 0x07000000)
++#define SXGMIIGC_CFG(x) (((x) << 20) & 0x00700000)
++#define SXGMIIGD_CFG(x) (((x) << 16) & 0x00070000)
++#define SXGMIIGE_CFG(x) (((x) << 12) & 0x00007000)
++#define SXGMIIGF_CFG(x) (((x) << 8) & 0x00000700)
++#define SXGMIIGG_CFG(x) (((x) << 4) & 0x00000070)
++#define SXGMIIGH_CFG(x) ((x) & 0x00000007)
+
+ /* PCCD contains the protocol configuration for E25G */
+ #define PCCD (SRDS_BASE + 0x10B4)
+@@ -75,6 +91,8 @@
+ #define PCCE (SRDS_BASE + 0x10B8)
+ #define E100GB_CFG(x) (((x) << 8) & 0x00000700)
+ #define E100GA_CFG(x) (((x) << 12) & 0x000007000)
++#define E40GB_CFG(x) (((x) << 24) & 0x07000000)
++#define E40GA_CFG(x) (((x) << 28) & 0x070000000)
+
+ #define PEXaCR0(a) (SRDS_BASE + (0x40 * (a)) + 0x1200)
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,65 @@
+From cbcd1e26bc5e2c07954fd01e55b3b330d4c7b214 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sun, 24 Aug 2025 14:21:00 +0200
+Subject: [PATCH 05/10] lx2160asi: add procedure converting sd1 lanes g&h from
+ 10g to 25g
+
+Add procedure converting sd1 lanes G and H from 10G to 25G, yielding in
+protocol 18 4x 25G plus 4x 10G ports total.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ lx2160asi/sd1_lane_g_h_xfi_to_25g.rcw | 41 +++++++++++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+ create mode 100644 lx2160asi/sd1_lane_g_h_xfi_to_25g.rcw
+
+diff --git a/lx2160asi/sd1_lane_g_h_xfi_to_25g.rcw b/lx2160asi/sd1_lane_g_h_xfi_to_25g.rcw
+new file mode 100644
+index 0000000..40756d8
+--- /dev/null
++++ b/lx2160asi/sd1_lane_g_h_xfi_to_25g.rcw
+@@ -0,0 +1,41 @@
++/* Convert the SD#1 LANE G and H from XFI to 25G */
++#define SRDS_BASE 0x1ea0000 /* SerDes 1 */
++#include <../serdes_28g.rcw>
++
++.pbi
++/* Issue a halt request on the lanes */
++write LNmTRSTCTL(6), T_HLT_REQ(1)
++write LNmRRSTCTL(6), R_HLT_REQ(1)
++write LNmTRSTCTL(7), T_HLT_REQ(1)
++write LNmRRSTCTL(7), R_HLT_REQ(1)
++wait 100
++
++/* Convert lane G from 10G to 25G */
++write LNmGCR0(6), PROTO_SEL(0x1a) | IF_WIDTH(0x4)
++write LNmTGCR0(6), 0x03000000
++write LNmRGCR0(6), 0x03000000
++write LNmRGCR1(6), 0x00000000
++
++/* Convert lane H from 10G to 25G */
++write LNmGCR0(7), PROTO_SEL(0x1a) | IF_WIDTH(0x4)
++write LNmTGCR0(7), 0x03000000
++write LNmRGCR0(7), 0x03000000
++write LNmRGCR1(7), 0x00000000
++
++/* Disable the 10G protocol converters on lanes G and H (enable on A-D, disable E-H) */
++/* TODO: don't change A-D bits? */
++write PCCC, SXGMIIGA_CFG(1) | SXGMIIGB_CFG(1) | SXGMIIGC_CFG(1) | SXGMIIGD_CFG(1) | SXGMIIGA_XFI(1) | SXGMIIGB_XFI(1) | SXGMIIGC_XFI(1) | SXGMIIGD_XFI(1)
++
++/* Enable the 25G protocol converters on lanes G and H (enable on E-H, disable A-D) */
++/* TODO: don't change A-D bits? */
++write PCCD, E25GA_CFG(1) | E25GB_CFG(1) | E25GC_CFG(1) | E25GD_CFG(1)
++
++/* Issue a reset request on the lanes */
++write LNmTRSTCTL(6), T_RST_REQ(1)
++write LNmRRSTCTL(6), R_RST_REQ(1)
++write LNmTRSTCTL(7), T_RST_REQ(1)
++write LNmRRSTCTL(7), R_RST_REQ(1)
++wait 100
++.end
++
++#undef SRDS_BASE
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,71 @@
+From fe2a405040fe87cd77cb4bf48bd57d0e65777811 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Thu, 7 Nov 2024 13:26:49 +0100
+Subject: [PATCH 06/10] solidrun: add script generating configs from template
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ GenerateSRConfigs.sh | 50 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+ create mode 100755 GenerateSRConfigs.sh
+
+diff --git a/GenerateSRConfigs.sh b/GenerateSRConfigs.sh
+new file mode 100755
+index 0000000..d29471e
+--- /dev/null
++++ b/GenerateSRConfigs.sh
+@@ -0,0 +1,51 @@
++#!/bin/bash -e
++
++generate() {
++ local template=${1}
++ local MODULE=${2}
++ local SOC_REVISION=${3}
++ local BOARD=${4}
++ local CPU_SPEED=${5}
++ local BUS_SPEED=${6}
++ local DDR_SPEED=${7}
++ local SD1=${8}
++ local SD2=${9}
++ local SD3=${10}
++ local BOOTSOURCE=${11}
++
++ local SOC_REVISION_SUFFIX="_rev${SOC_REVISION}"
++ if [ "${SOC_REVISION_SUFFIX}" = "_rev1" ]; then
++ SOC_REVISION_SUFFIX=
++ fi
++
++ local nSD1=${SD1}
++ if [[ $SD1 = *S ]]; then
++ nSD1=${SD1%S}
++ fi
++
++ local nSD2=${SD2}
++ if [[ $SD2 = *S ]]; then
++ nSD2=${SD2%S}
++ fi
++
++ local nSD3=${SD3}
++ if [[ $SD3 = *S ]]; then
++ nSD3=${SD3%S}
++ fi
++
++ local rcw="${MODULE,,}${SOC_REVISION_SUFFIX,,}/${BOARD,,}/rcw_${CPU_SPEED}_${BUS_SPEED}_${DDR_SPEED}_${SD1}_${SD2}_${SD3}_${BOOTSOURCE,,}.rcw"
++ mkdir -p $(dirname $rcw)
++ cat "$template" | sed \
++ -e "s;%module%;${MODULE,,};g" -e "s;%MODULE%;${MODULE^^};g" \
++ -e "s;%SOC_REVISION%;${SOC_REVISION};g" \
++ -e "s;%board%;${BOARD,,};g" -e "s;%BOARD%;${BOARD^^};g" \
++ -e "s;%CPU_SPEED%;${CPU_SPEED};g" \
++ -e "s;%BUS_SPEED%;${BUS_SPEED};g" \
++ -e "s;%DDR_SPEED%;${DDR_SPEED};g" \
++ -e "s;%bootsource%;${BOOTSOURCE,,};g" -e "s;%BOOTSOURCE%;${BOOTSOURCE^^};g" \
++ -e "s;%SD1%;${SD1};g" -e "s;%nSD1%;${nSD1};g" \
++ -e "s;%SD2%;${SD2};g" -e "s;%nSD2%;${nSD2};g" \
++ -e "s;%SD3%;${SD3};g" -e "s;%nSD3%;${nSD3};g" \
++ > "$rcw"
++ echo "Generated $rcw"
++}
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,735 @@
+From 081f7ed231e93d741df55365bcadc9dc699f578e Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Wed, 12 Jun 2024 15:19:39 +0200
+Subject: [PATCH 07/10] add configuration solidrun lx2160a-cex-7 on clearfog-cx
+ board
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ GenerateSRConfigs.sh | 12 +++
+ lx2160acex7/Makefile | 1 +
+ lx2160acex7/clearfog-cx/sd1_8_eq.rcwi | 39 ++++++++
+ lx2160acex7/include/SD1_18.rcwi | 24 +++++
+ lx2160acex7/include/SD1_20.rcwi | 24 +++++
+ lx2160acex7/include/SD1_4.rcwi | 25 +++++
+ lx2160acex7/include/SD1_8.rcwi | 24 +++++
+ lx2160acex7/include/SD1_8S.rcwi | 24 +++++
+ lx2160acex7/include/SD2_5.rcwi | 30 ++++++
+ lx2160acex7/include/SD3_2.rcwi | 30 ++++++
+ lx2160acex7/include/bootlocptr.rcwi | 13 +++
+ lx2160acex7/include/common.rcwi | 91 +++++++++++++++++++
+ lx2160acex7/include/common_pbi.rcwi | 57 ++++++++++++
+ lx2160acex7/include/pll_2000_700_xxxx.rcwi | 14 +++
+ lx2160acex7/include/pll_2200_750_xxxx.rcwi | 14 +++
+ lx2160acex7/include/pll_xxxx_xxx_2400.rcwi | 12 +++
+ lx2160acex7/include/pll_xxxx_xxx_2600.rcwi | 12 +++
+ lx2160acex7/include/pll_xxxx_xxx_2666.rcwi | 12 +++
+ lx2160acex7/include/pll_xxxx_xxx_2900.rcwi | 12 +++
+ lx2160acex7/include/pll_xxxx_xxx_3200.rcwi | 12 +++
+ lx2160acex7/include/xspi_limit_17M.rcwi | 12 +++
+ lx2160acex7_clearfog-cx.tmpl | 43 +++++++++
+ lx2160acex7_rev2/Makefile | 1 +
+ 325 files changed, 13438 insertions(+)
+ create mode 100644 lx2160acex7/Makefile
+ create mode 100644 lx2160acex7/clearfog-cx/sd1_8_eq.rcwi
+ create mode 100644 lx2160acex7/include/SD1_18.rcwi
+ create mode 100644 lx2160acex7/include/SD1_20.rcwi
+ create mode 100644 lx2160acex7/include/SD1_4.rcwi
+ create mode 100644 lx2160acex7/include/SD1_8.rcwi
+ create mode 100644 lx2160acex7/include/SD1_8S.rcwi
+ create mode 100644 lx2160acex7/include/SD2_5.rcwi
+ create mode 100644 lx2160acex7/include/SD3_2.rcwi
+ create mode 100644 lx2160acex7/include/bootlocptr.rcwi
+ create mode 100644 lx2160acex7/include/common.rcwi
+ create mode 100644 lx2160acex7/include/common_pbi.rcwi
+ create mode 100644 lx2160acex7/include/pll_2000_700_xxxx.rcwi
+ create mode 100644 lx2160acex7/include/pll_2200_750_xxxx.rcwi
+ create mode 100644 lx2160acex7/include/pll_xxxx_xxx_2400.rcwi
+ create mode 100644 lx2160acex7/include/pll_xxxx_xxx_2600.rcwi
+ create mode 100644 lx2160acex7/include/pll_xxxx_xxx_2666.rcwi
+ create mode 100644 lx2160acex7/include/pll_xxxx_xxx_2900.rcwi
+ create mode 100644 lx2160acex7/include/pll_xxxx_xxx_3200.rcwi
+ create mode 100644 lx2160acex7/include/xspi_limit_17M.rcwi
+ create mode 100644 lx2160acex7_clearfog-cx.tmpl
+ create mode 100644 lx2160acex7_rev2/Makefile
+
+diff --git a/GenerateSRConfigs.sh b/GenerateSRConfigs.sh
+index d29471e..aa0ad68 100755
+--- a/GenerateSRConfigs.sh
++++ b/GenerateSRConfigs.sh
+@@ -48,3 +48,15 @@ generate() {
+ > "$rcw"
+ echo "Generated $rcw"
+ }
++
++# generate LX2160A CEX-7 Clearfog-CX
++for DDR_SPEED in 2400 2600 2666 2900 3200; do
++ for SOC_REVISION in 1 2; do
++ for BOOTSOURCE in auto sdhc xspi; do
++ for SD1 in 4 8 8S 18 20; do
++ generate lx2160acex7_clearfog-cx.tmpl lx2160acex7 ${SOC_REVISION} clearfog-cx 2000 700 ${DDR_SPEED} ${SD1} 5 2 ${BOOTSOURCE}
++ generate lx2160acex7_clearfog-cx.tmpl lx2160acex7 ${SOC_REVISION} clearfog-cx 2200 750 ${DDR_SPEED} ${SD1} 5 2 ${BOOTSOURCE}
++ done
++ done
++ done
++done
+diff --git a/lx2160acex7/Makefile b/lx2160acex7/Makefile
+new file mode 100644
+index 0000000..f77e46b
+--- /dev/null
++++ b/lx2160acex7/Makefile
+@@ -0,0 +1 @@
++include ../Makefile.inc
+new file mode 100644
+index 0000000..44961c1
+--- /dev/null
++++ b/lx2160acex7/clearfog-cx/sd1_8_eq.rcwi
+@@ -0,0 +1,39 @@
++/*
++ * SERDES tuning based on the following hardware -
++ * - SolidRun COM express type 7 revision 1.7 and newer
++ * - SolidRun ClearFog CX revision 1.3 with TI retimers and EPT COM express headers
++ */
++
++.pbi
++/* Lane E (SD1 TX/RX 3) */
++write 0x01EA0C28,0x00000000
++write 0x01EA0C30,0x20818120
++write 0x01EA0C34,0x23000000
++write 0x01EA0C68,0x80000000
++write 0x01EA0C74,0x00002020
++write 0x01EA0C80,0x00008000
++
++/* Lane F (SD1 TX/RX 2)*/
++write 0x01EA0D28,0x00000000
++write 0x01EA0D30,0x20818120
++write 0x01EA0D34,0x23000000
++write 0x01EA0D68,0x80000000
++write 0x01EA0D74,0x00002020
++write 0x01EA0D80,0x00008000
++
++/* Lane G (SD1 TX/RX 1)*/
++write 0x01EA0E28,0x00000000
++write 0x01EA0E30,0x20818120
++write 0x01EA0E34,0x23000000
++write 0x01EA0E68,0x80000000
++write 0x01EA0E74,0x00002020
++write 0x01EA0E80,0x00008000
++
++/* Lane H (SD1 TX/RX 0)*/
++write 0x01EA0F28,0x00000000
++write 0x01EA0F30,0x20818120
++write 0x01EA0F34,0x23000000
++write 0x01EA0F68,0x80000000
++write 0x01EA0F74,0x00002020
++write 0x01EA0F80,0x00008000
++.end
+diff --git a/lx2160acex7/include/SD1_18.rcwi b/lx2160acex7/include/SD1_18.rcwi
+new file mode 100644
+index 0000000..cf67395
+--- /dev/null
++++ b/lx2160acex7/include/SD1_18.rcwi
+@@ -0,0 +1,24 @@
++/*
++ * Serdes 1 Reference Clocks:
++ * - PLLF = 161.1328125MHz
++ * - PLLS = 100MHz
++ */
++
++/* Serdes 1 Protocol 18: 6x10Gbps + 2x25Gbps */
++SRDS_PRTCL_S1=18
++
++/* Enable PLLF */
++SRDS_PLL_PD_PLL1=0
++
++/* Use PLLF for PLLS */
++SRDS_INTRA_REF_CLK_S1=1
++
++/* Enable PLLS */
++SRDS_PLL_PD_PLL2=0
++
++/*
++ * Select PLLF frequency 161.1328125MH for 25G mode: Bit 0 = 0
++ * Select PLLS frequency 161.1328125MHz for 10G mode: Bit 1 = 1
++ * (See QorIQ LX2160A Reference Manual, Rev. 0, 07/2020, 4.9.8.9 Reset Control Word (RCW) Register Descriptions, Bits 932-933)
++ */
++SRDS_PLL_REF_CLK_SEL_S1=2
+diff --git a/lx2160acex7/include/SD1_20.rcwi b/lx2160acex7/include/SD1_20.rcwi
+new file mode 100644
+index 0000000..f5c0c66
+--- /dev/null
++++ b/lx2160acex7/include/SD1_20.rcwi
+@@ -0,0 +1,24 @@
++/*
++ * Serdes 1 Reference Clocks:
++ * - PLLF = 161.1328125MHz
++ * - PLLS = 100MHz
++ */
++
++/* Serdes 1 Protocol 20: 2x40Gbps */
++SRDS_PRTCL_S1=20
++
++/* Disable PLLF */
++SRDS_PLL_PD_PLL1=1
++
++/* Use PLLF for PLLS */
++SRDS_INTRA_REF_CLK_S1=1
++
++/* Enable PLLS */
++SRDS_PLL_PD_PLL2=0
++
++/*
++ * Select PLLF frequency 156.25MHz for 10G mode: Bit 0 = 0 (don't care)
++ * Select PLLS frequency 161.1328125MHz for 10G mode: Bit 1 = 1
++ * (See QorIQ LX2160A Reference Manual, Rev. 0, 07/2020, 4.9.8.9 Reset Control Word (RCW) Register Descriptions, Bits 932-933)
++ */
++SRDS_PLL_REF_CLK_SEL_S1=2
+diff --git a/lx2160acex7/include/SD1_4.rcwi b/lx2160acex7/include/SD1_4.rcwi
+new file mode 100644
+index 0000000..3c6023a
+--- /dev/null
++++ b/lx2160acex7/include/SD1_4.rcwi
+@@ -0,0 +1,25 @@
++/*
++ * Serdes 1 Reference Clocks:
++ * - PLLF = 161.1328125MHz
++ * - PLLS = 100MHz
++ */
++
++/* Serdes 1 Protocol 4: 8x1Gbps */
++SRDS_PRTCL_S1=4
++
++/* Disable PLLF */
++SRDS_PLL_PD_PLL1=1
++SRDS_REFCLKF_DIS_S1=1
++
++/* Don't use PLLF for PLLS */
++SRDS_INTRA_REF_CLK_S1=0
++
++/* Enable PLLS */
++SRDS_PLL_PD_PLL2=0
++
++/*
++ * Select PLLF frequency 100MHz (don't care): Bit 0 = 0
++ * Select PLLS frequency 100MHz: Bit 1 = 0
++ * (See QorIQ LX2160A Reference Manual, Rev. 0, 07/2020, 4.9.8.9 Reset Control Word (RCW) Register Descriptions, Bits 932-933)
++ */
++SRDS_PLL_REF_CLK_SEL_S1=0
+diff --git a/lx2160acex7/include/SD1_8.rcwi b/lx2160acex7/include/SD1_8.rcwi
+new file mode 100644
+index 0000000..1646de8
+--- /dev/null
++++ b/lx2160acex7/include/SD1_8.rcwi
+@@ -0,0 +1,24 @@
++/*
++ * Serdes 1 Reference Clocks:
++ * - PLLF = 161.1328125MHz
++ * - PLLS = 100MHz
++ */
++
++/* Serdes 1 Protocol 8: 8x10Gbps */
++SRDS_PRTCL_S1=8
++
++/* Disable PLLF */
++SRDS_PLL_PD_PLL1=1
++
++/* Use PLLF for PLLS */
++SRDS_INTRA_REF_CLK_S1=1
++
++/* Enable PLLS */
++SRDS_PLL_PD_PLL2=0
++
++/*
++ * Select PLLF frequency 100MHz (don't care): Bit 0 = 0
++ * Select PLLS frequency 161.1328125MHz: Bit 1 = 1
++ * (See QorIQ LX2160A Reference Manual, Rev. 0, 07/2020, 4.9.8.9 Reset Control Word (RCW) Register Descriptions, Bits 932-933)
++ */
++SRDS_PLL_REF_CLK_SEL_S1=2
+diff --git a/lx2160acex7/include/SD1_8S.rcwi b/lx2160acex7/include/SD1_8S.rcwi
+new file mode 100644
+index 0000000..c043eef
+--- /dev/null
++++ b/lx2160acex7/include/SD1_8S.rcwi
+@@ -0,0 +1,24 @@
++/*
++ * Serdes 1 Reference Clocks:
++ * - PLLF = 100MHz
++ * - PLLS = 161.1328125MHz
++ */
++
++/* Serdes 1 Protocol 8: 8x10Gbps */
++SRDS_PRTCL_S1=8
++
++/* Enable PLLF (to support sgmii protocol switch) */
++SRDS_PLL_PD_PLL1=0
++
++/* Don't use PLLF for PLLS */
++SRDS_INTRA_REF_CLK_S1=0
++
++/* Enable PLLS */
++SRDS_PLL_PD_PLL2=0
++
++/*
++ * Select PLLF frequency 100MHz (to support sgmii protocol switch): Bit 0 = 0
++ * Select PLLS frequency 161.1328125MHz: Bit 1 = 1
++ * (See QorIQ LX2160A Reference Manual, Rev. 0, 07/2020, 4.9.8.9 Reset Control Word (RCW) Register Descriptions, Bits 932-933)
++ */
++SRDS_PLL_REF_CLK_SEL_S1=2
+diff --git a/lx2160acex7/include/SD2_5.rcwi b/lx2160acex7/include/SD2_5.rcwi
+new file mode 100644
+index 0000000..c01ed1f
+--- /dev/null
++++ b/lx2160acex7/include/SD2_5.rcwi
+@@ -0,0 +1,30 @@
++/*
++ * Serdes 2 Reference Clocks:
++ * - PLLF = 100MHz
++ * - PLLS = 100MHz
++ */
++
++/* Serdes 2 Protocol 5: 1x PCI-e x4 Gen 3 + 4x SATA */
++SRDS_PRTCL_S2=5
++
++/* Enable PLLF */
++SRDS_PLL_PD_PLL3=0
++
++/* Don't use PLLF for PLLS */
++SRDS_INTRA_REF_CLK_S2=0
++
++/* Enable PLLS */
++SRDS_PLL_PD_PLL4=0
++
++/*
++ * Select PLLF frequency 100MHz: Bit 0 = 0
++ * Select PLLS frequency 100MHz: Bit 1 = 0
++ * (See QorIQ LX2160A Reference Manual, Rev. 0, 07/2020, 4.9.8.9 Reset Control Word (RCW) Register Descriptions, Bits 934-935)
++ */
++SRDS_PLL_REF_CLK_SEL_S2=0
++
++/* Support up to PCI-e Gen 3 */
++SRDS_DIV_PEX_S2=1
++
++/* indicate PCI ports for pbi section errata application*/
++#define HAVE_PEX3
+diff --git a/lx2160acex7/include/SD3_2.rcwi b/lx2160acex7/include/SD3_2.rcwi
+new file mode 100644
+index 0000000..630b0b2
+--- /dev/null
++++ b/lx2160acex7/include/SD3_2.rcwi
+@@ -0,0 +1,30 @@
++/*
++ * Serdes 3 Reference Clocks:
++ * - PLLF = 100MHz
++ * - PLLS = 100MHz
++ */
++
++/* Serdes 3 Protocol 2: 1x PCI-e x8 Gen 3 */
++SRDS_PRTCL_S3=2
++
++/* Disable PLLF */
++SRDS_PLL_PD_PLL5=1
++
++/* Don't use Serdes 3 PLLF for PLLS */
++SRDS_INTRA_REF_CLK_S3=0
++
++/* Enable PLLS */
++SRDS_PLL_PD_PLL6=0
++
++/*
++ * Select PLLF frequency 100MHz: Bit 0 = 0
++ * Select PLLS frequency 100MHz: Bit 1 = 0
++ * (See QorIQ LX2160A Reference Manual, Rev. 0, 07/2020, 4.9.8.9 Reset Control Word (RCW) Register Descriptions, Bits 936-937)
++ */
++SRDS_PLL_REF_CLK_SEL_S3=0
++
++/* Support up to PCI-e Gen 3 */
++SRDS_DIV_PEX_S3=1
++
++/* indicate PCI ports for pbi section errata application*/
++#define HAVE_PEX5
+diff --git a/lx2160acex7/include/bootlocptr.rcwi b/lx2160acex7/include/bootlocptr.rcwi
+new file mode 100644
+index 0000000..4bbfc5c
+--- /dev/null
++++ b/lx2160acex7/include/bootlocptr.rcwi
+@@ -0,0 +1,13 @@
++#if defined(LX_BOOTSOURCE_AUTO)
++/*
++ * For automatic boot-media selection ATF patches blockcopy and bootlocptr
++ * instructions in-place for all 3 supported boot media.
++ * Add the necessary jump instructions and placeholders.
++ */
++#include <../lx2160asi/bootlocptr_auto.rcw>
++#else
++/*
++ * ATF create_pbl will automatically append bootlocptr instructions,
++ * no need to include ../lx2160asi/bootlocptr_{nor,sd}.rcw
++ */
++#endif
+diff --git a/lx2160acex7/include/common.rcwi b/lx2160acex7/include/common.rcwi
+new file mode 100644
+index 0000000..c76b174
+--- /dev/null
++++ b/lx2160acex7/include/common.rcwi
+@@ -0,0 +1,91 @@
++/*
++ * LX2160A COM-Express Type 7 Common Configuration
++ */
++
++/* C[5:8]_PLL are CG[5:8] div 1 */
++C5_PLL_SEL=0
++C6_PLL_SEL=0
++C7_PLL_SEL=0
++C8_PLL_SEL=0
++/* Cluster group A clock is PLL1 div 1 (unused on LX2160A) */
++HWA_CGA_M1_CLK_SEL=1
++/* Cluster group B clock is PLL2 div 2 (for DCE) */
++HWA_CGB_M1_CLK_SEL=6
++/*
++ * fall-back boot-mode when DCFG boot location pointer registers are null
++ * - 0b10101 (21): OCRAM
++ * - 0b11010 (26): XSPI
++ */
++BOOT_LOC=21
++/* SYSCLK is 100MHz */
++SYSCLK_FREQ=600
++/* USB-3.0 clock is 100MHz */
++USB3_CLK_FSEL=39
++
++/* IIC1 is I2C */
++IIC1_PMUX=0
++/* IIC2 is SD Card-Detect */
++IIC2_PMUX=6
++/* IIC3 is I2C */
++IIC3_PMUX=0
++/* IIC4 is I2C (unused) */
++IIC4_PMUX=0
++/* IIC5 is I2C */
++IIC5_PMUX=0
++/* IIC6 is I2C (unused) */
++IIC6_PMUX=0
++/*
++ * SDHC1 CMD/CLK/VBUS/DAT[0:3] are SDHC
++ * SPI3_PCS0 is VSEL
++ */
++SDHC1_BASE_PMUX=0
++/* SDHC1_DS is GPIO (unused) */
++SDHC1_DS_PMUX=1
++/* SDHC1_CMD/DAT0/DAT1_DIR (SPI3_PCS[1:3]) are GPIO1[14:12] */
++SDHC1_DIR_PMUX=1
++/* USB[1:2]_DRVVBUS/PWRFAULT are GPIO4[28:25] (unused) */
++USB_EXT_PMUX=1
++/* XSPI1_A_DQS/SCK/CS0_B/CS1_B are SPI */
++XSPI1_A_BASE_PMUX=0
++/* XSPI1_A_DATA[3:0] are SPI */
++XSPI1_A_DATA30_PMUX=0
++/* XSPI1_A_DATA[7:4] are SPI */
++XSPI1_A_DATA74_PMUX=0
++/* ASLEEP is ASLEEP (unused) */
++ASLEEP_PMUX=0
++/* EVT[2:0] are GPIO3[14:12] */
++EVT20_PMUX=1
++/* EVT[4:3] are GPIO3[16:15] */
++EVT43_PMUX=1
++/* CLK_OUT is GPIO (unused) */
++CLK_OUT_PMUX=1
++/* IRQ[3:0] are GPIO3[3:0] */
++IRQ03_00_PMUX=1
++/* IRQ[7:4] are GPIO3[7:4] */
++IRQ07_04_PMUX=1
++/* IRQ[11:8] are GPIO3[11:8] */
++IRQ11_08_PMUX=1
++/* EC1_* are RGMII */
++EC1_PMUX=0
++/* EC2_* are PTP */
++EC2_PMUX=2
++/* EC_GTX_CLK125 is PTP */
++GTX_CLK_PMUX=0
++/* UART1_SOUT/SIN are UART1 */
++UART1_SOUTSIN_PMUX=0
++/* UART1_RTS/CTS_B are GPIO (unused) */
++UART1_RTSCTS_PMUX=1
++/* UART2_SOUT/SIN are UART2 */
++UART2_SOUTSIN_PMUX=0
++/* UART2_RTS/CTS_B are GPIO (unused) */
++UART2_RTSCTS_PMUX=1
++/* SDHC2_CMD/DAT[3:0]/DS/CLK are SDHC */
++SDHC2_BASE_PMUX=0
++/* SDHC2_DAT[7:4] are SDHC */
++SDHC2_DAT74_PMUX=0
++
++/*
++ * Original SolidRun Settings in LSDK-21.08
++ *
++ * HWA_CGB_M1_CLK_SEL=7 // Cluster Group B PLL 2 / 3 is clock
++ */
+diff --git a/lx2160acex7/include/common_pbi.rcwi b/lx2160acex7/include/common_pbi.rcwi
+new file mode 100644
+index 0000000..13c60b9
+--- /dev/null
++++ b/lx2160acex7/include/common_pbi.rcwi
+@@ -0,0 +1,57 @@
++/*
++ * LX2160A COM-Express Type 7 Common Configuration
++ */
++
++/* Drive the fan full speed pin */
++.pbi
++write 0x2320000,0x20000000
++.end
++
++/* Errata to write on scratch reg for validation */
++#include <../lx2160asi/scratchrw1.rcw>
++
++/* Errata for SATA controller */
++#include <../lx2160asi/a010554.rcw>
++
++#if LX_SR == 1
++/* Errata for PCIe controller */
++#include <../lx2160asi/a011270.rcw>
++#include <../lx2160asi/a050234.rcw>
++#endif
++
++/* common PBI commands */
++#include <../lx2160asi/common.rcw>
++
++#if LX_SR == 2
++/* PCIe Errata A-009531, A-008851 */
++#ifdef HAVE_PEX1
++#include <../lx2160asi/a009531_PEX1.rcw>
++#include <../lx2160asi/a008851_PEX1.rcw>
++#endif /* HAVE_PEX1 */
++#ifdef HAVE_PEX2
++#include <../lx2160asi/a009531_PEX2.rcw>
++#include <../lx2160asi/a008851_PEX2.rcw>
++#endif /* HAVE_PEX2 */
++#ifdef HAVE_PEX3
++#include <../lx2160asi/a009531_PEX3.rcw>
++#include <../lx2160asi/a008851_PEX3.rcw>
++#endif /* HAVE_PEX3 */
++#ifdef HAVE_PEX4
++#include <../lx2160asi/a009531_PEX4.rcw>
++#include <../lx2160asi/a008851_PEX4.rcw>
++#endif /* HAVE_PEX4 */
++#ifdef HAVE_PEX5
++#include <../lx2160asi/a009531_PEX5.rcw>
++#include <../lx2160asi/a008851_PEX5.rcw>
++#endif /* HAVE_PEX5 */
++#ifdef HAVE_PEX6
++#include <../lx2160asi/a009531_PEX6.rcw>
++#include <../lx2160asi/a008851_PEX6.rcw>
++#endif /* HAVE_PEX6 */
++
++/*SerDes Errata A-050479*/
++#include <../lx2160asi/a050479.rcw>
++#endif
++
++/* Errata A-050426 */
++#include <../lx2160asi/a050426.rcw>
+diff --git a/lx2160acex7/include/pll_2000_700_xxxx.rcwi b/lx2160acex7/include/pll_2000_700_xxxx.rcwi
+new file mode 100644
+index 0000000..2a3725f
+--- /dev/null
++++ b/lx2160acex7/include/pll_2000_700_xxxx.rcwi
+@@ -0,0 +1,14 @@
++/*
++ * Core and Platform Clocks:
++ * - Platform: 700MHz
++ * - Core: 2000MHz
++ */
++
++/* platform clock is system clock mul 14 div 2 = 700 */
++SYS_PLL_RAT=14
++
++/* core clocks are 2000 */
++CGA_PLL1_RAT=20
++CGA_PLL2_RAT=20
++CGB_PLL1_RAT=20
++CGB_PLL2_RAT=7
+diff --git a/lx2160acex7/include/pll_2200_750_xxxx.rcwi b/lx2160acex7/include/pll_2200_750_xxxx.rcwi
+new file mode 100644
+index 0000000..0f57b67
+--- /dev/null
++++ b/lx2160acex7/include/pll_2200_750_xxxx.rcwi
+@@ -0,0 +1,14 @@
++/*
++ * Core and Platform Clocks:
++ * - Platform: 750MHz
++ * - Core: 2200MHz
++ */
++
++/* platform clock is system clock mul 15 div 2 = 750 */
++SYS_PLL_RAT=15
++
++/* core clocks are 2200 */
++CGA_PLL1_RAT=22
++CGA_PLL2_RAT=22
++CGB_PLL1_RAT=22
++CGB_PLL2_RAT=7
+diff --git a/lx2160acex7/include/pll_xxxx_xxx_2400.rcwi b/lx2160acex7/include/pll_xxxx_xxx_2400.rcwi
+new file mode 100644
+index 0000000..6356b36
+--- /dev/null
++++ b/lx2160acex7/include/pll_xxxx_xxx_2400.rcwi
+@@ -0,0 +1,12 @@
++/*
++ * DDR Rate: 2400MHz
++ *
++ * DDR PHY Clock (half ddr clock, quarter mts rate)
++ * multiplier = 24 (24)
++ * divider = 4 (3)
++ * 100MHz x 24 / 4 = 600MHz (MTS = 4 x 600 = 2400MHz)
++ */
++MEM_PLL_RAT=24
++MEM_PLL_CFG=3
++MEM2_PLL_RAT=24
++MEM2_PLL_CFG=3
+diff --git a/lx2160acex7/include/pll_xxxx_xxx_2600.rcwi b/lx2160acex7/include/pll_xxxx_xxx_2600.rcwi
+new file mode 100644
+index 0000000..d72047d
+--- /dev/null
++++ b/lx2160acex7/include/pll_xxxx_xxx_2600.rcwi
+@@ -0,0 +1,12 @@
++/*
++ * DDR Rate: 2600MHz
++ *
++ * DDR PHY Clock (half ddr clock, quarter mts rate)
++ * multiplier = 26 (26)
++ * divider = 4 (3)
++ * 100MHz x 26 / 4 = 650MHz (MTS = 4 x 650 = 2600MHz)
++ */
++MEM_PLL_RAT=26
++MEM_PLL_CFG=3
++MEM2_PLL_RAT=26
++MEM2_PLL_CFG=3
+diff --git a/lx2160acex7/include/pll_xxxx_xxx_2666.rcwi b/lx2160acex7/include/pll_xxxx_xxx_2666.rcwi
+new file mode 100644
+index 0000000..06d3da1
+--- /dev/null
++++ b/lx2160acex7/include/pll_xxxx_xxx_2666.rcwi
+@@ -0,0 +1,12 @@
++/*
++ * DDR Rate: 2666MHz
++ *
++ * DDR PHY Clock (half ddr clock, quarter mts rate)
++ * multiplier = 20 (20)
++ * divider = 3 (2)
++ * 100MHz x 20 / 3 = 666MHz (MTS = 4 x 666 = 2666MHz)
++ */
++MEM_PLL_RAT=20
++MEM_PLL_CFG=2
++MEM2_PLL_RAT=20
++MEM2_PLL_CFG=2
+diff --git a/lx2160acex7/include/pll_xxxx_xxx_2900.rcwi b/lx2160acex7/include/pll_xxxx_xxx_2900.rcwi
+new file mode 100644
+index 0000000..9ad274f
+--- /dev/null
++++ b/lx2160acex7/include/pll_xxxx_xxx_2900.rcwi
+@@ -0,0 +1,12 @@
++/*
++ * DDR Rate: 2900MHz
++ *
++ * DDR PHY Clock (half ddr clock, quarter mts rate)
++ * multiplier = 29 (29)
++ * divider = 4 (3)
++ * 100MHz x 29 / 4 = 725MHz (MTS = 4 x 725 = 2900MHz)
++ */
++MEM_PLL_RAT=29
++MEM_PLL_CFG=3
++MEM2_PLL_RAT=29
++MEM2_PLL_CFG=3
+diff --git a/lx2160acex7/include/pll_xxxx_xxx_3200.rcwi b/lx2160acex7/include/pll_xxxx_xxx_3200.rcwi
+new file mode 100644
+index 0000000..abf7e9d
+--- /dev/null
++++ b/lx2160acex7/include/pll_xxxx_xxx_3200.rcwi
+@@ -0,0 +1,12 @@
++/*
++ * DDR Rate: 3200MHz
++ *
++ * DDR PHY Clock (half ddr clock, quarter mts rate)
++ * multiplier = 32 (32)
++ * divider = 4 (3)
++ * 100MHz x 32 / 4 = 800MHz (MTS = 4 x 800 = 3200MHz)
++ */
++MEM_PLL_RAT=32
++MEM_PLL_CFG=3
++MEM2_PLL_RAT=32
++MEM2_PLL_CFG=3
+diff --git a/lx2160acex7/include/xspi_limit_17M.rcwi b/lx2160acex7/include/xspi_limit_17M.rcwi
+new file mode 100644
+index 0000000..0de9191
+--- /dev/null
++++ b/lx2160acex7/include/xspi_limit_17M.rcwi
+@@ -0,0 +1,12 @@
++/*
++ * FlexSPI controller supports modifcation of the FlexSPI Clock
++ * divisor value, default value of this is 80.
++ * For 700 MHz, FlexSPI clock runs with default value is
++ * (Platform Clock * 2) / (Divisor value)
++ * => 700 * 2 / 80 ==> 17MHz
++ * On Clearfog-CX bus speed is limited to 20MHz by a mux on carrier board.
++ * Explicitly set the default value again, in case it was modified elsewhere.
++ */
++.pbi
++write 0x1e00900,0x00000014
++.end
+diff --git a/lx2160acex7_clearfog-cx.tmpl b/lx2160acex7_clearfog-cx.tmpl
+new file mode 100644
+index 0000000..a651132
+--- /dev/null
++++ b/lx2160acex7_clearfog-cx.tmpl
+@@ -0,0 +1,43 @@
++/*
++ * SerDes Protocol 1 - %SD1%
++ * SerDes Protocol 2 - %SD2%
++ * SerDes Protocol 3 - %SD3%
++ *
++ * Frequencies:
++ * Core -- %CPU_SPEED% MHz
++ * Platform -- %BUS_SPEED% MHz
++ * DDR -- %DDR_SPEED% MT/s
++ *
++ * Silicon %SOC_REVISION%.0
++ * Boot from %BOOTSOURCE%
++ */
++
++#define LX_SR %SOC_REVISION%
++#define LX_BOOTSOURCE_%BOOTSOURCE%
++
++#include <../lx2160asi/lx2160a.rcwi>
++#include <../%module%/include/pll_%CPU_SPEED%_%BUS_SPEED%_xxxx.rcwi>
++#include <../%module%/include/pll_xxxx_xxx_%DDR_SPEED%.rcwi>
++#include <../%module%/include/common.rcwi>
++#include <../%module%/include/SD1_%SD1%.rcwi>
++#include <../%module%/include/SD2_%SD2%.rcwi>
++#include <../%module%/include/SD3_%SD3%.rcwi>
++#include <../%module%/include/common_pbi.rcwi>
++#include <../%module%/include/xspi_limit_17M.rcwi>
++#include <../%module%/include/bootlocptr.rcwi>
++
++#if %nSD1% == 18 || %nSD1% == -18
++/* protocol 18 2x-25g-6x-10g convert 2x10g-25g for 4x25g on qsfp */
++#include <../lx2160asi/sd1_lane_g_h_xfi_to_25g.rcw>
++/* set default serdes lane equalization parameters for 25G */
++#include <../lx2160asi/25g_eq_s1_lane_e.rcw>
++#include <../lx2160asi/25g_eq_s1_lane_f.rcw>
++#include <../lx2160asi/25g_eq_s1_lane_g.rcw>
++#include <../lx2160asi/25g_eq_s1_lane_h.rcw>
++#endif
++
++#if %nSD1% == 20 || %nSD1% == -20
++/* protocol 20 dual-40g split second port into 4x10g */
++#include <../lx2160asi/e40g2_split.rcw>
++#endif
++
+diff --git a/lx2160acex7_rev2/Makefile b/lx2160acex7_rev2/Makefile
+new file mode 100644
+index 0000000..f77e46b
+--- /dev/null
++++ b/lx2160acex7_rev2/Makefile
+@@ -0,0 +1 @@
++include ../Makefile.inc
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,66 @@
+From affb5ce1d897868b5b0df464dce8aa31dc741c84 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Wed, 3 Apr 2024 17:58:37 +0200
+Subject: [PATCH 01/14] pci: ls_pcie_g4: Wait 100ms for Link Up in
+ ls_pcie_g4_probe
+
+PCI Link-up can be delayed especially with pci bridges or fpga starting
+up slowly.
+
+Add a 100ms delay during probe polling for link-up.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/pci/pcie_layerscape_gen4.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pcie_layerscape_gen4.c b/drivers/pci/pcie_layerscape_gen4.c
+index 021c975869f..2fbb507c628 100644
+--- a/drivers/pci/pcie_layerscape_gen4.c
++++ b/drivers/pci/pcie_layerscape_gen4.c
+@@ -19,6 +19,10 @@
+
+ #include "pcie_layerscape_gen4.h"
+
++#include <linux/delay.h>
++#define LINK_WAIT_RETRIES 100
++#define LINK_WAIT_TIMEOUT 1000
++
+ DECLARE_GLOBAL_DATA_PTR;
+
+ LIST_HEAD(ls_pcie_g4_list);
+@@ -50,6 +53,22 @@ static int ls_pcie_g4_link_up(struct ls_pcie_g4 *pcie)
+ return 1;
+ }
+
++static int ls_pcie_g4_wait_for_link(struct ls_pcie_g4 *pcie)
++{
++ int retries;
++
++ /* check if the link is up or not */
++ for (retries = 0; retries < LINK_WAIT_RETRIES; retries++) {
++ if (ls_pcie_g4_link_up(pcie)) {
++ return 1;
++ }
++
++ udelay(LINK_WAIT_TIMEOUT);
++ }
++
++ return 0;
++}
++
+ static void ls_pcie_g4_ep_enable_cfg(struct ls_pcie_g4 *pcie)
+ {
+ ccsr_writel(pcie, GPEX_CFG_READY, PCIE_CONFIG_READY);
+@@ -548,7 +567,7 @@ static int ls_pcie_g4_probe(struct udevice *dev)
+ val |= PPIO_EN;
+ ccsr_writel(pcie, PAB_PEX_PIO_CTRL(0), val);
+
+- if (!ls_pcie_g4_link_up(pcie)) {
++ if (!ls_pcie_g4_wait_for_link(pcie)) {
+ /* Let the user know there's no PCIe link */
+ printf(": no link\n");
+ return 0;
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,65 @@
+From ad862f120ce4f6b0627cd1ea70a9de8b2f8a264c Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sun, 14 Apr 2024 16:45:42 +0200
+Subject: [PATCH 02/14] pci: ls_pcie: Wait 100ms for Link Up in ls_pcie_probe
+
+PCI Link-up can be delayed especially with pci bridges or fpga starting
+up slowly.
+
+Add a 100ms delay during probe polling for link-up.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/pci/pcie_layerscape_rc.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/pci/pcie_layerscape_rc.c b/drivers/pci/pcie_layerscape_rc.c
+index 6a5bf88da23..33bd14ad81a 100644
+--- a/drivers/pci/pcie_layerscape_rc.c
++++ b/drivers/pci/pcie_layerscape_rc.c
+@@ -19,6 +19,10 @@
+ #endif
+ #include "pcie_layerscape.h"
+
++#include <linux/delay.h>
++#define LINK_WAIT_RETRIES 100
++#define LINK_WAIT_TIMEOUT 1000
++
+ DECLARE_GLOBAL_DATA_PTR;
+
+ struct ls_pcie_drvdata {
+@@ -27,6 +30,22 @@ struct ls_pcie_drvdata {
+ bool big_endian;
+ };
+
++static int ls_pcie_wait_for_link(struct ls_pcie *pcie)
++{
++ int retries;
++
++ /* check if the link is up or not */
++ for (retries = 0; retries < LINK_WAIT_RETRIES; retries++) {
++ if (ls_pcie_link_up(pcie)) {
++ return 1;
++ }
++
++ udelay(LINK_WAIT_TIMEOUT);
++ }
++
++ return 0;
++}
++
+ static void ls_pcie_cfg0_set_busdev(struct ls_pcie_rc *pcie_rc, u32 busdev)
+ {
+ struct ls_pcie *pcie = pcie_rc->pcie;
+@@ -375,7 +394,7 @@ static int ls_pcie_probe(struct udevice *dev)
+ "Root Complex");
+ ls_pcie_setup_ctrl(pcie_rc);
+
+- if (!ls_pcie_link_up(pcie)) {
++ if (!ls_pcie_wait_for_link(pcie)) {
+ /* Let the user know there's no PCIe link */
+ printf(": no link\n");
+ return 0;
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,63 @@
+From 991e3e98563aff0f980bb70b4bee205d2b597b45 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Tue, 8 Oct 2024 13:29:36 +0200
+Subject: [PATCH 03/14] fsl-lsch3: update calculation of ddr clock rate to
+ include divider
+
+DDR clock is passes through a divider and a multiplier - and is then
+again doubled once by the phy and once by the controller.
+The doubling was previously hidden by divider default value of 4.
+
+Take into account the divider value per MEM_PLL_CFG when calculating ddr
+bus frequency, and multiply the result by 4.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c | 8 ++++++++
+ arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h | 4 ++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c
+index 137778dc136..04045839a27 100644
+--- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c
++++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c
+@@ -92,11 +92,19 @@ void get_sys_info(struct sys_info *sys_info)
+ sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
+ FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT) &
+ FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK;
++ sys_info->freq_ddrbus /= ((gur_in32(&gur->rcwsr[0]) >>
++ FSL_CHASSIS3_RCWSR0_MEM_PLL_CFG_SHIFT) &
++ FSL_CHASSIS3_RCWSR0_MEM_PLL_CFG_MASK) + 1;
++ /* ddr clock is doubled at phy, then doubled again controller */
++ sys_info->freq_ddrbus *= 4;
+ #ifdef CONFIG_SYS_FSL_HAS_DP_DDR
+ if (soc_has_dp_ddr()) {
+ sys_info->freq_ddrbus2 *= (gur_in32(&gur->rcwsr[0]) >>
+ FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT) &
+ FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK;
++ sys_info->freq_ddrbus2 /= ((gur_in32(&gur->rcwsr[0]) >>
++ FSL_CHASSIS3_RCWSR0_MEM2_PLL_CFG_SHIFT) &
++ FSL_CHASSIS3_RCWSR0_MEM2_PLL_CFG_MASK) + 1;
+ } else {
+ sys_info->freq_ddrbus2 = 0;
+ }
+diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
+index ca5e33379ba..968173480f4 100644
+--- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
++++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h
+@@ -375,8 +375,12 @@ struct ccsr_gur {
+
+ #define FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_SHIFT 2
+ #define FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_MASK 0x1f
++#define FSL_CHASSIS3_RCWSR0_MEM_PLL_CFG_SHIFT 8
++#define FSL_CHASSIS3_RCWSR0_MEM_PLL_CFG_MASK 0x3
+ #define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT 10
+ #define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK 0x3f
++#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_CFG_SHIFT 16
++#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_CFG_MASK 0x3
+ #define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT 18
+ #define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK 0x3f
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,103 @@
+From 078a1018543d76c7e875abbd0fc9d041c8441529 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Thu, 24 Oct 2024 16:17:49 +0200
+Subject: [PATCH 04/14] armv8: lx2160a: enable workaround for SPI erratum
+ A-050752
+
+When RCW is loaded from SDHC1, chip-selects signals for SPI3 are always
+low and not usable.
+
+Implement workaround for erratum A-050752 by clearing rcw source values
+in dynamic configuration register and masking HRESET_B.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 4 ++++
+ arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 3 +++
+ arch/arm/cpu/armv8/fsl-layerscape/soc.c | 18 ++++++++++++++++++
+ arch/arm/include/asm/arch-fsl-layerscape/soc.h | 4 ++++
+ 4 files changed, 29 insertions(+)
+
+diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+index 27509fcca2c..6937d9f5b92 100644
+--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
++++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+@@ -308,6 +308,7 @@ config ARCH_LX2160A
+ select SYS_FSL_EC2
+ select SYS_FSL_ERRATUM_A050204
+ select SYS_FSL_ERRATUM_A011334
++ select SYS_FSL_ERRATUM_A050752
+ select SYS_FSL_ESDHC_UNRELIABLE_PULSE_DETECTION_WORKAROUND
+ select SYS_FSL_HAS_RGMII
+ select SYS_FSL_HAS_SEC
+@@ -667,6 +668,9 @@ config SYS_FSL_ERRATUM_A009660
+ config SYS_FSL_ERRATUM_A050382
+ bool
+
++config SYS_FSL_ERRATUM_A050752
++ bool
++
+ config SYS_FSL_HAS_RGMII
+ bool
+ depends on SYS_FSL_EC1 || SYS_FSL_EC2
+diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+index 12d31184ad9..ac39f11e3b3 100644
+--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
++++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+@@ -1128,6 +1128,9 @@ int arch_early_init_r(void)
+ #endif
+ #if defined(CONFIG_SYS_FSL_ERRATUM_A009942) && defined(CONFIG_SYS_FSL_DDR)
+ erratum_a009942_check_cpo();
++#endif
++#ifdef CONFIG_SYS_FSL_ERRATUM_A050752
++ erratum_a050752();
+ #endif
+ if (check_psci()) {
+ debug("PSCI: PSCI does not exist.\n");
+diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+index 4c61d28c20f..d04f802967a 100644
+--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
++++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+@@ -318,6 +318,24 @@ void erratum_a009635(void)
+ writel(val | 0x80000000, EPU_EPGCR);
+ }
+ #endif /* CONFIG_SYS_FSL_ERRATUM_A009635 */
++#ifdef CONFIG_SYS_FSL_ERRATUM_A050752
++#define RESET_BASE 0x01e60000
++#define RESET_CCSR 0
++#define RESET_CCSR_HRESET_B_DIS BIT(25)
++
++void erratum_a050752(void)
++{
++ u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
++ u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE;
++ u32 __iomem *reset_ccsr = (u32 __iomem *)RESET_BASE;
++ u32 val;
++
++ val = in_le32(dcfg_ccsr + DCFG_PORSR1 / 4);
++ val &= ~DCFG_PORSR1_RCW_SRC;
++ out_le32(dcfg_dcsr + DCFG_DCSR_PORCR1 / 4, val);
++ out_le32(reset_ccsr + RESET_CCSR / 4, RESET_CCSR_HRESET_B_DIS);
++}
++#endif /* CONFIG_SYS_FSL_ERRATUM_A050752 */
+
+ static void erratum_rcw_src(void)
+ {
+diff --git a/arch/arm/include/asm/arch-fsl-layerscape/soc.h b/arch/arm/include/asm/arch-fsl-layerscape/soc.h
+index bd41df1be44..3e7c5b0e724 100644
+--- a/arch/arm/include/asm/arch-fsl-layerscape/soc.h
++++ b/arch/arm/include/asm/arch-fsl-layerscape/soc.h
+@@ -131,6 +131,10 @@ void erratum_a009635(void);
+ void erratum_a010315(void);
+ #endif
+
++#ifdef CONFIG_SYS_FSL_ERRATUM_A050752
++void erratum_a050752(void);
++#endif
++
+ bool soc_has_dp_ddr(void);
+ bool soc_has_aiop(void);
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,57 @@
+From 53600ad97598faf966eb5155f243b42e5a2c0ce5 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Mon, 4 Nov 2024 15:08:01 +0100
+Subject: [PATCH 06/14] cmd: tlv_eeprom: support specifying tlv eeprom in DT
+ alias tlv[0-255]
+
+Systems might have many eeproms of which only some might be used for TLV
+data.
+If present, use aliases tlv0, tlv1, ... for finding tlv eeproms.
+
+If no eeproms are found by alias, fall back to current logic if using
+first eeproms in the system.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ cmd/tlv_eeprom.c | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+
+diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c
+index b178c23d394..27eb4e3488a 100644
+--- a/cmd/tlv_eeprom.c
++++ b/cmd/tlv_eeprom.c
+@@ -912,9 +912,31 @@ static void show_tlv_devices(int current_dev)
+ static int find_tlv_devices(struct udevice **tlv_devices_p)
+ {
+ int ret;
++ char alias_name[7];
+ int count_dev = 0;
++ ofnode node;
+ struct udevice *dev;
+
++ /* find by alias */
++ for (int i = 0; i < MAX_TLV_DEVICES; i++) {
++ snprintf(alias_name, sizeof(alias_name), "tlv%d", i);
++ node = ofnode_get_aliases_node(alias_name);
++ if (!ofnode_valid(node))
++ continue;
++
++ ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, node, &dev);
++ if (ret) {
++ debug("get device \"%s\" failed with %d\n", alias_name, ret);
++ continue;
++ }
++
++ tlv_devices_p[i] = dev;
++ count_dev++;
++ }
++ if (count_dev)
++ return 0;
++
++ /* fall-back: find among all eeproms */
+ for (ret = uclass_first_device_check(UCLASS_I2C_EEPROM, &dev);
+ dev;
+ ret = uclass_next_device_check(&dev)) {
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,29 @@
+From 5e3071d8030e57b82207c0c81e9d73204de0a10d Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Tue, 29 Jul 2025 11:09:55 +0200
+Subject: [PATCH 07/14] gpio: mpc8xxx: fix build on layerscape arch
+
+asm/gpio.h include does not pull in the arch-specific gpio header for
+layerscape - include it explicitly for now (likely breaking powerpc
+platforms)
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/gpio/mpc8xxx_gpio.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c
+index f7ffd8926ad..e30d434ae82 100644
+--- a/drivers/gpio/mpc8xxx_gpio.c
++++ b/drivers/gpio/mpc8xxx_gpio.c
+@@ -13,6 +13,7 @@
+ #include <dm.h>
+ #include <mapmem.h>
+ #include <asm/gpio.h>
++#include <asm/arch-fsl-layerscape/gpio.h>
+ #include <asm/io.h>
+ #include <dm/of_access.h>
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,386 @@
+From f37a22f89c8c09f9f9d5dcbcf5dce431b955f574 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Fri, 8 Aug 2025 16:48:32 +0200
+Subject: [PATCH 08/14] arch: arm: dts: fsl-lx2160a.dtsi: add pcs phys
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ arch/arm/dts/fsl-lx2160a.dtsi | 253 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 253 insertions(+)
+
+diff --git a/arch/arm/dts/fsl-lx2160a.dtsi b/arch/arm/dts/fsl-lx2160a.dtsi
+index 680c69c7b73..4320a8d08bf 100644
+--- a/arch/arm/dts/fsl-lx2160a.dtsi
++++ b/arch/arm/dts/fsl-lx2160a.dtsi
+@@ -487,108 +487,126 @@
+ dpmac1: dpmac@1 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x1>;
++ pcs-handle = <&pcs1>;
+ status = "disabled";
+ };
+
+ dpmac2: dpmac@2 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x2>;
++ pcs-handle = <&pcs2>;
+ status = "disabled";
+ };
+
+ dpmac3: dpmac@3 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x3>;
++ pcs-handle = <&pcs3>;
+ status = "disabled";
+ };
+
+ dpmac4: dpmac@4 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x4>;
++ pcs-handle = <&pcs4>;
+ status = "disabled";
+ };
+
+ dpmac5: dpmac@5 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x5>;
++ pcs-handle = <&pcs5>;
+ status = "disabled";
+ };
+
+ dpmac6: dpmac@6 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x6>;
++ pcs-handle = <&pcs6>;
+ status = "disabled";
+ };
+
+ dpmac7: dpmac@7 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x7>;
++ pcs-handle = <&pcs7>;
+ status = "disabled";
+ };
+
+ dpmac8: dpmac@8 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x8>;
++ pcs-handle = <&pcs8>;
+ status = "disabled";
+ };
+
+ dpmac9: dpmac@9 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x9>;
++ pcs-handle = <&pcs9>;
+ status = "disabled";
+ };
+
+ dpmac10: dpmac@a {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0xa>;
++ pcs-handle = <&pcs10>;
+ status = "disabled";
+ };
+
+ dpmac11: dpmac@b {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0xb>;
++ pcs-handle = <&pcs11>;
+ status = "disabled";
+ };
+
+ dpmac12: dpmac@c {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0xc>;
++ pcs-handle = <&pcs12>;
+ status = "disabled";
+ };
+
+ dpmac13: dpmac@d {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0xd>;
++ pcs-handle = <&pcs13>;
+ status = "disabled";
+ };
+
+ dpmac14: dpmac@e {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0xe>;
++ pcs-handle = <&pcs14>;
+ status = "disabled";
+ };
+
+ dpmac15: dpmac@f {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0xf>;
++ pcs-handle = <&pcs15>;
+ status = "disabled";
+ };
+
+ dpmac16: dpmac@10 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x10>;
++ pcs-handle = <&pcs16>;
+ status = "disabled";
+ };
+
+ dpmac17: dpmac@11 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x11>;
++ pcs-handle = <&pcs17>;
+ status = "disabled";
+ };
+
+ dpmac18: dpmac@12 {
+ compatible = "fsl,qoriq-mc-dpmac";
+ reg = <0x12>;
++ pcs-handle = <&pcs18>;
+ status = "disabled";
+ };
+ };
+@@ -613,6 +631,241 @@
+ #size-cells = <0>;
+ status = "disabled";
+ };
++
++ pcs_mdio1: mdio@8c07000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c07000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs1: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio2: mdio@8c0b000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c0b000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs2: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio3: mdio@8c0f000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c0f000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs3: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio4: mdio@8c13000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c13000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs4: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio5: mdio@8c17000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c17000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs5: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio6: mdio@8c1b000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c1b000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs6: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio7: mdio@8c1f000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c1f000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs7: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio8: mdio@8c23000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c23000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs8: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio9: mdio@8c27000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c27000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs9: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio10: mdio@8c2b000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c2b000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs10: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio11: mdio@8c2f000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c2f000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs11: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio12: mdio@8c33000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c33000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs12: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio13: mdio@8c37000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c37000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs13: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio14: mdio@8c3b000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c3b000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs14: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio15: mdio@8c3f000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c3f000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs15: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio16: mdio@8c43000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c43000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs16: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio17: mdio@8c47000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c47000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs17: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
++ pcs_mdio18: mdio@8c4b000 {
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8c4b000 0x0 0x1000>;
++ little-endian;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pcs18: ethernet-phy@0 {
++ reg = <0>;
++ };
++ };
++
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,30 @@
+From c45ae8075ca32d9dd815f769e8ab0dc6b293360b Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Fri, 8 Aug 2025 13:59:05 +0200
+Subject: [PATCH 09/14] arch: arm: dts: fsl-lx2160a.dtsi: add psci node
+
+LX2160A uses arm-trusted-firmware as first stage loader implementing
+psci. Add description for the psci functionality.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ arch/arm/dts/fsl-lx2160a.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/dts/fsl-lx2160a.dtsi b/arch/arm/dts/fsl-lx2160a.dtsi
+index 4320a8d08bf..70f5287ad58 100644
+--- a/arch/arm/dts/fsl-lx2160a.dtsi
++++ b/arch/arm/dts/fsl-lx2160a.dtsi
+@@ -872,4 +872,9 @@
+ method = "smc";
+ };
+ };
++
++ psci {
++ compatible = "arm,psci-0.2";
++ method = "smc";
++ };
+ };
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,43 @@
+From a88cc54f83c53735d908daf77166214fd03a25c6 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Fri, 8 Aug 2025 16:49:33 +0200
+Subject: [PATCH 10/14] net: phy: marvell10g: add support for 88e2580 phy
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ drivers/net/phy/marvell10g.c | 9 +++++++++
+ include/marvell_phy.h | 1 +
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
+index 9e64672f5ca..f5d8d18d10f 100644
+--- a/drivers/net/phy/marvell10g.c
++++ b/drivers/net/phy/marvell10g.c
+@@ -603,3 +603,12 @@ U_BOOT_PHY_DRIVER(mv88e2110_mv88e2111) = {
+ .data = (ulong)&mv2110_mv2111_type,
+ .config = mv3310_config,
+ };
++
++U_BOOT_PHY_DRIVER(mv88e2580) = {
++ .name = "mv88e2580",
++ .uid = MARVELL_PHY_ID_88E2580,
++ .mask = MARVELL_PHY_ID_MASK,
++ .features = PHY_10G_FEATURES,
++ .data = (ulong)&mv3310_mv3340_type,
++ .config = mv3310_config,
++};
+diff --git a/include/marvell_phy.h b/include/marvell_phy.h
+index 0f06c2287b5..8fab10be087 100644
+--- a/include/marvell_phy.h
++++ b/include/marvell_phy.h
+@@ -25,6 +25,7 @@
+ #define MARVELL_PHY_ID_88X3310 0x002b09a0
+ #define MARVELL_PHY_ID_88E2110 0x002b09b0
+ #define MARVELL_PHY_ID_88X2222 0x01410f10
++#define MARVELL_PHY_ID_88E2580 0x002b0bc3
+
+ /* Marvel 88E1111 in Finisar SFP module with modified PHY ID */
+ #define MARVELL_PHY_ID_88E1111_FINISAR 0x01ff0cc0
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,1753 @@
+From 11c1b62e4f9c7ca0f4b3574353c1537c3b3d9cb6 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Thu, 13 Jun 2024 17:26:47 +0200
+Subject: [PATCH 11/14] add solidrun lx2160-cex7 board support
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ arch/arm/Kconfig | 14 +
+ arch/arm/dts/Makefile | 1 +
+ arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi | 36 ++
+ arch/arm/dts/fsl-lx2160a-cex7.dts | 17 +
+ arch/arm/dts/fsl-lx2160a-cex7.dtsi | 184 +++++++
+ board/solidrun/lx2160acex7/Kconfig | 15 +
+ board/solidrun/lx2160acex7/Makefile | 11 +
+ board/solidrun/lx2160acex7/ddr.c | 22 +
+ board/solidrun/lx2160acex7/eth_lx2160acex7.c | 45 ++
+ board/solidrun/lx2160acex7/lx2160a.c | 269 +++++++++
+ board/solidrun/lx2160acex7/serdes.c | 512 ++++++++++++++++++
+ configs/lx2160acex7_tfa_SECURE_BOOT_defconfig | 97 ++++
+ configs/lx2160acex7_tfa_defconfig | 109 ++++
+ include/configs/lx2160acex7.h | 282 ++++++++++
+ 14 files changed, 1614 insertions(+)
+ create mode 100644 arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi
+ create mode 100644 arch/arm/dts/fsl-lx2160a-cex7.dts
+ create mode 100644 arch/arm/dts/fsl-lx2160a-cex7.dtsi
+ create mode 100644 board/solidrun/lx2160acex7/Kconfig
+ create mode 100644 board/solidrun/lx2160acex7/Makefile
+ create mode 100644 board/solidrun/lx2160acex7/ddr.c
+ create mode 100644 board/solidrun/lx2160acex7/eth_lx2160acex7.c
+ create mode 100644 board/solidrun/lx2160acex7/lx2160a.c
+ create mode 100644 board/solidrun/lx2160acex7/serdes.c
+ create mode 100644 configs/lx2160acex7_tfa_SECURE_BOOT_defconfig
+ create mode 100644 configs/lx2160acex7_tfa_defconfig
+ create mode 100644 include/configs/lx2160acex7.h
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index eaf2c5d3df7..786d05d8d0c 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1462,6 +1462,19 @@ config TARGET_LS2081ARDB
+ development platform that supports the QorIQ LS2081A/LS2041A
+ Layerscape Architecture processor.
+
++config TARGET_LX2160ACEX7
++ bool "Support lx2160acex7"
++ select ARCH_LX2160A
++ select ARM64
++ select ARMV8_MULTIENTRY
++ select ARCH_SUPPORT_TFABOOT
++ select BOARD_LATE_INIT
++ help
++ Support for SolidRun LX2160ACEX7 platform.
++ The lx2160acex7 (LX2160A COM-Express Type 7)
++ is a high-performance platform based on the
++ QorIQ LX2160A Layerscape Architecture processor.
++
+ config TARGET_LX2160ARDB
+ bool "Support lx2160ardb"
+ select ARCH_LX2160A
+@@ -2458,6 +2458,7 @@
+ source "board/samsung/common/Kconfig"
+ source "board/siemens/common/Kconfig"
+ source "board/seeed/npi_imx6ull/Kconfig"
++source "board/solidrun/lx2160acex7/Kconfig"
+ source "board/socionext/developerbox/Kconfig"
+ source "board/tcl/sl50/Kconfig"
+ source "board/traverse/ten64/Kconfig"
+diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
+index 737e959a6b5..e12136af4ab 100644
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -598,6 +598,7 @@ dtb-$(CONFIG_FSL_LSCH3) += fsl-ls2080a-qds.dtb \
+ fsl-ls1028a-rdb.dtb \
+ fsl-ls1028a-qds-duart.dtb \
+ fsl-ls1028a-qds-lpuart.dtb \
++ fsl-lx2160a-cex7.dtb \
+ fsl-lx2160a-rdb.dtb \
+ fsl-lx2160a-qds.dtb \
+ fsl-lx2160a-qds-3-x-x.dtb \
+diff --git a/arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi b/arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi
+new file mode 100644
+index 00000000000..9394c36d70e
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi
+@@ -0,0 +1,36 @@
++// SPDX-License-Identifier: GPL-2.0+
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ aliases {
++ tlv0 = &{/i2c@2000000/i2c-mux@77/i2c@0/eeprom@57};
++ serial0 = &uart0;
++ };
++};
++
++&gpio2 {
++ /*
++ * AMC6821 THERM signal uses open-drain logic and can be driven
++ * by either the host (force full-speed) or the chip
++ * (thermal warning). Firmware drives it low during reset.
++ *
++ * Force fan full-speed while bootloader is active.
++ * TODO: Add fan-controller driver.
++ */
++ fan-full-speed-hog {
++ gpio-hog;
++ gpios = <2 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
++ output-high;
++ line-name = "fan-full-speed";
++ };
++};
++
++&{/i2c@2000000/i2c-mux@77/i2c@1/fan-temperature-ctrlr@18} {
++ /*u-boot does not currently have a driver for this fan-controller */
++ status = "disabled";
++};
++
++&uart0 {
++ status = "okay";
++};
+diff --git a/arch/arm/dts/fsl-lx2160a-cex7.dts b/arch/arm/dts/fsl-lx2160a-cex7.dts
+new file mode 100644
+index 00000000000..3816034e279
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-cex7.dts
+@@ -0,0 +1,17 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/*
++ * Device Tree file for LX2160A-CEx7 Standalone (Generic Carrier Board)
++ *
++ * Copyright 2024 Josua Mayer <josua@solid-run.com>
++ */
++
++#include "fsl-lx2160a-cex7.dtsi"
++
++/* for SD-Card Boot */
++&esdhc0 {
++ sd-uhs-sdr104;
++ sd-uhs-sdr50;
++ sd-uhs-sdr25;
++ sd-uhs-sdr12;
++ status = "okay";
++};
+diff --git a/arch/arm/dts/fsl-lx2160a-cex7.dtsi b/arch/arm/dts/fsl-lx2160a-cex7.dtsi
+new file mode 100644
+index 00000000000..e4b72707081
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-cex7.dtsi
+@@ -0,0 +1,184 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++//
++// Device Tree file for LX2160A-CEx7
++//
++// Copyright 2019 SolidRun Ltd.
++
++/dts-v1/;
++
++#include "fsl-lx2160a.dtsi"
++
++/ {
++ model = "SolidRun LX2160A COM Express Type 7 module";
++ compatible = "solidrun,lx2160a-cex7", "fsl,lx2160a";
++
++ aliases {
++ crypto = &crypto;
++ };
++
++ sb_3v3: regulator-sb3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "RT7290";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++};
++
++&crypto {
++ status = "okay";
++};
++
++&dpmac17 {
++ phy-handle = <&rgmii_phy1>;
++ phy-connection-type = "rgmii-id";
++};
++
++&emdio1 {
++ status = "okay";
++
++ rgmii_phy1: ethernet-phy@1 {
++ reg = <1>;
++ qca,smarteee-tw-us-1g = <24>;
++ };
++};
++
++&esdhc1 {
++ mmc-hs200-1_8v;
++ mmc-hs400-1_8v;
++ bus-width = <8>;
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++
++ i2c-mux@77 {
++ compatible = "nxp,pca9547";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x77>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ eeprom@50 {
++ compatible = "atmel,24c512";
++ reg = <0x50>;
++ };
++
++ eeprom@51 {
++ compatible = "atmel,spd";
++ reg = <0x51>;
++ };
++
++ eeprom@53 {
++ compatible = "atmel,spd";
++ reg = <0x53>;
++ };
++
++ eeprom@57 {
++ compatible = "atmel,24c02";
++ reg = <0x57>;
++ };
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++
++ fan-temperature-ctrlr@18 {
++ compatible = "ti,amc6821";
++ reg = <0x18>;
++ };
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++
++ regulator@5c {
++ compatible = "lltc,ltc3882";
++ reg = <0x5c>;
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++
++ temperature-sensor@48 {
++ compatible = "nxp,sa56004";
++ reg = <0x48>;
++ vcc-supply = <&sb_3v3>;
++ };
++ };
++
++ sfp0_i2c: i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ };
++
++ sfp1_i2c: i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ };
++
++ sfp2_i2c: i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ };
++
++ sfp3_i2c: i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ };
++ };
++};
++
++&i2c2 {
++ status = "okay";
++};
++
++&i2c4 {
++ status = "okay";
++
++ rtc@51 {
++ compatible = "nxp,pcf2129";
++ reg = <0x51>;
++ };
++};
++
++&fspi {
++ status = "okay";
++
++ flash@0 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "micron,m25p80";
++ m25p,fast-read;
++ spi-max-frequency = <50000000>;
++ reg = <0>;
++ /* The following setting enables 1-1-8 (CMD-ADDR-DATA) mode */
++ spi-rx-bus-width = <8>;
++ spi-tx-bus-width = <1>;
++ };
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&usb1 {
++ status = "okay";
++};
+diff --git a/board/solidrun/lx2160acex7/Kconfig b/board/solidrun/lx2160acex7/Kconfig
+new file mode 100644
+index 00000000000..85673846a4a
+--- /dev/null
++++ b/board/solidrun/lx2160acex7/Kconfig
+@@ -0,0 +1,15 @@
++if TARGET_LX2160ACEX7
++
++config SYS_BOARD
++ default "lx2160acex7"
++
++config SYS_VENDOR
++ default "solidrun"
++
++config SYS_SOC
++ default "fsl-layerscape"
++
++config SYS_CONFIG_NAME
++ default "lx2160acex7"
++
++endif
+diff --git a/board/solidrun/lx2160acex7/Makefile b/board/solidrun/lx2160acex7/Makefile
+new file mode 100644
+index 00000000000..a4bcd539cf8
+--- /dev/null
++++ b/board/solidrun/lx2160acex7/Makefile
+@@ -0,0 +1,11 @@
++#
++# Copyright 2018 Freescale Semiconductor
++# Copyright 2024 Josua Mayer <josua@solid-run.com>
++#
++# SPDX-License-Identifier: GPL-2.0+
++#
++
++obj-y += lx2160a.o
++obj-y += ddr.o
++obj-$(CONFIG_TARGET_LX2160ACEX7) += eth_lx2160acex7.o
++obj-y += serdes.o
+diff --git a/board/solidrun/lx2160acex7/ddr.c b/board/solidrun/lx2160acex7/ddr.c
+new file mode 100644
+index 00000000000..d872e575306
+--- /dev/null
++++ b/board/solidrun/lx2160acex7/ddr.c
+@@ -0,0 +1,22 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright 2018 NXP
++ * Copyright 2024 Josua Mayer <josua@solid-run.com>
++ */
++
++#include <config.h>
++#include <fsl_ddr_sdram.h>
++#include <fsl_ddr_dimm_params.h>
++#include <asm/global_data.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++int fsl_initdram(void)
++{
++ gd->ram_size = tfa_get_dram_size();
++
++ if (!gd->ram_size)
++ gd->ram_size = fsl_ddr_sdram_size();
++
++ return 0;
++}
+diff --git a/board/solidrun/lx2160acex7/eth_lx2160acex7.c b/board/solidrun/lx2160acex7/eth_lx2160acex7.c
+new file mode 100644
+index 00000000000..bc7ae231c58
+--- /dev/null
++++ b/board/solidrun/lx2160acex7/eth_lx2160acex7.c
+@@ -0,0 +1,45 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright 2018-2021 NXP
++ *
++ */
++
++#include <config.h>
++#include <asm/io.h>
++#include <command.h>
++#include <fm_eth.h>
++#include <fsl_mdio.h>
++#include <fsl-mc/fsl_mc.h>
++#include <fsl-mc/ldpaa_wriop.h>
++#include <netdev.h>
++#include <asm/arch/clock.h>
++#include <fdt_support.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++int board_eth_init(struct bd_info *bis)
++{
++ return pci_eth_init(bis);
++}
++
++#if defined(CONFIG_RESET_PHY_R)
++void reset_phy(void)
++{
++#if defined(CONFIG_FSL_MC_ENET)
++ mc_env_boot();
++#endif
++}
++#endif /* CONFIG_RESET_PHY_R */
++
++#ifndef CONFIG_CMD_TLV_EEPROM
++int mac_read_from_eeprom(void)
++{
++ return 0;
++}
++#endif
++
++int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
++{
++ puts("Not implemented.\n");
++ return CMD_RET_FAILURE;
++}
+diff --git a/board/solidrun/lx2160acex7/lx2160a.c b/board/solidrun/lx2160acex7/lx2160a.c
+new file mode 100644
+index 00000000000..632fbff52dc
+--- /dev/null
++++ b/board/solidrun/lx2160acex7/lx2160a.c
+@@ -0,0 +1,269 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright 2018-2021 NXP
++ * Copyright 2024 Josua Mayer <josua@solid-run.com>
++ */
++
++#include <config.h>
++#include <asm/arch/clock.h>
++#include <asm/arch-fsl-layerscape/fsl_icid.h>
++#include <asm/arch/soc.h>
++#include <asm/gpio.h>
++#include <clock_legacy.h>
++#include <display_options.h>
++#include <dm.h>
++#include <dm/platform_data/serial_pl01x.h>
++#include <fdt_support.h>
++#include <fsl-mc/fsl_mc.h>
++#include <fsl_ddr.h>
++#include <init.h>
++#include <malloc.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++int board_early_init_f(void)
++{
++ fsl_lsch3_early_init_f();
++ return 0;
++}
++
++#ifdef CONFIG_OF_BOARD_FIXUP
++void board_fix_fdt_eth(void *fdt, u32 srds_s1, u32 srds_s2, u32 is_lx2162);
++void board_fix_fdt_serdes_ports(void *fdt);
++
++static void board_fix_fdt_pci_silicon(void *fdt) {
++ char *reg_names, *reg_name;
++ int names_len, old_name_len, new_name_len, remaining_names_len;
++ struct str_map {
++ char *old_str;
++ char *new_str;
++ } reg_names_map[] = {
++ { "ccsr", "dbi" },
++ { "pf_ctrl", "ctrl" }
++ };
++ int off = -1, i = 0;
++
++ /* skip pci fixup on silicon version 1 */
++ if (IS_SVR_REV(get_svr(), 1, 0))
++ return;
++
++ /* fixup pci controller for silicon version 2 */
++ off = fdt_node_offset_by_compatible(fdt, -1, "fsl,lx2160a-pcie");
++ while (off != -FDT_ERR_NOTFOUND) {
++ fdt_setprop(fdt, off, "compatible", "fsl,ls-pcie",
++ strlen("fsl,ls-pcie") + 1);
++
++ reg_names = (char *)fdt_getprop(fdt, off, "reg-names",
++ &names_len);
++ if (!reg_names)
++ continue;
++
++ reg_name = reg_names;
++ remaining_names_len = names_len - (reg_name - reg_names);
++ i = 0;
++ while ((i < ARRAY_SIZE(reg_names_map)) && remaining_names_len) {
++ old_name_len = strlen(reg_names_map[i].old_str);
++ new_name_len = strlen(reg_names_map[i].new_str);
++ if (memcmp(reg_name, reg_names_map[i].old_str,
++ old_name_len) == 0) {
++ /* first only leave required bytes for new_str
++ * and copy rest of the string after it
++ */
++ memcpy(reg_name + new_name_len,
++ reg_name + old_name_len,
++ remaining_names_len - old_name_len);
++ /* Now copy new_str */
++ memcpy(reg_name, reg_names_map[i].new_str,
++ new_name_len);
++ names_len -= old_name_len;
++ names_len += new_name_len;
++ i++;
++ }
++
++ reg_name = memchr(reg_name, '\0', remaining_names_len);
++ if (!reg_name)
++ break;
++
++ reg_name += 1;
++
++ remaining_names_len = names_len -
++ (reg_name - reg_names);
++ }
++
++ fdt_setprop(fdt, off, "reg-names", reg_names, names_len);
++ off = fdt_node_offset_by_compatible(fdt, off,
++ "fsl,lx2160a-pcie");
++ }
++}
++
++/* fdt fixup for u-boot itself */
++int board_fix_fdt(void *fdt)
++{
++ /* allocate space in case properties must be added */
++ fdt_increase_size(fdt, 512);
++
++ /* fix fdt */
++ board_fix_fdt_serdes_ports(fdt);
++ board_fix_fdt_pci_silicon(fdt);
++
++ return 0;
++}
++#endif
++
++int checkboard(void)
++{
++ enum boot_src src = get_boot_src();
++ char buf[64];
++
++ cpu_name(buf);
++
++ puts("Boot Source: ");
++ if (src == BOOT_SOURCE_SD_MMC) {
++ puts("SD\n");
++ } else if (src == BOOT_SOURCE_SD_MMC2) {
++ puts("eMMC\n");
++ } else if (src == BOOT_SOURCE_XSPI_NOR) {
++ puts("FlexSPI\n");
++ } else {
++ puts("Unknown\n");
++ }
++
++ return 0;
++}
++
++unsigned long get_board_sys_clk(void)
++{
++ return 100000000;
++}
++
++unsigned long get_board_ddr_clk(void)
++{
++ return 100000000;
++}
++
++int board_init(void)
++{
++#if !defined(CONFIG_SYS_EARLY_PCI_INIT)
++ pci_init();
++#endif
++
++ return 0;
++}
++
++#ifdef CONFIG_BOARD_LATE_INIT
++int fsl_board_late_init(void) {
++ /* TODO: configure fan-controller here and release gpio-hog */
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_FSL_MC_ENET
++void fdt_fixup_board_enet(void *fdt)
++{
++ int offset;
++
++ /* mainline linux has fsl-mc below soc node */
++ offset = fdt_path_offset(fdt, "/soc/fsl-mc");
++
++ if (offset < 0)
++ /* older versions had fsl-mc at root level */
++ offset = fdt_path_offset(fdt, "/fsl-mc");
++
++ if (offset < 0) {
++ printf("%s: fsl-mc node not found in device tree (error %d)\n",
++ __func__, offset);
++ return;
++ }
++
++ if (get_mc_boot_status() == 0 &&
++ (is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0)) {
++ fdt_status_okay(fdt, offset);
++ } else {
++ /* mc startup failed, disable in dtb */
++ fdt_status_fail(fdt, offset);
++ }
++}
++
++void board_quiesce_devices(void)
++{
++ fsl_mc_ldpaa_exit(gd->bd);
++}
++#endif
++
++#ifdef CONFIG_OF_BOARD_SETUP
++int ft_board_setup(void *blob, struct bd_info *bd)
++{
++ int i;
++ u16 mc_memory_bank = 0;
++
++ u64 *base;
++ u64 *size;
++ u64 mc_memory_base = 0;
++ u64 mc_memory_size = 0;
++ u16 total_memory_banks;
++ int err;
++
++ err = fdt_increase_size(blob, 512);
++ if (err) {
++ printf("%s fdt_increase_size: err=%s\n", __func__,
++ fdt_strerror(err));
++ return err;
++ }
++
++ ft_cpu_setup(blob, bd);
++
++ fdt_fixup_mc_ddr(&mc_memory_base, &mc_memory_size);
++
++ if (mc_memory_base != 0)
++ mc_memory_bank++;
++
++ total_memory_banks = CONFIG_NR_DRAM_BANKS + mc_memory_bank;
++
++ base = calloc(total_memory_banks, sizeof(u64));
++ size = calloc(total_memory_banks, sizeof(u64));
++
++ /* fixup DT for the three GPP DDR banks */
++ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
++ base[i] = gd->bd->bi_dram[i].start;
++ size[i] = gd->bd->bi_dram[i].size;
++ }
++
++#ifdef CONFIG_RESV_RAM
++ /* reduce size if reserved memory is within this bank */
++ if (gd->arch.resv_ram >= base[0] &&
++ gd->arch.resv_ram < base[0] + size[0])
++ size[0] = gd->arch.resv_ram - base[0];
++ else if (gd->arch.resv_ram >= base[1] &&
++ gd->arch.resv_ram < base[1] + size[1])
++ size[1] = gd->arch.resv_ram - base[1];
++ else if (gd->arch.resv_ram >= base[2] &&
++ gd->arch.resv_ram < base[2] + size[2])
++ size[2] = gd->arch.resv_ram - base[2];
++#endif
++
++ if (mc_memory_base != 0) {
++ for (i = 0; i <= total_memory_banks; i++) {
++ if (base[i] == 0 && size[i] == 0) {
++ base[i] = mc_memory_base;
++ size[i] = mc_memory_size;
++ break;
++ }
++ }
++ }
++
++ fdt_fixup_memory_banks(blob, base, size, total_memory_banks);
++
++#ifdef CONFIG_USB_HOST
++ fsl_fdt_fixup_dr_usb(blob, bd);
++#endif
++
++#ifdef CONFIG_FSL_MC_ENET
++ fdt_fsl_mc_fixup_iommu_map_entry(blob);
++ fdt_fixup_board_enet(blob);
++ fdt_reserve_mc_mem(blob, 0x4000);
++#endif
++ fdt_fixup_icid(blob);
++
++ return 0;
++}
++#endif
+diff --git a/board/solidrun/lx2160acex7/serdes.c b/board/solidrun/lx2160acex7/serdes.c
+new file mode 100644
+index 00000000000..c6b6d9bbfdc
+--- /dev/null
++++ b/board/solidrun/lx2160acex7/serdes.c
+@@ -0,0 +1,512 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright 2025 Josua Mayer <josua@solid-run.com>
++ *
++ */
++
++#include <fdt_support.h>
++
++/* SerDes base address */
++#define LYNX_28G_SDn_BASE(block) ((void *)0x01EA0000 + (block) * 0x10000)
++
++/* Protocol Configuration Register 0 */
++#define LYNX_28G_PCC0 0x1080
++#define LYNX_28G_PCC0_PEXA_CFG GENMASK(30, 28)
++#define LYNX_28G_PCC0_PEXB_CFG GENMASK(26, 24)
++
++/* Protocol Configuration Register 2 */
++#define LYNX_28G_PCC2 0x1088
++#define LYNX_28G_PCC2_SATAA_CFG GENMASK(30, 28)
++#define LYNX_28G_PCC2_SATAB_CFG GENMASK(26, 24)
++#define LYNX_28G_PCC2_SATAC_CFG GENMASK(22, 20)
++#define LYNX_28G_PCC2_SATAD_CFG GENMASK(18, 16)
++
++/* Protocol Configuration Register 8 */
++#define LYNX_28G_PCC8 0x10A0
++#define LYNX_28G_PCC8_SGMIIA_CFG GENMASK(30, 28)
++#define LYNX_28G_PCC8_SGMIIB_CFG GENMASK(26, 24)
++#define LYNX_28G_PCC8_SGMIIC_CFG GENMASK(22, 20)
++#define LYNX_28G_PCC8_SGMIID_CFG GENMASK(18, 16)
++#define LYNX_28G_PCC8_SGMIIE_CFG GENMASK(14, 12)
++#define LYNX_28G_PCC8_SGMIIF_CFG GENMASK(10, 8)
++#define LYNX_28G_PCC8_SGMIIG_CFG GENMASK(6, 4)
++#define LYNX_28G_PCC8_SGMIIH_CFG GENMASK(2, 0)
++
++/* Protocol Configuration Register C */
++#define LYNX_28G_PCCC 0x10B0
++#define LYNX_28G_PCCC_SXGMIIA_CFG GENMASK(30, 28)
++#define LYNX_28G_PCCC_SXGMIIB_CFG GENMASK(26, 24)
++#define LYNX_28G_PCCC_SXGMIIC_CFG GENMASK(22, 20)
++#define LYNX_28G_PCCC_SXGMIID_CFG GENMASK(18, 16)
++#define LYNX_28G_PCCC_SXGMIIE_CFG GENMASK(14, 12)
++#define LYNX_28G_PCCC_SXGMIIF_CFG GENMASK(10, 8)
++#define LYNX_28G_PCCC_SXGMIIG_CFG GENMASK(6, 4)
++#define LYNX_28G_PCCC_SXGMIIH_CFG GENMASK(2, 0)
++
++/* Protocol Configuration Register D */
++#define LYNX_28G_PCCD 0x10B4
++#define LYNX_28G_PCCD_E25GA_CFG GENMASK(30, 28)
++#define LYNX_28G_PCCD_E25GB_CFG GENMASK(26, 24)
++#define LYNX_28G_PCCD_E25GC_CFG GENMASK(22, 20)
++#define LYNX_28G_PCCD_E25GD_CFG GENMASK(18, 16)
++#define LYNX_28G_PCCD_E25GE_CFG GENMASK(14, 12)
++#define LYNX_28G_PCCD_E25GF_CFG GENMASK(10, 8)
++#define LYNX_28G_PCCD_E25GG_CFG GENMASK(6, 4)
++#define LYNX_28G_PCCD_E25GH_CFG GENMASK(2, 0)
++
++/* Protocol Configuration Register E */
++#define LYNX_28G_PCCE 0x10B8
++#define LYNX_28G_PCCE_E40GA_CFG GENMASK(30, 28)
++#define LYNX_28G_PCCE_E40GB_CFG GENMASK(26, 24)
++#define LYNX_28G_PCCE_E50GA_CFG GENMASK(22, 20)
++#define LYNX_28G_PCCE_E50GB_CFG GENMASK(18, 16)
++#define LYNX_28G_PCCE_E100GA_CFG GENMASK(14, 12)
++#define LYNX_28G_PCCE_E100GB_CFG GENMASK(10, 8)
++
++/* Lane a General Control Register */
++#define LYNX_28G_LNaGCR0(lane) (0x800 + (lane) * 0x100 + 0x0)
++#define LYNX_28G_LNaGCR0_PORT_RST_LEFT BIT(17)
++#define LYNX_28G_LNaGCR0_PORT_LN0_B BIT(16)
++#define LYNX_28G_LNaGCR0_PROTO_SEL_MSK GENMASK(7, 3)
++#define LYNX_28G_LNaGCR0_PROTO_SEL_PCI 0x0
++#define LYNX_28G_LNaGCR0_PROTO_SEL_SGMII 0x8
++#define LYNX_28G_LNaGCR0_PROTO_SEL_SATA 0x10
++#define LYNX_28G_LNaGCR0_PROTO_SEL_XFI 0x50
++#define LYNX_28G_LNaGCR0_PROTO_SEL_25G 0xD0
++
++/* Lane a Tx Reset Control Register */
++#define LYNX_28G_LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20)
++#define LYNX_28G_LNaTRSTCTL_DIS BIT(24)
++
++/* Lane a Rx Reset Control Register */
++#define LYNX_28G_LNaRRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x40)
++#define LYNX_28G_LNaRRSTCTL_DIS BIT(24)
++
++/* Reset Control Word 27 (RO) */
++#define RCWSR27_R ((void *)0x01e00168)
++#define RCWSR27_EC1_PMUX_MASK 0x00000003
++#define RCWSR27_EC1_PMUX_WRIOP_MAC_17_RGMII 0x00000000
++#define RCWSR27_EC2_PMUX_MASK 0x0000000C
++#define RCWSR27_EC2_PMUX_WRIOP_MAC_18_RGMII 0x00000000
++
++enum {
++ DPMAC1 = 0,
++ DPMAC2,
++ DPMAC3,
++ DPMAC4,
++ DPMAC5,
++ DPMAC6,
++ DPMAC7,
++ DPMAC8,
++ DPMAC9,
++ DPMAC10,
++ DPMAC11,
++ DPMAC12,
++ DPMAC13,
++ DPMAC14,
++ DPMAC15,
++ DPMAC16,
++ DPMAC17,
++ DPMAC18,
++ DPMAC_MAX
++};
++
++#ifdef CONFIG_OF_BOARD_FIXUP
++
++/* fix mac nodes based on serdes protocol */
++static void board_fix_fdt_macs(void *fdt) {
++ struct mac_node {
++ const char *const path;
++ const char *status;
++ const char *mode;
++ } macs[DPMAC_MAX] = {
++ { "/fsl-mc@80c000000/dpmacs/dpmac@1", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@2", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@3", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@4", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@5", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@6", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@7", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@8", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@9", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@a", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@b", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@c", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@d", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@e", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@f", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@10", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@11", "disabled" },
++ { "/fsl-mc@80c000000/dpmacs/dpmac@12", "disabled" },
++ };
++
++ struct {
++ const u32 __iomem *pcr;
++ const u32 pcr_ena_mask;
++ const char *const mode;
++ const unsigned int mac;
++ } ports[] = {
++ {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIA_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC3,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIB_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC4,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIC_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC5,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIID_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC6,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIE_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC7,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIF_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC8,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIG_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC9,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIH_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC10,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIA_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC3,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIB_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC4,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIC_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC5,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIID_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC6,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIE_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC7,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIF_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC8,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC9,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC10,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GA_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC3,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GB_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC4,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GC_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC5,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GD_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC6,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GE_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC7,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GF_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC8,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GG_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC9,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GH_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC10,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
++ .pcr_ena_mask = LYNX_28G_PCCE_E40GA_CFG,
++ .mode = "xlaui4",
++ .mac = DPMAC1,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
++ .pcr_ena_mask = LYNX_28G_PCCE_E40GB_CFG,
++ .mode = "xlaui4",
++ .mac = DPMAC2,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
++ .pcr_ena_mask = LYNX_28G_PCCE_E50GA_CFG,
++ .mode = "caui2",
++ .mac = DPMAC1,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
++ .pcr_ena_mask = LYNX_28G_PCCE_E50GB_CFG,
++ .mode = "caui2",
++ .mac = DPMAC2,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
++ .pcr_ena_mask = LYNX_28G_PCCE_E100GA_CFG,
++ .mode = "caui4",
++ .mac = DPMAC1,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
++ .pcr_ena_mask = LYNX_28G_PCCE_E100GB_CFG,
++ .mode = "caui4",
++ .mac = DPMAC2,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIA_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC18,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIB_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC17,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIC_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC16,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIID_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC15,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIE_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC14,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIF_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC13,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIG_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC12,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIH_CFG,
++ .mode = "sgmii",
++ .mac = DPMAC11,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIA_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC18,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIB_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC17,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIC_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC16,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIID_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC15,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIE_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC14,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIF_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC13,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC12,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG,
++ .mode = "xgmii",
++ .mac = DPMAC11,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GA_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC18,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GB_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC17,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GC_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC16,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GD_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC15,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GE_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC14,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GF_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC13,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GG_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC12,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GH_CFG,
++ .mode = "25g-aui",
++ .mac = DPMAC11,
++ }
++ };
++
++ for (int i = 0; i < ARRAY_SIZE(ports); i++) {
++ if (*ports[i].pcr & ports[i].pcr_ena_mask) {
++ macs[ports[i].mac].status = "okay";
++ macs[ports[i].mac].mode = ports[i].mode;
++ }
++ }
++
++ /* workaround for dpmac17.18 rgmii ports */
++ {
++ const u32 __iomem *const rcwsr27 = RCWSR27_R;
++ if ((*rcwsr27 & RCWSR27_EC1_PMUX_MASK) == RCWSR27_EC1_PMUX_WRIOP_MAC_17_RGMII) {
++ macs[DPMAC17].status = "okay";
++ macs[DPMAC17].mode = "rgmii-id";
++ }
++ if ((*rcwsr27 & RCWSR27_EC2_PMUX_MASK) == RCWSR27_EC2_PMUX_WRIOP_MAC_18_RGMII) {
++ macs[DPMAC18].status = "okay";
++ macs[DPMAC18].mode = "rgmii-id";
++ }
++ }
++
++ for (int i = 0; i < ARRAY_SIZE(macs); i++) {
++ fdt_delprop(fdt, fdt_path_offset(fdt, macs[i].path), "phy-mode");
++ do_fixup_by_path_string(fdt, macs[i].path, "status", macs[i].status);
++ do_fixup_by_path_string(fdt, macs[i].path, "phy-connection-type", macs[i].mode);
++ }
++}
++
++static void board_fix_fdt_pci_sata(void *fdt) {
++ struct {
++ const u32 __iomem *pcr;
++ const u32 pcr_ena_mask;
++ const char *const path;
++ } ports[] = {
++ {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC0,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG,
++ .path = "/pcie@3400000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC0,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG,
++ .path = "/pcie@3500000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC0,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG,
++ .path = "/pcie@3600000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC0,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG,
++ .path = "/pcie@3700000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(2) + LYNX_28G_PCC0,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG,
++ .path = "/pcie@3800000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(2) + LYNX_28G_PCC0,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG,
++ .path = "/pcie@3900000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC2,
++ .pcr_ena_mask = LYNX_28G_PCC2_SATAA_CFG,
++ .path = "/sata@3200000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC2,
++ .pcr_ena_mask = LYNX_28G_PCC2_SATAB_CFG,
++ .path = "/sata@3210000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC2,
++ .pcr_ena_mask = LYNX_28G_PCC2_SATAC_CFG,
++ .path = "/sata@3220000",
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC2,
++ .pcr_ena_mask = LYNX_28G_PCC2_SATAD_CFG,
++ .path = "/sata@3230000",
++ },
++ };
++
++ for (int i = 0; i < ARRAY_SIZE(ports); i++) {
++ const char *status = "disabled";
++ if (*ports[i].pcr & ports[i].pcr_ena_mask)
++ status = "okay";
++
++ do_fixup_by_path_string(fdt, ports[i].path, "status", status);
++ }
++}
++
++void board_fix_fdt_serdes_ports(void *fdt) {
++ board_fix_fdt_pci_sata(fdt);
++ board_fix_fdt_macs(fdt);
++}
++
++#endif /* CONFIG_OF_BOARD_FIXUP */
+diff --git a/configs/lx2160acex7_tfa_SECURE_BOOT_defconfig b/configs/lx2160acex7_tfa_SECURE_BOOT_defconfig
+new file mode 100644
+index 00000000000..d55bdb24a4b
+--- /dev/null
++++ b/configs/lx2160acex7_tfa_SECURE_BOOT_defconfig
+@@ -0,0 +1,97 @@
++CONFIG_ARM=y
++CONFIG_SKIP_LOWLEVEL_INIT=y
++CONFIG_GIC_V3_ITS=y
++CONFIG_TARGET_LX2160ACEX7=y
++CONFIG_TFABOOT=y
++CONFIG_SYS_TEXT_BASE=0x82000000
++CONFIG_SYS_MALLOC_LEN=0x202000
++CONFIG_SYS_MALLOC_F_LEN=0x6000
++CONFIG_NR_DRAM_BANKS=3
++CONFIG_ENV_SIZE=0x2000
++CONFIG_NXP_ESBC=y
++CONFIG_DM_GPIO=y
++CONFIG_DEFAULT_DEVICE_TREE="fsl-lx2160a-cex7"
++CONFIG_FSPI_AHB_EN_4BYTE=y
++CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y
++CONFIG_SEC_FIRMWARE_ARMV8_PSCI=y
++CONFIG_AHCI=y
++CONFIG_OF_BOARD_FIXUP=y
++CONFIG_REMAKE_ELF=y
++CONFIG_MP=y
++CONFIG_FIT_VERBOSE=y
++CONFIG_OF_BOARD_SETUP=y
++CONFIG_OF_STDOUT_VIA_ALIAS=y
++CONFIG_DYNAMIC_SYS_CLK_FREQ=y
++CONFIG_USE_BOOTARGS=y
++CONFIG_BOOTARGS="console=ttyAMA0,115200 root=/dev/ram0 earlycon=pl011,mmio32,0x21c0000 ramdisk_size=0x2000000 default_hugepagesz=1024m hugepagesz=1024m hugepages=2 pci=pcie_bus_perf"
++CONFIG_DEFAULT_FDT_FILE="boot/fsl-lx2160a-clearfog-cx.dtb"
++CONFIG_MISC_INIT_R=y
++CONFIG_CMD_GREPENV=y
++CONFIG_CMD_EEPROM=y
++CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=3
++CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=5
++CONFIG_CMD_DM=y
++CONFIG_CMD_GPIO=y
++CONFIG_CMD_GPT=y
++CONFIG_CMD_I2C=y
++CONFIG_CMD_MMC=y
++CONFIG_CMD_OPTEE_RPMB=y
++CONFIG_CMD_PCI=y
++CONFIG_CMD_USB=y
++CONFIG_CMD_WDT=y
++CONFIG_CMD_CACHE=y
++CONFIG_OF_CONTROL=y
++CONFIG_ENV_OVERWRITE=y
++CONFIG_NET_RANDOM_ETHADDR=y
++CONFIG_DM=y
++CONFIG_SATA=y
++CONFIG_SATA_CEVA=y
++CONFIG_FSL_CAAM=y
++CONFIG_DYNAMIC_DDR_CLK_FREQ=y
++CONFIG_DDR_ECC=y
++CONFIG_ECC_INIT_VIA_DDRCONTROLLER=y
++CONFIG_MPC8XXX_GPIO=y
++CONFIG_DM_I2C=y
++CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
++CONFIG_SYS_I2C_EEPROM_ADDR=0x57
++CONFIG_SUPPORT_EMMC_RPMB=y
++CONFIG_SUPPORT_EMMC_BOOT=y
++CONFIG_MMC_HS400_SUPPORT=y
++CONFIG_FSL_ESDHC=y
++CONFIG_MTD=y
++CONFIG_DM_SPI_FLASH=y
++CONFIG_SPI_FLASH_STMICRO=y
++CONFIG_SPI_FLASH_MT35XU=y
++CONFIG_SPI_FLASH_WINBOND=y
++# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
++CONFIG_PHYLIB=y
++CONFIG_PHY_ATHEROS=y
++CONFIG_DM_ETH=y
++CONFIG_DM_MDIO=y
++CONFIG_E1000=y
++CONFIG_MII=y
++CONFIG_FSL_LS_MDIO=y
++CONFIG_NVME_PCI=y
++CONFIG_PCI=y
++CONFIG_PCIE_LAYERSCAPE_RC=y
++CONFIG_PCIE_LAYERSCAPE_GEN4=y
++CONFIG_DM_RTC=y
++CONFIG_RTC_PCF2127=y
++CONFIG_DM_SCSI=y
++CONFIG_DM_SERIAL=y
++CONFIG_PL01X_SERIAL=y
++CONFIG_SPI=y
++CONFIG_DM_SPI=y
++CONFIG_FSL_DSPI=y
++CONFIG_NXP_FSPI=y
++CONFIG_TEE=y
++CONFIG_OPTEE=y
++CONFIG_USB=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_DWC3=y
++CONFIG_RSA=y
++CONFIG_SPL_RSA=y
++CONFIG_RSA_SOFTWARE_EXP=y
++CONFIG_WDT=y
++CONFIG_WDT_SBSA=y
++CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
+diff --git a/configs/lx2160acex7_tfa_defconfig b/configs/lx2160acex7_tfa_defconfig
+new file mode 100644
+index 00000000000..016daa899c8
+--- /dev/null
++++ b/configs/lx2160acex7_tfa_defconfig
+@@ -0,0 +1,109 @@
++CONFIG_ARM=y
++CONFIG_SKIP_LOWLEVEL_INIT=y
++CONFIG_GIC_V3_ITS=y
++CONFIG_TARGET_LX2160ACEX7=y
++CONFIG_TFABOOT=y
++CONFIG_TEXT_BASE=0x82000000
++CONFIG_SYS_MALLOC_LEN=0x202000
++CONFIG_SYS_MALLOC_F_LEN=0x6000
++CONFIG_NR_DRAM_BANKS=3
++CONFIG_ENV_SIZE=0x2000
++CONFIG_ENV_OFFSET=0x500000
++CONFIG_ENV_SECT_SIZE=0x20000
++CONFIG_DM_GPIO=y
++CONFIG_DEFAULT_DEVICE_TREE="fsl-lx2160a-cex7"
++CONFIG_FSPI_AHB_EN_4BYTE=y
++CONFIG_SYS_MONITOR_LEN=958464
++CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y
++CONFIG_SEC_FIRMWARE_ARMV8_PSCI=y
++CONFIG_ENV_ADDR=0x20500000
++CONFIG_PCI=y
++CONFIG_AHCI=y
++CONFIG_OF_BOARD_FIXUP=y
++CONFIG_SYS_FSL_NUM_CC_PLLS=4
++CONFIG_REMAKE_ELF=y
++CONFIG_MP=y
++CONFIG_DYNAMIC_SYS_CLK_FREQ=y
++CONFIG_FIT_VERBOSE=y
++CONFIG_BOOTDELAY=10
++CONFIG_OF_BOARD_SETUP=y
++CONFIG_OF_STDOUT_VIA_ALIAS=y
++CONFIG_USE_BOOTARGS=y
++CONFIG_BOOTARGS="console=ttyAMA0,115200 root=/dev/ram0 earlycon=pl011,mmio32,0x21c0000 ramdisk_size=0x2000000 default_hugepagesz=1024m hugepagesz=1024m hugepages=2 pci=pcie_bus_perf"
++CONFIG_DEFAULT_FDT_FILE="boot/fsl-lx2160a-clearfog-cx.dtb"
++CONFIG_SYS_PBSIZE=532
++CONFIG_CMD_TLV_EEPROM=y
++CONFIG_CMD_GREPENV=y
++CONFIG_CMD_EEPROM=y
++CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=3
++CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=5
++CONFIG_CMD_DM=y
++CONFIG_CMD_GPIO=y
++CONFIG_CMD_GPT=y
++CONFIG_CMD_I2C=y
++CONFIG_CMD_MMC=y
++CONFIG_CMD_OPTEE_RPMB=y
++CONFIG_CMD_PCI=y
++CONFIG_CMD_POWEROFF=y
++CONFIG_CMD_USB=y
++CONFIG_CMD_WDT=y
++CONFIG_CMD_CACHE=y
++CONFIG_OF_CONTROL=y
++CONFIG_ENV_OVERWRITE=y
++CONFIG_ENV_IS_IN_MMC=y
++CONFIG_ENV_IS_IN_SPI_FLASH=y
++CONFIG_USE_ETHPRIME=y
++CONFIG_ETHPRIME="DPMAC17@rgmii-id"
++CONFIG_NET_RANDOM_ETHADDR=y
++CONFIG_SATA=y
++CONFIG_SATA_CEVA=y
++CONFIG_FSL_CAAM=y
++CONFIG_DYNAMIC_DDR_CLK_FREQ=y
++CONFIG_DDR_ECC=y
++CONFIG_ECC_INIT_VIA_DDRCONTROLLER=y
++CONFIG_SYS_FSL_DDR_INTLV_256B=y
++CONFIG_MPC8XXX_GPIO=y
++CONFIG_DM_I2C=y
++CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
++CONFIG_I2C_MUX=y
++CONFIG_I2C_MUX_PCA954x=y
++CONFIG_I2C_EEPROM=y
++CONFIG_SYS_I2C_EEPROM_ADDR=0x57
++CONFIG_SUPPORT_EMMC_RPMB=y
++CONFIG_SUPPORT_EMMC_BOOT=y
++CONFIG_MMC_HS400_SUPPORT=y
++CONFIG_FSL_ESDHC=y
++CONFIG_MTD=y
++CONFIG_DM_SPI_FLASH=y
++CONFIG_SPI_FLASH_STMICRO=y
++CONFIG_SPI_FLASH_MT35XU=y
++CONFIG_SPI_FLASH_WINBOND=y
++# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
++CONFIG_PHYLIB=y
++CONFIG_PHY_AQUANTIA=y
++CONFIG_PHY_ATHEROS=y
++CONFIG_FSL_MEMAC=y
++CONFIG_SYS_MEMAC_LITTLE_ENDIAN=y
++CONFIG_DM_ETH_PHY=y
++CONFIG_E1000=y
++CONFIG_MII=y
++CONFIG_NVME_PCI=y
++CONFIG_PCIE_LAYERSCAPE_RC=y
++CONFIG_PCIE_LAYERSCAPE_GEN4=y
++CONFIG_DM_RTC=y
++CONFIG_RTC_PCF2127=y
++CONFIG_DM_SERIAL=y
++CONFIG_PL01X_SERIAL=y
++CONFIG_SPI=y
++CONFIG_DM_SPI=y
++CONFIG_FSL_DSPI=y
++CONFIG_NXP_FSPI=y
++CONFIG_TEE=y
++CONFIG_OPTEE=y
++CONFIG_USB=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_XHCI_DWC3=y
++CONFIG_USB_MAX_CONTROLLER_COUNT=2
++CONFIG_WDT=y
++CONFIG_WDT_SBSA=y
++CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
+diff --git a/include/configs/lx2160acex7.h b/include/configs/lx2160acex7.h
+new file mode 100644
+index 00000000000..652cce98b66
+--- /dev/null
++++ b/include/configs/lx2160acex7.h
+@@ -0,0 +1,282 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ * Copyright 2018-2022 NXP
++ * Copyright 2024-2025 Josua Mayer <josua@solid-run.com>
++ */
++
++#ifndef __CONFIG_LX2160ACEX7_H
++#define __CONFIG_LX2160ACEX7_H
++
++#include <asm/arch/stream_id_lsch3.h>
++#include <asm/arch/config.h>
++#include <asm/arch/soc.h>
++
++#define CFG_SYS_FLASH_BASE 0x20000000
++
++/* DDR */
++#define CFG_SYS_DDR_SDRAM_BASE 0x80000000UL
++#define CFG_SYS_FSL_DDR_SDRAM_BASE_PHY 0
++#define CFG_SYS_DDR_BLOCK2_BASE 0x2080000000ULL
++#define CFG_SYS_SDRAM_SIZE 0x200000000UL
++#define CFG_SYS_SDRAM_BASE CFG_SYS_DDR_SDRAM_BASE
++#define SPD_EEPROM_ADDRESS1 0x51
++#define SPD_EEPROM_ADDRESS2 0x52
++#define SPD_EEPROM_ADDRESS3 0x53
++#define SPD_EEPROM_ADDRESS4 0x54
++#define SPD_EEPROM_ADDRESS5 0x55
++#define SPD_EEPROM_ADDRESS6 0x56
++#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1
++
++/* SMP Definitinos */
++#define CPU_RELEASE_ADDR secondary_boot_addr
++
++/* Generic Timer Definitions */
++/*
++ * This is not an accurate number. It is used in start.S. The frequency
++ * will be udpated later when get_bus_freq(0) is available.
++ */
++
++
++/* Serial Port */
++#define CFG_PL011_CLOCK (get_bus_freq(0) / 4)
++#define CFG_SYS_SERIAL0 0x21c0000
++#define CFG_SYS_SERIAL1 0x21d0000
++#define CFG_SYS_SERIAL2 0x21e0000
++#define CFG_SYS_SERIAL3 0x21f0000
++/*below might needs to be removed*/
++#define CFG_PL01x_PORTS {(void *)CFG_SYS_SERIAL0, \
++ (void *)CFG_SYS_SERIAL1, \
++ (void *)CFG_SYS_SERIAL2, \
++ (void *)CFG_SYS_SERIAL3 }
++
++/* MC firmware */
++#define CFG_SYS_LS_MC_DPC_MAX_LENGTH 0x20000
++#define CFG_SYS_LS_MC_DRAM_DPC_OFFSET 0x00F00000
++#define CFG_SYS_LS_MC_DPL_MAX_LENGTH 0x20000
++#define CFG_SYS_LS_MC_DRAM_DPL_OFFSET 0x00F20000
++#define CFG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
++
++/* Define phy_reset function to boot the MC based on mcinitcmd.
++ * This happens late enough to properly fixup u-boot env MAC addresses.
++ */
++#define CONFIG_RESET_PHY_R
++
++/*
++ * Carve out a DDR region which will not be used by u-boot/Linux
++ *
++ * It will be used by MC and Debug Server. The MC region must be
++ * 512MB aligned, so the min size to hide is 512MB.
++ */
++#ifdef CONFIG_FSL_MC_ENET
++#define CFG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024)
++#endif
++
++/* USB */
++
++#define COUNTER_FREQUENCY_REAL (get_board_sys_clk() / 4)
++
++#define HWCONFIG_BUFFER_SIZE 128
++
++/*
++ * Memory Layout Ovverview:
++ *
++ */
++
++/*
++ * Boot-Media Latout:
++ * - SD/eMMC MC offsets (in sectors):
++ * - 0x3000: kernel header
++ * - 0x3200: mc firmware header
++ * - 0x3400: dpc header
++ * - 0x5000: firmware
++ * - 0x6800: dpl
++ * - 0x7000: dpc
++ * - 0x7800: dtb
++ * - 0x8000: kernel
++ * - SPI offsets (in byte):
++ * - 0x0600000: kernel header
++ * - 0x0640000: mc firmware header
++ * - 0x0680000: dpc header
++ * - 0x0a00000: mc firmware
++ * - 0x0e00000: dpc
++ * - 0x0d00000: dpl
++ * - 0x0f00000: dtb
++ * - 0x1000000: kernel
++ */
++
++/*
++ * Load Adresses (different from lx2160a_common.h):
++ * Use GPP DRAM Region #1 (2GB: [0x80000000-0xffffffff]).
++ * - 16MB for secure-boot / mc ([0x80000000-0x80ffffff])
++ * - 1MB for boot-script
++ * - 1MB for pxe
++ * - 1MB for DTB
++ * - 64MB for compressed kernel
++ * - 512MB for uncompressed kernel
++ * - ~1.5GB for ramdisk
++ */
++#define SCRIPT_ADDR_R __stringify(0x81000000)
++#define PXEFILE_ADDR_R __stringify(0x81100000)
++#define FDT_ADDR_R __stringify(0x81200000)
++#define KERNEL_COMP_ADDR_R __stringify(0x81300000)
++#define KERNEL_COMP_SIZE __stringify(0x04000000)
++#define KERNEL_ADDR_R __stringify(0x85300000)
++#define RAMDISK_ADDR_R __stringify(0xa5300000)
++#define FDT_RELOCATION_LIMIT __stringify(0xffffffff)
++
++/* Initial environment variables */
++#define XSPI_MC_INIT_CMD \
++ "sf probe 0:0 && " \
++ "sf read 0x80640000 0x640000 0x80000 && " \
++ "sf read $fdt_addr_r 0xf00000 0x100000 && " \
++ "env exists secureboot && " \
++ "esbc_validate 0x80640000 && " \
++ "esbc_validate 0x80680000; " \
++ "sf read 0x80a00000 0xa00000 0x300000 && " \
++ "sf read 0x80e00000 0xe00000 0x100000; " \
++ "fsl_mc start mc 0x80a00000 0x80e00000\0"
++
++#define SD_MC_INIT_CMD \
++ "mmc read 0x80a00000 0x5000 0x1200;" \
++ "mmc read 0x80e00000 0x7000 0x800;" \
++ "mmc read $fdt_addr_r 0x7800 0x800;" \
++ "env exists secureboot && " \
++ "mmc read 0x80640000 0x3200 0x20 && " \
++ "mmc read 0x80680000 0x3400 0x20 && " \
++ "esbc_validate 0x80640000 && " \
++ "esbc_validate 0x80680000 ;" \
++ "fsl_mc start mc 0x80a00000 0x80e00000\0"
++
++#define SD2_MC_INIT_CMD \
++ "mmc dev 1; mmc read 0x80a00000 0x5000 0x1200;" \
++ "mmc read 0x80e00000 0x7000 0x800;" \
++ "mmc read $fdt_addr_r 0x7800 0x800;" \
++ "env exists secureboot && " \
++ "mmc read 0x80640000 0x3200 0x20 && " \
++ "mmc read 0x80680000 0x3400 0x20 && " \
++ "esbc_validate 0x80640000 && " \
++ "esbc_validate 0x80680000 ;" \
++ "fsl_mc start mc 0x80a00000 0x80e00000\0"
++
++#define EXTRA_ENV_SETTINGS \
++ "hwconfig=fsl_ddr:bank_intlv=auto\0" \
++ "ramdisk_addr_r=" RAMDISK_ADDR_R "\0" \
++ "fdt_high=" FDT_RELOCATION_LIMIT "\0" \
++ "initrd_high=0xffffffffffffffff\0" \
++ "kernel_start=0x1000000\0" \
++ "kernelheader_start=0x600000\0" \
++ "scriptaddr=" SCRIPT_ADDR_R "\0" \
++ "scripthdraddr=0x80080000\0" \
++ "fdtheader_addr_r=0x80100000\0" \
++ "kernelheader_addr_r=0x80200000\0" \
++ "kernel_addr_r=" KERNEL_ADDR_R "\0" \
++ "kernelheader_size=0x40000\0" \
++ "fdt_addr_r=" FDT_ADDR_R "\0" \
++ "fdt_addr=" FDT_ADDR_R "\0" \
++ "pxefile_addr_r=" PXEFILE_ADDR_R "\0" \
++ "kernel_comp_addr_r=" KERNEL_COMP_ADDR_R "\0" \
++ "kernel_comp_size=" KERNEL_COMP_SIZE "\0" \
++ "load_addr=" KERNEL_ADDR_R "\0" \
++ "kernel_size=0x2800000\0" \
++ "kernel_addr_sd=0x8000\0" \
++ "kernelhdr_addr_sd=0x3000\0" \
++ "kernel_size_sd=0x14000\0" \
++ "kernelhdr_size_sd=0x20\0" \
++ "console=ttyAMA0,115200n8\0" \
++ BOOTENV \
++ "mcmemsize=0x70000000\0" \
++ XSPI_MC_INIT_CMD \
++ "scan_dev_for_boot_part=" \
++ "part list ${devtype} ${devnum} devplist; " \
++ "env exists devplist || setenv devplist 1; " \
++ "for distro_bootpart in ${devplist}; do " \
++ "if fstype ${devtype} " \
++ "${devnum}:${distro_bootpart} " \
++ "bootfstype; then " \
++ "run scan_dev_for_boot; " \
++ "fi; " \
++ "done\0" \
++ "boot_a_script=" \
++ "load ${devtype} ${devnum}:${distro_bootpart} " \
++ "${scriptaddr} ${prefix}${script}; " \
++ "env exists secureboot && load ${devtype} " \
++ "${devnum}:${distro_bootpart} " \
++ "${scripthdraddr} ${prefix}${boot_script_hdr} " \
++ "&& esbc_validate ${scripthdraddr};" \
++ "source ${scriptaddr}\0"
++
++#define XSPI_NOR_BOOTCOMMAND \
++ "sf probe 0:0; " \
++ "sf read 0x806c0000 0x6c0000 0x40000; " \
++ "env exists mcinitcmd && env exists secureboot" \
++ " && esbc_validate 0x806c0000; " \
++ "sf read 0x80d00000 0xd00000 0x100000; " \
++ "env exists mcinitcmd && " \
++ "fsl_mc lazyapply dpl 0x80d00000; " \
++ "run distro_bootcmd;run xspi_bootcmd; " \
++ "env exists secureboot && esbc_halt;"
++
++#define SD_BOOTCOMMAND \
++ "env exists mcinitcmd && mmcinfo; " \
++ "mmc read 0x80d00000 0x6800 0x800; " \
++ "env exists mcinitcmd && env exists secureboot " \
++ " && mmc read 0x806C0000 0x3600 0x20 " \
++ "&& esbc_validate 0x806C0000;env exists mcinitcmd " \
++ "&& fsl_mc lazyapply dpl 0x80d00000;" \
++ "run distro_bootcmd;run sd_bootcmd;" \
++ "env exists secureboot && esbc_halt;"
++
++#define SD2_BOOTCOMMAND \
++ "mmc dev 1; env exists mcinitcmd && mmcinfo; " \
++ "mmc read 0x80d00000 0x6800 0x800; " \
++ "env exists mcinitcmd && env exists secureboot " \
++ " && mmc read 0x806C0000 0x3600 0x20 " \
++ "&& esbc_validate 0x806C0000;env exists mcinitcmd " \
++ "&& fsl_mc lazyapply dpl 0x80d00000;" \
++ "run distro_bootcmd;run sd2_bootcmd;" \
++ "env exists secureboot && esbc_halt;"
++
++/* configure boot order for distro-boot feature */
++#define BOOT_TARGET_DEVICES(func) \
++ func(USB, usb, 0) \
++ func(MMC, mmc, 0) \
++ func(MMC, mmc, 1) \
++ func(NVME, nvme, 0) \
++ func(SCSI, scsi, 0) \
++ func(SCSI, scsi, 1) \
++ func(SCSI, scsi, 2) \
++ func(SCSI, scsi, 3) \
++ func(PXE, pxe, na) \
++ func(DHCP, dhcp, na)
++#include <config_distro_bootcmd.h>
++
++#define CFG_EXTRA_ENV_SETTINGS \
++ EXTRA_ENV_SETTINGS \
++ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
++ "boot_scripts=lx2160acex7_boot.scr\0" \
++ "boot_script_hdr=hdr_lx2160acex7_bs.out\0" \
++ "BOARD=lx2160acex7\0" \
++ "xspi_bootcmd=echo Trying load from flexspi..;" \
++ "sf probe 0:0 && sf read $load_addr " \
++ "$kernel_start $kernel_size ; env exists secureboot &&" \
++ "sf read $kernelheader_addr_r $kernelheader_start " \
++ "$kernelheader_size && esbc_validate ${kernelheader_addr_r}; "\
++ " bootm $load_addr#$BOARD\0" \
++ "sd_bootcmd=echo Trying load from sd card..;" \
++ "mmc dev 0; mmcinfo; mmc read $load_addr " \
++ "$kernel_addr_sd $kernel_size_sd ;" \
++ "env exists secureboot && mmc read $kernelheader_addr_r "\
++ "$kernelhdr_addr_sd $kernelhdr_size_sd " \
++ " && esbc_validate ${kernelheader_addr_r};" \
++ "bootm $load_addr#$BOARD\0" \
++ "sd2_bootcmd=echo Trying load from emmc card..;" \
++ "mmc dev 1; mmcinfo; mmc read $load_addr " \
++ "$kernel_addr_sd $kernel_size_sd ;" \
++ "env exists secureboot && mmc read $kernelheader_addr_r "\
++ "$kernelhdr_addr_sd $kernelhdr_size_sd " \
++ " && esbc_validate ${kernelheader_addr_r};" \
++ "bootm $load_addr#$BOARD\0"
++
++#include <asm/fsl_secure_boot.h>
++
++#endif /* __CONFIG_LX2160ACEX7_H */
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,238 @@
+From c932c5e0139c026c82bb0bdf7e27117d8a13590c Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Fri, 8 Aug 2025 18:05:24 +0200
+Subject: [PATCH 14/14] board: solidrun: lx2160cex7: add support for
+ clearfog-cx & honeycomb
+
+Compile with CONFIG_DEFAULT_DEVICE_TREE=fsl-lx2160a-clearfog-cx
+or CONFIG_DEFAULT_DEVICE_TREE=fsl-lx2160a-honeycomb
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ .../dts/fsl-lx2160a-clearfog-cx-u-boot.dtsi | 3 +
+ arch/arm/dts/fsl-lx2160a-clearfog-cx.dts | 15 ++
+ .../dts/fsl-lx2160a-clearfog-itx-u-boot.dtsi | 3 +
+ arch/arm/dts/fsl-lx2160a-clearfog-itx.dtsi | 135 ++++++++++++++++++
+ .../arm/dts/fsl-lx2160a-honeycomb-u-boot.dtsi | 3 +
+ arch/arm/dts/fsl-lx2160a-honeycomb.dts | 15 ++
+ 6 files changed, 174 insertions(+)
+ create mode 100644 arch/arm/dts/fsl-lx2160a-clearfog-cx-u-boot.dtsi
+ create mode 100644 arch/arm/dts/fsl-lx2160a-clearfog-cx.dts
+ create mode 100644 arch/arm/dts/fsl-lx2160a-clearfog-itx-u-boot.dtsi
+ create mode 100644 arch/arm/dts/fsl-lx2160a-clearfog-itx.dtsi
+ create mode 100644 arch/arm/dts/fsl-lx2160a-honeycomb-u-boot.dtsi
+ create mode 100644 arch/arm/dts/fsl-lx2160a-honeycomb.dts
+
+diff --git a/arch/arm/dts/fsl-lx2160a-clearfog-cx-u-boot.dtsi b/arch/arm/dts/fsl-lx2160a-clearfog-cx-u-boot.dtsi
+new file mode 100644
+index 00000000000..fc1b1692755
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-clearfog-cx-u-boot.dtsi
+@@ -0,0 +1,3 @@
++// SPDX-License-Identifier: GPL-2.0+
++
++#include "fsl-lx2160a-clearfog-itx-u-boot.dtsi"
+diff --git a/arch/arm/dts/fsl-lx2160a-clearfog-cx.dts b/arch/arm/dts/fsl-lx2160a-clearfog-cx.dts
+new file mode 100644
+index 00000000000..86a9b771428
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-clearfog-cx.dts
+@@ -0,0 +1,15 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++//
++// Device Tree file for LX2160A Clearfog CX board
++//
++// Copyright 2019 SolidRun Ltd.
++
++/dts-v1/;
++
++#include "fsl-lx2160a-clearfog-itx.dtsi"
++
++/ {
++ model = "SolidRun LX2160A Clearfog CX";
++ compatible = "solidrun,clearfog-cx",
++ "solidrun,lx2160a-cex7", "fsl,lx2160a";
++};
+diff --git a/arch/arm/dts/fsl-lx2160a-clearfog-itx-u-boot.dtsi b/arch/arm/dts/fsl-lx2160a-clearfog-itx-u-boot.dtsi
+new file mode 100644
+index 00000000000..2ab1b63addf
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-clearfog-itx-u-boot.dtsi
+@@ -0,0 +1,3 @@
++// SPDX-License-Identifier: GPL-2.0+
++
++#include "fsl-lx2160a-cex7-u-boot.dtsi"
+diff --git a/arch/arm/dts/fsl-lx2160a-clearfog-itx.dtsi b/arch/arm/dts/fsl-lx2160a-clearfog-itx.dtsi
+new file mode 100644
+index 00000000000..91a2fd0c260
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-clearfog-itx.dtsi
+@@ -0,0 +1,135 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++//
++// Device Tree file for LX2160A Clearfog ITX board; this contains the
++// common parts shared between the Clearfog CX and Honeycomb builds.
++//
++// Copyright 2019 SolidRun Ltd.
++
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++
++#include "fsl-lx2160a-cex7.dtsi"
++#include <dt-bindings/input/linux-event-codes.h>
++
++/ {
++ aliases {
++ serial0 = &uart0;
++ serial1 = &uart1;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
++ gpio-keys {
++ compatible = "gpio-keys";
++
++ key {
++ label = "power";
++ linux,can-disable;
++ linux,code = <KEY_POWER>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
++ };
++ };
++
++ sfp0: sfp-0 {
++ compatible = "sff,sfp";
++ i2c-bus = <&sfp0_i2c>;
++ mod-def0-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
++ maximum-power-milliwatt = <2000>;
++ };
++
++ sfp1: sfp-1 {
++ compatible = "sff,sfp";
++ i2c-bus = <&sfp1_i2c>;
++ mod-def0-gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
++ maximum-power-milliwatt = <2000>;
++ };
++
++ sfp2: sfp-2 {
++ compatible = "sff,sfp";
++ i2c-bus = <&sfp2_i2c>;
++ mod-def0-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
++ maximum-power-milliwatt = <2000>;
++ };
++
++ sfp3: sfp-3 {
++ compatible = "sff,sfp";
++ i2c-bus = <&sfp3_i2c>;
++ mod-def0-gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
++ maximum-power-milliwatt = <2000>;
++ };
++};
++
++&dpmac7 {
++ sfp = <&sfp0>;
++ managed = "in-band-status";
++};
++
++&dpmac8 {
++ sfp = <&sfp1>;
++ managed = "in-band-status";
++};
++
++&dpmac9 {
++ sfp = <&sfp2>;
++ managed = "in-band-status";
++};
++
++&dpmac10 {
++ sfp = <&sfp3>;
++ managed = "in-band-status";
++};
++
++&emdio2 {
++ status = "okay";
++};
++
++&esdhc0 {
++ sd-uhs-sdr104;
++ sd-uhs-sdr50;
++ sd-uhs-sdr25;
++ sd-uhs-sdr12;
++ status = "okay";
++};
++
++&pcs_mdio7 {
++ status = "okay";
++};
++
++&pcs_mdio8 {
++ status = "okay";
++};
++
++&pcs_mdio9 {
++ status = "okay";
++};
++
++&pcs_mdio10 {
++ status = "okay";
++};
++
++&sata0 {
++ status = "okay";
++};
++
++&sata1 {
++ status = "okay";
++};
++
++&sata2 {
++ status = "okay";
++};
++
++&sata3 {
++ status = "okay";
++};
++
++&uart0 {
++ status = "okay";
++};
++
++&uart1 {
++ status = "okay";
++};
+diff --git a/arch/arm/dts/fsl-lx2160a-honeycomb-u-boot.dtsi b/arch/arm/dts/fsl-lx2160a-honeycomb-u-boot.dtsi
+new file mode 100644
+index 00000000000..fc1b1692755
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-honeycomb-u-boot.dtsi
+@@ -0,0 +1,3 @@
++// SPDX-License-Identifier: GPL-2.0+
++
++#include "fsl-lx2160a-clearfog-itx-u-boot.dtsi"
+diff --git a/arch/arm/dts/fsl-lx2160a-honeycomb.dts b/arch/arm/dts/fsl-lx2160a-honeycomb.dts
+new file mode 100644
+index 00000000000..fe19f3009ea
+--- /dev/null
++++ b/arch/arm/dts/fsl-lx2160a-honeycomb.dts
+@@ -0,0 +1,15 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++//
++// Device Tree file for LX2160A Honeycomb board
++//
++// Copyright 2019 SolidRun Ltd.
++
++/dts-v1/;
++
++#include "fsl-lx2160a-clearfog-itx.dtsi"
++
++/ {
++ model = "SolidRun LX2160A Honeycomb";
++ compatible = "solidrun,honeycomb",
++ "solidrun,lx2160a-cex7", "fsl,lx2160a";
++};
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,138 @@
+From 5a25d2b4237e08345c61c8e9affa34031c2363ac Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sat, 9 Aug 2025 15:25:05 +0200
+Subject: [PATCH] board: solidrun: lx2160cex7: configure fan-controller
+ defaults
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Configure default values for fan-controller register according to
+maximum ratings of LX2160/LX2162 SoC tuned for quiet operation.
+
+Fan starts to speed up at 64°C, reaching maximum at 101°C - 4° short of
+SoC absolute maximum. LX2160 is designed to support continuous operation
+at 105°C junction.
+
+Linux driver keeps bootloader defaults till the user applies changes
+through sysfs interface.
+
+After communication with fan-controller succeeded, release the gpio
+forcing full-speed to allow quiet operation.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi | 22 ---------
+ board/solidrun/lx2160acex7/lx2160a.c | 55 ++++++++++++++++++++++-
+ 2 files changed, 54 insertions(+), 23 deletions(-)
+
+diff --git a/arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi b/arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi
+index 9394c36d70e..0e547229d74 100644
+--- a/arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi
++++ b/arch/arm/dts/fsl-lx2160a-cex7-u-boot.dtsi
+@@ -9,28 +9,6 @@
+ };
+ };
+
+-&gpio2 {
+- /*
+- * AMC6821 THERM signal uses open-drain logic and can be driven
+- * by either the host (force full-speed) or the chip
+- * (thermal warning). Firmware drives it low during reset.
+- *
+- * Force fan full-speed while bootloader is active.
+- * TODO: Add fan-controller driver.
+- */
+- fan-full-speed-hog {
+- gpio-hog;
+- gpios = <2 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+- output-high;
+- line-name = "fan-full-speed";
+- };
+-};
+-
+-&{/i2c@2000000/i2c-mux@77/i2c@1/fan-temperature-ctrlr@18} {
+- /*u-boot does not currently have a driver for this fan-controller */
+- status = "disabled";
+-};
+-
+ &uart0 {
+ status = "okay";
+ };
+diff --git a/board/solidrun/lx2160acex7/lx2160a.c b/board/solidrun/lx2160acex7/lx2160a.c
+index 632fbff52dc..f6b3856b8dc 100644
+--- a/board/solidrun/lx2160acex7/lx2160a.c
++++ b/board/solidrun/lx2160acex7/lx2160a.c
+@@ -18,6 +18,7 @@
+ #include <fsl_ddr.h>
+ #include <init.h>
+ #include <malloc.h>
++#include <i2c.h>
+
+ DECLARE_GLOBAL_DATA_PTR;
+
+@@ -151,8 +152,60 @@ int board_init(void)
+ }
+
+ #ifdef CONFIG_BOARD_LATE_INIT
++static int setup_fan_ctrl(void) {
++ int ret = -ENODEV;
++ struct udevice *bus, *dev;
++
++ struct {
++ const char *const machine;
++ const char *const bus;
++ uint8_t addr;
++ u32 __iomem *const gpio_reg;
++ uint32_t gpio_mask;
++ } fanctrl[] = {
++ {
++ .machine = "solidrun,lx2160a-cex7",
++ .bus = "i2c@2000000->i2c-mux@77->i2c@1",
++ .addr = 0x18,
++ .gpio_reg = (void *)0x02320000,
++ .gpio_mask = (1 << 29),
++ }, {
++ .machine = "solidrun,lx2162a-som",
++ .bus = "i2c@2000000",
++ .addr = 0x18,
++ },
++ };
++
++ for (int i = 0; i < ARRAY_SIZE(fanctrl); i++) {
++ if (!of_machine_is_compatible(fanctrl[i].machine))
++ continue;
++
++ ret = uclass_get_device_by_name(UCLASS_I2C, fanctrl[i].bus, &bus);
++ if (ret)
++ continue;
++
++ ret = i2c_get_chip(bus, fanctrl[i].addr, 1, &dev);
++ if (ret)
++ continue;
++
++ /* set low temperatur threshold 64C, slope 1.57%/C, full-speed at 101C (safe for LX2160/LX2162 SoC) */
++ ret = dm_i2c_reg_write(dev, 0x25, 0x83);
++ if (ret)
++ continue;
++
++ /* change gpio direction from output to input for low->high transition with external PU */
++ if (fanctrl[i].gpio_reg)
++ *fanctrl[i].gpio_reg &= ~fanctrl[i].gpio_mask;
++
++ printf("Fan: Low 64°C, High 101°C, Slope 1.57%%\n");
++ }
++
++ return ret;
++}
++
+ int fsl_board_late_init(void) {
+- /* TODO: configure fan-controller here and release gpio-hog */
++ setup_fan_ctrl();
++
+ return 0;
+ }
+ #endif
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,48 @@
+From 86632dc5b14530a088c87e0513caae4784d5cd43 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sat, 9 Aug 2025 18:54:35 +0200
+Subject: [PATCH 16/17] board: solidrun: lx2160cex7: fix read rcw from dcsr
+ memory
+
+LX2160 can override RCW configuration at runtime in the DCSR memory at
+0x700100100 and following while the original values in the DCFG memory
+at 0x01e00100 are read-only.
+
+The DCSR area however must be initialised by a write before
+reading from it, otherwise zero is read.
+
+This causes several subtle bugs, e.g. introduced by mainline kernel
+since 6.12 changing pinmux of i2c does accidentally also change sdhc
+card-detect pinmux causing software to detect sdcard removal during
+boot.
+
+Copy the RCW from DCFG to DCSR during board_early_init_f to ensure
+successive reads from the reconfiguration area are valid.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ board/solidrun/lx2160acex7/lx2160a.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/board/solidrun/lx2160acex7/lx2160a.c b/board/solidrun/lx2160acex7/lx2160a.c
+index f6b3856b8dc..76302e8e568 100644
+--- a/board/solidrun/lx2160acex7/lx2160a.c
++++ b/board/solidrun/lx2160acex7/lx2160a.c
+@@ -25,6 +25,14 @@ DECLARE_GLOBAL_DATA_PTR;
+ int board_early_init_f(void)
+ {
+ fsl_lsch3_early_init_f();
++
++ /*
++ * RCW DCSR area for runtime re-configuration must be written
++ * before read to avoid reading (invalid) zeros.
++ * copy RCW values from read-only DCFG to read-write DCSR.
++ */
++ memcpy((void *)0x700100100, (void *)0x01e00100, 0x180);
++
+ return 0;
+ }
+
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,56 @@
+From ef94c50ce8f609ab319aef9a15195ef25bc57602 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sun, 10 Aug 2025 12:27:10 +0200
+Subject: [PATCH] lib: optee: always copy optee to OS DTB regardless if already
+ present
+
+OS DTB can't know whether optee is present or not, regardless if it has
+been put there previously.
+
+Always patch OS DTB.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ lib/optee/optee.c | 19 ++++++-------------
+ 1 file changed, 6 insertions(+), 13 deletions(-)
+
+diff --git a/lib/optee/optee.c b/lib/optee/optee.c
+index 393f2715a9c..53a08370b73 100644
+--- a/lib/optee/optee.c
++++ b/lib/optee/optee.c
+@@ -80,9 +80,12 @@ static int optee_copy_firmware_node(ofnode node, void *fdt_blob)
+ return offs;
+ }
+
+- offs = fdt_add_subnode(fdt_blob, offs, "optee");
+- if (offs < 0)
+- return offs;
++ offs = fdt_path_offset(fdt_blob, "/firmware/optee");
++ if (offs < 0) {
++ offs = fdt_add_subnode(fdt_blob, offs, "optee");
++ if (offs < 0)
++ return offs;
++ }
+
+ /* copy the compatible property */
+ prop = ofnode_get_property(node, "compatible", &len);
+@@ -125,16 +128,6 @@ int optee_copy_fdt_nodes(void *new_blob)
+ return 0;
+ }
+
+- /*
+- * Do not proceed if the target dt already has an OP-TEE node.
+- * In this case assume that the system knows better somehow,
+- * so do not interfere.
+- */
+- if (fdt_path_offset(new_blob, "/firmware/optee") >= 0) {
+- debug("OP-TEE Device Tree node already exists in target");
+- return 0;
+- }
+-
+ ret = optee_copy_firmware_node(node, new_blob);
+ if (ret < 0) {
+ printf("Failed to add OP-TEE firmware node\n");
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,30 @@
+From 01418030bef11425c956caaff185e08e34ce4553 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sun, 10 Aug 2025 15:56:54 +0200
+Subject: [PATCH] board: solidrun: lx2160cex7: fix xspi flash compatible string
+
+The SPI nor flash on LX2160A CEX-7 is not an m25p80 but MT35.
+Fi the device-tree compatible string to use jedec ids and automatic
+identification.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ arch/arm/dts/fsl-lx2160a-cex7.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/dts/fsl-lx2160a-cex7.dtsi b/arch/arm/dts/fsl-lx2160a-cex7.dtsi
+index e4b72707081..fa5bae4d796 100644
+--- a/arch/arm/dts/fsl-lx2160a-cex7.dtsi
++++ b/arch/arm/dts/fsl-lx2160a-cex7.dtsi
+@@ -165,7 +165,7 @@
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+- compatible = "micron,m25p80";
++ compatible = "jedec,spi-nor";
+ m25p,fast-read;
+ spi-max-frequency = <50000000>;
+ reg = <0>;
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,124 @@
+From 54e0af56a7f7b87fd1da202a296d10e7037bc000 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Sun, 24 Aug 2025 16:31:56 +0200
+Subject: [PATCH] board: solidrun: lx2160acex7: fix serdes lane dpmac swap
+
+SerDes lane numbering and protocol converter register bitfield names are
+inconsistent on LX2160 for SerDes #1.
+
+E.g. 10G Protocol converter Port C is SD1 lane F (number 2) dpmac 5.
+
+Swap the dpmacs in lookup tables so that correct speed and status are
+configured during board_fix_fdt.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ board/solidrun/lx2160acex7/serdes.c | 32 ++++++++++++++---------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/board/solidrun/lx2160acex7/serdes.c b/board/solidrun/lx2160acex7/serdes.c
+index c6b6d9bbfdc..c62a54d1681 100644
+--- a/board/solidrun/lx2160acex7/serdes.c
++++ b/board/solidrun/lx2160acex7/serdes.c
+@@ -150,82 +150,82 @@ static void board_fix_fdt_macs(void *fdt) {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIA_CFG,
+ .mode = "sgmii",
+- .mac = DPMAC3,
++ .mac = DPMAC10,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIB_CFG,
+ .mode = "sgmii",
+- .mac = DPMAC4,
++ .mac = DPMAC9,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIC_CFG,
+ .mode = "sgmii",
+- .mac = DPMAC5,
++ .mac = DPMAC8,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+ .pcr_ena_mask = LYNX_28G_PCC8_SGMIID_CFG,
+ .mode = "sgmii",
+- .mac = DPMAC6,
++ .mac = DPMAC7,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIE_CFG,
+ .mode = "sgmii",
+- .mac = DPMAC7,
++ .mac = DPMAC6,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIF_CFG,
+ .mode = "sgmii",
+- .mac = DPMAC8,
++ .mac = DPMAC5,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIG_CFG,
+ .mode = "sgmii",
+- .mac = DPMAC9,
++ .mac = DPMAC4,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIH_CFG,
+ .mode = "sgmii",
+- .mac = DPMAC10,
++ .mac = DPMAC3,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIA_CFG,
+ .mode = "xgmii",
+- .mac = DPMAC3,
++ .mac = DPMAC10,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIB_CFG,
+ .mode = "xgmii",
+- .mac = DPMAC4,
++ .mac = DPMAC9,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIC_CFG,
+ .mode = "xgmii",
+- .mac = DPMAC5,
++ .mac = DPMAC8,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIID_CFG,
+ .mode = "xgmii",
+- .mac = DPMAC6,
++ .mac = DPMAC7,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIE_CFG,
+ .mode = "xgmii",
+- .mac = DPMAC7,
++ .mac = DPMAC6,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIF_CFG,
+ .mode = "xgmii",
+- .mac = DPMAC8,
++ .mac = DPMAC5,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG,
+ .mode = "xgmii",
+- .mac = DPMAC9,
++ .mac = DPMAC4,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG,
+ .mode = "xgmii",
+- .mac = DPMAC10,
++ .mac = DPMAC3,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+ .pcr_ena_mask = LYNX_28G_PCCD_E25GA_CFG,
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,31 @@
+From 843be8bb55370449e0b331a84e0b99dc89b4edb4 Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Mon, 25 Aug 2025 12:47:18 +0200
+Subject: [PATCH] lib: optee: fix adding optee subnode if not present
+
+OS DTB may or may not have /firmware/optee node.
+After probing for the node, offs variable was -1 and no longer pointing
+to the /firmware node.
+Re-initialise it before trying to create subnode optee under /firmware.
+
+Fixes: "lib: optee: always copy optee to OS DTB regardless if already present"
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ lib/optee/optee.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/lib/optee/optee.c b/lib/optee/optee.c
+index 53a08370b73..bfdce258a38 100644
+--- a/lib/optee/optee.c
++++ b/lib/optee/optee.c
+@@ -82,6 +82,7 @@ static int optee_copy_firmware_node(ofnode node, void *fdt_blob)
+
+ offs = fdt_path_offset(fdt_blob, "/firmware/optee");
+ if (offs < 0) {
++ offs = fdt_path_offset(fdt_blob, "/firmware");
+ offs = fdt_add_subnode(fdt_blob, offs, "optee");
+ if (offs < 0)
+ return offs;
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,66 @@
+From 730de8472646472408611b394e94f797252ab27d Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Tue, 12 Aug 2025 14:55:25 +0200
+Subject: [PATCH 23/23] board: solidrun: disable some unused config options
+
+---
+ configs/lx2160acex7_tfa_defconfig | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/configs/lx2160acex7_tfa_defconfig b/configs/lx2160acex7_tfa_defconfig
+index 64432d9f76b..461abb76af2 100644
+--- a/configs/lx2160acex7_tfa_defconfig
++++ b/configs/lx2160acex7_tfa_defconfig
+@@ -33,13 +33,9 @@ CONFIG_BOOTARGS="console=ttyAMA0,115200 root=/dev/ram0 earlycon=pl011,mmio32,0x2
+ CONFIG_DEFAULT_FDT_FILE="boot/fsl-lx2160a-clearfog-cx.dtb"
+ CONFIG_SYS_PBSIZE=532
+ CONFIG_CMD_TLV_EEPROM=y
+-CONFIG_CMD_GREPENV=y
+-CONFIG_CMD_EEPROM=y
+-CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=3
+ CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=5
+ CONFIG_CMD_DM=y
+ CONFIG_CMD_GPIO=y
+-CONFIG_CMD_GPT=y
+ CONFIG_CMD_I2C=y
+ CONFIG_CMD_MMC=y
+ CONFIG_CMD_OPTEE_RPMB=y
+@@ -47,7 +43,6 @@ CONFIG_CMD_PCI=y
+ CONFIG_CMD_POWEROFF=y
+ CONFIG_CMD_USB=y
+ CONFIG_CMD_WDT=y
+-CONFIG_CMD_CACHE=y
+ CONFIG_OF_CONTROL=y
+ CONFIG_ENV_OVERWRITE=y
+ CONFIG_ENV_IS_IN_MMC=y
+@@ -72,13 +67,11 @@ CONFIG_I2C_EEPROM=y
+ CONFIG_SYS_I2C_EEPROM_ADDR=0x57
+ CONFIG_SUPPORT_EMMC_RPMB=y
+ CONFIG_SUPPORT_EMMC_BOOT=y
+-CONFIG_MMC_HS400_SUPPORT=y
+ CONFIG_FSL_ESDHC=y
+ CONFIG_MTD=y
+ CONFIG_DM_SPI_FLASH=y
+ CONFIG_SPI_FLASH_STMICRO=y
+ CONFIG_SPI_FLASH_MT35XU=y
+-CONFIG_SPI_FLASH_WINBOND=y
+ # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+ CONFIG_PHYLIB=y
+ CONFIG_PHY_AQUANTIA=y
+@@ -87,7 +80,6 @@ CONFIG_PHY_MARVELL_10G=y
+ CONFIG_FSL_MEMAC=y
+ CONFIG_SYS_MEMAC_LITTLE_ENDIAN=y
+ CONFIG_DM_ETH_PHY=y
+-CONFIG_E1000=y
+ CONFIG_MII=y
+ CONFIG_NVME_PCI=y
+ CONFIG_PCIE_LAYERSCAPE_RC=y
+@@ -108,4 +100,5 @@ CONFIG_USB_XHCI_DWC3=y
+ CONFIG_USB_MAX_CONTROLLER_COUNT=2
+ CONFIG_WDT=y
+ CONFIG_WDT_SBSA=y
++# CONFIG_FAT_WRITE is not set
+ CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,703 @@
+From a5f43e23c745093b58b2df1dce0cad0580fba6fc Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Wed, 27 Aug 2025 12:31:04 +0200
+Subject: [PATCH 24/25] board: solidrun: lx2160acex7: fix various mistakes in
+ serdes #2 regs
+
+1. The protocol converter register bitfield names and dpmac numbers are
+ inconsistent on LX2160 SerDes #2.
+
+ In particular on SerDes #2:
+ - 1G protocol converter port A is lane A (number 0) dpmac 11
+ - 1G protocol converter port E is lane E (number 4) dpmac 15
+ - 10G protocol converter port G is lane G (number 6) dpmac 13
+ - 10G protocol converter port H is lane H (number 7) dpmac 14
+
+ Reorder the dpmacs in lookup tables so that correct speed and status
+ are configured during board_fix_fdt.
+
+2. SerDes #2 only supports 10G speeds on lanes G/H dpmac 13/14, and
+ does not support 25G speeds at all.
+
+ Remove code handling these configurations.
+
+3. Match the protocol converter configuration registers by value instead
+ of not-equal-zero so that configurations such as usxgmii/xfi can be
+ matched accurately.
+
+4. Add USXXGMII configurations. For now usxgmii is only enabled through
+ DPL, when starting Linux, hence for u-boot itself this changes
+ nothing.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ board/solidrun/lx2160acex7/serdes.c | 417 +++++++++++++++++-----------
+ 1 file changed, 253 insertions(+), 164 deletions(-)
+
+diff --git a/board/solidrun/lx2160acex7/serdes.c b/board/solidrun/lx2160acex7/serdes.c
+index c62a54d1681..8e19a471b04 100644
+--- a/board/solidrun/lx2160acex7/serdes.c
++++ b/board/solidrun/lx2160acex7/serdes.c
+@@ -6,62 +6,109 @@
+
+ #include <fdt_support.h>
+
++/* Devoce Configuration Register base address */
++#define DCFG_CCSR_BASE (void *)0x01E00000
++
+ /* SerDes base address */
+-#define LYNX_28G_SDn_BASE(block) ((void *)0x01EA0000 + (block) * 0x10000)
++#define LYNX_28G_SDn_BASE(block) (DCFG_CCSR_BASE + 0x000A0000 + (block) * 0x10000)
+
+ /* Protocol Configuration Register 0 */
+ #define LYNX_28G_PCC0 0x1080
+-#define LYNX_28G_PCC0_PEXA_CFG GENMASK(30, 28)
+-#define LYNX_28G_PCC0_PEXB_CFG GENMASK(26, 24)
++#define LYNX_28G_PCC0_PEXA_CFG_MASK GENMASK(30, 28)
++#define LYNX_28G_PCC0_PEXA_CFG(val) ((val << 28) & LYNX_28G_PCC0_PEXA_CFG_MASK)
++#define LYNX_28G_PCC0_PEXB_CFG_MASK GENMASK(26, 24)
++#define LYNX_28G_PCC0_PEXB_CFG(val) ((val << 24) & LYNX_28G_PCC0_PEXB_CFG_MASK)
+
+ /* Protocol Configuration Register 2 */
+ #define LYNX_28G_PCC2 0x1088
+-#define LYNX_28G_PCC2_SATAA_CFG GENMASK(30, 28)
+-#define LYNX_28G_PCC2_SATAB_CFG GENMASK(26, 24)
+-#define LYNX_28G_PCC2_SATAC_CFG GENMASK(22, 20)
+-#define LYNX_28G_PCC2_SATAD_CFG GENMASK(18, 16)
++#define LYNX_28G_PCC2_SATAA_CFG_MASK GENMASK(30, 28)
++#define LYNX_28G_PCC2_SATAA_CFG(val) ((val << 28) & LYNX_28G_PCC2_SATAA_CFG_MASK)
++#define LYNX_28G_PCC2_SATAB_CFG_MASK GENMASK(26, 24)
++#define LYNX_28G_PCC2_SATAB_CFG(val) ((val << 24) & LYNX_28G_PCC2_SATAB_CFG_MASK)
++#define LYNX_28G_PCC2_SATAC_CFG_MASK GENMASK(22, 20)
++#define LYNX_28G_PCC2_SATAC_CFG(val) ((val << 20) & LYNX_28G_PCC2_SATAC_CFG_MASK)
++#define LYNX_28G_PCC2_SATAD_CFG_MASK GENMASK(18, 16)
++#define LYNX_28G_PCC2_SATAD_CFG(val) ((val << 16) & LYNX_28G_PCC2_SATAD_CFG_MASK)
+
+ /* Protocol Configuration Register 8 */
+ #define LYNX_28G_PCC8 0x10A0
+-#define LYNX_28G_PCC8_SGMIIA_CFG GENMASK(30, 28)
+-#define LYNX_28G_PCC8_SGMIIB_CFG GENMASK(26, 24)
+-#define LYNX_28G_PCC8_SGMIIC_CFG GENMASK(22, 20)
+-#define LYNX_28G_PCC8_SGMIID_CFG GENMASK(18, 16)
+-#define LYNX_28G_PCC8_SGMIIE_CFG GENMASK(14, 12)
+-#define LYNX_28G_PCC8_SGMIIF_CFG GENMASK(10, 8)
+-#define LYNX_28G_PCC8_SGMIIG_CFG GENMASK(6, 4)
+-#define LYNX_28G_PCC8_SGMIIH_CFG GENMASK(2, 0)
++#define LYNX_28G_PCC8_SGMIIA_CFG_MASK GENMASK(30, 28)
++#define LYNX_28G_PCC8_SGMIIA_CFG(val) ((val << 28) & LYNX_28G_PCC8_SGMIIA_CFG_MASK)
++#define LYNX_28G_PCC8_SGMIIB_CFG_MASK GENMASK(26, 24)
++#define LYNX_28G_PCC8_SGMIIB_CFG(val) ((val << 24) & LYNX_28G_PCC8_SGMIIB_CFG_MASK)
++#define LYNX_28G_PCC8_SGMIIC_CFG_MASK GENMASK(22, 20)
++#define LYNX_28G_PCC8_SGMIIC_CFG(val) ((val << 20) & LYNX_28G_PCC8_SGMIIC_CFG_MASK)
++#define LYNX_28G_PCC8_SGMIID_CFG_MASK GENMASK(18, 16)
++#define LYNX_28G_PCC8_SGMIID_CFG(val) ((val << 16) & LYNX_28G_PCC8_SGMIID_CFG_MASK)
++#define LYNX_28G_PCC8_SGMIIE_CFG_MASK GENMASK(14, 12)
++#define LYNX_28G_PCC8_SGMIIE_CFG(val) ((val << 12) & LYNX_28G_PCC8_SGMIIE_CFG_MASK)
++#define LYNX_28G_PCC8_SGMIIF_CFG_MASK GENMASK(10, 8)
++#define LYNX_28G_PCC8_SGMIIF_CFG(val) ((val << 8) & LYNX_28G_PCC8_SGMIIF_CFG_MASK)
++#define LYNX_28G_PCC8_SGMIIG_CFG_MASK GENMASK(6, 4)
++#define LYNX_28G_PCC8_SGMIIG_CFG(val) ((val << 4) & LYNX_28G_PCC8_SGMIIG_CFG_MASK)
++#define LYNX_28G_PCC8_SGMIIH_CFG_MASK GENMASK(2, 0)
++#define LYNX_28G_PCC8_SGMIIH_CFG(val) ((val << 0) & LYNX_28G_PCC8_SGMIIH_CFG_MASK)
+
+ /* Protocol Configuration Register C */
+ #define LYNX_28G_PCCC 0x10B0
+-#define LYNX_28G_PCCC_SXGMIIA_CFG GENMASK(30, 28)
+-#define LYNX_28G_PCCC_SXGMIIB_CFG GENMASK(26, 24)
+-#define LYNX_28G_PCCC_SXGMIIC_CFG GENMASK(22, 20)
+-#define LYNX_28G_PCCC_SXGMIID_CFG GENMASK(18, 16)
+-#define LYNX_28G_PCCC_SXGMIIE_CFG GENMASK(14, 12)
+-#define LYNX_28G_PCCC_SXGMIIF_CFG GENMASK(10, 8)
+-#define LYNX_28G_PCCC_SXGMIIG_CFG GENMASK(6, 4)
+-#define LYNX_28G_PCCC_SXGMIIH_CFG GENMASK(2, 0)
++#define LYNX_28G_PCCC_SXGMIIA_XFI BIT(31)
++#define LYNX_28G_PCCC_SXGMIIA_CFG_MASK GENMASK(30, 28)
++#define LYNX_28G_PCCC_SXGMIIA_CFG(val) ((val << 28) & LYNX_28G_PCCC_SXGMIIA_CFG_MASK)
++#define LYNX_28G_PCCC_SXGMIIB_XFI BIT(27)
++#define LYNX_28G_PCCC_SXGMIIB_CFG_MASK GENMASK(26, 24)
++#define LYNX_28G_PCCC_SXGMIIB_CFG(val) ((val << 24) & LYNX_28G_PCCC_SXGMIIB_CFG_MASK)
++#define LYNX_28G_PCCC_SXGMIIC_XFI BIT(23)
++#define LYNX_28G_PCCC_SXGMIIC_CFG_MASK GENMASK(22, 20)
++#define LYNX_28G_PCCC_SXGMIIC_CFG(val) ((val << 20) & LYNX_28G_PCCC_SXGMIIC_CFG_MASK)
++#define LYNX_28G_PCCC_SXGMIID_XFI BIT(19)
++#define LYNX_28G_PCCC_SXGMIID_CFG_MASK GENMASK(18, 16)
++#define LYNX_28G_PCCC_SXGMIID_CFG(val) ((val << 16) & LYNX_28G_PCCC_SXGMIID_CFG_MASK)
++#define LYNX_28G_PCCC_SXGMIIE_XFI BIT(15)
++#define LYNX_28G_PCCC_SXGMIIE_CFG_MASK GENMASK(14, 12)
++#define LYNX_28G_PCCC_SXGMIIE_CFG(val) ((val << 12) & LYNX_28G_PCCC_SXGMIIE_CFG_MASK)
++#define LYNX_28G_PCCC_SXGMIIF_XFI BIT(11)
++#define LYNX_28G_PCCC_SXGMIIF_CFG_MASK GENMASK(10, 8)
++#define LYNX_28G_PCCC_SXGMIIF_CFG(val) ((val << 8) & LYNX_28G_PCCC_SXGMIIF_CFG_MASK)
++#define LYNX_28G_PCCC_SXGMIIG_XFI BIT(7)
++#define LYNX_28G_PCCC_SXGMIIG_CFG_MASK GENMASK(6, 4)
++#define LYNX_28G_PCCC_SXGMIIG_CFG(val) ((val << 4) & LYNX_28G_PCCC_SXGMIIG_CFG_MASK)
++#define LYNX_28G_PCCC_SXGMIIH_XFI BIT(3)
++#define LYNX_28G_PCCC_SXGMIIH_CFG_MASK GENMASK(2, 0)
++#define LYNX_28G_PCCC_SXGMIIH_CFG(val) ((val << 0) & LYNX_28G_PCCC_SXGMIIH_CFG_MASK)
+
+ /* Protocol Configuration Register D */
+ #define LYNX_28G_PCCD 0x10B4
+-#define LYNX_28G_PCCD_E25GA_CFG GENMASK(30, 28)
+-#define LYNX_28G_PCCD_E25GB_CFG GENMASK(26, 24)
+-#define LYNX_28G_PCCD_E25GC_CFG GENMASK(22, 20)
+-#define LYNX_28G_PCCD_E25GD_CFG GENMASK(18, 16)
+-#define LYNX_28G_PCCD_E25GE_CFG GENMASK(14, 12)
+-#define LYNX_28G_PCCD_E25GF_CFG GENMASK(10, 8)
+-#define LYNX_28G_PCCD_E25GG_CFG GENMASK(6, 4)
+-#define LYNX_28G_PCCD_E25GH_CFG GENMASK(2, 0)
++#define LYNX_28G_PCCD_E25GA_CFG_MASK GENMASK(30, 28)
++#define LYNX_28G_PCCD_E25GA_CFG(val) ((val << 28) & LYNX_28G_PCCD_E25GA_CFG_MASK)
++#define LYNX_28G_PCCD_E25GB_CFG_MASK GENMASK(26, 24)
++#define LYNX_28G_PCCD_E25GB_CFG(val) ((val << 24) & LYNX_28G_PCCD_E25GB_CFG_MASK)
++#define LYNX_28G_PCCD_E25GC_CFG_MASK GENMASK(22, 20)
++#define LYNX_28G_PCCD_E25GC_CFG(val) ((val << 20) & LYNX_28G_PCCD_E25GC_CFG_MASK)
++#define LYNX_28G_PCCD_E25GD_CFG_MASK GENMASK(18, 16)
++#define LYNX_28G_PCCD_E25GD_CFG(val) ((val << 16) & LYNX_28G_PCCD_E25GD_CFG_MASK)
++#define LYNX_28G_PCCD_E25GE_CFG_MASK GENMASK(14, 12)
++#define LYNX_28G_PCCD_E25GE_CFG(val) ((val << 12) & LYNX_28G_PCCD_E25GE_CFG_MASK)
++#define LYNX_28G_PCCD_E25GF_CFG_MASK GENMASK(10, 8)
++#define LYNX_28G_PCCD_E25GF_CFG(val) ((val << 8) & LYNX_28G_PCCD_E25GF_CFG_MASK)
++#define LYNX_28G_PCCD_E25GG_CFG_MASK GENMASK(6, 4)
++#define LYNX_28G_PCCD_E25GG_CFG(val) ((val << 4) & LYNX_28G_PCCD_E25GG_CFG_MASK)
++#define LYNX_28G_PCCD_E25GH_CFG_MASK GENMASK(2, 0)
++#define LYNX_28G_PCCD_E25GH_CFG(val) ((val << 0) & LYNX_28G_PCCD_E25GH_CFG_MASK)
+
+ /* Protocol Configuration Register E */
+ #define LYNX_28G_PCCE 0x10B8
+-#define LYNX_28G_PCCE_E40GA_CFG GENMASK(30, 28)
+-#define LYNX_28G_PCCE_E40GB_CFG GENMASK(26, 24)
+-#define LYNX_28G_PCCE_E50GA_CFG GENMASK(22, 20)
+-#define LYNX_28G_PCCE_E50GB_CFG GENMASK(18, 16)
+-#define LYNX_28G_PCCE_E100GA_CFG GENMASK(14, 12)
+-#define LYNX_28G_PCCE_E100GB_CFG GENMASK(10, 8)
++#define LYNX_28G_PCCE_E40GA_CFG_MASK GENMASK(30, 28)
++#define LYNX_28G_PCCE_E40GA_CFG(val) ((val << 28) & LYNX_28G_PCCE_E40GA_CFG_MASK)
++#define LYNX_28G_PCCE_E40GB_CFG_MASK GENMASK(26, 24)
++#define LYNX_28G_PCCE_E40GB_CFG(val) ((val << 24) & LYNX_28G_PCCE_E40GB_CFG_MASK)
++#define LYNX_28G_PCCE_E50GA_CFG_MASK GENMASK(22, 20)
++#define LYNX_28G_PCCE_E50GA_CFG(val) ((val << 20) & LYNX_28G_PCCE_E50GA_CFG_MASK)
++#define LYNX_28G_PCCE_E50GB_CFG_MASK GENMASK(18, 16)
++#define LYNX_28G_PCCE_E50GB_CFG(val) ((val << 16) & LYNX_28G_PCCE_E50GB_CFG_MASK)
++#define LYNX_28G_PCCE_E100GA_CFG_MASK GENMASK(14, 12)
++#define LYNX_28G_PCCE_E100GA_CFG(val) ((val << 12) & LYNX_28G_PCCE_E100GA_CFG_MASK)
++#define LYNX_28G_PCCE_E100GB_CFG_MASK GENMASK(10, 8)
++#define LYNX_28G_PCCE_E100GB_CFG(val) ((val << 8) & LYNX_28G_PCCE_E100GB_CFG_MASK)
+
+ /* Lane a General Control Register */
+ #define LYNX_28G_LNaGCR0(lane) (0x800 + (lane) * 0x100 + 0x0)
+@@ -141,286 +188,317 @@ static void board_fix_fdt_macs(void *fdt) {
+ };
+
+ struct {
+- const u32 __iomem *pcr;
++ const u32 __iomem *const pcr;
+ const u32 pcr_ena_mask;
++ const u32 pcr_ena_val;
+ const char *const mode;
+ const unsigned int mac;
+ } ports[] = {
+ {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIA_CFG(1),
+ .mode = "sgmii",
+ .mac = DPMAC10,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIB_CFG(1),
+ .mode = "sgmii",
+ .mac = DPMAC9,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIC_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIC_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIC_CFG(1),
+ .mode = "sgmii",
+ .mac = DPMAC8,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIID_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIID_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIID_CFG(1),
+ .mode = "sgmii",
+ .mac = DPMAC7,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIE_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIE_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIE_CFG(1),
+ .mode = "sgmii",
+ .mac = DPMAC6,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIF_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIF_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIF_CFG(1),
+ .mode = "sgmii",
+ .mac = DPMAC5,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIG_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIG_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIG_CFG(1),
+ .mode = "sgmii",
+ .mac = DPMAC4,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIH_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIH_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIH_CFG(1),
+ .mode = "sgmii",
+ .mac = DPMAC3,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIA_CFG_MASK | LYNX_28G_PCCC_SXGMIIA_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIA_CFG(1) | LYNX_28G_PCCC_SXGMIIA_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC10,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIB_CFG_MASK | LYNX_28G_PCCC_SXGMIIB_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIB_CFG(1) | LYNX_28G_PCCC_SXGMIIB_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC9,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIC_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIC_CFG_MASK | LYNX_28G_PCCC_SXGMIIC_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIC_CFG(1) | LYNX_28G_PCCC_SXGMIIC_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC8,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIID_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIID_CFG_MASK | LYNX_28G_PCCC_SXGMIID_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIID_CFG(1) | LYNX_28G_PCCC_SXGMIID_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC7,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIE_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIE_CFG_MASK | LYNX_28G_PCCC_SXGMIIE_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIE_CFG(1) | LYNX_28G_PCCC_SXGMIIE_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC6,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIF_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIF_CFG_MASK | LYNX_28G_PCCC_SXGMIIF_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIF_CFG(1) | LYNX_28G_PCCC_SXGMIIF_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC5,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG_MASK | LYNX_28G_PCCC_SXGMIIG_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIG_CFG(1) | LYNX_28G_PCCC_SXGMIIG_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC4,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG_MASK | LYNX_28G_PCCC_SXGMIIH_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIH_CFG(1) | LYNX_28G_PCCC_SXGMIIH_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC3,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIA_CFG_MASK | LYNX_28G_PCCC_SXGMIIA_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIA_CFG(1),
++ .mode = "usxgmii",
++ .mac = DPMAC10,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIB_CFG_MASK | LYNX_28G_PCCC_SXGMIIB_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIB_CFG(1),
++ .mode = "usxgmii",
++ .mac = DPMAC9,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIC_CFG_MASK | LYNX_28G_PCCC_SXGMIIC_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIC_CFG(1),
++ .mode = "usxgmii",
++ .mac = DPMAC8,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIID_CFG_MASK | LYNX_28G_PCCC_SXGMIID_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIID_CFG(1),
++ .mode = "usxgmii",
++ .mac = DPMAC7,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIE_CFG_MASK | LYNX_28G_PCCC_SXGMIIE_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIE_CFG(1),
++ .mode = "usxgmii",
++ .mac = DPMAC6,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIF_CFG_MASK | LYNX_28G_PCCC_SXGMIIF_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIF_CFG(1),
++ .mode = "usxgmii",
++ .mac = DPMAC5,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG_MASK | LYNX_28G_PCCC_SXGMIIG_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIG_CFG(1),
++ .mode = "usxgmii",
++ .mac = DPMAC4,
++ }, {
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG_MASK | LYNX_28G_PCCC_SXGMIIH_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIH_CFG(1),
++ .mode = "usxgmii",
++ .mac = DPMAC3,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCD_E25GA_CFG(1),
+ .mode = "25g-aui",
+ .mac = DPMAC3,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCD_E25GB_CFG(1),
+ .mode = "25g-aui",
+ .mac = DPMAC4,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GC_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GC_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCD_E25GC_CFG(1),
+ .mode = "25g-aui",
+ .mac = DPMAC5,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GD_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GD_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCD_E25GD_CFG(1),
+ .mode = "25g-aui",
+ .mac = DPMAC6,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GE_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GE_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCD_E25GE_CFG(1),
+ .mode = "25g-aui",
+ .mac = DPMAC7,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GF_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GF_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCD_E25GF_CFG(1),
+ .mode = "25g-aui",
+ .mac = DPMAC8,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GG_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GG_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCD_E25GG_CFG(1),
+ .mode = "25g-aui",
+ .mac = DPMAC9,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GH_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCD_E25GH_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCD_E25GH_CFG(1),
+ .mode = "25g-aui",
+ .mac = DPMAC10,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
+- .pcr_ena_mask = LYNX_28G_PCCE_E40GA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCE_E40GA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCE_E40GA_CFG(1),
+ .mode = "xlaui4",
+ .mac = DPMAC1,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
+- .pcr_ena_mask = LYNX_28G_PCCE_E40GB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCE_E40GB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCE_E40GB_CFG(1),
+ .mode = "xlaui4",
+ .mac = DPMAC2,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
+- .pcr_ena_mask = LYNX_28G_PCCE_E50GA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCE_E50GA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCE_E50GA_CFG(1),
+ .mode = "caui2",
+ .mac = DPMAC1,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
+- .pcr_ena_mask = LYNX_28G_PCCE_E50GB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCE_E50GB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCE_E50GB_CFG(1),
+ .mode = "caui2",
+ .mac = DPMAC2,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
+- .pcr_ena_mask = LYNX_28G_PCCE_E100GA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCE_E100GA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCE_E100GA_CFG(1),
+ .mode = "caui4",
+ .mac = DPMAC1,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
+- .pcr_ena_mask = LYNX_28G_PCCE_E100GB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCE_E100GB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCCE_E100GB_CFG(1),
+ .mode = "caui4",
+ .mac = DPMAC2,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIA_CFG(1),
+ .mode = "sgmii",
+- .mac = DPMAC18,
++ .mac = DPMAC11,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIB_CFG(1),
+ .mode = "sgmii",
+- .mac = DPMAC17,
++ .mac = DPMAC12,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIC_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIC_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIC_CFG(1),
+ .mode = "sgmii",
+- .mac = DPMAC16,
++ .mac = DPMAC17,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIID_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIID_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIID_CFG(1),
+ .mode = "sgmii",
+- .mac = DPMAC15,
++ .mac = DPMAC18,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIE_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIE_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIE_CFG(1),
+ .mode = "sgmii",
+- .mac = DPMAC14,
++ .mac = DPMAC15,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIF_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIF_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIF_CFG(1),
+ .mode = "sgmii",
+- .mac = DPMAC13,
++ .mac = DPMAC16,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIG_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIG_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIG_CFG(1),
+ .mode = "sgmii",
+- .mac = DPMAC12,
++ .mac = DPMAC13,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
+- .pcr_ena_mask = LYNX_28G_PCC8_SGMIIH_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC8_SGMIIH_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC8_SGMIIH_CFG(1),
+ .mode = "sgmii",
+- .mac = DPMAC11,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIA_CFG,
+- .mode = "xgmii",
+- .mac = DPMAC18,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIB_CFG,
+- .mode = "xgmii",
+- .mac = DPMAC17,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIC_CFG,
+- .mode = "xgmii",
+- .mac = DPMAC16,
++ .mac = DPMAC14,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIID_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG_MASK | LYNX_28G_PCCC_SXGMIIG_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIG_CFG(1) | LYNX_28G_PCCC_SXGMIIG_XFI,
+ .mode = "xgmii",
+- .mac = DPMAC15,
++ .mac = DPMAC13,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIE_CFG,
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG_MASK | LYNX_28G_PCCC_SXGMIIH_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIH_CFG(1) | LYNX_28G_PCCC_SXGMIIH_XFI,
+ .mode = "xgmii",
+ .mac = DPMAC14,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIF_CFG,
+- .mode = "xgmii",
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG_MASK | LYNX_28G_PCCC_SXGMIIG_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIG_CFG(1),
++ .mode = "usxgmii",
+ .mac = DPMAC13,
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIG_CFG,
+- .mode = "xgmii",
+- .mac = DPMAC12,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
+- .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG,
+- .mode = "xgmii",
+- .mac = DPMAC11,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GA_CFG,
+- .mode = "25g-aui",
+- .mac = DPMAC18,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GB_CFG,
+- .mode = "25g-aui",
+- .mac = DPMAC17,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GC_CFG,
+- .mode = "25g-aui",
+- .mac = DPMAC16,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GD_CFG,
+- .mode = "25g-aui",
+- .mac = DPMAC15,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GE_CFG,
+- .mode = "25g-aui",
++ .pcr_ena_mask = LYNX_28G_PCCC_SXGMIIH_CFG_MASK | LYNX_28G_PCCC_SXGMIIH_XFI,
++ .pcr_ena_val = LYNX_28G_PCCC_SXGMIIH_CFG(1),
++ .mode = "usxgmii",
+ .mac = DPMAC14,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GF_CFG,
+- .mode = "25g-aui",
+- .mac = DPMAC13,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GG_CFG,
+- .mode = "25g-aui",
+- .mac = DPMAC12,
+- }, {
+- .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCD,
+- .pcr_ena_mask = LYNX_28G_PCCD_E25GH_CFG,
+- .mode = "25g-aui",
+- .mac = DPMAC11,
+ }
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(ports); i++) {
+- if (*ports[i].pcr & ports[i].pcr_ena_mask) {
++ if ((*ports[i].pcr & ports[i].pcr_ena_mask) == ports[i].pcr_ena_val) {
+ macs[ports[i].mac].status = "okay";
+ macs[ports[i].mac].mode = ports[i].mode;
+ }
+@@ -448,56 +526,67 @@ static void board_fix_fdt_macs(void *fdt) {
+
+ static void board_fix_fdt_pci_sata(void *fdt) {
+ struct {
+- const u32 __iomem *pcr;
++ const u32 __iomem *const pcr;
+ const u32 pcr_ena_mask;
++ const u32 pcr_ena_val;
+ const char *const path;
+ } ports[] = {
+ {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC0,
+- .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC0_PEXA_CFG(1),
+ .path = "/pcie@3400000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC0,
+- .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC0_PEXB_CFG(1),
+ .path = "/pcie@3500000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC0,
+- .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC0_PEXA_CFG(1),
+ .path = "/pcie@3600000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC0,
+- .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC0_PEXB_CFG(1),
+ .path = "/pcie@3700000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(2) + LYNX_28G_PCC0,
+- .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC0_PEXA_CFG(1),
+ .path = "/pcie@3800000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(2) + LYNX_28G_PCC0,
+- .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC0_PEXB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC0_PEXB_CFG(1),
+ .path = "/pcie@3900000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC2,
+- .pcr_ena_mask = LYNX_28G_PCC2_SATAA_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC2_SATAA_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC2_SATAA_CFG(1),
+ .path = "/sata@3200000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC2,
+- .pcr_ena_mask = LYNX_28G_PCC2_SATAB_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC2_SATAB_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC2_SATAB_CFG(1),
+ .path = "/sata@3210000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC2,
+- .pcr_ena_mask = LYNX_28G_PCC2_SATAC_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC2_SATAC_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC2_SATAC_CFG(1),
+ .path = "/sata@3220000",
+ }, {
+ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC2,
+- .pcr_ena_mask = LYNX_28G_PCC2_SATAD_CFG,
++ .pcr_ena_mask = LYNX_28G_PCC2_SATAD_CFG_MASK,
++ .pcr_ena_val = LYNX_28G_PCC2_SATAD_CFG(1),
+ .path = "/sata@3230000",
+ },
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(ports); i++) {
+ const char *status = "disabled";
+- if (*ports[i].pcr & ports[i].pcr_ena_mask)
++ if ((*ports[i].pcr & ports[i].pcr_ena_mask) == ports[i].pcr_ena_val)
+ status = "okay";
+
+ do_fixup_by_path_string(fdt, ports[i].path, "status", status);
+--
+2.43.0
+
new file mode 100644
@@ -0,0 +1,367 @@
+From 7e08716c520590240497c3beedb1a34f0603af3b Mon Sep 17 00:00:00 2001
+From: Josua Mayer <josua@solid-run.com>
+Date: Wed, 27 Aug 2025 17:06:19 +0200
+Subject: [PATCH 25/25] board: solidrun: lx2160acex7: disable disabled ports
+ protocol converters
+
+LX2160A can disable ports through DEVDISR registers, which cuts their
+root clocks. This does not disable the protocol converters connected to
+the MACs.
+
+Evaluate DEVDISR2 register to disable the protocol converters for
+disabled MACs.
+
+Signed-off-by: Josua Mayer <josua@solid-run.com>
+---
+ board/solidrun/lx2160acex7/lx2160a.c | 5 +
+ board/solidrun/lx2160acex7/serdes.c | 304 +++++++++++++++++++++++++++
+ 2 files changed, 309 insertions(+)
+
+diff --git a/board/solidrun/lx2160acex7/lx2160a.c b/board/solidrun/lx2160acex7/lx2160a.c
+index dbfb1dc9d4d..6e12f868759 100644
+--- a/board/solidrun/lx2160acex7/lx2160a.c
++++ b/board/solidrun/lx2160acex7/lx2160a.c
+@@ -22,6 +22,8 @@
+
+ DECLARE_GLOBAL_DATA_PTR;
+
++void board_disable_unused_proto_converters(void);
++
+ int board_early_init_f(void)
+ {
+ fsl_lsch3_early_init_f();
+@@ -33,6 +35,9 @@ int board_early_init_f(void)
+ */
+ memcpy((void *)0x700100100, (void *)0x01e00100, 0x180);
+
++ /* disable unused protocol converters on disabled ports */
++ board_disable_unused_proto_converters();
++
+ return 0;
+ }
+
+diff --git a/board/solidrun/lx2160acex7/serdes.c b/board/solidrun/lx2160acex7/serdes.c
+index 8e19a471b04..b4bc78c5d2c 100644
+--- a/board/solidrun/lx2160acex7/serdes.c
++++ b/board/solidrun/lx2160acex7/serdes.c
+@@ -9,6 +9,40 @@
+ /* Devoce Configuration Register base address */
+ #define DCFG_CCSR_BASE (void *)0x01E00000
+
++/* Device Disable Register 1 */
++#define DCFG_CCSR_DEVDISR1 0x0070
++#define DCFG_CCSR_DEVDISR1_DCE BIT(25)
++#define DCFG_CCSR_DEVDISR1_SEC BIT(22)
++#define DCFG_CCSR_DEVDISR1_SATA4 BIT(19)
++#define DCFG_CCSR_DEVDISR1_SATA3 BIT(18)
++#define DCFG_CCSR_DEVDISR1_SATA2 BIT(17)
++#define DCFG_CCSR_DEVDISR1_SATA1 BIT(16)
++#define DCFG_CCSR_DEVDISR1_USB1 BIT(12)
++#define DCFG_CCSR_DEVDISR1_ESDHC2 BIT(10)
++#define DCFG_CCSR_DEVDISR1_QDMA BIT(8)
++#define DCFG_CCSR_DEVDISR1_ESDHC1 BIT(2)
++
++/* Device Disable Register 2 */
++#define DCFG_CCSR_DEVDISR2 0x0074
++#define DCFG_CCSR_DEVDISR2_MAC18 BIT(17)
++#define DCFG_CCSR_DEVDISR2_MAC17 BIT(16)
++#define DCFG_CCSR_DEVDISR2_MAC16 BIT(15)
++#define DCFG_CCSR_DEVDISR2_MAC15 BIT(14)
++#define DCFG_CCSR_DEVDISR2_MAC14 BIT(13)
++#define DCFG_CCSR_DEVDISR2_MAC13 BIT(12)
++#define DCFG_CCSR_DEVDISR2_MAC12 BIT(11)
++#define DCFG_CCSR_DEVDISR2_MAC11 BIT(10)
++#define DCFG_CCSR_DEVDISR2_MAC10 BIT(9)
++#define DCFG_CCSR_DEVDISR2_MAC9 BIT(8)
++#define DCFG_CCSR_DEVDISR2_MAC8 BIT(7)
++#define DCFG_CCSR_DEVDISR2_MAC7 BIT(6)
++#define DCFG_CCSR_DEVDISR2_MAC6 BIT(5)
++#define DCFG_CCSR_DEVDISR2_MAC5 BIT(4)
++#define DCFG_CCSR_DEVDISR2_MAC4 BIT(3)
++#define DCFG_CCSR_DEVDISR2_MAC3 BIT(2)
++#define DCFG_CCSR_DEVDISR2_MAC2 BIT(1)
++#define DCFG_CCSR_DEVDISR2_MAC1 BIT(0)
++
+ /* SerDes base address */
+ #define LYNX_28G_SDn_BASE(block) (DCFG_CCSR_BASE + 0x000A0000 + (block) * 0x10000)
+
+@@ -158,6 +192,276 @@ enum {
+ DPMAC_MAX
+ };
+
++/* Device Disable Register 1 */
++#define DCFG_CCSR_DEVDISR1 0x0070
++#define DCFG_CCSR_DEVDISR1_DCE BIT(25)
++#define DCFG_CCSR_DEVDISR1_SEC BIT(22)
++#define DCFG_CCSR_DEVDISR1_SATA4 BIT(19)
++#define DCFG_CCSR_DEVDISR1_SATA3 BIT(18)
++#define DCFG_CCSR_DEVDISR1_SATA2 BIT(17)
++#define DCFG_CCSR_DEVDISR1_SATA1 BIT(16)
++#define DCFG_CCSR_DEVDISR1_USB1 BIT(12)
++#define DCFG_CCSR_DEVDISR1_ESDHC2 BIT(10)
++#define DCFG_CCSR_DEVDISR1_QDMA BIT(8)
++#define DCFG_CCSR_DEVDISR1_ESDHC1 BIT(2)
++
++/* Device Disable Register 2 */
++#define DCFG_CCSR_DEVDISR2 0x0074
++#define DCFG_CCSR_DEVDISR2_MAC18 BIT(17)
++#define DCFG_CCSR_DEVDISR2_MAC17 BIT(16)
++#define DCFG_CCSR_DEVDISR2_MAC16 BIT(15)
++#define DCFG_CCSR_DEVDISR2_MAC15 BIT(14)
++#define DCFG_CCSR_DEVDISR2_MAC14 BIT(13)
++#define DCFG_CCSR_DEVDISR2_MAC13 BIT(12)
++#define DCFG_CCSR_DEVDISR2_MAC12 BIT(11)
++#define DCFG_CCSR_DEVDISR2_MAC11 BIT(10)
++#define DCFG_CCSR_DEVDISR2_MAC10 BIT(9)
++#define DCFG_CCSR_DEVDISR2_MAC9 BIT(8)
++#define DCFG_CCSR_DEVDISR2_MAC8 BIT(7)
++#define DCFG_CCSR_DEVDISR2_MAC7 BIT(6)
++#define DCFG_CCSR_DEVDISR2_MAC6 BIT(5)
++#define DCFG_CCSR_DEVDISR2_MAC5 BIT(4)
++#define DCFG_CCSR_DEVDISR2_MAC4 BIT(3)
++#define DCFG_CCSR_DEVDISR2_MAC3 BIT(2)
++#define DCFG_CCSR_DEVDISR2_MAC2 BIT(1)
++#define DCFG_CCSR_DEVDISR2_MAC1 BIT(0)
++
++/*
++ * evaluate DEVDISR registers to understand which interfaces are not
++ * available, and disable their protocol converters.
++ */
++void board_disable_unused_proto_converters(void) {
++ struct {
++ const u32 __iomem *devdisr;
++ const u32 devdisr_bit;
++ u32 __iomem *const pcr;
++ const u32 pcr_dis_mask;
++ const u32 pcr_dis_val;
++ } map[] = {
++ { /* dpmac1: 40G/50G/100G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC1,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
++ .pcr_dis_mask = LYNX_28G_PCCE_E40GA_CFG_MASK | LYNX_28G_PCCE_E50GA_CFG_MASK | LYNX_28G_PCCE_E100GA_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCE_E40GA_CFG(0) | LYNX_28G_PCCE_E50GA_CFG(0) | LYNX_28G_PCCE_E100GA_CFG(0),
++ }, { /* dpmac2: 40G/50G/100G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC2,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCE,
++ .pcr_dis_mask = LYNX_28G_PCCE_E40GB_CFG_MASK | LYNX_28G_PCCE_E50GB_CFG_MASK | LYNX_28G_PCCE_E100GB_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCE_E40GB_CFG(0) | LYNX_28G_PCCE_E50GB_CFG(0) | LYNX_28G_PCCE_E100GB_CFG(0),
++ }, { /* dpmac3: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC3,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIH_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIH_CFG(0),
++ }, { /* dpmac3: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC3,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIH_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIH_CFG(0),
++ }, { /* dpmac3: 25G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC3,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_dis_mask = LYNX_28G_PCCD_E25GA_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCD_E25GA_CFG(0),
++ }, { /* dpmac4: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC4,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIG_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIG_CFG(0),
++ }, { /* dpmac4: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC4,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIG_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIG_CFG(0),
++ }, { /* dpmac4: 25G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC4,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_dis_mask = LYNX_28G_PCCD_E25GB_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCD_E25GB_CFG(0),
++ }, { /* dpmac5: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC5,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIF_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIF_CFG(0),
++ }, { /* dpmac5: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC5,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIF_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIF_CFG(0),
++ }, { /* dpmac5: 25G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC5,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_dis_mask = LYNX_28G_PCCD_E25GC_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCD_E25GC_CFG(0),
++ }, { /* dpmac6: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC6,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIE_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIE_CFG(0),
++ }, { /* dpmac6: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC6,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIE_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIE_CFG(0),
++ }, { /* dpmac6: 25G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC6,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_dis_mask = LYNX_28G_PCCD_E25GD_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCD_E25GD_CFG(0),
++ }, { /* dpmac7: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC7,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIID_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIID_CFG(0),
++ }, { /* dpmac7: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC7,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIID_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIID_CFG(0),
++ }, { /* dpmac7: 25G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC7,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_dis_mask = LYNX_28G_PCCD_E25GE_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCD_E25GE_CFG(0),
++ }, { /* dpmac8: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC8,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIC_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIC_CFG(0),
++ }, { /* dpmac8: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC8,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIC_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIC_CFG(0),
++ }, { /* dpmac8: 25G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC8,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_dis_mask = LYNX_28G_PCCD_E25GF_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCD_E25GF_CFG(0),
++ }, { /* dpmac9: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC9,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIB_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIB_CFG(0),
++ }, { /* dpmac9: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC9,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIB_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIB_CFG(0),
++ }, { /* dpmac9: 25G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC9,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_dis_mask = LYNX_28G_PCCD_E25GG_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCD_E25GG_CFG(0),
++ }, { /* dpmac10: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC10,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIA_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIA_CFG(0),
++ }, { /* dpmac10: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC10,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIA_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIA_CFG(0),
++ }, { /* dpmac10: 25G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC10,
++ .pcr = LYNX_28G_SDn_BASE(0) + LYNX_28G_PCCD,
++ .pcr_dis_mask = LYNX_28G_PCCD_E25GH_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCD_E25GH_CFG(0),
++ }, { /* dpmac11: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC11,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIA_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIA_CFG(0),
++ }, { /* dpmac12: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC12,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIB_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIB_CFG(0),
++ }, { /* dpmac17: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC17,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIC_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIC_CFG(0),
++ }, { /* dpmac18: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC18,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIID_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIID_CFG(0),
++ }, { /* dpmac15: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC15,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIE_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIE_CFG(0),
++ }, { /* dpmac16: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC16,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIF_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIF_CFG(0),
++ }, { /* dpmac13: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC13,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIG_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIG_CFG(0),
++ }, { /* dpmac13: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC13,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIG_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIG_CFG(0),
++ }, { /* dpmac14: 1G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC14,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCC8,
++ .pcr_dis_mask = LYNX_28G_PCC8_SGMIIH_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCC8_SGMIIH_CFG(0),
++ }, { /* dpmac14: 10G */
++ .devdisr = DCFG_CCSR_BASE + DCFG_CCSR_DEVDISR2,
++ .devdisr_bit = DCFG_CCSR_DEVDISR2_MAC14,
++ .pcr = LYNX_28G_SDn_BASE(1) + LYNX_28G_PCCC,
++ .pcr_dis_mask = LYNX_28G_PCCC_SXGMIIH_CFG_MASK,
++ .pcr_dis_val = LYNX_28G_PCCC_SXGMIIH_CFG(0),
++ },
++ };
++
++ for (int i = 0; i < ARRAY_SIZE(map); i++)
++ if (*map[i].devdisr & map[i].devdisr_bit)
++ *map[i].pcr &= ~map[i].pcr_dis_mask | map[i].pcr_dis_val;
++}
++
+ #ifdef CONFIG_OF_BOARD_FIXUP
+
+ /* fix mac nodes based on serdes protocol */
+--
+2.43.0
+
new file mode 100755
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+BOARD_DIR="$(dirname $0)"
+PARTUUID="$($HOST_DIR/bin/uuidgen)"
+
+install -d "$TARGET_DIR/boot/extlinux/"
+touch "$BINARIES_DIR/boot.scr"
+sed "s/%PARTUUID%/$PARTUUID/g" "$BOARD_DIR/extlinux.conf" > "$TARGET_DIR/boot/extlinux/extlinux.conf"
+sed "s/%PARTUUID%/$PARTUUID/g" "$BOARD_DIR/extlinux.conf" > "$BINARIES_DIR/extlinux.conf"
+sed "s/%PARTUUID%/$PARTUUID/g" "$BOARD_DIR/genimage.cfg" > "$BINARIES_DIR/genimage.cfg"
new file mode 100644
@@ -0,0 +1,142 @@
+*********************
+SolidRun LX2160A-CEx7
+*********************
+
+This file documents the Buildroot support for the NXP Layerscape CEx7 LX2160A
+board made by SolidRun. The CEx7 (COM Express type 7) is a Computer On Module
+which can be plugged into different carrier boards. It is sold either
+separately, or with the HoneyComb LX2 or Clearfog CX LX2 carrier boards, both
+having Mini ITX form factors.
+
+Both the HoneyComb LX2 and Clearfog CX LX2 carrier boards are targeted towards
+networking use cases, with 4 10G-capable SFP+ cages, and the Clearfog
+additionally having a 4x25G-capable QSFP28 cage. In addition, the carrier
+boards have 4x SATA III interfaces, PCIe Gen 3 x8, 2x USB 3.0, an m.2 slot
+compatible with NVMe SSDs, pin headers for traditional PC/NAS cases, and
+regular RJ45 1G Ethernet.
+
+The developer resources for the platform can be found at:
+ - https://solidrun.atlassian.net/wiki/spaces/developer/pages/197493977/NXP+LX2160A+Based+Products
+
+SolidRun keeps build scripts for the firmware on GitHub, which track NXP Linux
+Factory (LF) releases in the form of patches:
+ - https://github.com/SolidRun/lx2160a_build
+
+The most recent functional branch is develop-ls-5.15.71-2.2.0. These patches
+are also included into Buildroot, except for the Linux kernel, where the most
+recent lf-6.6.36-2.1.0 NXP tag is used directly.
+
+The Buildroot support is for the maximal configuration, which is the CEX7
+platform on the Clearfog CX LX2 carrier board.
+
+Set DDR
+=======
+
+At boot, the LX2160 programs its DDR controller from the RCW.
+Select the RCW matching the maximum DDR performance.
+Update the following configuration options:
+
+ BR2_PACKAGE_HOST_QORIQ_RCW_INTREE="lx2160acex7_rev2/clearfog-cx/rcw_2000_700_2600_8_5_2_sdhc.rcw"
+
+where 2600 is for a DDR4 2666.
+
+If you do have the proper settings, you'll likely face such error:
+
+ NOTICE: BL2: v2.10.0 (release):custom
+ NOTICE: BL2: Built : 01:06:19, Sep 4 2025
+ NOTICE: UDIMM TIMETEC-ESD4-2666
+ ERROR: DDR Clk: MCLK cycle is 625 ps.
+ ERROR: DDR Clk is faster than DIMM can support.
+ ERROR: cas latency is too large 41
+ ERROR: Calculating DDR registers failed
+ ERROR: Calculate register error
+ ERROR: DDR init failed.
+ ERROR: Asserting as the DDR is not initialized yet.
+
+Build
+=====
+
+First, configure Buildroot for the LX2160A-CEX7 platform:
+
+ make solidrun_lx2160acex7_defconfig
+
+Build all components:
+
+ make
+
+You will find in output/images/ the following files:
+ - bl2_sd.pbl - RCW + ATF BL2 stage
+ - dpc.dtb
+ - dpl.dtb
+ - fip.bin - U-Boot packaged as ATF payload
+ - fip_ddr.bin - DDR PHY firmware
+ - fsl-lx2160a-clearfog-cx.dtb
+ - fsl-lx2160a-honeycomb.dtb
+ - Image
+ - mc.itb - MC firmware
+ - PBL.bin
+ - rootfs.ext2
+ - rootfs.ext4
+ - sdcard.img
+ - u-boot.bin
+ - uboot-env.bin
+
+Create a bootable SD card
+=========================
+
+To determine the device associated to the SD card have a look in the
+/proc/partitions file:
+
+ cat /proc/partitions
+
+Buildroot prepares a bootable "sdcard.img" image in the output/images/
+directory, ready to be dumped on a SD card. Launch the following
+command as root:
+
+ dd if=output/images/sdcard.img of=/dev/sdX
+
+*** WARNING! This will destroy all the card content. Use with care! ***
+
+For details about the medium image layout, see the definition in
+board/solidrun/lx2160acex7/genimage.cfg.
+
+Boot the LX2160A-CEX7 board
+===========================
+
+To boot your newly created system:
+- configure the DIP switches for SD boot selection as per SolidRun instructions:
+ https://solidrun.atlassian.net/wiki/spaces/developer/pages/197494288/HoneyComb+LX2+ClearFog+CX+LX2+Quick+Start+Guide#Boot-Select
+- insert the Micro-SD card in the Micro-SD slot of the board
+- put a Micro-USB cable into the Micro-USB connector labeled CONSOLE (CON9)
+ and connect using a terminal emulator at 115200 bps, 8n1.
+- power on the board.
+
+The DPL file only contains a static description for the 1G RGMII RJ45 port
+(endpmac17). By default, this will attempt acquire an IP address over DHCP.
+
+The 4 interfaces routed to the SFP+ cages are endpmac7, endpmac8, endpmac9 and
+endpmac10. Among the more usual networking choices, one could create individual
+DPNIs for each MAC:
+
+$ ls-addni dpmac.7 && ls-addni dpmac.8 && ls-addni dpmac.9 && ls-addni dpmac.10
+
+or a DPSW object to accelerate L2 forwarding between them:
+
+$ ls-addsw --num-ifs=4 --max-fdbs=4 --flooding-cfg=DPSW_FLOODING_PER_FDB \
+ --broadcast-cfg=DPSW_BROADCAST_PER_FDB dpmac.7 dpmac.8 dpmac.9 dpmac.10
+$ ip link add br0 type bridge vlan_filtering 1 && ip link set br0 up
+$ for eth in endpmac7 endpmac8 endpmac9 endpmac10; do \
+ ip link set $eth master br0 && ip link set $eth up; done
+
+Once the runtime configuration is satisfactory, it can be converted back into a
+permanent DPL file which can be plugged back into the build system:
+
+$ restool dprc generate-dpl > dpl-new.dts
+
+Networking options through the QSFP28 cage have not yet been investigated.
+
+u-boot notes
+============
+
+It is a basic example that has been mainly tested with a Clearfog board. Should both Honeycomb
+and Cleafog be supported with the same build, we should set CONFIG_OF_LIST with both DTB.
new file mode 100644
@@ -0,0 +1,12 @@
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 1", NAME="endpmac1"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 2", NAME="endpmac2"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 3", NAME="endpmac3"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 4", NAME="endpmac4"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 5", NAME="endpmac5"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 6", NAME="endpmac6"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 7", NAME="endpmac7"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 8", NAME="endpmac8"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 9", NAME="endpmac9"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at a", NAME="endpmac10"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 11", NAME="endpmac17"
+SUBSYSTEM=="net", ACTION=="add|change|online|offline|change", DRIVERS=="fsl_dpaa2_eth|fsl_dpaa2_switch", ENV{OF_FULLNAME}=="/soc/fsl-mc at 80c000000/dpmacs/ethernet at 12", NAME="endpmac18"
new file mode 100644
@@ -0,0 +1,96 @@
+BOARD=lx2160acex7
+arch=arm
+baudrate=115200
+board=lx2160a
+board_name=lx2160a
+boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; env exists secureboot && load ${devtype} ${devnum}:${distro_bootpart} ${scripthdraddr} ${prefix}${boot_script_hdr} && esbc_validate ${scripthdraddr};source ${scriptaddr}
+boot_efi_binary=load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootaa64.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi
+boot_efi_bootmgr=if fdt addr ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr;fi
+boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
+boot_net_usb_start=usb start
+boot_pci_enum=pci enum
+boot_prefixes=/ /boot/
+boot_script_dhcp=boot.scr.uimg
+boot_scripts=boot.scr.uimg boot.scr
+boot_syslinux_conf=extlinux/extlinux.conf
+boot_targets=usb0 mmc0 mmc1 scsi0 nvme0 dhcp
+bootargs=console=ttyAMA0,115200 earlycon=pl011,mmio32,0x21c0000 default_hugepagesz=1024m hugepagesz=1024m hugepages=2 pci=pcie_bus_perf cma=256M iommu.passthrough=1 arm-smmu.disable_bypass=0
+bootcmd=run distro_bootcmd
+bootcmd_dhcp=devtype=dhcp; run boot_net_usb_start; run boot_pci_enum; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; setenv efi_old_vci ${bootp_vci};setenv efi_old_arch ${bootp_arch};setenv bootp_vci PXEClient:Arch:00011:UNDI:003000;setenv bootp_arch 0xb;if dhcp ${kernel_addr_r}; then tftpboot ${fdt_addr_r} dtb/${efi_fdtfile};if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r}; else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi;fi;setenv bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv efi_fdtfile;setenv efi_old_arch;setenv efi_old_vci;
+bootcmd_mmc0=devnum=0; run mmc_boot
+bootcmd_mmc1=devnum=1; run mmc_boot
+bootcmd_nvme0=devnum=0; run nvme_boot
+bootcmd_scsi0=devnum=0; run scsi_boot
+bootcmd_usb0=devnum=0; run usb_boot
+bootdelay=10
+console=ttyAMA0,115200
+cpu=armv8
+distro_bootcmd=scsi_need_init=; setenv nvme_need_init; for target in ${boot_targets}; do run bootcmd_${target}; done
+efi_dtb_prefixes=/ /dtb/ /dtb/current/
+emmc_bootcmd=echo Trying load from emmc card..;mmc dev 1; mmcinfo; mmc read $load_addr $kernel_addr_sd $kernel_size_sd ;env exists secureboot && mmc read $kernelheader_addr_r $kernelhdr_addr_sd $kernelhdr_size_sd && esbc_validate ${kernelheader_addr_r};bootm $load_addr#$BOARD
+eth10addr=00:11:22:44:11:4E
+eth11addr=00:11:22:44:11:4F
+eth12addr=00:11:22:44:11:50
+eth13addr=00:11:22:44:11:51
+eth14addr=00:11:22:44:11:52
+eth15addr=00:11:22:44:11:53
+eth1addr=00:11:22:44:11:45
+eth2addr=00:11:22:44:11:46
+eth3addr=00:11:22:44:11:47
+eth4addr=00:11:22:44:11:48
+eth5addr=00:11:22:44:11:49
+eth6addr=00:11:22:44:11:4A
+eth7addr=00:11:22:44:11:4B
+eth8addr=00:11:22:44:11:4C
+eth9addr=00:11:22:44:11:4D
+ethaddr=00:11:22:44:11:44
+ethprime=DPMAC17@rgmii-id
+fdt_addr=0x81000000
+fdt_addr_r=0x81000000
+fdt_high=0xa0000000
+fdtfile=fsl-lx2160a-clearfog-cx.dtb
+fdtheader_addr_r=0x80100000
+hwconfig=fsl_ddr:bank_intlv=auto
+initrd_high=0xffffffffffffffff
+kernel_addr_r=0x81100000
+kernel_addr_sd=0x8000
+kernel_comp_addr_r=0x9f000000
+kernel_comp_size=0x10000000
+kernel_size=0x2800000
+kernel_size_sd=0x14000
+kernel_start=0x1000000
+kernelhdr_addr_sd=0x3000
+kernelhdr_size_sd=0x20
+kernelheader_addr_r=0x80200000
+kernelheader_size=0x40000
+kernelheader_start=0x600000
+load_addr=0xa0000000
+load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
+lx2160acex7_vdd_mv=800
+dpl_addr_r=0x80d00000
+mc_fw_addr_r=0x80a00000
+dpc_addr_r=0x80e00000
+mcinitcmd=mmcinfo && mmc read $mc_fw_addr_r 0x5000 0x1200 && mmc read $dpc_addr_r 0x7000 0x800 && mmc read $dpl_addr_r 0x6800 0x800 && fsl_mc start mc $mc_fw_addr_r $dpc_addr_r && fsl_mc lazyapply dpl $dpl_addr_r
+mcmemsize=0x70000000
+fsl_bootcmd_mcinitcmd_set=y
+mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
+nvme_boot=run boot_pci_enum; run nvme_init; if nvme dev ${devnum}; then devtype=nvme; run scan_dev_for_boot_part; fi
+nvme_init=if ${nvme_need_init}; then setenv nvme_need_init false; nvme scan; fi
+nvme_need_init=true
+ramdisk_addr=0x85100000
+ramdisk_addr_r=0x85100000
+ramdisk_size=0x2000000
+scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
+scan_dev_for_boot_part=part list ${devtype} ${devnum} devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done
+scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;run boot_efi_bootmgr;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootaa64.efi; then echo Found EFI removable media binary efi/boot/bootaa64.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile
+scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
+scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
+scriptaddr=0x80000000
+scripthdraddr=0x80080000
+scsi_boot=run scsi_init; if scsi dev ${devnum}; then devtype=scsi; run scan_dev_for_boot_part; fi
+scsi_init=if ${scsi_need_init}; then scsi_need_init=false; scsi scan; fi
+sd_bootcmd=echo Trying load from sd card..;mmcinfo; mmc read $load_addr $kernel_addr_sd $kernel_size_sd ;env exists secureboot && mmc read $kernelheader_addr_r $kernelhdr_addr_sd $kernelhdr_size_sd && esbc_validate ${kernelheader_addr_r};bootm $load_addr#$BOARD
+soc=fsl-layerscape
+usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fi
+vendor=solidrun
+xspi_bootcmd=echo Trying load from flexspi..;sf probe 0:0 && sf read $load_addr $kernel_start $kernel_size ; env exists secureboot &&sf read $kernelheader_addr_r $kernelheader_start $kernelheader_size && esbc_validate ${kernelheader_addr_r}; bootm $load_addr#$BOARD
new file mode 100644
@@ -0,0 +1,2 @@
+CONFIG_EFI_LOADER=n
+CONFIG_EFI_PARTITION=n
new file mode 100644
@@ -0,0 +1,56 @@
+BR2_aarch64=y
+BR2_cortex_a72=y
+BR2_KERNEL_HEADERS_6_16=y
+BR2_GLOBAL_PATCH_DIR="board/solidrun/lx2160acex7/patches"
+BR2_TARGET_GENERIC_HOSTNAME="lx2160acex7"
+BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y
+BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0"
+BR2_ROOTFS_OVERLAY="board/solidrun/lx2160acex7/rootfs_overlay"
+BR2_ROOTFS_POST_BUILD_SCRIPT="board/solidrun/lx2160acex7/post-build.sh"
+BR2_ROOTFS_POST_IMAGE_SCRIPT="support/scripts/genimage.sh"
+BR2_ROOTFS_POST_SCRIPT_ARGS="-c $(BINARIES_DIR)/genimage.cfg"
+BR2_LINUX_KERNEL=y
+BR2_LINUX_KERNEL_CUSTOM_VERSION=y
+BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.16.5"
+BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
+BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/solidrun/lx2160acex7/linux.config"
+BR2_LINUX_KERNEL_DTS_SUPPORT=y
+BR2_LINUX_KERNEL_INTREE_DTS_NAME="freescale/fsl-lx2160a-clearfog-cx freescale/fsl-lx2160a-honeycomb"
+BR2_LINUX_KERNEL_INSTALL_TARGET=y
+BR2_PACKAGE_QORIQ_DDR_PHY_BINARY=y
+BR2_PACKAGE_QORIQ_MC_BINARY=y
+BR2_PACKAGE_QORIQ_MC_BINARY_TARGET_LX2160A=y
+BR2_PACKAGE_QORIQ_MC_UTILS=y
+BR2_PACKAGE_QORIQ_MC_UTILS_DPC_CUSTOM_PATH="board/solidrun/lx2160acex7/clearfog-cx-s1_8-s2_0-dpc"
+BR2_PACKAGE_QORIQ_MC_UTILS_DPL_CUSTOM_PATH="board/solidrun/lx2160acex7/clearfog-cx-s1_8-s2_0-dpl"
+BR2_PACKAGE_QORIQ_MC_UTILS_TARGET_INSTALL_PATH="usr/share/mc/"
+BR2_PACKAGE_QORIQ_RESTOOL=y
+BR2_TARGET_ROOTFS_CPIO=y
+BR2_TARGET_ROOTFS_CPIO_GZIP=y
+BR2_TARGET_ROOTFS_EXT2=y
+BR2_TARGET_ROOTFS_EXT2_4=y
+BR2_TARGET_ROOTFS_EXT2_SIZE="130M"
+BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
+BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y
+BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="c48c11e7b7a04e2647e96df7ad7630020a494831"
+BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="lx2160acex7"
+BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
+BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
+BR2_TARGET_ARM_TRUSTED_FIRMWARE_RCW=y
+BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="BOOT_MODE=sd"
+BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="*.bin *.pbl"
+BR2_TARGET_UBOOT=y
+BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
+BR2_TARGET_UBOOT_FORMAT_DTB=y
+BR2_TARGET_UBOOT_CUSTOM_VERSION=y
+BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2025.07"
+BR2_TARGET_UBOOT_BOARD_DEFCONFIG="lx2160acex7_tfa"
+BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="board/solidrun/lx2160acex7/u-boot.config"
+BR2_TARGET_UBOOT_NEEDS_DTC=y
+BR2_PACKAGE_HOST_GENIMAGE=y
+BR2_PACKAGE_HOST_QORIQ_RCW=y
+BR2_PACKAGE_HOST_QORIQ_RCW_INTREE="lx2160acex7_rev2/clearfog-cx/rcw_2000_700_2600_8_5_2_sdhc.rcw"
+BR2_PACKAGE_HOST_UBOOT_TOOLS=y
+BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE=y
+BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE_SOURCE="board/solidrun/lx2160acex7/u-boot-environment-sd.txt"
+BR2_PACKAGE_HOST_UBOOT_TOOLS_ENVIMAGE_SIZE="0x2000"